aboutsummaryrefslogtreecommitdiffstats
path: root/src/libmime/smtp_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libmime/smtp_utils.c')
-rw-r--r--src/libmime/smtp_utils.c218
1 files changed, 147 insertions, 71 deletions
diff --git a/src/libmime/smtp_utils.c b/src/libmime/smtp_utils.c
index 8ed169fa7..606d7de51 100644
--- a/src/libmime/smtp_utils.c
+++ b/src/libmime/smtp_utils.c
@@ -30,7 +30,7 @@
void
free_smtp_session (gpointer arg)
{
- struct smtp_session *session = arg;
+ struct smtp_session *session = arg;
if (session) {
if (session->task) {
@@ -60,12 +60,17 @@ free_smtp_session (gpointer arg)
gboolean
create_smtp_upstream_connection (struct smtp_session *session)
{
- struct smtp_upstream *selected;
+ struct smtp_upstream *selected;
/* Try to select upstream */
- selected = (struct smtp_upstream *)get_upstream_round_robin (session->ctx->upstreams,
- session->ctx->upstream_num, sizeof (struct smtp_upstream),
- session->session_time, DEFAULT_UPSTREAM_ERROR_TIME, DEFAULT_UPSTREAM_DEAD_TIME, DEFAULT_UPSTREAM_MAXERRORS);
+ selected = (struct smtp_upstream *)get_upstream_round_robin (
+ session->ctx->upstreams,
+ session->ctx->upstream_num,
+ sizeof (struct smtp_upstream),
+ session->session_time,
+ DEFAULT_UPSTREAM_ERROR_TIME,
+ DEFAULT_UPSTREAM_DEAD_TIME,
+ DEFAULT_UPSTREAM_MAXERRORS);
if (selected == NULL) {
msg_err ("no upstreams suitable found");
return FALSE;
@@ -74,19 +79,32 @@ create_smtp_upstream_connection (struct smtp_session *session)
session->upstream = selected;
/* Now try to create socket */
- session->upstream_sock = make_universal_socket (selected->addr, selected->port, SOCK_STREAM, TRUE, FALSE, FALSE);
+ session->upstream_sock = make_universal_socket (selected->addr,
+ selected->port,
+ SOCK_STREAM,
+ TRUE,
+ FALSE,
+ FALSE);
if (session->upstream_sock == -1) {
msg_err ("cannot make a connection to %s", selected->name);
upstream_fail (&selected->up, session->session_time);
return FALSE;
}
/* Create a dispatcher for upstream connection */
- session->upstream_dispatcher = rspamd_create_dispatcher (session->ev_base, session->upstream_sock, BUFFER_LINE,
- smtp_upstream_read_socket, smtp_upstream_write_socket, smtp_upstream_err_socket,
- &session->ctx->smtp_timeout, session);
+ session->upstream_dispatcher = rspamd_create_dispatcher (session->ev_base,
+ session->upstream_sock,
+ BUFFER_LINE,
+ smtp_upstream_read_socket,
+ smtp_upstream_write_socket,
+ smtp_upstream_err_socket,
+ &session->ctx->smtp_timeout,
+ session);
session->state = SMTP_STATE_WAIT_UPSTREAM;
session->upstream_state = SMTP_STATE_GREETING;
- register_async_event (session->s, (event_finalizer_t)smtp_upstream_finalize_connection, session, g_quark_from_static_string ("smtp proxy"));
+ register_async_event (session->s,
+ (event_finalizer_t)smtp_upstream_finalize_connection,
+ session,
+ g_quark_from_static_string ("smtp proxy"));
return TRUE;
}
@@ -98,7 +116,8 @@ smtp_send_upstream_message (struct smtp_session *session)
session->upstream_state = SMTP_STATE_IN_SENDFILE;
session->state = SMTP_STATE_WAIT_UPSTREAM;
- if (! rspamd_dispatcher_sendfile (session->upstream_dispatcher, session->temp_fd, session->temp_size)) {
+ if (!rspamd_dispatcher_sendfile (session->upstream_dispatcher,
+ session->temp_fd, session->temp_size)) {
msg_err ("sendfile failed: %s", strerror (errno));
goto err;
}
@@ -107,7 +126,8 @@ smtp_send_upstream_message (struct smtp_session *session)
err:
session->error = SMTP_ERROR_FILE;
session->state = SMTP_STATE_CRITICAL_ERROR;
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE,
+ TRUE)) {
return FALSE;
}
destroy_session (session->s);
@@ -115,32 +135,35 @@ err:
}
struct smtp_metric_callback_data {
- struct smtp_session *session;
- enum rspamd_metric_action action;
- struct metric_result *res;
- gchar *log_buf;
- gint log_offset;
- gint log_size;
- gboolean alive;
+ struct smtp_session *session;
+ enum rspamd_metric_action action;
+ struct metric_result *res;
+ gchar *log_buf;
+ gint log_offset;
+ gint log_size;
+ gboolean alive;
};
static void
smtp_metric_symbols_callback (gpointer key, gpointer value, void *user_data)
{
- struct smtp_metric_callback_data *cd = user_data;
+ struct smtp_metric_callback_data *cd = user_data;
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "%s,", (gchar *)key);
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "%s,",
+ (gchar *)key);
}
static void
smtp_metric_callback (gpointer key, gpointer value, gpointer ud)
{
struct smtp_metric_callback_data *cd = ud;
- struct metric_result *metric_res = value;
- enum rspamd_metric_action action = METRIC_ACTION_NOACTION;
- double ms = 0, rs = 0;
- gboolean is_spam = FALSE;
- struct rspamd_task *task;
+ struct metric_result *metric_res = value;
+ enum rspamd_metric_action action = METRIC_ACTION_NOACTION;
+ double ms = 0, rs = 0;
+ gboolean is_spam = FALSE;
+ struct rspamd_task *task;
task = cd->session->task;
@@ -152,8 +175,10 @@ smtp_metric_callback (gpointer key, gpointer value, gpointer ud)
ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
rs = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
}
- if (! check_metric_action_settings (task, metric_res, metric_res->score, &action)) {
- action = check_metric_action (metric_res->score, ms, metric_res->metric);
+ if (!check_metric_action_settings (task, metric_res, metric_res->score,
+ &action)) {
+ action =
+ check_metric_action (metric_res->score, ms, metric_res->metric);
}
#endif
if (metric_res->score >= ms) {
@@ -165,42 +190,70 @@ smtp_metric_callback (gpointer key, gpointer value, gpointer ud)
}
if (!task->is_skipped) {
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "(%s: %c (%s): [%.2f/%.2f/%.2f] [",
- (gchar *)key, is_spam ? 'T' : 'F', str_action_metric (action), metric_res->score, ms, rs);
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "(%s: %c (%s): [%.2f/%.2f/%.2f] [",
+ (gchar *)key,
+ is_spam ? 'T' : 'F',
+ str_action_metric (action),
+ metric_res->score,
+ ms,
+ rs);
}
else {
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "(%s: %c (default): [%.2f/%.2f/%.2f] [",
- (gchar *)key, 'S', metric_res->score, ms, rs);
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "(%s: %c (default): [%.2f/%.2f/%.2f] [",
+ (gchar *)key,
+ 'S',
+ metric_res->score,
+ ms,
+ rs);
}
- g_hash_table_foreach (metric_res->symbols, smtp_metric_symbols_callback, cd);
+ g_hash_table_foreach (metric_res->symbols, smtp_metric_symbols_callback,
+ cd);
/* Remove last , from log buf */
if (cd->log_buf[cd->log_offset - 1] == ',') {
cd->log_buf[--cd->log_offset] = '\0';
}
#ifdef HAVE_CLOCK_GETTIME
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "]), len: %z, time: %s,",
- task->msg->len, calculate_check_time (&task->tv, &task->ts, task->cfg->clock_res, &task->scan_milliseconds));
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "]), len: %z, time: %s,",
+ task->msg->len,
+ calculate_check_time (&task->tv, &task->ts, task->cfg->clock_res,
+ &task->scan_milliseconds));
#else
- cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset, cd->log_size - cd->log_offset, "]), len: %z, time: %s,",
- task->msg->len, calculate_check_time (&task->tv, task->cfg->clock_res, &task->scan_milliseconds));
+ cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
+ cd->log_size - cd->log_offset,
+ "]), len: %z, time: %s,",
+ task->msg->len,
+ calculate_check_time (&task->tv, task->cfg->clock_res,
+ &task->scan_milliseconds));
#endif
}
gboolean
make_smtp_tempfile (struct smtp_session *session)
{
- gsize r;
+ gsize r;
r = strlen (session->cfg->temp_dir) + sizeof ("/rspamd-XXXXXX");
session->temp_name = rspamd_mempool_alloc (session->pool, r);
- rspamd_snprintf (session->temp_name, r, "%s%crspamd-XXXXXX", session->cfg->temp_dir, G_DIR_SEPARATOR);
+ rspamd_snprintf (session->temp_name,
+ r,
+ "%s%crspamd-XXXXXX",
+ session->cfg->temp_dir,
+ G_DIR_SEPARATOR);
#ifdef HAVE_MKSTEMP
/* Umask is set before */
session->temp_fd = mkstemp (session->temp_name);
#else
- session->temp_fd = g_mkstemp_full (session->temp_name, O_RDWR, S_IWUSR | S_IRUSR);
+ session->temp_fd = g_mkstemp_full (session->temp_name,
+ O_RDWR,
+ S_IWUSR | S_IRUSR);
#endif
if (session->temp_fd == -1) {
msg_err ("mkstemp error: %s", strerror (errno));
@@ -214,23 +267,28 @@ make_smtp_tempfile (struct smtp_session *session)
gboolean
write_smtp_reply (struct smtp_session *session)
{
- gchar logbuf[1024], *new_subject;
- const gchar *old_subject;
+ gchar logbuf[1024], *new_subject;
+ const gchar *old_subject;
struct smtp_metric_callback_data cd;
- GMimeStream *stream;
- gint old_fd, sublen;
+ GMimeStream *stream;
+ gint old_fd, sublen;
/* Check metrics */
cd.session = session;
cd.action = METRIC_ACTION_NOACTION;
cd.res = NULL;
cd.log_buf = logbuf;
- cd.log_offset = rspamd_snprintf (logbuf, sizeof (logbuf), "id: <%s>, qid: <%s>, ",
- session->task->message_id, session->task->queue_id);
+ cd.log_offset = rspamd_snprintf (logbuf,
+ sizeof (logbuf),
+ "id: <%s>, qid: <%s>, ",
+ session->task->message_id,
+ session->task->queue_id);
cd.log_size = sizeof (logbuf);
if (session->task->user) {
- cd.log_offset += rspamd_snprintf (logbuf + cd.log_offset, sizeof (logbuf) - cd.log_offset,
- "user: %s, ", session->task->user);
+ cd.log_offset += rspamd_snprintf (logbuf + cd.log_offset,
+ sizeof (logbuf) - cd.log_offset,
+ "user: %s, ",
+ session->task->user);
}
g_hash_table_foreach (session->task->results, smtp_metric_callback, &cd);
@@ -238,22 +296,26 @@ write_smtp_reply (struct smtp_session *session)
msg_info ("%s", logbuf);
if (cd.action <= METRIC_ACTION_REJECT) {
- if (! rspamd_dispatcher_write (session->dispatcher, session->ctx->reject_message, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher,
+ session->ctx->reject_message, 0, FALSE, TRUE)) {
return FALSE;
}
- if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) -
+ 1, FALSE, TRUE)) {
return FALSE;
}
destroy_session (session->s);
return FALSE;
}
- else if (cd.action <= METRIC_ACTION_ADD_HEADER || cd.action <= METRIC_ACTION_REWRITE_SUBJECT) {
+ else if (cd.action <= METRIC_ACTION_ADD_HEADER || cd.action <=
+ METRIC_ACTION_REWRITE_SUBJECT) {
old_fd = session->temp_fd;
- if (! make_smtp_tempfile (session)) {
+ if (!make_smtp_tempfile (session)) {
session->error = SMTP_ERROR_FILE;
session->state = SMTP_STATE_CRITICAL_ERROR;
rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ 0, FALSE, TRUE)) {
goto err;
}
destroy_session (session->s);
@@ -266,7 +328,11 @@ write_smtp_reply (struct smtp_session *session)
if (old_subject != NULL) {
sublen = strlen (old_subject) + sizeof (SPAM_SUBJECT);
new_subject = rspamd_mempool_alloc (session->pool, sublen);
- rspamd_snprintf (new_subject, sublen, "%s%s", SPAM_SUBJECT, old_subject);
+ rspamd_snprintf (new_subject,
+ sublen,
+ "%s%s",
+ SPAM_SUBJECT,
+ old_subject);
}
else {
new_subject = SPAM_SUBJECT;
@@ -275,21 +341,26 @@ write_smtp_reply (struct smtp_session *session)
}
else if (cd.action <= METRIC_ACTION_ADD_HEADER) {
#ifndef GMIME24
- g_mime_message_add_header (session->task->message, "X-Spam", "true");
+ g_mime_message_add_header (session->task->message, "X-Spam",
+ "true");
#else
- g_mime_object_append_header (GMIME_OBJECT (session->task->message), "X-Spam", "true");
+ g_mime_object_append_header (GMIME_OBJECT (
+ session->task->message), "X-Spam", "true");
#endif
}
stream = g_mime_stream_fs_new (session->temp_fd);
g_mime_stream_fs_set_owner (GMIME_STREAM_FS (stream), FALSE);
close (old_fd);
- if (g_mime_object_write_to_stream (GMIME_OBJECT (session->task->message), stream) == -1) {
- msg_err ("cannot write MIME object to stream: %s", strerror (errno));
+ if (g_mime_object_write_to_stream (GMIME_OBJECT (session->task->message),
+ stream) == -1) {
+ msg_err ("cannot write MIME object to stream: %s",
+ strerror (errno));
session->error = SMTP_ERROR_FILE;
session->state = SMTP_STATE_CRITICAL_ERROR;
rspamd_dispatcher_restore (session->dispatcher);
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error,
+ 0, FALSE, TRUE)) {
goto err;
}
destroy_session (session->s);
@@ -302,7 +373,8 @@ write_smtp_reply (struct smtp_session *session)
err:
session->error = SMTP_ERROR_FILE;
session->state = SMTP_STATE_CRITICAL_ERROR;
- if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE,
+ TRUE)) {
return FALSE;
}
destroy_session (session->s);
@@ -310,29 +382,33 @@ err:
}
gboolean
-parse_upstreams_line (rspamd_mempool_t *pool, struct smtp_upstream *upstreams, const gchar *line, gsize *count)
+parse_upstreams_line (rspamd_mempool_t *pool,
+ struct smtp_upstream *upstreams,
+ const gchar *line,
+ gsize *count)
{
- gchar **strv, *p, *t, *tt, *err_str;
- guint32 num, i;
- struct smtp_upstream *cur;
- gchar resolved_path[PATH_MAX];
+ gchar **strv, *p, *t, *tt, *err_str;
+ guint32 num, i;
+ struct smtp_upstream *cur;
+ gchar resolved_path[PATH_MAX];
strv = g_strsplit_set (line, ",; ", -1);
num = g_strv_length (strv);
if (num >= MAX_SMTP_UPSTREAMS) {
- msg_err ("cannot define %d upstreams %d is max", num, MAX_SMTP_UPSTREAMS);
+ msg_err ("cannot define %d upstreams %d is max", num,
+ MAX_SMTP_UPSTREAMS);
return FALSE;
}
*count = 0;
- for (i = 0; i < num; i ++) {
+ for (i = 0; i < num; i++) {
p = strv[i];
cur = &upstreams[*count];
if ((t = strrchr (p, ':')) != NULL && (tt = strchr (p, ':')) != t) {
/* Assume that after last `:' we have weigth */
*t = '\0';
- t ++;
+ t++;
errno = 0;
cur->up.priority = strtoul (t, &err_str, 10);
if (errno != 0 || (err_str && *err_str != '\0')) {
@@ -349,15 +425,15 @@ parse_upstreams_line (rspamd_mempool_t *pool, struct smtp_upstream *upstreams, c
return FALSE;
}
cur->name = rspamd_mempool_strdup (pool, resolved_path);
- (*count) ++;
+ (*count)++;
}
else {
- if (! rspamd_parse_host_port (pool, p, &cur->addr, &cur->port)) {
+ if (!rspamd_parse_host_port (pool, p, &cur->addr, &cur->port)) {
g_strfreev (strv);
return FALSE;
}
cur->name = rspamd_mempool_strdup (pool, p);
- (*count) ++;
+ (*count)++;
}
}