diff options
Diffstat (limited to 'src/libmime')
-rw-r--r-- | src/libmime/expressions.c | 553 | ||||
-rw-r--r-- | src/libmime/expressions.h | 53 | ||||
-rw-r--r-- | src/libmime/filter.c | 529 | ||||
-rw-r--r-- | src/libmime/filter.h | 68 | ||||
-rw-r--r-- | src/libmime/images.c | 56 | ||||
-rw-r--r-- | src/libmime/images.h | 2 | ||||
-rw-r--r-- | src/libmime/message.c | 918 | ||||
-rw-r--r-- | src/libmime/message.h | 17 | ||||
-rw-r--r-- | src/libmime/smtp_proto.c | 799 | ||||
-rw-r--r-- | src/libmime/smtp_proto.h | 24 | ||||
-rw-r--r-- | src/libmime/smtp_utils.c | 220 | ||||
-rw-r--r-- | src/libmime/smtp_utils.h | 5 |
12 files changed, 1258 insertions, 1986 deletions
diff --git a/src/libmime/expressions.c b/src/libmime/expressions.c index c17388315..5d19626bb 100644 --- a/src/libmime/expressions.c +++ b/src/libmime/expressions.c @@ -22,56 +22,36 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "cfg_file.h" #include "config.h" -#include "diff.h" -#include "expressions.h" +#include "util.h" +#include "cfg_file.h" +#include "main.h" +#include "message.h" #include "fuzzy.h" +#include "expressions.h" #include "html.h" #include "lua/lua_common.h" -#include "main.h" -#include "message.h" -#include "util.h" +#include "diff.h" -gboolean rspamd_compare_encoding (struct rspamd_task *task, - GList * args, - void *unused); -gboolean rspamd_header_exists (struct rspamd_task *task, - GList * args, - void *unused); -gboolean rspamd_parts_distance (struct rspamd_task *task, - GList * args, - void *unused); -gboolean rspamd_recipients_distance (struct rspamd_task *task, - GList * args, - void *unused); -gboolean rspamd_has_only_html_part (struct rspamd_task *task, - GList * args, - void *unused); -gboolean rspamd_is_recipients_sorted (struct rspamd_task *task, - GList * args, - void *unused); -gboolean rspamd_compare_transfer_encoding (struct rspamd_task *task, - GList * args, - void *unused); -gboolean rspamd_is_html_balanced (struct rspamd_task *task, - GList * args, - void *unused); -gboolean rspamd_has_html_tag (struct rspamd_task *task, - GList * args, - void *unused); -gboolean rspamd_has_fake_html (struct rspamd_task *task, - GList * args, - void *unused); +gboolean rspamd_compare_encoding (struct rspamd_task *task, GList * args, void *unused); +gboolean rspamd_header_exists (struct rspamd_task *task, GList * args, void *unused); +gboolean rspamd_parts_distance (struct rspamd_task *task, GList * args, void *unused); +gboolean rspamd_recipients_distance (struct rspamd_task *task, GList * args, void *unused); +gboolean rspamd_has_only_html_part (struct rspamd_task *task, GList * args, void *unused); +gboolean rspamd_is_recipients_sorted (struct rspamd_task *task, GList * args, void *unused); +gboolean rspamd_compare_transfer_encoding (struct rspamd_task *task, GList * args, void *unused); +gboolean rspamd_is_html_balanced (struct rspamd_task *task, GList * args, void *unused); +gboolean rspamd_has_html_tag (struct rspamd_task *task, GList * args, void *unused); +gboolean rspamd_has_fake_html (struct rspamd_task *task, GList * args, void *unused); /* * List of internal functions of rspamd * Sorted by name to use bsearch */ static struct _fl { - const gchar *name; - rspamd_internal_func_t func; - void *user_data; + const gchar *name; + rspamd_internal_func_t func; + void *user_data; } rspamd_functions_list[] = { {"compare_encoding", rspamd_compare_encoding, NULL}, {"compare_parts_distance", rspamd_parts_distance, NULL}, @@ -85,32 +65,30 @@ static struct _fl { {"is_recipients_sorted", rspamd_is_recipients_sorted, NULL} }; -static struct _fl *list_ptr = &rspamd_functions_list[0]; -static guint32 functions_number = sizeof (rspamd_functions_list) / - sizeof (struct _fl); -static gboolean list_allocated = FALSE; +static struct _fl *list_ptr = &rspamd_functions_list[0]; +static guint32 functions_number = sizeof (rspamd_functions_list) / sizeof (struct _fl); +static gboolean list_allocated = FALSE; /* Bsearch routine */ static gint fl_cmp (const void *s1, const void *s2) { - struct _fl *fl1 = (struct _fl *)s1; - struct _fl *fl2 = (struct _fl *)s2; + struct _fl *fl1 = (struct _fl *)s1; + struct _fl *fl2 = (struct _fl *)s2; return strcmp (fl1->name, fl2->name); } /* Cache for regular expressions that are used in functions */ -void * +void * re_cache_check (const gchar *line, rspamd_mempool_t *pool) { - GHashTable *re_cache; - + GHashTable *re_cache; + re_cache = rspamd_mempool_get_variable (pool, "re_cache"); if (re_cache == NULL) { re_cache = g_hash_table_new (rspamd_str_hash, rspamd_str_equal); - rspamd_mempool_set_variable (pool, "re_cache", re_cache, - (rspamd_mempool_destruct_t)g_hash_table_destroy); + rspamd_mempool_set_variable (pool, "re_cache", re_cache, (rspamd_mempool_destruct_t)g_hash_table_destroy); return NULL; } return g_hash_table_lookup (re_cache, line); @@ -119,14 +97,13 @@ re_cache_check (const gchar *line, rspamd_mempool_t *pool) void re_cache_add (const gchar *line, void *pointer, rspamd_mempool_t *pool) { - GHashTable *re_cache; - + GHashTable *re_cache; + re_cache = rspamd_mempool_get_variable (pool, "re_cache"); if (re_cache == NULL) { re_cache = g_hash_table_new (rspamd_str_hash, rspamd_str_equal); - rspamd_mempool_set_variable (pool, "re_cache", re_cache, - (rspamd_mempool_destruct_t)g_hash_table_destroy); + rspamd_mempool_set_variable (pool, "re_cache", re_cache, (rspamd_mempool_destruct_t)g_hash_table_destroy); } g_hash_table_insert (re_cache, (gpointer)line, pointer); @@ -135,7 +112,7 @@ re_cache_add (const gchar *line, void *pointer, rspamd_mempool_t *pool) void re_cache_del (const gchar *line, rspamd_mempool_t *pool) { - GHashTable *re_cache; + GHashTable *re_cache; re_cache = rspamd_mempool_get_variable (pool, "re_cache"); @@ -149,19 +126,17 @@ re_cache_del (const gchar *line, rspamd_mempool_t *pool) * Functions for parsing expressions */ struct expression_stack { - gchar op; - struct expression_stack *next; + gchar op; + struct expression_stack *next; }; /* - * Push operand or operator to stack + * Push operand or operator to stack */ static struct expression_stack * -push_expression_stack (rspamd_mempool_t * pool, - struct expression_stack *head, - gchar op) +push_expression_stack (rspamd_mempool_t * pool, struct expression_stack *head, gchar op) { - struct expression_stack *new; + struct expression_stack *new; new = rspamd_mempool_alloc (pool, sizeof (struct expression_stack)); new->op = op; new->next = head; @@ -174,8 +149,8 @@ push_expression_stack (rspamd_mempool_t * pool, static gchar delete_expression_stack (struct expression_stack **head) { - struct expression_stack *cur; - gchar res; + struct expression_stack *cur; + gchar res; if (*head == NULL) return 0; @@ -210,7 +185,7 @@ logic_priority (gchar a) * Return FALSE if symbol is not operation symbol (operand) * Return TRUE if symbol is operation symbol */ -static gboolean +static gboolean is_operation_symbol (gchar *a) { switch (*a) { @@ -222,22 +197,19 @@ is_operation_symbol (gchar *a) return TRUE; case 'O': case 'o': - if (g_ascii_strncasecmp (a, "or", - sizeof ("or") - 1) == 0 && g_ascii_isspace (a[2])) { + if (g_ascii_strncasecmp (a, "or", sizeof ("or") - 1) == 0&& g_ascii_isspace (a[2])) { return TRUE; } break; case 'A': case 'a': - if (g_ascii_strncasecmp (a, "and", - sizeof ("and") - 1) == 0 && g_ascii_isspace (a[3])) { + if (g_ascii_strncasecmp (a, "and", sizeof ("and") - 1) == 0&& g_ascii_isspace (a[3])) { return TRUE; } break; case 'N': case 'n': - if (g_ascii_strncasecmp (a, "not", - sizeof ("not") - 1) == 0 && g_ascii_isspace (a[3])) { + if (g_ascii_strncasecmp (a, "not", sizeof ("not") - 1) == 0 && g_ascii_isspace (a[3])) { return TRUE; } break; @@ -287,7 +259,7 @@ op_to_char (gchar *a, gchar **next) /* * Return TRUE if symbol can be regexp flag */ -static gboolean +static gboolean is_regexp_flag (gchar a) { switch (a) { @@ -312,14 +284,9 @@ is_regexp_flag (gchar a) } static void -insert_expression (rspamd_mempool_t * pool, - struct expression **head, - gint type, - gchar op, - void *operand, - const gchar *orig) +insert_expression (rspamd_mempool_t * pool, struct expression **head, gint type, gchar op, void *operand, const gchar *orig) { - struct expression *new, *cur; + struct expression *new, *cur; new = rspamd_mempool_alloc (pool, sizeof (struct expression)); new->type = type; @@ -344,11 +311,11 @@ insert_expression (rspamd_mempool_t * pool, } } -static struct expression * +static struct expression * maybe_parse_expression (rspamd_mempool_t * pool, gchar *line) { - struct expression *expr; - gchar *p = line; + struct expression *expr; + gchar *p = line; while (*p) { if (is_operation_symbol (p)) { @@ -369,17 +336,17 @@ maybe_parse_expression (rspamd_mempool_t * pool, gchar *line) * Make inverse polish record for specified expression * Memory is allocated from given pool */ -struct expression * +struct expression * parse_expression (rspamd_mempool_t * pool, gchar *line) { - struct expression *expr = NULL; - struct expression_stack *stack = NULL; - struct expression_function *func = NULL; - struct expression *arg; - GQueue *function_stack; - gchar *p, *c, *str, op, newop, *copy, *next; - gboolean in_regexp = FALSE; - gint brackets = 0; + struct expression *expr = NULL; + struct expression_stack *stack = NULL; + struct expression_function *func = NULL; + struct expression *arg; + GQueue *function_stack; + gchar *p, *c, *str, op, newop, *copy, *next; + gboolean in_regexp = FALSE; + gint brackets = 0; enum { SKIP_SPACES, @@ -429,12 +396,7 @@ parse_expression (rspamd_mempool_t * pool, gchar *line) while (stack && stack->op != '(') { op = delete_expression_stack (&stack); if (op != '(') { - insert_expression (pool, - &expr, - EXPR_OPERATION, - op, - NULL, - copy); + insert_expression (pool, &expr, EXPR_OPERATION, op, NULL, copy); } } if (stack) { @@ -459,23 +421,15 @@ parse_expression (rspamd_mempool_t * pool, gchar *line) else { newop = op_to_char (p, &next); if (newop != '\0') { - if (logic_priority (stack->op) < - logic_priority (newop)) { + if (logic_priority (stack->op) < logic_priority (newop)) { stack = push_expression_stack (pool, stack, newop); } else { /* Pop all operations that have higher priority than this one */ - while ((stack != NULL) && - (logic_priority (stack->op) >= - logic_priority (newop))) { + while ((stack != NULL) && (logic_priority (stack->op) >= logic_priority (newop))) { op = delete_expression_stack (&stack); if (op != '(') { - insert_expression (pool, - &expr, - EXPR_OPERATION, - op, - NULL, - copy); + insert_expression (pool, &expr, EXPR_OPERATION, op, NULL, copy); } } stack = push_expression_stack (pool, stack, newop); @@ -505,8 +459,7 @@ parse_expression (rspamd_mempool_t * pool, gchar *line) case READ_REGEXP_FLAGS: if (!is_regexp_flag (*p) || *(p + 1) == '\0') { if (c != p) { - if ((is_regexp_flag (*p) || *p == - '/') && *(p + 1) == '\0') { + if ((is_regexp_flag (*p) || *p == '/') && *(p + 1) == '\0') { p++; } str = rspamd_mempool_alloc (pool, p - c + 2); @@ -514,12 +467,7 @@ parse_expression (rspamd_mempool_t * pool, gchar *line) g_strstrip (str); msg_debug ("found regexp: %s", str); if (strlen (str) > 0) { - insert_expression (pool, - &expr, - EXPR_REGEXP, - 0, - str, - copy); + insert_expression (pool, &expr, EXPR_REGEXP, 0, str, copy); } } c = p; @@ -538,9 +486,7 @@ parse_expression (rspamd_mempool_t * pool, gchar *line) p++; } else if (*p == '(') { - func = - rspamd_mempool_alloc (pool, - sizeof (struct expression_function)); + func = rspamd_mempool_alloc (pool, sizeof (struct expression_function)); func->name = rspamd_mempool_alloc (pool, p - c + 1); func->args = NULL; rspamd_strlcpy (func->name, c, (p - c + 1)); @@ -640,14 +586,14 @@ parse_expression (rspamd_mempool_t * pool, gchar *line) /* * Rspamd regexp utility functions */ -struct rspamd_regexp * +struct rspamd_regexp * parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode) { - const gchar *begin, *end, *p, *src, *start; - gchar *dbegin, *dend; - struct rspamd_regexp *result, *check; - gint regexp_flags = G_REGEX_OPTIMIZE | G_REGEX_NO_AUTO_CAPTURE; - GError *err = NULL; + const gchar *begin, *end, *p, *src, *start; + gchar *dbegin, *dend; + struct rspamd_regexp *result, *check; + gint regexp_flags = G_REGEX_OPTIMIZE | G_REGEX_NO_AUTO_CAPTURE; + GError *err = NULL; if (line == NULL) { msg_err ("cannot parse NULL line"); @@ -675,7 +621,7 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode) end = p; break; } - p--; + p --; } if (end) { result->header = rspamd_mempool_alloc (pool, end - line + 1); @@ -704,9 +650,7 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode) } else { /* We got header name earlier but have not found // expression, so it is invalid regexp */ - msg_warn ( - "got no header name (eg. header=) but without corresponding regexp, %s", - src); + msg_warn ("got no header name (eg. header=) but without corresponding regexp, %s", src); return NULL; } /* Find end */ @@ -751,7 +695,7 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode) result->is_raw = TRUE; p++; break; - /* Type flags */ + /* Type flags */ case 'H': if (result->type == REGEXP_NONE) { result->type = REGEXP_HEADER; @@ -784,13 +728,13 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode) break; case 'T': result->is_test = TRUE; - p++; + p ++; break; case 'S': result->is_strong = TRUE; - p++; + p ++; break; - /* Stop flags parsing */ + /* Stop flags parsing */ default: p = NULL; break; @@ -807,12 +751,9 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode) } /* Avoid multiply regexp structures for similar regexps */ - if ((check = - (struct rspamd_regexp *)re_cache_check (result->regexp_text, - pool)) != NULL) { + if ((check = (struct rspamd_regexp *)re_cache_check (result->regexp_text, pool)) != NULL) { /* Additional check for headers */ - if (result->type == REGEXP_HEADER || result->type == - REGEXP_RAW_HEADER) { + if (result->type == REGEXP_HEADER || result->type == REGEXP_RAW_HEADER) { if (result->header && check->header) { if (strcmp (result->header, check->header) == 0) { return check; @@ -828,31 +769,20 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode) result->raw_regexp = result->regexp; } else { - result->raw_regexp = g_regex_new (dbegin, - regexp_flags | G_REGEX_RAW, - 0, - &err); - rspamd_mempool_add_destructor (pool, - (rspamd_mempool_destruct_t) g_regex_unref, - (void *)result->raw_regexp); - } - rspamd_mempool_add_destructor (pool, - (rspamd_mempool_destruct_t) g_regex_unref, - (void *)result->regexp); + result->raw_regexp = g_regex_new (dbegin, regexp_flags | G_REGEX_RAW, 0, &err); + rspamd_mempool_add_destructor (pool, (rspamd_mempool_destruct_t) g_regex_unref, (void *)result->raw_regexp); + } + rspamd_mempool_add_destructor (pool, (rspamd_mempool_destruct_t) g_regex_unref, (void *)result->regexp); *dend = '/'; if (result->regexp == NULL || err != NULL) { - msg_warn ("could not read regexp: %s while reading regexp %s", - err->message, - src); + msg_warn ("could not read regexp: %s while reading regexp %s", err->message, src); return NULL; } if (result->raw_regexp == NULL || err != NULL) { - msg_warn ("could not read raw regexp: %s while reading regexp %s", - err->message, - src); + msg_warn ("could not read raw regexp: %s while reading regexp %s", err->message, src); return NULL; } @@ -862,19 +792,13 @@ parse_regexp (rspamd_mempool_t * pool, const gchar *line, gboolean raw_mode) } gboolean -call_expression_function (struct expression_function * func, - struct rspamd_task * task, - lua_State *L) +call_expression_function (struct expression_function * func, struct rspamd_task * task, lua_State *L) { - struct _fl *selected, key; + struct _fl *selected, key; key.name = func->name; - selected = bsearch (&key, - list_ptr, - functions_number, - sizeof (struct _fl), - fl_cmp); + selected = bsearch (&key, list_ptr, functions_number, sizeof (struct _fl), fl_cmp); if (selected == NULL) { /* Try to check lua function */ return FALSE; @@ -883,26 +807,21 @@ call_expression_function (struct expression_function * func, return selected->func (task, func->args, selected->user_data); } -struct expression_argument * -get_function_arg (struct expression *expr, - struct rspamd_task *task, - gboolean want_string) +struct expression_argument * +get_function_arg (struct expression *expr, struct rspamd_task *task, gboolean want_string) { - GQueue *stack; - gsize cur, op1, op2; - struct expression_argument *res; - struct expression *it; + GQueue *stack; + gsize cur, op1, op2; + struct expression_argument *res; + struct expression *it; if (expr == NULL) { msg_warn ("NULL expression passed"); return NULL; } if (expr->next == NULL) { - res = - rspamd_mempool_alloc (task->task_pool, - sizeof (struct expression_argument)); - if (expr->type == EXPR_REGEXP || expr->type == EXPR_STR || expr->type == - EXPR_REGEXP_PARSED) { + res = rspamd_mempool_alloc (task->task_pool, sizeof (struct expression_argument)); + if (expr->type == EXPR_REGEXP || expr->type == EXPR_STR || expr->type == EXPR_REGEXP_PARSED) { res->type = EXPRESSION_ARGUMENT_NORMAL; res->data = expr->content.operand; } @@ -912,36 +831,27 @@ get_function_arg (struct expression *expr, res->data = GSIZE_TO_POINTER (cur); } else { - msg_warn ( - "cannot parse argument: it contains operator or bool expression that is not wanted"); + msg_warn ("cannot parse argument: it contains operator or bool expression that is not wanted"); return NULL; } return res; } else if (!want_string) { - res = - rspamd_mempool_alloc (task->task_pool, - sizeof (struct expression_argument)); + res = rspamd_mempool_alloc (task->task_pool, sizeof (struct expression_argument)); res->type = EXPRESSION_ARGUMENT_BOOL; stack = g_queue_new (); it = expr; while (it) { - if (it->type == EXPR_REGEXP || it->type == EXPR_REGEXP_PARSED || - it->type == EXPR_STR) { + if (it->type == EXPR_REGEXP || it->type == EXPR_REGEXP_PARSED || it->type == EXPR_STR) { g_queue_free (stack); res->type = EXPRESSION_ARGUMENT_EXPR; res->data = expr; return res; } else if (it->type == EXPR_FUNCTION) { - cur = - (gsize) call_expression_function ((struct - expression_function - *)it->content.operand, task, NULL); - debug_task ("function %s returned %s", - ((struct expression_function *)it->content.operand)->name, - cur ? "true" : "false"); + cur = (gsize) call_expression_function ((struct expression_function *)it->content.operand, task, NULL); + debug_task ("function %s returned %s", ((struct expression_function *)it->content.operand)->name, cur ? "true" : "false"); } else if (it->type == EXPR_OPERATION) { if (g_queue_is_empty (stack)) { @@ -991,11 +901,9 @@ get_function_arg (struct expression *expr, } void -register_expression_function (const gchar *name, - rspamd_internal_func_t func, - void *user_data) +register_expression_function (const gchar *name, rspamd_internal_func_t func, void *user_data) { - static struct _fl *new; + static struct _fl *new; functions_number++; @@ -1016,7 +924,7 @@ register_expression_function (const gchar *name, gboolean rspamd_compare_encoding (struct rspamd_task *task, GList * args, void *unused) { - struct expression_argument *arg; + struct expression_argument *arg; if (args == NULL || task == NULL) { return FALSE; @@ -1035,8 +943,8 @@ rspamd_compare_encoding (struct rspamd_task *task, GList * args, void *unused) gboolean rspamd_header_exists (struct rspamd_task * task, GList * args, void *unused) { - struct expression_argument *arg; - GList *headerlist; + struct expression_argument *arg; + GList *headerlist; if (args == NULL || task == NULL) { return FALSE; @@ -1049,10 +957,7 @@ rspamd_header_exists (struct rspamd_task * task, GList * args, void *unused) } debug_task ("try to get header %s", (gchar *)arg->data); - headerlist = message_get_header (task->task_pool, - task->message, - (gchar *)arg->data, - FALSE); + headerlist = message_get_header (task->task_pool, task->message, (gchar *)arg->data, FALSE); if (headerlist) { g_list_free (headerlist); return TRUE; @@ -1062,20 +967,20 @@ rspamd_header_exists (struct rspamd_task * task, GList * args, void *unused) /* * This function is designed to find difference between text/html and text/plain parts - * It takes one argument: difference threshold, if we have two text parts, compare + * It takes one argument: difference threshold, if we have two text parts, compare * its hashes and check for threshold, if value is greater than threshold, return TRUE * and return FALSE otherwise. */ gboolean rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused) { - gint threshold, threshold2 = -1, diff; - struct mime_text_part *p1, *p2; - GList *cur; - struct expression_argument *arg; - GMimeObject *parent; - const GMimeContentType *ct; - gint *pdiff; + gint threshold, threshold2 = -1, diff; + struct mime_text_part *p1, *p2; + GList *cur; + struct expression_argument *arg; + GMimeObject *parent; + const GMimeContentType *ct; + gint *pdiff; if (args == NULL) { debug_task ("no threshold is specified, assume it 100"); @@ -1086,8 +991,7 @@ rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused) arg = get_function_arg (args->data, task, TRUE); threshold = strtoul ((gchar *)arg->data, NULL, 10); if (errno != 0) { - msg_info ("bad numeric value for threshold \"%s\", assume it 100", - (gchar *)args->data); + msg_info ("bad numeric value for threshold \"%s\", assume it 100", (gchar *)args->data); threshold = 100; } if (args->next) { @@ -1095,22 +999,17 @@ rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused) errno = 0; threshold2 = strtoul ((gchar *)arg->data, NULL, 10); if (errno != 0) { - msg_info ("bad numeric value for threshold \"%s\", ignore it", - (gchar *)arg->data); + msg_info ("bad numeric value for threshold \"%s\", ignore it", (gchar *)arg->data); threshold2 = -1; } } } - if ((pdiff = - rspamd_mempool_get_variable (task->task_pool, - "parts_distance")) != NULL) { + if ((pdiff = rspamd_mempool_get_variable (task->task_pool, "parts_distance")) != NULL) { diff = *pdiff; if (diff != -1) { if (threshold2 > 0) { - if (diff >= - MIN (threshold, - threshold2) && diff < MAX (threshold, threshold2)) { + if (diff >= MIN (threshold, threshold2) && diff < MAX (threshold, threshold2)) { return TRUE; } } @@ -1143,52 +1042,32 @@ rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused) parent = p1->parent; ct = g_mime_object_get_content_type (parent); #ifndef GMIME24 - if (ct == NULL || - !g_mime_content_type_is_type (ct, "multipart", "alternative")) { + if (ct == NULL || ! g_mime_content_type_is_type (ct, "multipart", "alternative")) { #else - if (ct == NULL || - !g_mime_content_type_is_type ((GMimeContentType *)ct, - "multipart", "alternative")) { + if (ct == NULL || ! g_mime_content_type_is_type ((GMimeContentType *)ct, "multipart", "alternative")) { #endif - debug_task ( - "two parts are not belong to multipart/alternative container, skip check"); - rspamd_mempool_set_variable (task->task_pool, - "parts_distance", - pdiff, - NULL); + debug_task ("two parts are not belong to multipart/alternative container, skip check"); + rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL); return FALSE; } } else { - debug_task ( - "message contains two parts but they are in different multi-parts"); - rspamd_mempool_set_variable (task->task_pool, - "parts_distance", - pdiff, - NULL); + debug_task ("message contains two parts but they are in different multi-parts"); + rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL); return FALSE; } if (!p1->is_empty && !p2->is_empty) { if (p1->diff_str != NULL && p2->diff_str != NULL) { - diff = compare_diff_distance_normalized (p1->diff_str, - p2->diff_str); + diff = compare_diff_distance_normalized (p1->diff_str, p2->diff_str); } else { diff = fuzzy_compare_parts (p1, p2); } - debug_task ( - "got likeliness between parts of %d%%, threshold is %d%%", - diff, - threshold); + debug_task ("got likeliness between parts of %d%%, threshold is %d%%", diff, threshold); *pdiff = diff; - rspamd_mempool_set_variable (task->task_pool, - "parts_distance", - pdiff, - NULL); + rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL); if (threshold2 > 0) { - if (diff >= - MIN (threshold, - threshold2) && diff < MAX (threshold, threshold2)) { + if (diff >= MIN (threshold, threshold2) && diff < MAX (threshold, threshold2)) { return TRUE; } } @@ -1198,51 +1077,41 @@ rspamd_parts_distance (struct rspamd_task * task, GList * args, void *unused) } } } - else if ((p1->is_empty && - !p2->is_empty) || (!p1->is_empty && p2->is_empty)) { + else if ((p1->is_empty && !p2->is_empty) || (!p1->is_empty && p2->is_empty)) { /* Empty and non empty parts are different */ *pdiff = 0; - rspamd_mempool_set_variable (task->task_pool, - "parts_distance", - pdiff, - NULL); + rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL); return TRUE; } } else { - debug_task ( - "message has too many text parts, so do not try to compare them with each other"); - rspamd_mempool_set_variable (task->task_pool, - "parts_distance", - pdiff, - NULL); + debug_task ("message has too many text parts, so do not try to compare them with each other"); + rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL); return FALSE; } - rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, - NULL); + rspamd_mempool_set_variable (task->task_pool, "parts_distance", pdiff, NULL); return FALSE; } struct addr_list { - const gchar *name; - const gchar *addr; + const gchar *name; + const gchar *addr; }; #define COMPARE_RCPT_LEN 3 #define MIN_RCPT_TO_COMPARE 7 gboolean -rspamd_recipients_distance (struct rspamd_task *task, GList * args, - void *unused) +rspamd_recipients_distance (struct rspamd_task *task, GList * args, void *unused) { - struct expression_argument *arg; - InternetAddressList *cur; - InternetAddress *addr; - double threshold; - struct addr_list *ar; - gchar *c; - gint num, i, j, hits = 0, total = 0; + struct expression_argument *arg; + InternetAddressList *cur; + InternetAddress *addr; + double threshold; + struct addr_list *ar; + gchar *c; + gint num, i, j, hits = 0, total = 0; if (args == NULL) { msg_warn ("no parameters to function"); @@ -1253,9 +1122,7 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, errno = 0; threshold = strtod ((gchar *)arg->data, NULL); if (errno != 0) { - msg_warn ("invalid numeric value '%s': %s", - (gchar *)arg->data, - strerror (errno)); + msg_warn ("invalid numeric value '%s': %s", (gchar *)arg->data, strerror (errno)); return FALSE; } @@ -1266,17 +1133,14 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, if (num < MIN_RCPT_TO_COMPARE) { return FALSE; } - ar = - rspamd_mempool_alloc0 (task->task_pool, num * - sizeof (struct addr_list)); + ar = rspamd_mempool_alloc0 (task->task_pool, num * sizeof (struct addr_list)); /* Fill array */ cur = task->rcpts; #ifdef GMIME24 - for (i = 0; i < num; i++) { + for (i = 0; i < num; i ++) { addr = internet_address_list_get_address (cur, i); - ar[i].name = rspamd_mempool_strdup (task->task_pool, - internet_address_get_name (addr)); + ar[i].name = rspamd_mempool_strdup (task->task_pool, internet_address_get_name (addr)); if (ar[i].name != NULL && (c = strchr (ar[i].name, '@')) != NULL) { *c = '\0'; ar[i].addr = c + 1; @@ -1287,8 +1151,7 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, while (cur) { addr = internet_address_list_get_address (cur); if (addr && internet_address_get_type (addr) == INTERNET_ADDRESS_NAME) { - ar[i].name = rspamd_mempool_strdup (task->task_pool, - internet_address_get_addr (addr)); + ar[i].name = rspamd_mempool_strdup (task->task_pool, internet_address_get_addr (addr)); if (ar[i].name != NULL && (c = strchr (ar[i].name, '@')) != NULL) { *c = '\0'; ar[i].addr = c + 1; @@ -1305,14 +1168,11 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, /* Cycle all elements in array */ for (i = 0; i < num; i++) { for (j = i + 1; j < num; j++) { - if (ar[i].name && ar[j].name && - g_ascii_strncasecmp (ar[i].name, ar[j].name, - COMPARE_RCPT_LEN) == 0) { + if (ar[i].name && ar[j].name && g_ascii_strncasecmp (ar[i].name, ar[j].name, COMPARE_RCPT_LEN) == 0) { /* Common name part */ hits++; } - else if (ar[i].addr && ar[j].addr && - g_ascii_strcasecmp (ar[i].addr, ar[j].addr) == 0) { + else if (ar[i].addr && ar[j].addr && g_ascii_strcasecmp (ar[i].addr, ar[j].addr) == 0) { /* Common address part, but different name */ hits++; } @@ -1328,12 +1188,11 @@ rspamd_recipients_distance (struct rspamd_task *task, GList * args, } gboolean -rspamd_has_only_html_part (struct rspamd_task * task, GList * args, - void *unused) +rspamd_has_only_html_part (struct rspamd_task * task, GList * args, void *unused) { - struct mime_text_part *p; - GList *cur; - gboolean res = FALSE; + struct mime_text_part *p; + GList *cur; + gboolean res = FALSE; cur = g_list_first (task->text_parts); while (cur) { @@ -1351,34 +1210,30 @@ rspamd_has_only_html_part (struct rspamd_task * task, GList * args, return res; } -static gboolean +static gboolean is_recipient_list_sorted (const InternetAddressList * ia) { - const InternetAddressList *cur; - InternetAddress *addr; - gboolean res = TRUE; - struct addr_list current = { NULL, NULL }, previous = { - NULL, NULL - }; + const InternetAddressList *cur; + InternetAddress *addr; + gboolean res = TRUE; + struct addr_list current = { NULL, NULL }, previous = { + NULL, NULL}; #ifdef GMIME24 - gint num, i; + gint num, i; #endif /* Do not check to short address lists */ - if (internet_address_list_length ((InternetAddressList *)ia) < - MIN_RCPT_TO_COMPARE) { + if (internet_address_list_length ((InternetAddressList *)ia) < MIN_RCPT_TO_COMPARE) { return FALSE; } #ifdef GMIME24 num = internet_address_list_length ((InternetAddressList *)ia); cur = ia; - for (i = 0; i < num; i++) { - addr = - internet_address_list_get_address ((InternetAddressList *)cur, i); + for (i = 0; i < num; i ++) { + addr = internet_address_list_get_address ((InternetAddressList *)cur, i); current.addr = (gchar *)internet_address_get_name (addr); if (previous.addr != NULL) { - if (current.addr && - g_ascii_strcasecmp (current.addr, previous.addr) < 0) { + if (current.addr && g_ascii_strcasecmp (current.addr, previous.addr) < 0) { res = FALSE; break; } @@ -1392,8 +1247,7 @@ is_recipient_list_sorted (const InternetAddressList * ia) if (internet_address_get_type (addr) == INTERNET_ADDRESS_NAME) { current.addr = internet_address_get_addr (addr); if (previous.addr != NULL) { - if (current.addr && - g_ascii_strcasecmp (current.addr, previous.addr) < 0) { + if (current.addr && g_ascii_strcasecmp (current.addr, previous.addr) < 0) { res = FALSE; break; } @@ -1408,21 +1262,16 @@ is_recipient_list_sorted (const InternetAddressList * ia) } gboolean -rspamd_is_recipients_sorted (struct rspamd_task * task, - GList * args, - void *unused) +rspamd_is_recipients_sorted (struct rspamd_task * task, GList * args, void *unused) { /* Check all types of addresses */ - if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, - GMIME_RECIPIENT_TYPE_TO)) == TRUE) { + if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, GMIME_RECIPIENT_TYPE_TO)) == TRUE) { return TRUE; } - if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, - GMIME_RECIPIENT_TYPE_BCC)) == TRUE) { + if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, GMIME_RECIPIENT_TYPE_BCC)) == TRUE) { return TRUE; } - if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, - GMIME_RECIPIENT_TYPE_CC)) == TRUE) { + if (is_recipient_list_sorted (g_mime_message_get_recipients (task->message, GMIME_RECIPIENT_TYPE_CC)) == TRUE) { return TRUE; } @@ -1430,17 +1279,15 @@ rspamd_is_recipients_sorted (struct rspamd_task * task, } gboolean -rspamd_compare_transfer_encoding (struct rspamd_task * task, - GList * args, - void *unused) +rspamd_compare_transfer_encoding (struct rspamd_task * task, GList * args, void *unused) { - GMimeObject *part; + GMimeObject *part; #ifndef GMIME24 - GMimePartEncodingType enc_req, part_enc; + GMimePartEncodingType enc_req, part_enc; #else - GMimeContentEncoding enc_req, part_enc; + GMimeContentEncoding enc_req, part_enc; #endif - struct expression_argument *arg; + struct expression_argument *arg; if (args == NULL) { msg_warn ("no parameters to function"); @@ -1477,9 +1324,7 @@ rspamd_compare_transfer_encoding (struct rspamd_task * task, #endif - debug_task ("got encoding in part: %d and compare with %d", - (gint)part_enc, - (gint)enc_req); + debug_task ("got encoding in part: %d and compare with %d", (gint)part_enc, (gint)enc_req); #ifndef GMIME24 g_object_unref (part); #endif @@ -1497,9 +1342,9 @@ rspamd_compare_transfer_encoding (struct rspamd_task * task, gboolean rspamd_is_html_balanced (struct rspamd_task * task, GList * args, void *unused) { - struct mime_text_part *p; - GList *cur; - gboolean res = TRUE; + struct mime_text_part *p; + GList *cur; + gboolean res = TRUE; cur = g_list_first (task->text_parts); while (cur) { @@ -1521,15 +1366,15 @@ rspamd_is_html_balanced (struct rspamd_task * task, GList * args, void *unused) } struct html_callback_data { - struct html_tag *tag; - gboolean *res; + struct html_tag *tag; + gboolean *res; }; -static gboolean +static gboolean search_html_node_callback (GNode * node, gpointer data) { - struct html_callback_data *cd = data; - struct html_node *nd; + struct html_callback_data *cd = data; + struct html_node *nd; nd = node->data; if (nd) { @@ -1545,12 +1390,12 @@ search_html_node_callback (GNode * node, gpointer data) gboolean rspamd_has_html_tag (struct rspamd_task * task, GList * args, void *unused) { - struct mime_text_part *p; - GList *cur; - struct expression_argument *arg; - struct html_tag *tag; - gboolean res = FALSE; - struct html_callback_data cd; + struct mime_text_part *p; + GList *cur; + struct expression_argument *arg; + struct html_tag *tag; + gboolean res = FALSE; + struct html_callback_data cd; if (args == NULL) { msg_warn ("no parameters to function"); @@ -1560,8 +1405,7 @@ rspamd_has_html_tag (struct rspamd_task * task, GList * args, void *unused) arg = get_function_arg (args->data, task, TRUE); tag = get_tag_by_name (arg->data); if (tag == NULL) { - msg_warn ("unknown tag type passed as argument: %s", - (gchar *)arg->data); + msg_warn ("unknown tag type passed as argument: %s", (gchar *)arg->data); return FALSE; } @@ -1572,12 +1416,7 @@ rspamd_has_html_tag (struct rspamd_task * task, GList * args, void *unused) while (cur && res == FALSE) { p = cur->data; if (!p->is_empty && p->is_html && p->html_nodes) { - g_node_traverse (p->html_nodes, - G_PRE_ORDER, - G_TRAVERSE_ALL, - -1, - search_html_node_callback, - &cd); + g_node_traverse (p->html_nodes, G_PRE_ORDER, G_TRAVERSE_ALL, -1, search_html_node_callback, &cd); } cur = g_list_next (cur); } @@ -1589,9 +1428,9 @@ rspamd_has_html_tag (struct rspamd_task * task, GList * args, void *unused) gboolean rspamd_has_fake_html (struct rspamd_task * task, GList * args, void *unused) { - struct mime_text_part *p; - GList *cur; - gboolean res = FALSE; + struct mime_text_part *p; + GList *cur; + gboolean res = FALSE; cur = g_list_first (task->text_parts); diff --git a/src/libmime/expressions.h b/src/libmime/expressions.h index 1ba02d956..954cc74f7 100644 --- a/src/libmime/expressions.h +++ b/src/libmime/expressions.h @@ -16,8 +16,8 @@ struct rspamd_regexp; * Rspamd expression function */ struct expression_function { - gchar *name; /**< name of function */ - GList *args; /**< its args */ + gchar *name; /**< name of function */ + GList *args; /**< its args */ }; /** @@ -28,31 +28,30 @@ struct expression_argument { EXPRESSION_ARGUMENT_NORMAL, EXPRESSION_ARGUMENT_BOOL, EXPRESSION_ARGUMENT_EXPR, - } type; /**< type of argument (text or other function) */ - void *data; /**< pointer to its data */ + } type; /**< type of argument (text or other function) */ + void *data; /**< pointer to its data */ }; -/** - * Logic expression +/** + * Logic expression */ struct expression { - enum { + enum { EXPR_REGEXP, - EXPR_OPERATION, - EXPR_FUNCTION, - EXPR_STR, + EXPR_OPERATION, + EXPR_FUNCTION, + EXPR_STR, EXPR_REGEXP_PARSED, - } type; /**< expression type */ + } type; /**< expression type */ union { void *operand; gchar operation; - } content; /**< union for storing operand or operation code */ - const gchar *orig; /**< original line */ - struct expression *next; /**< chain link */ + } content; /**< union for storing operand or operation code */ + const gchar *orig; /**< original line */ + struct expression *next; /**< chain link */ }; -typedef gboolean (*rspamd_internal_func_t)(struct rspamd_task *, GList *args, - void *user_data); +typedef gboolean (*rspamd_internal_func_t)(struct rspamd_task *, GList *args, void *user_data); /** * Parse regexp line to regexp structure @@ -60,9 +59,7 @@ typedef gboolean (*rspamd_internal_func_t)(struct rspamd_task *, GList *args, * @param line incoming line * @return regexp structure or NULL in case of error */ -struct rspamd_regexp * parse_regexp (rspamd_mempool_t *pool, - const gchar *line, - gboolean raw_mode); +struct rspamd_regexp* parse_regexp (rspamd_mempool_t *pool, const gchar *line, gboolean raw_mode); /** * Parse composites line to composites structure (eg. "SYMBOL1&SYMBOL2|!SYMBOL3") @@ -70,7 +67,7 @@ struct rspamd_regexp * parse_regexp (rspamd_mempool_t *pool, * @param line incoming line * @return expression structure or NULL in case of error */ -struct expression * parse_expression (rspamd_mempool_t *pool, gchar *line); +struct expression* parse_expression (rspamd_mempool_t *pool, gchar *line); /** * Call specified fucntion and return boolean result @@ -79,18 +76,14 @@ struct expression * parse_expression (rspamd_mempool_t *pool, gchar *line); * @param L lua specific state * @return TRUE or FALSE depending on function result */ -gboolean call_expression_function (struct expression_function *func, - struct rspamd_task *task, - lua_State *L); +gboolean call_expression_function (struct expression_function *func, struct rspamd_task *task, lua_State *L); /** * Register specified function to rspamd internal functions list * @param name name of function * @param func pointer to function */ -void register_expression_function (const gchar *name, - rspamd_internal_func_t func, - void *user_data); +void register_expression_function (const gchar *name, rspamd_internal_func_t func, void *user_data); /** * Add regexp to regexp cache @@ -118,9 +111,7 @@ void re_cache_del (const gchar *line, rspamd_mempool_t *pool); * @param pointer regexp data * @param result numeric result of this regexp */ -void task_cache_add (struct rspamd_task *task, - struct rspamd_regexp *re, - gint32 result); +void task_cache_add (struct rspamd_task *task, struct rspamd_regexp *re, gint32 result); /** * Check regexp in cache @@ -137,8 +128,6 @@ gint32 task_cache_check (struct rspamd_task *task, struct rspamd_regexp *re); * @param want_string return NULL if argument is not a string * @return expression argument structure or NULL if failed */ -struct expression_argument * get_function_arg (struct expression *expr, - struct rspamd_task *task, - gboolean want_string); +struct expression_argument *get_function_arg (struct expression *expr, struct rspamd_task *task, gboolean want_string); #endif diff --git a/src/libmime/filter.c b/src/libmime/filter.c index f296617cf..2068c79e3 100644 --- a/src/libmime/filter.c +++ b/src/libmime/filter.c @@ -22,18 +22,18 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "binlog.h" -#include "cfg_file.h" -#include "classifiers/classifiers.h" #include "config.h" -#include "diff.h" -#include "expressions.h" +#include "mem_pool.h" #include "filter.h" #include "main.h" -#include "mem_pool.h" #include "message.h" -#include "tokenizers/tokenizers.h" +#include "cfg_file.h" #include "util.h" +#include "expressions.h" +#include "binlog.h" +#include "diff.h" +#include "classifiers/classifiers.h" +#include "tokenizers/tokenizers.h" #ifdef WITH_LUA # include "lua/lua_common.h" @@ -44,56 +44,44 @@ #ifndef PARAM_H_HAS_BITSET /* Bit map related macros. */ #define NBBY 8 /* number of bits in a byte */ -#define setbit(a, \ - i) (((unsigned char *)(a))[(i) / NBBY] |= 1 << ((i) % NBBY)) -#define clrbit(a, \ - i) (((unsigned char *)(a))[(i) / NBBY] &= ~(1 << ((i) % NBBY))) +#define setbit(a,i) (((unsigned char *)(a))[(i)/NBBY] |= 1<<((i)%NBBY)) +#define clrbit(a,i) (((unsigned char *)(a))[(i)/NBBY] &= ~(1<<((i)%NBBY))) #define isset(a,i) \ - (((const unsigned char *)(a))[(i) / NBBY] & (1 << ((i) % NBBY))) + (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) #define isclr(a,i) \ - ((((const unsigned char *)(a))[(i) / NBBY] & (1 << ((i) % NBBY))) == 0) + ((((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) == 0) #endif -#define BITSPERBYTE (8 * sizeof (gchar)) -#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE) +#define BITSPERBYTE (8*sizeof (gchar)) +#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE) -static inline GQuark +static inline GQuark filter_error_quark (void) { return g_quark_from_static_string ("g-filter-error-quark"); } static void -insert_metric_result (struct rspamd_task *task, - struct metric *metric, - const gchar *symbol, - double flag, - GList * opts, - gboolean single) +insert_metric_result (struct rspamd_task *task, struct metric *metric, const gchar *symbol, + double flag, GList * opts, gboolean single) { - struct metric_result *metric_res; - struct symbol *s; - gdouble *weight, w; + struct metric_result *metric_res; + struct symbol *s; + gdouble *weight, w; metric_res = g_hash_table_lookup (task->results, metric->name); if (metric_res == NULL) { /* Create new metric chain */ - metric_res = - rspamd_mempool_alloc (task->task_pool, - sizeof (struct metric_result)); - metric_res->symbols = g_hash_table_new (rspamd_str_hash, - rspamd_str_equal); + metric_res = rspamd_mempool_alloc (task->task_pool, sizeof (struct metric_result)); + metric_res->symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal); metric_res->checked = FALSE; - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_hash_table_unref, - metric_res->symbols); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_hash_table_unref, metric_res->symbols); metric_res->metric = metric; metric_res->grow_factor = 0; metric_res->score = 0; - g_hash_table_insert (task->results, (gpointer) metric->name, - metric_res); + g_hash_table_insert (task->results, (gpointer) metric->name, metric_res); } - + weight = g_hash_table_lookup (metric->symbols, symbol); if (weight == NULL) { w = 0.0; @@ -106,7 +94,7 @@ insert_metric_result (struct rspamd_task *task, if ((s = g_hash_table_lookup (metric_res->symbols, symbol)) != NULL) { if (s->options && opts && opts != s->options) { /* Append new options */ - s->options = g_list_concat (s->options, g_list_copy (opts)); + s->options = g_list_concat (s->options, g_list_copy(opts)); /* * Note that there is no need to add new destructor of GList as elements of appended * GList are used directly, so just free initial GList @@ -114,8 +102,7 @@ insert_metric_result (struct rspamd_task *task, } else if (opts) { s->options = g_list_copy (opts); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_list_free, s->options); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_list_free, s->options); } if (!single) { /* Handle grow factor */ @@ -152,8 +139,7 @@ insert_metric_result (struct rspamd_task *task, if (opts) { s->options = g_list_copy (opts); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_list_free, s->options); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_list_free, s->options); } else { s->options = NULL; @@ -161,30 +147,22 @@ insert_metric_result (struct rspamd_task *task, g_hash_table_insert (metric_res->symbols, (gpointer) symbol, s); } - debug_task ("symbol %s, score %.2f, metric %s, factor: %f", - symbol, - s->score, - metric->name, - w); - + debug_task ("symbol %s, score %.2f, metric %s, factor: %f", symbol, s->score, metric->name, w); + } #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30)) -static GStaticMutex result_mtx = G_STATIC_MUTEX_INIT; +static GStaticMutex result_mtx = G_STATIC_MUTEX_INIT; #else G_LOCK_DEFINE (result_mtx); #endif static void -insert_result_common (struct rspamd_task *task, - const gchar *symbol, - double flag, - GList * opts, - gboolean single) +insert_result_common (struct rspamd_task *task, const gchar *symbol, double flag, GList * opts, gboolean single) { - struct metric *metric; - struct cache_item *item; - GList *cur, *metric_list; + struct metric *metric; + struct cache_item *item; + GList *cur, *metric_list; /* Avoid concurrenting inserting of results */ #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30)) @@ -195,7 +173,7 @@ insert_result_common (struct rspamd_task *task, metric_list = g_hash_table_lookup (task->cfg->metrics_symbols, symbol); if (metric_list) { cur = metric_list; - + while (cur) { metric = cur->data; insert_metric_result (task, metric, symbol, flag, opts, single); @@ -204,12 +182,7 @@ insert_result_common (struct rspamd_task *task, } else { /* Insert symbol to default metric */ - insert_metric_result (task, - task->cfg->default_metric, - symbol, - flag, - opts, - single); + insert_metric_result (task, task->cfg->default_metric, symbol, flag, opts, single); } /* Process cache item */ @@ -233,27 +206,21 @@ insert_result_common (struct rspamd_task *task, /* Insert result that may be increased on next insertions */ void -insert_result (struct rspamd_task *task, - const gchar *symbol, - double flag, - GList * opts) +insert_result (struct rspamd_task *task, const gchar *symbol, double flag, GList * opts) { insert_result_common (task, symbol, flag, opts, task->cfg->one_shot_mode); } /* Insert result as a single option */ void -insert_result_single (struct rspamd_task *task, - const gchar *symbol, - double flag, - GList * opts) +insert_result_single (struct rspamd_task *task, const gchar *symbol, double flag, GList * opts) { insert_result_common (task, symbol, flag, opts, TRUE); } static gboolean check_metric_settings (struct rspamd_task *task, struct metric *metric, - double *score) + double *score) { const ucl_object_t *mobj, *reject; double val; @@ -276,11 +243,11 @@ check_metric_settings (struct rspamd_task *task, struct metric *metric, } /* Return true if metric has score that is more than spam score for it */ -static gboolean +static gboolean check_metric_is_spam (struct rspamd_task *task, struct metric *metric) { - struct metric_result *res; - double ms; + struct metric_result *res; + double ms; /* Avoid concurrency while checking results */ #if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30)) @@ -313,9 +280,9 @@ check_metric_is_spam (struct rspamd_task *task, struct metric *metric) gint process_filters (struct rspamd_task *task) { - GList *cur; - struct metric *metric; - gpointer item = NULL; + GList *cur; + struct metric *metric; + gpointer item = NULL; /* Process metrics symbols */ while (call_symbol_callback (task, task->cfg->cache, &item)) { @@ -324,8 +291,8 @@ process_filters (struct rspamd_task *task) while (cur) { metric = cur->data; if (!task->pass_all_filters && - metric->actions[METRIC_ACTION_REJECT].score > 0 && - check_metric_is_spam (task, metric)) { + metric->actions[METRIC_ACTION_REJECT].score > 0 && + check_metric_is_spam (task, metric)) { task->state = WRITE_REPLY; return 1; } @@ -340,22 +307,22 @@ process_filters (struct rspamd_task *task) struct composites_data { - struct rspamd_task *task; - struct metric_result *metric_res; - GTree *symbols_to_remove; - guint8 *checked; + struct rspamd_task *task; + struct metric_result *metric_res; + GTree *symbols_to_remove; + guint8 *checked; }; struct symbol_remove_data { - struct symbol *ms; - gboolean remove_weight; - gboolean remove_symbol; + struct symbol *ms; + gboolean remove_weight; + gboolean remove_symbol; }; static gint remove_compare_data (gconstpointer a, gconstpointer b) { - const gchar *ca = a, *cb = b; + const gchar *ca = a, *cb = b; return strcmp (ca, cb); } @@ -363,16 +330,16 @@ remove_compare_data (gconstpointer a, gconstpointer b) static void composites_foreach_callback (gpointer key, gpointer value, void *data) { - struct composites_data *cd = (struct composites_data *)data; - struct rspamd_composite *composite = value, *ncomp; - struct expression *expr; - GQueue *stack; - GList *symbols = NULL, *s; - gsize cur, op1, op2; - gchar logbuf[256], *sym, *check_sym; - gint r; - struct symbol *ms; - struct symbol_remove_data *rd; + struct composites_data *cd = (struct composites_data *)data; + struct rspamd_composite *composite = value, *ncomp; + struct expression *expr; + GQueue *stack; + GList *symbols = NULL, *s; + gsize cur, op1, op2; + gchar logbuf[256], *sym, *check_sym; + gint r; + struct symbol *ms; + struct symbol_remove_data *rd; expr = composite->expr; @@ -388,19 +355,16 @@ composites_foreach_callback (gpointer key, gpointer value, void *data) /* Find corresponding symbol */ sym = expr->content.operand; if (*sym == '~' || *sym == '-') { - sym++; + sym ++; } if (g_hash_table_lookup (cd->metric_res->symbols, sym) == NULL) { cur = 0; - if ((ncomp = - g_hash_table_lookup (cd->task->cfg->composite_symbols, - sym)) != NULL) { + if ((ncomp = g_hash_table_lookup (cd->task->cfg->composite_symbols, sym)) != NULL) { /* Set checked for this symbol to avoid cyclic references */ if (isclr (cd->checked, ncomp->id)) { setbit (cd->checked, composite->id); composites_foreach_callback (sym, ncomp, cd); - if (g_hash_table_lookup (cd->metric_res->symbols, - sym) != NULL) { + if (g_hash_table_lookup (cd->metric_res->symbols, sym) != NULL) { cur = 1; } } @@ -448,11 +412,7 @@ composites_foreach_callback (gpointer key, gpointer value, void *data) if (op1) { /* Remove all symbols that are in composite symbol */ s = g_list_first (symbols); - r = rspamd_snprintf (logbuf, - sizeof (logbuf), - "<%s>, insert symbol %s instead of symbols: ", - cd->task->message_id, - key); + r = rspamd_snprintf (logbuf, sizeof (logbuf), "<%s>, insert symbol %s instead of symbols: ", cd->task->message_id, key); while (s) { sym = s->data; if (*sym == '~' || *sym == '-') { @@ -465,23 +425,18 @@ composites_foreach_callback (gpointer key, gpointer value, void *data) if (ms == NULL) { /* Try to process other composites */ - if ((ncomp = - g_hash_table_lookup (cd->task->cfg->composite_symbols, - check_sym)) != NULL) { + if ((ncomp = g_hash_table_lookup (cd->task->cfg->composite_symbols, check_sym)) != NULL) { /* Set checked for this symbol to avoid cyclic references */ if (isclr (cd->checked, ncomp->id)) { setbit (cd->checked, composite->id); composites_foreach_callback (check_sym, ncomp, cd); - ms = g_hash_table_lookup (cd->metric_res->symbols, - check_sym); + ms = g_hash_table_lookup (cd->metric_res->symbols, check_sym); } } } if (ms != NULL) { - rd = - rspamd_mempool_alloc (cd->task->task_pool, - sizeof (struct symbol_remove_data)); + rd = rspamd_mempool_alloc (cd->task->task_pool, sizeof (struct symbol_remove_data)); rd->ms = ms; if (G_UNLIKELY (*sym == '~')) { rd->remove_weight = FALSE; @@ -496,9 +451,7 @@ composites_foreach_callback (gpointer key, gpointer value, void *data) rd->remove_weight = TRUE; } if (!g_tree_lookup (cd->symbols_to_remove, rd)) { - g_tree_insert (cd->symbols_to_remove, - (gpointer)ms->name, - rd); + g_tree_insert (cd->symbols_to_remove, (gpointer)ms->name, rd); } } else { @@ -506,16 +459,10 @@ composites_foreach_callback (gpointer key, gpointer value, void *data) } if (s->next) { - r += rspamd_snprintf (logbuf + r, - sizeof (logbuf) - r, - "%s, ", - s->data); + r += rspamd_snprintf (logbuf + r, sizeof (logbuf) -r, "%s, ", s->data); } else { - r += rspamd_snprintf (logbuf + r, - sizeof (logbuf) - r, - "%s", - s->data); + r += rspamd_snprintf (logbuf + r, sizeof (logbuf) -r, "%s", s->data); } s = g_list_next (s); } @@ -532,13 +479,12 @@ composites_foreach_callback (gpointer key, gpointer value, void *data) return; } -static gboolean -check_autolearn (struct statfile_autolearn_params *params, - struct rspamd_task *task) +static gboolean +check_autolearn (struct statfile_autolearn_params *params, struct rspamd_task *task) { - gchar *metric_name = DEFAULT_METRIC; - struct metric_result *metric_res; - GList *cur; + gchar *metric_name = DEFAULT_METRIC; + struct metric_result *metric_res; + GList *cur; if (params->metric != NULL) { metric_name = (gchar *)params->metric; @@ -556,16 +502,12 @@ check_autolearn (struct statfile_autolearn_params *params, } else { /* Process score of metric */ - if ((params->threshold_min != 0 && metric_res->score > - params->threshold_min) || - (params->threshold_max != 0 && metric_res->score < - params->threshold_max)) { + if ((params->threshold_min != 0 && metric_res->score > params->threshold_min) || (params->threshold_max != 0 && metric_res->score < params->threshold_max)) { /* Now check for specific symbols */ if (params->symbols) { cur = params->symbols; while (cur) { - if (g_hash_table_lookup (metric_res->symbols, - cur->data) == NULL) { + if (g_hash_table_lookup (metric_res->symbols, cur->data) == NULL) { return FALSE; } cur = g_list_next (cur); @@ -580,47 +522,28 @@ check_autolearn (struct statfile_autolearn_params *params, } void -process_autolearn (struct rspamd_statfile_config *st, - struct rspamd_task *task, - GTree * tokens, - struct classifier *classifier, - gchar *filename, - struct classifier_ctx *ctx) +process_autolearn (struct rspamd_statfile_config *st, struct rspamd_task *task, GTree * tokens, struct classifier *classifier, gchar *filename, struct classifier_ctx *ctx) { - stat_file_t *statfile; - struct rspamd_statfile_config *unused; + stat_file_t *statfile; + struct rspamd_statfile_config *unused; if (check_autolearn (st->autolearn, task)) { if (tokens) { /* Take care of subject */ tokenize_subject (task, &tokens); - msg_info ("message with id <%s> autolearned statfile '%s'", - task->message_id, - filename); - + msg_info ("message with id <%s> autolearned statfile '%s'", task->message_id, filename); + /* Get or create statfile */ - statfile = get_statfile_by_symbol (task->worker->srv->statfile_pool, - ctx->cfg, - st->symbol, - &unused, - TRUE); - + statfile = get_statfile_by_symbol (task->worker->srv->statfile_pool, ctx->cfg, + st->symbol, &unused, TRUE); + if (statfile == NULL) { return; } - classifier->learn_func (ctx, - task->worker->srv->statfile_pool, - st->symbol, - tokens, - TRUE, - NULL, - 1., - NULL); + classifier->learn_func (ctx, task->worker->srv->statfile_pool, st->symbol, tokens, TRUE, NULL, 1., NULL); maybe_write_binlog (ctx->cfg, st, statfile, tokens); - statfile_pool_plan_invalidate (task->worker->srv->statfile_pool, - DEFAULT_STATFILE_INVALIDATE_TIME, - DEFAULT_STATFILE_INVALIDATE_JITTER); + statfile_pool_plan_invalidate (task->worker->srv->statfile_pool, DEFAULT_STATFILE_INVALIDATE_TIME, DEFAULT_STATFILE_INVALIDATE_JITTER); } } } @@ -628,8 +551,8 @@ process_autolearn (struct rspamd_statfile_config *st, static gboolean composites_remove_symbols (gpointer key, gpointer value, gpointer data) { - struct composites_data *cd = data; - struct symbol_remove_data *rd = value; + struct composites_data *cd = data; + struct symbol_remove_data *rd = value; if (rd->remove_symbol) { g_hash_table_remove (cd->metric_res->symbols, key); @@ -644,22 +567,17 @@ composites_remove_symbols (gpointer key, gpointer value, gpointer data) static void composites_metric_callback (gpointer key, gpointer value, gpointer data) { - struct rspamd_task *task = (struct rspamd_task *)data; - struct composites_data *cd = - rspamd_mempool_alloc (task->task_pool, sizeof (struct composites_data)); - struct metric_result *metric_res = (struct metric_result *)value; + struct rspamd_task *task = (struct rspamd_task *)data; + struct composites_data *cd = rspamd_mempool_alloc (task->task_pool, sizeof (struct composites_data)); + struct metric_result *metric_res = (struct metric_result *)value; cd->task = task; cd->metric_res = (struct metric_result *)metric_res; cd->symbols_to_remove = g_tree_new (remove_compare_data); - cd->checked = - rspamd_mempool_alloc0 (task->task_pool, - NBYTES (g_hash_table_size (task->cfg->composite_symbols))); + cd->checked = rspamd_mempool_alloc0 (task->task_pool, NBYTES (g_hash_table_size (task->cfg->composite_symbols))); /* Process hash table */ - g_hash_table_foreach (task->cfg->composite_symbols, - composites_foreach_callback, - cd); + g_hash_table_foreach (task->cfg->composite_symbols, composites_foreach_callback, cd); /* Remove symbols that are in composites */ g_tree_foreach (cd->symbols_to_remove, composites_remove_symbols, cd); @@ -681,32 +599,30 @@ struct classifiers_cbdata { static void classifiers_callback (gpointer value, void *arg) { - struct classifiers_cbdata *cbdata = arg; - struct rspamd_task *task; - struct rspamd_classifier_config *cl = value; - struct classifier_ctx *ctx; - struct mime_text_part *text_part, *p1, *p2; - struct rspamd_statfile_config *st; - GTree *tokens = NULL; - GList *cur; - f_str_t c; - gchar *header = NULL; - gint *dist = NULL, diff; - gboolean is_twopart = FALSE; - + struct classifiers_cbdata *cbdata = arg; + struct rspamd_task *task; + struct rspamd_classifier_config *cl = value; + struct classifier_ctx *ctx; + struct mime_text_part *text_part, *p1, *p2; + struct rspamd_statfile_config *st; + GTree *tokens = NULL; + GList *cur; + f_str_t c; + gchar *header = NULL; + gint *dist = NULL, diff; + gboolean is_twopart = FALSE; + task = cbdata->task; if ((header = g_hash_table_lookup (cl->opts, "header")) != NULL) { - cur = - message_get_header (task->task_pool, task->message, header, FALSE); + cur = message_get_header (task->task_pool, task->message, header, FALSE); if (cur) { - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t)g_list_free, cur); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_list_free, cur); } } else { cur = g_list_first (task->text_parts); - dist = rspamd_mempool_get_variable (task->task_pool, "parts_distance"); + dist = rspamd_mempool_get_variable (task->task_pool, "parts_distance"); if (cur != NULL && cur->next != NULL && cur->next->next == NULL) { is_twopart = TRUE; } @@ -719,8 +635,7 @@ classifiers_callback (gpointer value, void *arg) c.len = strlen (cur->data); if (c.len > 0) { c.begin = cur->data; - if (!cl->tokenizer->tokenize_func (cl->tokenizer, - task->task_pool, &c, &tokens, FALSE, FALSE, NULL)) { + if (!cl->tokenizer->tokenize_func (cl->tokenizer, task->task_pool, &c, &tokens, FALSE, FALSE, NULL)) { msg_info ("cannot tokenize input"); return; } @@ -736,9 +651,7 @@ classifiers_callback (gpointer value, void *arg) /* Compare part's content */ if (*dist >= COMMON_PART_FACTOR) { - msg_info ( - "message <%s> has two common text parts, ignore the last one", - task->message_id); + msg_info ("message <%s> has two common text parts, ignore the last one", task->message_id); break; } } @@ -746,25 +659,21 @@ classifiers_callback (gpointer value, void *arg) p1 = cur->prev->data; p2 = text_part; if (p1->diff_str != NULL && p2->diff_str != NULL) { - diff = - compare_diff_distance (p1->diff_str, p2->diff_str); + diff = compare_diff_distance (p1->diff_str, p2->diff_str); } else { diff = fuzzy_compare_parts (p1, p2); } if (diff >= COMMON_PART_FACTOR) { - msg_info ( - "message <%s> has two common text parts, ignore the last one", - task->message_id); + msg_info ("message <%s> has two common text parts, ignore the last one", task->message_id); break; } } c.begin = (gchar *)text_part->content->data; c.len = text_part->content->len; /* Tree would be freed at task pool freeing */ - if (!cl->tokenizer->tokenize_func (cl->tokenizer, - task->task_pool, &c, &tokens, - FALSE, text_part->is_utf, text_part->urls_offset)) { + if (!cl->tokenizer->tokenize_func (cl->tokenizer, task->task_pool, &c, &tokens, + FALSE, text_part->is_utf, text_part->urls_offset)) { msg_info ("cannot tokenize input"); return; } @@ -783,20 +692,12 @@ classifiers_callback (gpointer value, void *arg) if (cbdata->nL != NULL) { rspamd_mutex_lock (cbdata->nL->m); - cl->classifier->classify_func (ctx, - task->worker->srv->statfile_pool, - tokens, - task, - cbdata->nL->L); + cl->classifier->classify_func (ctx, task->worker->srv->statfile_pool, tokens, task, cbdata->nL->L); rspamd_mutex_unlock (cbdata->nL->m); } else { /* Non-threaded case */ - cl->classifier->classify_func (ctx, - task->worker->srv->statfile_pool, - tokens, - task, - task->cfg->lua_state); + cl->classifier->classify_func (ctx, task->worker->srv->statfile_pool, tokens, task, task->cfg->lua_state); } /* Autolearning */ @@ -806,12 +707,7 @@ classifiers_callback (gpointer value, void *arg) if (st->autolearn) { if (check_autolearn (st->autolearn, task)) { /* Process autolearn */ - process_autolearn (st, - task, - tokens, - cl->classifier, - st->path, - ctx); + process_autolearn (st, task, tokens, cl->classifier, st->path, ctx); } } cur = g_list_next (cur); @@ -822,7 +718,7 @@ classifiers_callback (gpointer value, void *arg) void process_statfiles (struct rspamd_task *task) { - struct classifiers_cbdata cbdata; + struct classifiers_cbdata cbdata; if (task->is_skipped) { return; @@ -830,8 +726,7 @@ process_statfiles (struct rspamd_task *task) if (task->tokens == NULL) { task->tokens = g_hash_table_new (g_direct_hash, g_direct_equal); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t)g_hash_table_unref, task->tokens); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_hash_table_unref, task->tokens); } cbdata.task = task; cbdata.nL = NULL; @@ -844,9 +739,9 @@ process_statfiles (struct rspamd_task *task) void process_statfiles_threaded (gpointer data, gpointer user_data) { - struct rspamd_task *task = (struct rspamd_task *)data; - struct lua_locked_state *nL = user_data; - struct classifiers_cbdata cbdata; + struct rspamd_task *task = (struct rspamd_task *)data; + struct lua_locked_state *nL = user_data; + struct classifiers_cbdata cbdata; if (task->is_skipped) { remove_async_thread (task->s); @@ -855,8 +750,7 @@ process_statfiles_threaded (gpointer data, gpointer user_data) if (task->tokens == NULL) { task->tokens = g_hash_table_new (g_direct_hash, g_direct_equal); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t)g_hash_table_unref, task->tokens); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_hash_table_unref, task->tokens); } cbdata.task = task; @@ -866,22 +760,18 @@ process_statfiles_threaded (gpointer data, gpointer user_data) } static void -insert_metric_header (gpointer metric_name, gpointer metric_value, - gpointer data) +insert_metric_header (gpointer metric_name, gpointer metric_value, gpointer data) { #ifndef GLIB_HASH_COMPAT - struct rspamd_task *task = (struct rspamd_task *)data; - gint r = 0; + struct rspamd_task *task = (struct rspamd_task *)data; + gint r = 0; /* Try to be rfc2822 compatible and avoid long headers with folding */ - gchar header_name[128], outbuf[1000]; - GList *symbols = NULL, *cur; - struct metric_result *metric_res = (struct metric_result *)metric_value; - double ms; + gchar header_name[128], outbuf[1000]; + GList *symbols = NULL, *cur; + struct metric_result *metric_res = (struct metric_result *)metric_value; + double ms; - rspamd_snprintf (header_name, - sizeof (header_name), - "X-Spam-%s", - metric_res->metric->name); + rspamd_snprintf (header_name, sizeof (header_name), "X-Spam-%s", metric_res->metric->name); if (!check_metric_settings (task, metric_res->metric, &ms)) { ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score; @@ -910,8 +800,7 @@ insert_metric_header (gpointer metric_name, gpointer metric_value, } g_list_free (symbols); #ifdef GMIME24 - g_mime_object_append_header (GMIME_OBJECT ( - task->message), header_name, outbuf); + g_mime_object_append_header (GMIME_OBJECT (task->message), header_name, outbuf); #else g_mime_message_add_header (task->message, header_name, outbuf); #endif @@ -931,16 +820,13 @@ check_action_str (const gchar *data, gint *result) if (g_ascii_strncasecmp (data, "reject", sizeof ("reject") - 1) == 0) { *result = METRIC_ACTION_REJECT; } - else if (g_ascii_strncasecmp (data, "greylist", - sizeof ("greylist") - 1) == 0) { + else if (g_ascii_strncasecmp (data, "greylist", sizeof ("greylist") - 1) == 0) { *result = METRIC_ACTION_GREYLIST; } - else if (g_ascii_strncasecmp (data, "add_header", sizeof ("add_header") - - 1) == 0) { + else if (g_ascii_strncasecmp (data, "add_header", sizeof ("add_header") - 1) == 0) { *result = METRIC_ACTION_ADD_HEADER; } - else if (g_ascii_strncasecmp (data, "rewrite_subject", - sizeof ("rewrite_subject") - 1) == 0) { + else if (g_ascii_strncasecmp (data, "rewrite_subject", sizeof ("rewrite_subject") - 1) == 0) { *result = METRIC_ACTION_REWRITE_SUBJECT; } else { @@ -975,9 +861,9 @@ str_action_metric (enum rspamd_metric_action action) gint check_metric_action (double score, double required_score, struct metric *metric) { - struct metric_action *action, *selected_action = NULL; - double max_score = 0; - int i; + struct metric_action *action, *selected_action = NULL; + double max_score = 0; + int i; if (score >= required_score) { return METRIC_ACTION_REJECT; @@ -986,7 +872,7 @@ check_metric_action (double score, double required_score, struct metric *metric) return METRIC_ACTION_NOACTION; } else { - for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) { + for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) { action = &metric->actions[i]; if (action->score < 0) { continue; @@ -1008,26 +894,24 @@ check_metric_action (double score, double required_score, struct metric *metric) gboolean learn_task (const gchar *statfile, struct rspamd_task *task, GError **err) { - GList *cur, *ex; - struct rspamd_classifier_config *cl; - struct classifier_ctx *cls_ctx; - gchar *s; - f_str_t c; - GTree *tokens = NULL; - struct rspamd_statfile_config *st; - stat_file_t *stf; - gdouble sum; - struct mime_text_part *part, *p1, *p2; - gboolean is_utf = FALSE, is_twopart = FALSE; - gint diff; + GList *cur, *ex; + struct rspamd_classifier_config *cl; + struct classifier_ctx *cls_ctx; + gchar *s; + f_str_t c; + GTree *tokens = NULL; + struct rspamd_statfile_config *st; + stat_file_t *stf; + gdouble sum; + struct mime_text_part *part, *p1, *p2; + gboolean is_utf = FALSE, is_twopart = FALSE; + gint diff; /* Load classifier by symbol */ cl = g_hash_table_lookup (task->cfg->classifiers_symbols, statfile); if (cl == NULL) { - g_set_error (err, - filter_error_quark (), 1, "Statfile %s is not configured in any classifier", - statfile); + g_set_error (err, filter_error_quark(), 1, "Statfile %s is not configured in any classifier", statfile); return FALSE; } @@ -1035,8 +919,7 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err) if ((s = g_hash_table_lookup (cl->opts, "header")) != NULL) { cur = message_get_header (task->task_pool, task->message, s, FALSE); if (cur) { - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t)g_list_free, cur); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_list_free, cur); } } else { @@ -1076,9 +959,7 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err) diff = fuzzy_compare_parts (p1, p2); } if (diff >= COMMON_PART_FACTOR) { - msg_info ( - "message <%s> has two common text parts, ignore the last one", - task->message_id); + msg_info ("message <%s> has two common text parts, ignore the last one", task->message_id); break; } } @@ -1087,8 +968,7 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err) if (!cl->tokenizer->tokenize_func ( cl->tokenizer, task->task_pool, &c, &tokens, FALSE, is_utf, ex)) { - g_set_error (err, - filter_error_quark (), 2, "Cannot tokenize message"); + g_set_error (err, filter_error_quark(), 2, "Cannot tokenize message"); return FALSE; } cur = g_list_next (cur); @@ -1096,10 +976,8 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err) /* Handle messages without text */ if (tokens == NULL) { - g_set_error (err, - filter_error_quark (), 3, "Cannot tokenize message, no text data"); - msg_info ("learn failed for message <%s>, no tokens to extract", - task->message_id); + g_set_error (err, filter_error_quark(), 3, "Cannot tokenize message, no text data"); + msg_info ("learn failed for message <%s>, no tokens to extract", task->message_id); return FALSE; } @@ -1108,7 +986,7 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err) /* Init classifier */ cls_ctx = cl->classifier->init_func ( - task->task_pool, cl); + task->task_pool, cl); /* Get or create statfile */ stf = get_statfile_by_symbol (task->worker->srv->statfile_pool, cl, statfile, &st, TRUE); @@ -1119,17 +997,12 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err) statfile, tokens, TRUE, &sum, 1.0, err)) { if (*err) { - msg_info ("learn failed for message <%s>, learn error: %s", - task->message_id, - (*err)->message); + msg_info ("learn failed for message <%s>, learn error: %s", task->message_id, (*err)->message); return FALSE; } else { - g_set_error (err, - filter_error_quark (), 4, - "Learn failed, unknown learn classifier error"); - msg_info ("learn failed for message <%s>, unknown learn error", - task->message_id); + g_set_error (err, filter_error_quark(), 4, "Learn failed, unknown learn classifier error"); + msg_info ("learn failed for message <%s>, unknown learn error", task->message_id); return FALSE; } } @@ -1137,31 +1010,25 @@ learn_task (const gchar *statfile, struct rspamd_task *task, GError **err) task->worker->srv->stat->messages_learned++; maybe_write_binlog (cl, st, stf, tokens); - msg_info ( - "learn success for message <%s>, for statfile: %s, sum weight: %.2f", - task->message_id, - statfile, - sum); + msg_info ("learn success for message <%s>, for statfile: %s, sum weight: %.2f", + task->message_id, statfile, sum); statfile_pool_plan_invalidate (task->worker->srv->statfile_pool, - DEFAULT_STATFILE_INVALIDATE_TIME, - DEFAULT_STATFILE_INVALIDATE_JITTER); + DEFAULT_STATFILE_INVALIDATE_TIME, + DEFAULT_STATFILE_INVALIDATE_JITTER); return TRUE; } gboolean -learn_task_spam (struct rspamd_classifier_config *cl, - struct rspamd_task *task, - gboolean is_spam, - GError **err) +learn_task_spam (struct rspamd_classifier_config *cl, struct rspamd_task *task, gboolean is_spam, GError **err) { - GList *cur, *ex; - struct classifier_ctx *cls_ctx; - f_str_t c; - GTree *tokens = NULL; - struct mime_text_part *part, *p1, *p2; - gboolean is_utf = FALSE, is_twopart = FALSE; - gint diff; + GList *cur, *ex; + struct classifier_ctx *cls_ctx; + f_str_t c; + GTree *tokens = NULL; + struct mime_text_part *part, *p1, *p2; + gboolean is_utf = FALSE, is_twopart = FALSE; + gint diff; cur = g_list_first (task->text_parts); if (cur != NULL && cur->next != NULL && cur->next->next == NULL) { @@ -1194,9 +1061,7 @@ learn_task_spam (struct rspamd_classifier_config *cl, diff = fuzzy_compare_parts (p1, p2); } if (diff >= COMMON_PART_FACTOR) { - msg_info ( - "message <%s> has two common text parts, ignore the last one", - task->message_id); + msg_info ("message <%s> has two common text parts, ignore the last one", task->message_id); break; } } @@ -1204,8 +1069,7 @@ learn_task_spam (struct rspamd_classifier_config *cl, if (!cl->tokenizer->tokenize_func ( cl->tokenizer, task->task_pool, &c, &tokens, FALSE, is_utf, ex)) { - g_set_error (err, - filter_error_quark (), 2, "Cannot tokenize message"); + g_set_error (err, filter_error_quark(), 2, "Cannot tokenize message"); return FALSE; } cur = g_list_next (cur); @@ -1213,10 +1077,8 @@ learn_task_spam (struct rspamd_classifier_config *cl, /* Handle messages without text */ if (tokens == NULL) { - g_set_error (err, - filter_error_quark (), 3, "Cannot tokenize message, no text data"); - msg_info ("learn failed for message <%s>, no tokens to extract", - task->message_id); + g_set_error (err, filter_error_quark(), 3, "Cannot tokenize message, no text data"); + msg_info ("learn failed for message <%s>, no tokens to extract", task->message_id); return FALSE; } @@ -1225,23 +1087,18 @@ learn_task_spam (struct rspamd_classifier_config *cl, /* Init classifier */ cls_ctx = cl->classifier->init_func ( - task->task_pool, cl); + task->task_pool, cl); /* Learn */ if (!cl->classifier->learn_spam_func ( cls_ctx, task->worker->srv->statfile_pool, tokens, task, is_spam, task->cfg->lua_state, err)) { if (*err) { - msg_info ("learn failed for message <%s>, learn error: %s", - task->message_id, - (*err)->message); + msg_info ("learn failed for message <%s>, learn error: %s", task->message_id, (*err)->message); return FALSE; } else { - g_set_error (err, - filter_error_quark (), 4, - "Learn failed, unknown learn classifier error"); - msg_info ("learn failed for message <%s>, unknown learn error", - task->message_id); + g_set_error (err, filter_error_quark(), 4, "Learn failed, unknown learn classifier error"); + msg_info ("learn failed for message <%s>, unknown learn error", task->message_id); return FALSE; } } @@ -1249,14 +1106,14 @@ learn_task_spam (struct rspamd_classifier_config *cl, task->worker->srv->stat->messages_learned++; msg_info ("learn success for message <%s>", - task->message_id); + task->message_id); statfile_pool_plan_invalidate (task->worker->srv->statfile_pool, - DEFAULT_STATFILE_INVALIDATE_TIME, - DEFAULT_STATFILE_INVALIDATE_JITTER); + DEFAULT_STATFILE_INVALIDATE_TIME, + DEFAULT_STATFILE_INVALIDATE_JITTER); return TRUE; } -/* - * vi:ts=4 +/* + * vi:ts=4 */ diff --git a/src/libmime/filter.h b/src/libmime/filter.h index f0a343483..2891ebd00 100644 --- a/src/libmime/filter.h +++ b/src/libmime/filter.h @@ -14,8 +14,7 @@ struct rspamd_task; struct rspamd_settings; struct rspamd_classifier_config; -typedef double (*metric_cons_func)(struct rspamd_task *task, - const gchar *metric_name, const gchar *func_name); +typedef double (*metric_cons_func)(struct rspamd_task *task, const gchar *metric_name, const gchar *func_name); typedef void (*filter_func)(struct rspamd_task *task); enum filter_type { C_FILTER, PERL_FILTER }; @@ -24,17 +23,17 @@ enum filter_type { C_FILTER, PERL_FILTER }; * Filter structure */ struct filter { - gchar *func_name; /**< function name */ - enum filter_type type; /**< filter type (c or perl) */ - module_t *module; + gchar *func_name; /**< function name */ + enum filter_type type; /**< filter type (c or perl) */ + module_t *module; }; /** * Rspamd symbol */ struct symbol { - double score; /**< symbol's score */ - GList *options; /**< list of symbol's options */ + double score; /**< symbol's score */ + GList *options; /**< list of symbol's options */ const gchar *name; }; @@ -47,25 +46,25 @@ struct metric_action { * Common definition of metric */ struct metric { - const gchar *name; /**< name of metric */ - gchar *func_name; /**< name of consolidation function */ - metric_cons_func func; /**< c consolidation function */ - double grow_factor; /**< grow factor for metric */ - GHashTable *symbols; /**< weights of symbols in metric */ - GHashTable *descriptions; /**< descriptions of symbols in metric */ + const gchar *name; /**< name of metric */ + gchar *func_name; /**< name of consolidation function */ + metric_cons_func func; /**< c consolidation function */ + double grow_factor; /**< grow factor for metric */ + GHashTable *symbols; /**< weights of symbols in metric */ + GHashTable *descriptions; /**< descriptions of symbols in metric */ struct metric_action actions[METRIC_ACTION_MAX]; /**< all actions of the metric */ - gchar *subject; /**< subject rewrite string */ + gchar *subject; /**< subject rewrite string */ }; /** * Result of metric processing */ struct metric_result { - struct metric *metric; /**< pointer to metric structure */ - double score; /**< total score */ - GHashTable *symbols; /**< symbols of metric */ - gboolean checked; /**< whether metric result is consolidated */ - double grow_factor; /**< current grow factor */ + struct metric *metric; /**< pointer to metric structure */ + double score; /**< total score */ + GHashTable *symbols; /**< symbols of metric */ + gboolean checked; /**< whether metric result is consolidated */ + double grow_factor; /**< current grow factor */ }; /** @@ -103,10 +102,7 @@ void process_statfiles_threaded (gpointer data, gpointer user_data); * @param flag numeric weight for symbol * @param opts list of symbol's options */ -void insert_result (struct rspamd_task *task, - const gchar *symbol, - double flag, - GList *opts); +void insert_result (struct rspamd_task *task, const gchar *symbol, double flag, GList *opts); /** * Insert a single result to task @@ -116,10 +112,7 @@ void insert_result (struct rspamd_task *task, * @param flag numeric weight for symbol * @param opts list of symbol's options */ -void insert_result_single (struct rspamd_task *task, - const gchar *symbol, - double flag, - GList *opts); +void insert_result_single (struct rspamd_task *task, const gchar *symbol, double flag, GList *opts); /** * Process all results and form composite metrics from existent metrics as it is defined in config @@ -128,15 +121,13 @@ void insert_result_single (struct rspamd_task *task, void make_composites (struct rspamd_task *task); /** - * Default consolidation function for metric, it get all symbols and multiply symbol + * Default consolidation function for metric, it get all symbols and multiply symbol * weight by some factor that is specified in config. Default factor is 1. * @param task worker's task that present message from user * @param metric_name name of metric * @return result metric weight */ -double factor_consolidation_func (struct rspamd_task *task, - const gchar *metric_name, - const gchar *unused); +double factor_consolidation_func (struct rspamd_task *task, const gchar *metric_name, const gchar *unused); /* * Learn specified statfile with message in a task @@ -145,9 +136,7 @@ double factor_consolidation_func (struct rspamd_task *task, * @param err pointer to GError * @return true if learn succeed */ -gboolean learn_task (const gchar *statfile, - struct rspamd_task *task, - GError **err); +gboolean learn_task (const gchar *statfile, struct rspamd_task *task, GError **err); /* * Learn specified statfile with message in a task @@ -156,10 +145,7 @@ gboolean learn_task (const gchar *statfile, * @param err pointer to GError * @return true if learn succeed */ -gboolean learn_task_spam (struct rspamd_classifier_config *cl, - struct rspamd_task *task, - gboolean is_spam, - GError **err); +gboolean learn_task_spam (struct rspamd_classifier_config *cl, struct rspamd_task *task, gboolean is_spam, GError **err); /* * Get action from a string @@ -169,13 +155,11 @@ gboolean check_action_str (const gchar *data, gint *result); /* * Return textual representation of action enumeration */ -const gchar * str_action_metric (enum rspamd_metric_action action); +const gchar *str_action_metric (enum rspamd_metric_action action); /* * Get action for specific metric */ -gint check_metric_action (double score, - double required_score, - struct metric *metric); +gint check_metric_action (double score, double required_score, struct metric *metric); #endif diff --git a/src/libmime/images.c b/src/libmime/images.c index 3b2ceecd1..ff07bbd72 100644 --- a/src/libmime/images.c +++ b/src/libmime/images.c @@ -32,20 +32,19 @@ static const guint8 jpg_sig2[] = {'J', 'F', 'I', 'F'}; static const guint8 gif_signature[] = {'G', 'I', 'F', '8'}; static const guint8 bmp_signature[] = {'B', 'M'}; -static void process_image (struct rspamd_task *task, struct mime_part *part); +static void process_image (struct rspamd_task *task, struct mime_part *part); void process_images (struct rspamd_task *task) { - GList *cur; - struct mime_part *part; + GList *cur; + struct mime_part *part; cur = task->parts; while (cur) { part = cur->data; - if (g_mime_content_type_is_type (part->type, "image", - "*") && part->content->len > 0) { + if (g_mime_content_type_is_type (part->type, "image", "*") && part->content->len > 0) { process_image (task, part); } cur = g_list_next (cur); @@ -86,9 +85,9 @@ detect_image_type (GByteArray *data) static struct rspamd_image * process_png_image (struct rspamd_task *task, GByteArray *data) { - struct rspamd_image *img; - guint32 t; - guint8 *p; + struct rspamd_image *img; + guint32 t; + guint8 *p; if (data->len < 24) { msg_info ("bad png detected (maybe striped): <%s>", task->message_id); @@ -120,10 +119,10 @@ process_png_image (struct rspamd_task *task, GByteArray *data) static struct rspamd_image * process_jpg_image (struct rspamd_task *task, GByteArray *data) { - guint8 *p; - guint16 t; - gsize remain; - struct rspamd_image *img; + guint8 *p; + guint16 t; + gsize remain; + struct rspamd_image *img; img = rspamd_mempool_alloc (task->task_pool, sizeof (struct rspamd_image)); img->type = IMAGE_TYPE_JPG; @@ -132,16 +131,15 @@ process_jpg_image (struct rspamd_task *task, GByteArray *data) p = data->data; remain = data->len; /* In jpeg we should find any data stream (ff c0 .. ff c3) and extract its height and width */ - while (remain--) { - if (*p == 0xFF && remain > 8 && - (*(p + 1) >= 0xC0 && *(p + 1) <= 0xC3)) { + while (remain --) { + if (*p == 0xFF && remain > 8 && (*(p + 1) >= 0xC0 && *(p + 1) <= 0xC3)) { memcpy (&t, p + 5, sizeof (guint16)); img->height = ntohs (t); memcpy (&t, p + 7, sizeof (guint16)); img->width = ntohs (t); return img; } - p++; + p ++; } return NULL; @@ -150,9 +148,9 @@ process_jpg_image (struct rspamd_task *task, GByteArray *data) static struct rspamd_image * process_gif_image (struct rspamd_task *task, GByteArray *data) { - struct rspamd_image *img; - guint8 *p; - guint16 t; + struct rspamd_image *img; + guint8 *p; + guint16 t; if (data->len < 10) { msg_info ("bad gif detected (maybe striped): <%s>", task->message_id); @@ -164,7 +162,7 @@ process_gif_image (struct rspamd_task *task, GByteArray *data) img->data = data; p = data->data + 6; - memcpy (&t, p, sizeof (guint16)); + memcpy (&t, p, sizeof (guint16)); img->width = GUINT16_FROM_LE (t); memcpy (&t, p + 2, sizeof (guint16)); img->height = GUINT16_FROM_LE (t); @@ -175,9 +173,9 @@ process_gif_image (struct rspamd_task *task, GByteArray *data) static struct rspamd_image * process_bmp_image (struct rspamd_task *task, GByteArray *data) { - struct rspamd_image *img; - gint32 t; - guint8 *p; + struct rspamd_image *img; + gint32 t; + guint8 *p; @@ -190,7 +188,7 @@ process_bmp_image (struct rspamd_task *task, GByteArray *data) img->type = IMAGE_TYPE_BMP; img->data = data; p = data->data + 18; - memcpy (&t, p, sizeof (gint32)); + memcpy (&t, p, sizeof (gint32)); img->width = abs (GINT32_FROM_LE (t)); memcpy (&t, p + 4, sizeof (gint32)); img->height = abs (GINT32_FROM_LE (t)); @@ -201,8 +199,8 @@ process_bmp_image (struct rspamd_task *task, GByteArray *data) static void process_image (struct rspamd_task *task, struct mime_part *part) { - enum known_image_types type; - struct rspamd_image *img = NULL; + enum known_image_types type; + struct rspamd_image *img = NULL; if ((type = detect_image_type (part->content)) != IMAGE_TYPE_UNKNOWN) { switch (type) { case IMAGE_TYPE_PNG: @@ -225,9 +223,9 @@ process_image (struct rspamd_task *task, struct mime_part *part) if (img != NULL) { debug_task ("detected %s image of size %ud x %ud in message <%s>", - image_type_str (img->type), - img->width, img->height, - task->message_id); + image_type_str (img->type), + img->width, img->height, + task->message_id); img->filename = part->filename; task->images = g_list_prepend (task->images, img); } diff --git a/src/libmime/images.h b/src/libmime/images.h index 5648f030f..c43941ebc 100644 --- a/src/libmime/images.h +++ b/src/libmime/images.h @@ -28,6 +28,6 @@ void process_images (struct rspamd_task *task); /* * Get textual representation of an image's type */ -const gchar * image_type_str (enum known_image_types type); +const gchar *image_type_str (enum known_image_types type); #endif /* IMAGES_H_ */ diff --git a/src/libmime/message.c b/src/libmime/message.c index c6de73782..4567869e9 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -22,30 +22,26 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "cfg_file.h" #include "config.h" -#include "html.h" -#include "images.h" +#include "util.h" #include "main.h" #include "message.h" -#include "util.h" +#include "cfg_file.h" +#include "html.h" +#include "images.h" #define RECURSION_LIMIT 30 #define UTF8_CHARSET "UTF-8" -GByteArray * -strip_html_tags (struct rspamd_task *task, - rspamd_mempool_t * pool, - struct mime_text_part *part, - GByteArray * src, - gint *stateptr) +GByteArray * +strip_html_tags (struct rspamd_task *task, rspamd_mempool_t * pool, struct mime_text_part *part, GByteArray * src, gint *stateptr) { - uint8_t *p, *rp, *tbegin = NULL, *end, c, lc; - gint br, i = 0, depth = 0, in_q = 0; - gint state = 0; - GByteArray *buf; - GNode *level_ptr = NULL; - gboolean erase = FALSE; + uint8_t *p, *rp, *tbegin = NULL, *end, c, lc; + gint br, i = 0, depth = 0, in_q = 0; + gint state = 0; + GByteArray *buf; + GNode *level_ptr = NULL; + gboolean erase = FALSE; if (stateptr) state = *stateptr; @@ -75,11 +71,11 @@ strip_html_tags (struct rspamd_task *task, } else if (state == 1) { /* Opening bracket without closing one */ - p--; + p --; while (g_ascii_isspace (*p) && p > src->data) { - p--; + p --; } - p++; + p ++; goto unbreak_tag; } break; @@ -119,19 +115,13 @@ strip_html_tags (struct rspamd_task *task, } unbreak_tag: switch (state) { - case 1: /* HTML/XML */ + case 1: /* HTML/XML */ lc = '>'; in_q = state = 0; - erase = !add_html_node (task, - pool, - part, - tbegin, - p - tbegin, - end - tbegin, - &level_ptr); + erase = !add_html_node (task, pool, part, tbegin, p - tbegin, end - tbegin, &level_ptr); break; - case 2: /* PHP */ + case 2: /* PHP */ if (!br && lc != '\"' && *(p - 1) == '?') { in_q = state = 0; } @@ -141,7 +131,7 @@ unbreak_tag: in_q = state = 0; break; - case 4: /* JavaScript/CSS/etc... */ + case 4: /* JavaScript/CSS/etc... */ if (p >= src->data + 2 && *(p - 1) == '-' && *(p - 2) == '-') { in_q = state = 0; } @@ -168,8 +158,7 @@ unbreak_tag: else if (state == 0 && !erase) { *(rp++) = c; } - if (state && p != src->data && *(p - 1) != '\\' && - (!in_q || *p == in_q)) { + if (state && p != src->data && *(p - 1) != '\\' && (!in_q || *p == in_q)) { if (in_q) { in_q = 0; } @@ -193,8 +182,7 @@ unbreak_tag: break; case '-': - if (state == 3 && p >= src->data + 2 && *(p - 1) == '-' && - *(p - 2) == '!') { + if (state == 3 && p >= src->data + 2 && *(p - 1) == '-' && *(p - 2) == '!') { state = 4; } else { @@ -216,14 +204,11 @@ unbreak_tag: if (state == 3 && p > src->data + 6 && g_ascii_tolower (*(p - 1)) == 'p' && g_ascii_tolower (*(p - 2)) == 'y' - && g_ascii_tolower (*(p - 3)) == 't' && - g_ascii_tolower (*(p - 4)) == 'c' && - g_ascii_tolower (*(p - 5)) == 'o' && - g_ascii_tolower (*(p - 6)) == 'd') { + && g_ascii_tolower (*(p - 3)) == 't' && g_ascii_tolower (*(p - 4)) == 'c' && g_ascii_tolower (*(p - 5)) == 'o' && g_ascii_tolower (*(p - 6)) == 'd') { state = 1; break; } - /* fall-through */ + /* fall-through */ case 'l': @@ -231,15 +216,14 @@ unbreak_tag: * state == 2 (PHP). Switch back to HTML. */ - if (state == 2 && p > src->data + 2 && *(p - 1) == 'm' && - *(p - 2) == 'x') { + if (state == 2 && p > src->data + 2 && *(p - 1) == 'm' && *(p - 2) == 'x') { state = 1; break; } - /* fall-through */ + /* fall-through */ default: -reg_char: + reg_char: if (state == 0 && !erase) { *(rp++) = c; } @@ -268,11 +252,9 @@ reg_char: } static void -parse_qmail_recv (rspamd_mempool_t * pool, - gchar *line, - struct received_header *r) +parse_qmail_recv (rspamd_mempool_t * pool, gchar *line, struct received_header *r) { - gchar *s, *p, t; + gchar *s, *p, t; /* We are interested only with received from network headers */ if ((p = strstr (line, "from network")) == NULL) { @@ -287,7 +269,7 @@ parse_qmail_recv (rspamd_mempool_t * pool, /* format is ip/host */ s = p; if (*p) { - while (g_ascii_isdigit (*++p) || *p == '.') ; + while (g_ascii_isdigit (*++p) || *p == '.'); if (*p != '/') { r->is_error = 1; return; @@ -298,8 +280,7 @@ parse_qmail_recv (rspamd_mempool_t * pool, *p = '/'; /* Now try to parse hostname */ s = ++p; - while (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == - '_') { + while (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') { p++; } t = *p; @@ -311,11 +292,9 @@ parse_qmail_recv (rspamd_mempool_t * pool, } static void -parse_recv_header (rspamd_mempool_t * pool, - gchar *line, - struct received_header *r) +parse_recv_header (rspamd_mempool_t * pool, gchar *line, struct received_header *r) { - gchar *p, *s, t, **res = NULL; + gchar *p, *s, t, **res = NULL; enum { RSPAMD_RECV_STATE_INIT = 0, RSPAMD_RECV_STATE_FROM, @@ -326,8 +305,8 @@ parse_recv_header (rspamd_mempool_t * pool, RSPAMD_RECV_STATE_SKIP_SPACES, RSPAMD_RECV_STATE_ERROR } state = RSPAMD_RECV_STATE_INIT, - next_state = RSPAMD_RECV_STATE_INIT; - gboolean is_exim = FALSE; + next_state = RSPAMD_RECV_STATE_INIT; + gboolean is_exim = FALSE; g_strstrip (line); p = line; @@ -335,18 +314,16 @@ parse_recv_header (rspamd_mempool_t * pool, while (*p) { switch (state) { - /* Initial state, search for from */ + /* Initial state, search for from */ case RSPAMD_RECV_STATE_INIT: if (*p == 'f' || *p == 'F') { - if (g_ascii_tolower (*++p) == 'r' && g_ascii_tolower (*++p) == - 'o' && g_ascii_tolower (*++p) == 'm') { + if (g_ascii_tolower (*++p) == 'r' && g_ascii_tolower (*++p) == 'o' && g_ascii_tolower (*++p) == 'm') { p++; state = RSPAMD_RECV_STATE_SKIP_SPACES; next_state = RSPAMD_RECV_STATE_FROM; } } - else if (g_ascii_tolower (*p) == 'b' && - g_ascii_tolower (*(p + 1)) == 'y') { + else if (g_ascii_tolower (*p) == 'b' && g_ascii_tolower (*(p + 1)) == 'y') { state = RSPAMD_RECV_STATE_IP_BLOCK; } else { @@ -355,7 +332,7 @@ parse_recv_header (rspamd_mempool_t * pool, return; } break; - /* Read hostname */ + /* Read hostname */ case RSPAMD_RECV_STATE_FROM: if (*p == '[') { /* This should be IP address */ @@ -364,8 +341,7 @@ parse_recv_header (rspamd_mempool_t * pool, next_state = RSPAMD_RECV_STATE_IP_BLOCK; s = ++p; } - else if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == - '_') { + else if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || *p == '_') { p++; } else { @@ -377,11 +353,10 @@ parse_recv_header (rspamd_mempool_t * pool, next_state = RSPAMD_RECV_STATE_IP_BLOCK; } break; - /* Try to extract additional info */ + /* Try to extract additional info */ case RSPAMD_RECV_STATE_IP_BLOCK: /* Try to extract ip or () info or by */ - if (g_ascii_tolower (*p) == 'b' && g_ascii_tolower (*(p + 1)) == - 'y') { + if (g_ascii_tolower (*p) == 'b' && g_ascii_tolower (*(p + 1)) == 'y') { p += 2; /* Skip spaces after by */ state = RSPAMD_RECV_STATE_SKIP_SPACES; @@ -403,11 +378,11 @@ parse_recv_header (rspamd_mempool_t * pool, p++; } break; - /* We are in () block. Here can be found real hostname and real ip, this is written by some MTA */ + /* We are in () block. Here can be found real hostname and real ip, this is written by some MTA */ case RSPAMD_RECV_STATE_BRACES_BLOCK: /* End of block */ if (g_ascii_isalnum (*p) || *p == '.' || *p == '-' || - *p == '_' || *p == ':') { + *p == '_' || *p == ':') { p++; } else if (*p == '[') { @@ -429,45 +404,41 @@ parse_recv_header (rspamd_mempool_t * pool, next_state = RSPAMD_RECV_STATE_BRACES_BLOCK; } else if (p - s == 4 && memcmp (s, "helo=", 5) == 0) { - p++; + p ++; is_exim = TRUE; - if (r->real_hostname == NULL && r->from_hostname != - NULL) { + if (r->real_hostname == NULL && r->from_hostname != NULL) { r->real_hostname = r->from_hostname; } s = p; - while (*p != ')' && !g_ascii_isspace (*p) && *p != - '\0') { - p++; + while (*p != ')' && !g_ascii_isspace (*p) && *p != '\0') { + p ++; } if (p > s) { - r->from_hostname = rspamd_mempool_alloc (pool, - p - s + 1); + r->from_hostname = rspamd_mempool_alloc (pool, p - s + 1); rspamd_strlcpy (r->from_hostname, s, p - s + 1); } } else if (p - s == 4 && memcmp (s, "port=", 5) == 0) { - p++; + p ++; is_exim = TRUE; while (g_ascii_isdigit (*p)) { - p++; + p ++; } state = RSPAMD_RECV_STATE_SKIP_SPACES; next_state = RSPAMD_RECV_STATE_BRACES_BLOCK; } else if (*p == '=' && is_exim) { /* Just skip unknown pairs */ - p++; - while (!g_ascii_isspace (*p) && *p != ')' && *p != - '\0') { - p++; + p ++; + while (!g_ascii_isspace (*p) && *p != ')' && *p != '\0') { + p ++; } state = RSPAMD_RECV_STATE_SKIP_SPACES; next_state = RSPAMD_RECV_STATE_BRACES_BLOCK; } else { /* skip all */ - while (*p++ != ')' && *p != '\0') ; + while (*p++ != ')' && *p != '\0'); state = RSPAMD_RECV_STATE_IP_BLOCK; } } @@ -486,13 +457,13 @@ parse_recv_header (rspamd_mempool_t * pool, continue; } if (*p == ')') { - p++; + p ++; state = RSPAMD_RECV_STATE_SKIP_SPACES; next_state = RSPAMD_RECV_STATE_IP_BLOCK; } } else if (*p == ')') { - p++; + p ++; state = RSPAMD_RECV_STATE_SKIP_SPACES; next_state = RSPAMD_RECV_STATE_IP_BLOCK; } @@ -502,11 +473,11 @@ parse_recv_header (rspamd_mempool_t * pool, } } break; - /* Got by word */ + /* Got by word */ case RSPAMD_RECV_STATE_BY_BLOCK: /* Here can be only hostname */ if ((g_ascii_isalnum (*p) || *p == '.' || *p == '-' - || *p == '_') && p[1] != '\0') { + || *p == '_') && p[1] != '\0') { p++; } else { @@ -528,8 +499,7 @@ parse_recv_header (rspamd_mempool_t * pool, } else if (r->from_ip == NULL && r->real_ip != NULL) { r->from_ip = r->real_ip; - if (r->real_hostname == NULL && r->from_hostname != - NULL) { + if (r->real_hostname == NULL && r->from_hostname != NULL) { r->real_hostname = r->from_hostname; } } @@ -538,10 +508,10 @@ parse_recv_header (rspamd_mempool_t * pool, } break; - /* Extract ip */ + /* Extract ip */ case RSPAMD_RECV_STATE_PARSE_IP: while (g_ascii_isxdigit (*p) || *p == '.' || *p == ':') { - p++; + p ++; } if (*p != ']') { /* Not an ip in fact */ @@ -557,7 +527,7 @@ parse_recv_header (rspamd_mempool_t * pool, } break; - /* Skip spaces */ + /* Skip spaces */ case RSPAMD_RECV_STATE_SKIP_SPACES: if (!g_ascii_isspace (*p)) { state = next_state; @@ -582,10 +552,10 @@ parse_recv_header (rspamd_mempool_t * pool, static void process_raw_headers (struct rspamd_task *task) { - struct raw_header *new = NULL, *lp; - gchar *p, *c, *tmp, *tp; - gint state = 0, l, next_state = 100, err_state = 100, t_state; - gboolean valid_folding = FALSE; + struct raw_header *new = NULL, *lp; + gchar *p, *c, *tmp, *tp; + gint state = 0, l, next_state = 100, err_state = 100, t_state; + gboolean valid_folding = FALSE; p = task->raw_headers_str; c = p; @@ -607,15 +577,13 @@ process_raw_headers (struct rspamd_task *task) case 1: /* We got something like header's name */ if (*p == ':') { - new = - rspamd_mempool_alloc0 (task->task_pool, - sizeof (struct raw_header)); + new = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct raw_header)); l = p - c; tmp = rspamd_mempool_alloc (task->task_pool, l + 1); rspamd_strlcpy (tmp, c, l + 1); new->name = tmp; new->empty_separator = TRUE; - p++; + p ++; state = 2; c = p; } @@ -625,7 +593,7 @@ process_raw_headers (struct rspamd_task *task) next_state = 0; } else { - p++; + p ++; } break; case 2: @@ -633,11 +601,11 @@ process_raw_headers (struct rspamd_task *task) if (*p == '\t') { new->tab_separated = TRUE; new->empty_separator = FALSE; - p++; + p ++; } else if (*p == ' ') { new->empty_separator = FALSE; - p++; + p ++; } else if (*p == '\n' || *p == '\r') { /* Process folding */ @@ -675,7 +643,7 @@ process_raw_headers (struct rspamd_task *task) state = 4; } else { - p++; + p ++; } break; case 4: @@ -684,16 +652,16 @@ process_raw_headers (struct rspamd_task *task) tmp = rspamd_mempool_alloc (task->task_pool, l + 1); tp = tmp; t_state = 0; - while (l--) { + while (l --) { if (t_state == 0) { /* Before folding */ if (*c == '\n' || *c == '\r') { t_state = 1; - c++; - *tp++ = ' '; + c ++; + *tp ++ = ' '; } else { - *tp++ = *c++; + *tp ++ = *c ++; } } else if (t_state == 1) { @@ -703,19 +671,18 @@ process_raw_headers (struct rspamd_task *task) } else { t_state = 0; - *tp++ = *c++; + *tp ++ = *c ++; } } } /* Strip last space that can be added by \r\n parsing */ if (*(tp - 1) == ' ') { - tp--; + tp --; } *tp = '\0'; new->value = tmp; new->next = NULL; - if ((lp = - g_hash_table_lookup (task->raw_headers, new->name)) != NULL) { + if ((lp = g_hash_table_lookup (task->raw_headers, new->name)) != NULL) { while (lp->next != NULL) { lp = lp->next; } @@ -731,8 +698,7 @@ process_raw_headers (struct rspamd_task *task) /* Header has only name, no value */ new->next = NULL; new->value = ""; - if ((lp = - g_hash_table_lookup (task->raw_headers, new->name)) != NULL) { + if ((lp = g_hash_table_lookup (task->raw_headers, new->name)) != NULL) { while (lp->next != NULL) { lp = lp->next; } @@ -751,12 +717,12 @@ process_raw_headers (struct rspamd_task *task) } else { if (*p == '\r' || *p == '\n') { - p++; + p ++; valid_folding = FALSE; } else if (*p == '\t' || *p == ' ') { /* Valid folding */ - p++; + p ++; valid_folding = TRUE; } else { @@ -776,24 +742,24 @@ process_raw_headers (struct rspamd_task *task) /* Fail state, skip line */ if (*p == '\r') { if (*(p + 1) == '\n') { - p++; + p ++; } - p++; + p ++; state = next_state; } else if (*p == '\n') { if (*(p + 1) == '\r') { - p++; + p ++; } - p++; + p ++; state = next_state; } else if (*(p + 1) == '\0') { state = next_state; - p++; + p ++; } else { - p++; + p ++; } break; } @@ -803,62 +769,45 @@ process_raw_headers (struct rspamd_task *task) static void free_byte_array_callback (void *pointer) { - GByteArray *arr = (GByteArray *) pointer; + GByteArray *arr = (GByteArray *) pointer; g_byte_array_free (arr, TRUE); } -static GByteArray * -convert_text_to_utf (struct rspamd_task *task, - GByteArray * part_content, - GMimeContentType * type, - struct mime_text_part *text_part) +static GByteArray * +convert_text_to_utf (struct rspamd_task *task, GByteArray * part_content, GMimeContentType * type, struct mime_text_part *text_part) { - GError *err = NULL; - gsize read_bytes, write_bytes; - const gchar *charset; - gchar *res_str; - GByteArray *result_array; + GError *err = NULL; + gsize read_bytes, write_bytes; + const gchar *charset; + gchar *res_str; + GByteArray *result_array; if (task->cfg->raw_mode) { text_part->is_raw = TRUE; return part_content; } - if ((charset = - g_mime_content_type_get_parameter (type, "charset")) == NULL) { + if ((charset = g_mime_content_type_get_parameter (type, "charset")) == NULL) { text_part->is_raw = TRUE; return part_content; } - if (g_ascii_strcasecmp (charset, - "utf-8") == 0 || g_ascii_strcasecmp (charset, "utf8") == 0) { + if (g_ascii_strcasecmp (charset, "utf-8") == 0 || g_ascii_strcasecmp (charset, "utf8") == 0) { if (g_utf8_validate (part_content->data, part_content->len, NULL)) { text_part->is_raw = FALSE; text_part->is_utf = TRUE; return part_content; } else { - msg_info ( - "<%s>: contains invalid utf8 characters, assume it as raw", - task->message_id); + msg_info ("<%s>: contains invalid utf8 characters, assume it as raw", task->message_id); text_part->is_raw = TRUE; return part_content; } } - res_str = g_convert_with_fallback (part_content->data, - part_content->len, - UTF8_CHARSET, - charset, - NULL, - &read_bytes, - &write_bytes, - &err); + res_str = g_convert_with_fallback (part_content->data, part_content->len, UTF8_CHARSET, charset, NULL, &read_bytes, &write_bytes, &err); if (res_str == NULL) { - msg_warn ("<%s>: cannot convert from %s to utf8: %s", - task->message_id, - charset, - err ? err->message : "unknown problem"); + msg_warn ("<%s>: cannot convert from %s to utf8: %s", task->message_id, charset, err ? err->message : "unknown problem"); text_part->is_raw = TRUE; return part_content; } @@ -866,9 +815,7 @@ convert_text_to_utf (struct rspamd_task *task, result_array = rspamd_mempool_alloc (task->task_pool, sizeof (GByteArray)); result_array->data = res_str; result_array->len = write_bytes; - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_free, - res_str); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_free, res_str); text_part->is_raw = FALSE; text_part->is_utf = TRUE; @@ -876,43 +823,31 @@ convert_text_to_utf (struct rspamd_task *task, } static void -process_text_part (struct rspamd_task *task, - GByteArray *part_content, - GMimeContentType *type, - GMimeObject *part, - GMimeObject *parent, - gboolean is_empty) +process_text_part (struct rspamd_task *task, GByteArray *part_content, GMimeContentType *type, + GMimeObject *part, GMimeObject *parent, gboolean is_empty) { - struct mime_text_part *text_part; - const gchar *cd; + struct mime_text_part *text_part; + const gchar *cd; /* Skip attachements */ #ifndef GMIME24 cd = g_mime_part_get_content_disposition (GMIME_PART (part)); - if (cd && - g_ascii_strcasecmp (cd, - "attachment") == 0 && !task->cfg->check_text_attachements) { + if (cd && g_ascii_strcasecmp (cd, "attachment") == 0 && !task->cfg->check_text_attachements) { debug_task ("skip attachments for checking as text parts"); return; } #else cd = g_mime_object_get_disposition (GMIME_OBJECT (part)); - if (cd && - g_ascii_strcasecmp (cd, - GMIME_DISPOSITION_ATTACHMENT) == 0 && - !task->cfg->check_text_attachements) { + if (cd && g_ascii_strcasecmp (cd, GMIME_DISPOSITION_ATTACHMENT) == 0 && !task->cfg->check_text_attachements) { debug_task ("skip attachments for checking as text parts"); return; } #endif - if (g_mime_content_type_is_type (type, "text", - "html") || g_mime_content_type_is_type (type, "text", "xhtml")) { + if (g_mime_content_type_is_type (type, "text", "html") || g_mime_content_type_is_type (type, "text", "xhtml")) { debug_task ("got urls from text/html part"); - text_part = - rspamd_mempool_alloc0 (task->task_pool, - sizeof (struct mime_text_part)); + text_part = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct mime_text_part)); text_part->is_html = TRUE; if (is_empty) { text_part->is_empty = TRUE; @@ -921,26 +856,18 @@ process_text_part (struct rspamd_task *task, task->text_parts = g_list_prepend (task->text_parts, text_part); return; } - text_part->orig = convert_text_to_utf (task, - part_content, - type, - text_part); + text_part->orig = convert_text_to_utf (task, part_content, type, text_part); text_part->is_balanced = TRUE; text_part->html_nodes = NULL; text_part->parent = parent; - text_part->content = strip_html_tags (task, - task->task_pool, - text_part, - text_part->orig, - NULL); + text_part->content = strip_html_tags (task, task->task_pool, text_part, text_part->orig, NULL); if (text_part->html_nodes == NULL) { url_parse_text (task->task_pool, task, text_part, FALSE); } else { - decode_entitles (text_part->content->data, - &text_part->content->len); + decode_entitles (text_part->content->data, &text_part->content->len); url_parse_text (task->task_pool, task, text_part, FALSE); #if 0 url_parse_text (task->task_pool, task, text_part, TRUE); @@ -948,17 +875,13 @@ process_text_part (struct rspamd_task *task, } fuzzy_init_part (text_part, task->task_pool, task->cfg->max_diff); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) free_byte_array_callback, - text_part->content); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) free_byte_array_callback, text_part->content); task->text_parts = g_list_prepend (task->text_parts, text_part); } else if (g_mime_content_type_is_type (type, "text", "*")) { debug_task ("got urls from text/plain part"); - text_part = - rspamd_mempool_alloc0 (task->task_pool, - sizeof (struct mime_text_part)); + text_part = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct mime_text_part)); text_part->is_html = FALSE; text_part->parent = parent; if (is_empty) { @@ -968,10 +891,7 @@ process_text_part (struct rspamd_task *task, task->text_parts = g_list_prepend (task->text_parts, text_part); return; } - text_part->orig = convert_text_to_utf (task, - part_content, - type, - text_part); + text_part->orig = convert_text_to_utf (task, part_content, type, text_part); text_part->content = text_part->orig; url_parse_text (task->task_pool, task, text_part, FALSE); fuzzy_init_part (text_part, task->task_pool, task->cfg->max_diff); @@ -981,20 +901,18 @@ process_text_part (struct rspamd_task *task, #ifdef GMIME24 static void -mime_foreach_callback (GMimeObject * parent, - GMimeObject * part, - gpointer user_data) +mime_foreach_callback (GMimeObject * parent, GMimeObject * part, gpointer user_data) #else static void mime_foreach_callback (GMimeObject * part, gpointer user_data) #endif { - struct rspamd_task *task = (struct rspamd_task *)user_data; - struct mime_part *mime_part; - GMimeContentType *type; - GMimeDataWrapper *wrapper; - GMimeStream *part_stream; - GByteArray *part_content; + struct rspamd_task *task = (struct rspamd_task *)user_data; + struct mime_part *mime_part; + GMimeContentType *type; + GMimeDataWrapper *wrapper; + GMimeStream *part_stream; + GByteArray *part_content; task->parts_count++; @@ -1003,7 +921,7 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data) /* find out what class 'part' is... */ if (GMIME_IS_MESSAGE_PART (part)) { /* message/rfc822 or message/news */ - GMimeMessage *message; + GMimeMessage *message; /* g_mime_message_foreach_part() won't descend into child message parts, so if we want to count any @@ -1039,13 +957,11 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data) else if (GMIME_IS_MULTIPART (part)) { /* multipart/mixed, multipart/alternative, multipart/related, multipart/signed, multipart/encrypted, etc... */ task->parser_parent_part = part; -#ifndef GMIME24 +#ifndef GMIME24 debug_task ("detected multipart part"); /* we'll get to finding out if this is a signed/encrypted multipart later... */ if (task->parser_recursion++ < RECURSION_LIMIT) { - g_mime_multipart_foreach ((GMimeMultipart *) part, - mime_foreach_callback, - task); + g_mime_multipart_foreach ((GMimeMultipart *) part, mime_foreach_callback, task); } else { msg_err ("endless recursion detected: %d", task->parser_recursion); @@ -1056,21 +972,17 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data) else if (GMIME_IS_PART (part)) { /* a normal leaf part, could be text/plain or image/jpeg etc */ #ifdef GMIME24 - type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT ( - part)); + type = (GMimeContentType *) g_mime_object_get_content_type (GMIME_OBJECT (part)); #else - type = - (GMimeContentType *) g_mime_part_get_content_type (GMIME_PART (part)); + type = (GMimeContentType *) g_mime_part_get_content_type (GMIME_PART (part)); #endif if (type == NULL) { msg_warn ("type of part is unknown, assume text/plain"); type = g_mime_content_type_new ("text", "plain"); #ifdef GMIME24 - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_object_unref, type); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_object_unref, type); #else - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_mime_content_type_destroy, type); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_mime_content_type_destroy, type); #endif } wrapper = g_mime_part_get_content_object (GMIME_PART (part)); @@ -1080,45 +992,29 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data) if (wrapper != NULL) { #endif part_stream = g_mime_stream_mem_new (); - if (g_mime_data_wrapper_write_to_stream (wrapper, - part_stream) != -1) { - g_mime_stream_mem_set_owner (GMIME_STREAM_MEM ( - part_stream), FALSE); - part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM ( - part_stream)); + if (g_mime_data_wrapper_write_to_stream (wrapper, part_stream) != -1) { + g_mime_stream_mem_set_owner (GMIME_STREAM_MEM (part_stream), FALSE); + part_content = g_mime_stream_mem_get_byte_array (GMIME_STREAM_MEM (part_stream)); g_object_unref (part_stream); - mime_part = - rspamd_mempool_alloc (task->task_pool, - sizeof (struct mime_part)); + mime_part = rspamd_mempool_alloc (task->task_pool, sizeof (struct mime_part)); mime_part->type = type; mime_part->content = part_content; mime_part->parent = task->parser_parent_part; - mime_part->filename = g_mime_part_get_filename (GMIME_PART ( - part)); - debug_task ("found part with content-type: %s/%s", - type->type, - type->subtype); + mime_part->filename = g_mime_part_get_filename (GMIME_PART (part)); + debug_task ("found part with content-type: %s/%s", type->type, type->subtype); task->parts = g_list_prepend (task->parts, mime_part); /* Skip empty parts */ - process_text_part (task, - part_content, - type, - part, - task->parser_parent_part, - (part_content->len <= 0)); + process_text_part (task, part_content, type, part, task->parser_parent_part, (part_content->len <= 0)); } else { - msg_warn ("write to stream failed: %d, %s", errno, - strerror (errno)); + msg_warn ("write to stream failed: %d, %s", errno, strerror (errno)); } #ifndef GMIME24 g_object_unref (wrapper); #endif } else { - msg_warn ("cannot get wrapper for mime part, type of part: %s/%s", - type->type, - type->subtype); + msg_warn ("cannot get wrapper for mime part, type of part: %s/%s", type->type, type->subtype); } } else { @@ -1129,7 +1025,7 @@ mime_foreach_callback (GMimeObject * part, gpointer user_data) static void destroy_message (void *pointer) { - GMimeMessage *msg = pointer; + GMimeMessage *msg = pointer; msg_debug ("freeing pointer %p", msg); g_object_unref (msg); @@ -1138,34 +1034,33 @@ destroy_message (void *pointer) gint process_message (struct rspamd_task *task) { - GMimeMessage *message; - GMimeParser *parser; - GMimeStream *stream; - GByteArray *tmp; - GList *first, *cur; - GMimePart *part; - GMimeDataWrapper *wrapper; - struct received_header *recv; - gchar *mid, *url_str, *p, *end, *url_end; - struct uri *subject_url; - gsize len; - gint rc; + GMimeMessage *message; + GMimeParser *parser; + GMimeStream *stream; + GByteArray *tmp; + GList *first, *cur; + GMimePart *part; + GMimeDataWrapper *wrapper; + struct received_header *recv; + gchar *mid, *url_str, *p, *end, *url_end; + struct uri *subject_url; + gsize len; + gint rc; tmp = rspamd_mempool_alloc (task->task_pool, sizeof (GByteArray)); tmp->data = task->msg->str; tmp->len = task->msg->len; stream = g_mime_stream_mem_new_with_byte_array (tmp); - /* - * This causes g_mime_stream not to free memory by itself as it is memory allocated by - * pool allocator - */ + /* + * This causes g_mime_stream not to free memory by itself as it is memory allocated by + * pool allocator + */ g_mime_stream_mem_set_owner (GMIME_STREAM_MEM (stream), FALSE); if (task->is_mime) { - debug_task ("construct mime parser from string length %d", - (gint)task->msg->len); + debug_task ("construct mime parser from string length %d", (gint)task->msg->len); /* create a new parser object to parse the stream */ parser = g_mime_parser_new_with_stream (stream); g_object_unref (stream); @@ -1179,8 +1074,7 @@ process_message (struct rspamd_task *task) } task->message = message; - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) destroy_message, task->message); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) destroy_message, task->message); /* Save message id for future use */ task->message_id = g_mime_message_get_message_id (task->message); @@ -1207,8 +1101,7 @@ process_message (struct rspamd_task *task) } #ifdef GMIME24 - task->raw_headers_str = - g_mime_object_get_headers (GMIME_OBJECT (task->message)); + task->raw_headers_str = g_mime_object_get_headers (GMIME_OBJECT (task->message)); #else task->raw_headers_str = g_mime_message_get_headers (task->message); #endif @@ -1216,13 +1109,10 @@ process_message (struct rspamd_task *task) process_images (task); /* Parse received headers */ - first = - message_get_header (task->task_pool, message, "Received", FALSE); + first = message_get_header (task->task_pool, message, "Received", FALSE); cur = first; while (cur) { - recv = - rspamd_mempool_alloc0 (task->task_pool, - sizeof (struct received_header)); + recv = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct received_header)); parse_recv_header (task->task_pool, cur->data, recv); task->received = g_list_prepend (task->received, recv); cur = g_list_next (cur); @@ -1232,21 +1122,16 @@ process_message (struct rspamd_task *task) } if (task->raw_headers_str) { - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_free, task->raw_headers_str); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_free, task->raw_headers_str); process_raw_headers (task); } task->rcpts = g_mime_message_get_all_recipients (message); if (task->rcpts) { #ifdef GMIME24 - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_object_unref, - task->rcpts); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_object_unref, task->rcpts); #else - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) internet_address_list_destroy, - task->rcpts); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) internet_address_list_destroy, task->rcpts); #endif } @@ -1264,33 +1149,26 @@ process_message (struct rspamd_task *task) /* Construct part for it */ part = g_mime_part_new_with_type ("text", "html"); #ifdef GMIME24 - wrapper = g_mime_data_wrapper_new_with_stream (stream, - GMIME_CONTENT_ENCODING_8BIT); + wrapper = g_mime_data_wrapper_new_with_stream (stream, GMIME_CONTENT_ENCODING_8BIT); #else - wrapper = g_mime_data_wrapper_new_with_stream (stream, - GMIME_PART_ENCODING_8BIT); + wrapper = g_mime_data_wrapper_new_with_stream (stream, GMIME_PART_ENCODING_8BIT); #endif g_mime_part_set_content_object (part, wrapper); g_mime_message_set_mime_part (task->message, GMIME_OBJECT (part)); /* Register destructors */ - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_object_unref, wrapper); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_object_unref, part); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) destroy_message, task->message); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_object_unref, wrapper); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_object_unref, part); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) destroy_message, task->message); /* Now parse in a normal way */ task->parser_recursion = 0; #ifdef GMIME24 g_mime_message_foreach (task->message, mime_foreach_callback, task); #else - g_mime_message_foreach_part (task->message, mime_foreach_callback, - task); + g_mime_message_foreach_part (task->message, mime_foreach_callback, task); #endif /* Generate message ID */ mid = g_mime_utils_generate_message_id ("localhost.localdomain"); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_free, mid); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_free, mid); g_mime_message_set_message_id (task->message, mid); task->message_id = mid; task->queue_id = mid; @@ -1304,10 +1182,7 @@ process_message (struct rspamd_task *task) if (task->rcpt) { cur = task->rcpt; while (cur) { - g_mime_message_add_recipient (task->message, - GMIME_RECIPIENT_TYPE_TO, - NULL, - (gchar *)cur->data); + g_mime_message_add_recipient (task->message, GMIME_RECIPIENT_TYPE_TO, NULL, (gchar *)cur->data); cur = g_list_next (cur); } } @@ -1323,29 +1198,22 @@ process_message (struct rspamd_task *task) while (p < end) { /* Search to the end of url */ - if (url_try_text (task->task_pool, p, end - p, NULL, &url_end, - &url_str, FALSE)) { + if (url_try_text (task->task_pool, p, end - p, NULL, &url_end, &url_str, FALSE)) { if (url_str != NULL) { - subject_url = rspamd_mempool_alloc0 (task->task_pool, - sizeof (struct uri)); + subject_url = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct uri)); if (subject_url != NULL) { /* Try to parse url */ rc = parse_uri (subject_url, url_str, task->task_pool); - if ((rc == URI_ERRNO_OK || rc == URI_ERRNO_NO_SLASHES || - rc == URI_ERRNO_NO_HOST_SLASH) && - subject_url->hostlen > 0) { + if ((rc == URI_ERRNO_OK || rc == URI_ERRNO_NO_SLASHES || rc == URI_ERRNO_NO_HOST_SLASH) && + subject_url->hostlen > 0) { if (subject_url->protocol != PROTOCOL_MAILTO) { if (!g_tree_lookup (task->urls, subject_url)) { - g_tree_insert (task->urls, - subject_url, - subject_url); + g_tree_insert (task->urls, subject_url, subject_url); } } } else if (rc != URI_ERRNO_OK) { - msg_info ("extract of url '%s' failed: %s", - url_str, - url_strerror (rc)); + msg_info ("extract of url '%s' failed: %s", url_str, url_strerror (rc)); } } } @@ -1363,15 +1231,15 @@ process_message (struct rspamd_task *task) } struct gmime_raw_header { - struct raw_header *next; - gchar *name; - gchar *value; + struct raw_header *next; + gchar *name; + gchar *value; }; typedef struct _GMimeHeader { - GHashTable *hash; - GHashTable *writers; - struct raw_header *headers; + GHashTable *hash; + GHashTable *writers; + struct raw_header *headers; } local_GMimeHeader; @@ -1393,20 +1261,13 @@ enum { */ #ifndef GMIME24 static void -header_iterate (rspamd_mempool_t * pool, - struct gmime_raw_header *h, - GList ** ret, - const gchar *field, - gboolean strong) +header_iterate (rspamd_mempool_t * pool, struct gmime_raw_header *h, GList ** ret, const gchar *field, gboolean strong) { while (h) { if (G_LIKELY (!strong)) { - if (h->value && - !g_ascii_strncasecmp (field, h->name, strlen (field))) { + if (h->value && !g_ascii_strncasecmp (field, h->name, strlen (field))) { if (pool != NULL) { - *ret = - g_list_prepend (*ret, - rspamd_mempool_strdup (pool, h->value)); + *ret = g_list_prepend (*ret, rspamd_mempool_strdup (pool, h->value)); } else { *ret = g_list_prepend (*ret, g_strdup (h->value)); @@ -1416,9 +1277,7 @@ header_iterate (rspamd_mempool_t * pool, else { if (h->value && !strncmp (field, h->name, strlen (field))) { if (pool != NULL) { - *ret = - g_list_prepend (*ret, - rspamd_mempool_strdup (pool, h->value)); + *ret = g_list_prepend (*ret, rspamd_mempool_strdup (pool, h->value)); } else { *ret = g_list_prepend (*ret, g_strdup (h->value)); @@ -1430,15 +1289,11 @@ header_iterate (rspamd_mempool_t * pool, } #else static void -header_iterate (rspamd_mempool_t * pool, - GMimeHeaderList * ls, - GList ** ret, - const gchar *field, - gboolean strong) +header_iterate (rspamd_mempool_t * pool, GMimeHeaderList * ls, GList ** ret, const gchar *field, gboolean strong) { /* Use iterator in case of gmime 2.4 */ - GMimeHeaderIter *iter; - const gchar *name; + GMimeHeaderIter *iter; + const gchar *name; if (ls == NULL) { *ret = NULL; @@ -1446,38 +1301,27 @@ header_iterate (rspamd_mempool_t * pool, } iter = g_mime_header_iter_new (); - if (g_mime_header_list_get_iter (ls, - iter) && g_mime_header_iter_first (iter)) { + if (g_mime_header_list_get_iter (ls, iter) && g_mime_header_iter_first (iter)) { /* Iterate throught headers */ while (g_mime_header_iter_is_valid (iter)) { name = g_mime_header_iter_get_name (iter); if (G_LIKELY (!strong)) { if (!g_ascii_strncasecmp (field, name, strlen (name))) { if (pool != NULL) { - *ret = - g_list_prepend (*ret, - rspamd_mempool_strdup (pool, - g_mime_header_iter_get_value (iter))); + *ret = g_list_prepend (*ret, rspamd_mempool_strdup (pool, g_mime_header_iter_get_value (iter))); } else { - *ret = - g_list_prepend (*ret, - g_strdup (g_mime_header_iter_get_value (iter))); + *ret = g_list_prepend (*ret, g_strdup (g_mime_header_iter_get_value (iter))); } } } else { if (!strncmp (field, name, strlen (name))) { if (pool != NULL) { - *ret = - g_list_prepend (*ret, - rspamd_mempool_strdup (pool, - g_mime_header_iter_get_value (iter))); + *ret = g_list_prepend (*ret, rspamd_mempool_strdup (pool, g_mime_header_iter_get_value (iter))); } else { - *ret = - g_list_prepend (*ret, - g_strdup (g_mime_header_iter_get_value (iter))); + *ret = g_list_prepend (*ret, g_strdup (g_mime_header_iter_get_value (iter))); } } } @@ -1492,12 +1336,12 @@ header_iterate (rspamd_mempool_t * pool, struct multipart_cb_data { - GList *ret; - rspamd_mempool_t *pool; - const gchar *field; - gboolean try_search; - gboolean strong; - gint rec; + GList *ret; + rspamd_mempool_t *pool; + const gchar *field; + gboolean try_search; + gboolean strong; + gint rec; }; #define MAX_REC 10 @@ -1509,21 +1353,21 @@ multipart_iterate (GMimeObject * parent, GMimeObject * part, gpointer user_data) multipart_iterate (GMimeObject * part, gpointer user_data) #endif { - struct multipart_cb_data *data = user_data; + struct multipart_cb_data *data = user_data; #ifndef GMIME24 - struct gmime_raw_header *h; + struct gmime_raw_header *h; #endif - GList *l = NULL; + GList *l = NULL; if (data->try_search && part != NULL && GMIME_IS_PART (part)) { #ifdef GMIME24 - GMimeHeaderList *ls; + GMimeHeaderList *ls; ls = g_mime_object_get_header_list (GMIME_OBJECT (part)); header_iterate (data->pool, ls, &l, data->field, data->strong); #else h = (struct gmime_raw_header *)part->headers->headers; - header_iterate (data->pool, h, &l, data->field, data->strong); + header_iterate (data->pool, h, &l, data->field, data->strong); #endif if (l == NULL) { /* Header not found, abandon search results */ @@ -1538,26 +1382,21 @@ multipart_iterate (GMimeObject * part, gpointer user_data) else if (data->try_search && GMIME_IS_MULTIPART (part)) { /* Maybe endless recursion here ? */ if (data->rec++ < MAX_REC) { - g_mime_multipart_foreach (GMIME_MULTIPART ( - part), multipart_iterate, data); + g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, data); } else { - msg_info ("maximum recurse limit is over, stop recursing, %d", - data->rec); + msg_info ("maximum recurse limit is over, stop recursing, %d", data->rec); data->try_search = FALSE; } } } -static GList * -local_message_get_header (rspamd_mempool_t * pool, - GMimeMessage * message, - const gchar *field, - gboolean strong) +static GList * +local_message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const gchar *field, gboolean strong) { - GList *gret = NULL; - GMimeObject *part; - struct multipart_cb_data cb = { + GList *gret = NULL; + GMimeObject *part; + struct multipart_cb_data cb = { .try_search = TRUE, .rec = 0, .ret = NULL, @@ -1567,7 +1406,7 @@ local_message_get_header (rspamd_mempool_t * pool, cb.strong = strong; #ifndef GMIME24 - struct gmime_raw_header *h; + struct gmime_raw_header *h; if (field == NULL) { return NULL; @@ -1579,18 +1418,14 @@ local_message_get_header (rspamd_mempool_t * pool, if (gret == NULL) { /* Try to iterate with mime part headers */ - msg_debug ("iterate over headers of mime part to find header %s", - field); + msg_debug ("iterate over headers of mime part to find header %s", field); part = g_mime_message_get_mime_part (message); if (part) { h = (struct gmime_raw_header *)part->headers->headers; header_iterate (pool, h, &gret, field, strong); if (gret == NULL && GMIME_IS_MULTIPART (part)) { - msg_debug ( - "iterate over headers of each multipart's subparts %s", - field); - g_mime_multipart_foreach (GMIME_MULTIPART ( - part), multipart_iterate, &cb); + msg_debug ("iterate over headers of each multipart's subparts %s", field); + g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, &cb); if (cb.ret != NULL) { gret = cb.ret; } @@ -1603,7 +1438,7 @@ local_message_get_header (rspamd_mempool_t * pool, return gret; #else - GMimeHeaderList *ls; + GMimeHeaderList *ls; ls = g_mime_object_get_header_list (GMIME_OBJECT (message)); header_iterate (pool, ls, &gret, field, strong); @@ -1614,8 +1449,7 @@ local_message_get_header (rspamd_mempool_t * pool, ls = g_mime_object_get_header_list (GMIME_OBJECT (part)); header_iterate (pool, ls, &gret, field, strong); if (gret == NULL && GMIME_IS_MULTIPART (part)) { - g_mime_multipart_foreach (GMIME_MULTIPART ( - part), multipart_iterate, &cb); + g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, &cb); if (cb.ret != NULL) { gret = cb.ret; } @@ -1632,18 +1466,17 @@ local_message_get_header (rspamd_mempool_t * pool, } /** - * g_mime_message_set_date_from_string: Set the message sent-date - * @message: MIME Message - * @string: A string of date - * - * Set the sent-date on a MIME Message. - **/ +* g_mime_message_set_date_from_string: Set the message sent-date +* @message: MIME Message +* @string: A string of date +* +* Set the sent-date on a MIME Message. +**/ void -local_mime_message_set_date_from_string (GMimeMessage * message, - const gchar * string) +local_mime_message_set_date_from_string (GMimeMessage * message, const gchar * string) { - time_t date; - gint offset = 0; + time_t date; + gint offset = 0; date = g_mime_utils_header_decode_date (string, &offset); g_mime_message_set_date (message, date, offset); @@ -1652,14 +1485,14 @@ local_mime_message_set_date_from_string (GMimeMessage * message, /* * Replacements for standart gmime functions but converting adresses to IA */ -static const gchar * +static const gchar * local_message_get_sender (GMimeMessage * message) { - gchar *res; - const gchar *from = g_mime_message_get_sender (message); - InternetAddressList *ia; + gchar *res; + const gchar *from = g_mime_message_get_sender (message); + InternetAddressList *ia; -#ifndef GMIME24 +#ifndef GMIME24 ia = internet_address_parse_string (from); #else ia = internet_address_list_parse_string (from); @@ -1668,7 +1501,7 @@ local_message_get_sender (GMimeMessage * message) return NULL; } res = internet_address_list_to_string (ia, FALSE); -#ifndef GMIME24 +#ifndef GMIME24 internet_address_list_destroy (ia); #else g_object_unref (ia); @@ -1677,14 +1510,14 @@ local_message_get_sender (GMimeMessage * message) return res; } -static const gchar * +static const gchar * local_message_get_reply_to (GMimeMessage * message) { - gchar *res; - const gchar *from = g_mime_message_get_reply_to (message); - InternetAddressList *ia; + gchar *res; + const gchar *from = g_mime_message_get_reply_to (message); + InternetAddressList *ia; -#ifndef GMIME24 +#ifndef GMIME24 ia = internet_address_parse_string (from); #else ia = internet_address_list_parse_string (from); @@ -1693,7 +1526,7 @@ local_message_get_reply_to (GMimeMessage * message) return NULL; } res = internet_address_list_to_string (ia, FALSE); -#ifndef GMIME24 +#ifndef GMIME24 internet_address_list_destroy (ia); #else g_object_unref (ia); @@ -1704,161 +1537,122 @@ local_message_get_reply_to (GMimeMessage * message) #ifdef GMIME24 -# define ADD_RECIPIENT_TEMPLATE(type,def) \ - static void \ - local_message_add_recipients_from_string_ ## type (GMimeMessage * message, \ - const gchar * string, \ - const gchar * value) \ - { \ - InternetAddressList *il, *new; \ - \ - il = g_mime_message_get_recipients (message, (def)); \ - new = internet_address_list_parse_string (string); \ - internet_address_list_append (il, new); \ - } \ - -ADD_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO) -ADD_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC) -ADD_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC) -# define GET_RECIPIENT_TEMPLATE(type,def) \ - static InternetAddressList * \ - local_message_get_recipients_ ## type (GMimeMessage * message, \ - const gchar * unused) \ - { \ - return g_mime_message_get_recipients (message, (def)); \ - } -GET_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO) -GET_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC) -GET_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC) +# define ADD_RECIPIENT_TEMPLATE(type,def) \ +static void \ +local_message_add_recipients_from_string_##type (GMimeMessage *message, const gchar *string, const gchar *value) \ +{ \ + InternetAddressList *il, *new; \ + \ + il = g_mime_message_get_recipients (message, (def)); \ + new = internet_address_list_parse_string (string); \ + internet_address_list_append (il, new); \ +} \ + +ADD_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO) + ADD_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC) + ADD_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC) +# define GET_RECIPIENT_TEMPLATE(type,def) \ +static InternetAddressList* \ +local_message_get_recipients_##type (GMimeMessage *message, const gchar *unused) \ +{ \ + return g_mime_message_get_recipients (message, (def)); \ +} + GET_RECIPIENT_TEMPLATE (to, GMIME_RECIPIENT_TYPE_TO) + GET_RECIPIENT_TEMPLATE (cc, GMIME_RECIPIENT_TYPE_CC) + GET_RECIPIENT_TEMPLATE (bcc, GMIME_RECIPIENT_TYPE_BCC) #endif /* different declarations for different types of set and get functions */ -typedef const gchar *(*GetFunc) (GMimeMessage * message); -typedef InternetAddressList *(*GetRcptFunc) (GMimeMessage * message, - const gchar *type); -typedef GList *(*GetListFunc) (rspamd_mempool_t * pool, GMimeMessage * message, - const gchar *type, gboolean strong); -typedef void (*SetFunc) (GMimeMessage * message, const gchar *value); -typedef void (*SetListFunc) (GMimeMessage * message, const gchar *field, - const gchar *value); + typedef const gchar *(*GetFunc) (GMimeMessage * message); + typedef InternetAddressList *(*GetRcptFunc) (GMimeMessage * message, const gchar *type); + typedef GList *(*GetListFunc) (rspamd_mempool_t * pool, GMimeMessage * message, const gchar *type, gboolean strong); + typedef void (*SetFunc) (GMimeMessage * message, const gchar *value); + typedef void (*SetListFunc) (GMimeMessage * message, const gchar *field, const gchar *value); /** different types of functions - * - * FUNC_CHARPTR - * - function with no arguments - * - get returns gchar* - * - * FUNC_IA (from Internet Address) - * - function with additional "field" argument from the fieldfunc table, - * - get returns Glist* - * - * FUNC_LIST - * - function with additional "field" argument (given arbitrary header field name) - * - get returns Glist* - **/ -enum { - FUNC_CHARPTR = 0, - FUNC_CHARFREEPTR, - FUNC_IA, - FUNC_LIST -}; +* +* FUNC_CHARPTR +* - function with no arguments +* - get returns gchar* +* +* FUNC_IA (from Internet Address) +* - function with additional "field" argument from the fieldfunc table, +* - get returns Glist* +* +* FUNC_LIST +* - function with additional "field" argument (given arbitrary header field name) +* - get returns Glist* +**/ + enum { + FUNC_CHARPTR = 0, + FUNC_CHARFREEPTR, + FUNC_IA, + FUNC_LIST + }; /** - * fieldfunc struct: structure of MIME fields and corresponding get and set - * functions. - **/ -static struct { - gchar *name; - GetFunc func; - GetRcptFunc rcptfunc; - GetListFunc getlistfunc; - SetFunc setfunc; - SetListFunc setlfunc; - gint functype; -} fieldfunc[] = +* fieldfunc struct: structure of MIME fields and corresponding get and set +* functions. +**/ + static struct { + gchar *name; + GetFunc func; + GetRcptFunc rcptfunc; + GetListFunc getlistfunc; + SetFunc setfunc; + SetListFunc setlfunc; + gint functype; + } fieldfunc[] = { { - "From", local_message_get_sender, NULL, NULL, g_mime_message_set_sender, - NULL, FUNC_CHARFREEPTR - }, { - "Reply-To", local_message_get_reply_to, NULL, NULL, - g_mime_message_set_reply_to, NULL, FUNC_CHARFREEPTR - }, + "From", local_message_get_sender, NULL, NULL, g_mime_message_set_sender, NULL, FUNC_CHARFREEPTR}, { + "Reply-To", local_message_get_reply_to, NULL, NULL, g_mime_message_set_reply_to, NULL, FUNC_CHARFREEPTR}, #ifndef GMIME24 { - "To", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, - (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA - }, { - "Cc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, - (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA - }, { - "Bcc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, - (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA - }, { - "Date", (GetFunc) g_mime_message_get_date_string, NULL, NULL, - local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR - }, + "To", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA}, { + "Cc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA}, { + "Bcc", NULL, (GetRcptFunc) g_mime_message_get_recipients, NULL, NULL, (SetListFunc) g_mime_message_add_recipients_from_string, FUNC_IA}, { + "Date", (GetFunc) g_mime_message_get_date_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR}, #else { - "To", NULL, local_message_get_recipients_to, NULL, NULL, - local_message_add_recipients_from_string_to, FUNC_IA - }, { - "Cc", NULL, local_message_get_recipients_cc, NULL, NULL, - local_message_add_recipients_from_string_cc, FUNC_IA - }, { - "Bcc", NULL, local_message_get_recipients_bcc, NULL, NULL, - local_message_add_recipients_from_string_bcc, FUNC_IA - }, { - "Date", (GetFunc)g_mime_message_get_date_as_string, NULL, NULL, - local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR - }, + "To", NULL, local_message_get_recipients_to, NULL, NULL, local_message_add_recipients_from_string_to, FUNC_IA}, { + "Cc", NULL, local_message_get_recipients_cc, NULL, NULL, local_message_add_recipients_from_string_cc, FUNC_IA}, { + "Bcc", NULL, local_message_get_recipients_bcc, NULL, NULL, local_message_add_recipients_from_string_bcc, FUNC_IA}, { + "Date", (GetFunc)g_mime_message_get_date_as_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR}, #endif { - "Subject", g_mime_message_get_subject, NULL, NULL, - g_mime_message_set_subject, NULL, FUNC_CHARPTR - }, { - "Message-Id", g_mime_message_get_message_id, NULL, NULL, - g_mime_message_set_message_id, NULL, FUNC_CHARPTR - }, + "Subject", g_mime_message_get_subject, NULL, NULL, g_mime_message_set_subject, NULL, FUNC_CHARPTR}, { + "Message-Id", g_mime_message_get_message_id, NULL, NULL, g_mime_message_set_message_id, NULL, FUNC_CHARPTR}, #ifndef GMIME24 { - NULL, NULL, NULL, local_message_get_header, NULL, - g_mime_message_add_header, FUNC_LIST - } + NULL, NULL, NULL, local_message_get_header, NULL, g_mime_message_add_header, FUNC_LIST} #else { - NULL, NULL, NULL, local_message_get_header, NULL, - (SetListFunc)g_mime_object_append_header, FUNC_LIST - } + NULL, NULL, NULL, local_message_get_header, NULL, (SetListFunc)g_mime_object_append_header, FUNC_LIST} #endif }; /** - * message_set_header: set header of any type excluding special (Content- and MIME-Version:) - **/ +* message_set_header: set header of any type excluding special (Content- and MIME-Version:) +**/ void -message_set_header (GMimeMessage * message, - const gchar *field, - const gchar *value) +message_set_header (GMimeMessage * message, const gchar *field, const gchar *value) { - gint i; + gint i; - if (!g_ascii_strcasecmp (field, - "MIME-Version:") || !g_ascii_strncasecmp (field, "Content-", 8)) { + if (!g_ascii_strcasecmp (field, "MIME-Version:") || !g_ascii_strncasecmp (field, "Content-", 8)) { return; } for (i = 0; i <= HEADER_UNKNOWN; ++i) { - if (!fieldfunc[i].name || - !g_ascii_strncasecmp (field, fieldfunc[i].name, - strlen (fieldfunc[i].name))) { + if (!fieldfunc[i].name || !g_ascii_strncasecmp (field, fieldfunc[i].name, strlen (fieldfunc[i].name))) { switch (fieldfunc[i].functype) { case FUNC_CHARPTR: - (*(fieldfunc[i].setfunc))(message, value); + (*(fieldfunc[i].setfunc)) (message, value); break; case FUNC_IA: - (*(fieldfunc[i].setlfunc))(message, fieldfunc[i].name, value); + (*(fieldfunc[i].setlfunc)) (message, fieldfunc[i].name, value); break; case FUNC_LIST: - (*(fieldfunc[i].setlfunc))(message, field, value); + (*(fieldfunc[i].setlfunc)) (message, field, value); break; } break; @@ -1868,45 +1662,37 @@ message_set_header (GMimeMessage * message, /** - * message_get_header: returns the list of 'any header' values - * (except of unsupported yet Content- and MIME-Version special headers) - * - * You should free the GList list by yourself. - **/ -GList * -message_get_header (rspamd_mempool_t * pool, - GMimeMessage * message, - const gchar *field, - gboolean strong) +* message_get_header: returns the list of 'any header' values +* (except of unsupported yet Content- and MIME-Version special headers) +* +* You should free the GList list by yourself. +**/ +GList * +message_get_header (rspamd_mempool_t * pool, GMimeMessage * message, const gchar *field, gboolean strong) { - gint i; - gchar *ret = NULL, *ia_string; - GList *gret = NULL; - InternetAddressList *ia_list = NULL, *ia; + gint i; + gchar *ret = NULL, *ia_string; + GList *gret = NULL; + InternetAddressList *ia_list = NULL, *ia; for (i = 0; i <= HEADER_UNKNOWN; ++i) { - if (!fieldfunc[i].name || - !g_ascii_strncasecmp (field, fieldfunc[i].name, - strlen (fieldfunc[i].name))) { + if (!fieldfunc[i].name || !g_ascii_strncasecmp (field, fieldfunc[i].name, strlen (fieldfunc[i].name))) { switch (fieldfunc[i].functype) { case FUNC_CHARFREEPTR: - ret = (gchar *)(*(fieldfunc[i].func))(message); + ret = (gchar *)(*(fieldfunc[i].func)) (message); break; case FUNC_CHARPTR: - ret = (gchar *)(*(fieldfunc[i].func))(message); + ret = (gchar *)(*(fieldfunc[i].func)) (message); break; case FUNC_IA: - ia_list = (*(fieldfunc[i].rcptfunc))(message, field); + ia_list = (*(fieldfunc[i].rcptfunc)) (message, field); ia = ia_list; #ifndef GMIME24 while (ia && ia->address) { - ia_string = internet_address_to_string ( - (InternetAddress *) ia->address, - FALSE); + ia_string = internet_address_to_string ((InternetAddress *) ia->address, FALSE); if (pool != NULL) { - rspamd_mempool_add_destructor (pool, - (rspamd_mempool_destruct_t) g_free, ia_string); + rspamd_mempool_add_destructor (pool, (rspamd_mempool_destruct_t) g_free, ia_string); } gret = g_list_prepend (gret, ia_string); ia = ia->next; @@ -1914,21 +1700,16 @@ message_get_header (rspamd_mempool_t * pool, #else i = internet_address_list_length (ia); while (--i >= 0) { - ia_string = internet_address_to_string (internet_address_list_get_address ( - ia, - i), - FALSE); + ia_string = internet_address_to_string (internet_address_list_get_address (ia, i), FALSE); if (pool != NULL) { - rspamd_mempool_add_destructor (pool, - (rspamd_mempool_destruct_t) g_free, ia_string); + rspamd_mempool_add_destructor (pool, (rspamd_mempool_destruct_t) g_free, ia_string); } gret = g_list_prepend (gret, ia_string); } #endif break; case FUNC_LIST: - gret = - (*(fieldfunc[i].getlistfunc))(pool, message, field, strong); + gret = (*(fieldfunc[i].getlistfunc)) (pool, message, field, strong); break; } break; @@ -1949,13 +1730,11 @@ message_get_header (rspamd_mempool_t * pool, return gret; } -GList * -message_get_raw_header (struct rspamd_task *task, - const gchar *field, - gboolean strong) +GList* +message_get_raw_header (struct rspamd_task *task, const gchar *field, gboolean strong) { - GList *gret = NULL; - struct raw_header *rh; + GList *gret = NULL; + struct raw_header *rh; rh = g_hash_table_lookup (task->raw_headers, field); @@ -1978,8 +1757,7 @@ message_get_raw_header (struct rspamd_task *task, } if (gret != NULL) { - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t)g_list_free, gret); + rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t)g_list_free, gret); } return gret; diff --git a/src/libmime/message.h b/src/libmime/message.h index fdb987c8c..5e27579d1 100644 --- a/src/libmime/message.h +++ b/src/libmime/message.h @@ -30,7 +30,7 @@ struct mime_text_part { GByteArray *orig; GByteArray *content; GNode *html_nodes; - GList *urls_offset; /**< list of offsets of urls */ + GList *urls_offset; /**< list of offsets of urls */ fuzzy_hash_t *fuzzy; fuzzy_hash_t *double_fuzzy; GMimeObject *parent; @@ -57,7 +57,7 @@ struct raw_header { }; /** - * Process message with all filters/statfiles, extract mime parts, urls and + * Process message with all filters/statfiles, extract mime parts, urls and * call metrics consolidation functions * @param task worker_task object * @return 0 if we have delayed filters to process and 1 if we have finished with processing @@ -67,9 +67,7 @@ gint process_message (struct rspamd_task *task); /* * Set header with specified name and value */ -void message_set_header (GMimeMessage *message, - const gchar *field, - const gchar *value); +void message_set_header (GMimeMessage *message, const gchar *field, const gchar *value); /* * Get a list of header's values with specified header's name @@ -79,10 +77,7 @@ void message_set_header (GMimeMessage *message, * @param strong if this flag is TRUE header's name is case sensitive, otherwise it is not * @return A list of header's values or NULL. If list is not NULL it MUST be freed. If pool is NULL elements must be freed as well. */ -GList * message_get_header (rspamd_mempool_t *pool, - GMimeMessage *message, - const gchar *field, - gboolean strong); +GList* message_get_header (rspamd_mempool_t *pool, GMimeMessage *message, const gchar *field, gboolean strong); /* * Get a list of header's values with specified header's name using raw headers @@ -91,8 +86,6 @@ GList * message_get_header (rspamd_mempool_t *pool, * @param strong if this flag is TRUE header's name is case sensitive, otherwise it is not * @return A list of header's values or NULL. Unlike previous function it is NOT required to free list or values. I should rework one of these functions some time. */ -GList * message_get_raw_header (struct rspamd_task *task, - const gchar *field, - gboolean strong); +GList* message_get_raw_header (struct rspamd_task *task, const gchar *field, gboolean strong); #endif diff --git a/src/libmime/smtp_proto.c b/src/libmime/smtp_proto.c index 3c8395784..3af1c3910 100644 --- a/src/libmime/smtp_proto.c +++ b/src/libmime/smtp_proto.c @@ -22,24 +22,21 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "cfg_file.h" #include "config.h" #include "main.h" +#include "cfg_file.h" +#include "util.h" #include "smtp.h" #include "smtp_proto.h" #include "smtp_utils.h" -#include "util.h" -gchar * -make_smtp_error (rspamd_mempool_t *pool, - gint error_code, - const gchar *format, - ...) +gchar * +make_smtp_error (rspamd_mempool_t *pool, gint error_code, const gchar *format, ...) { - va_list vp; - gchar *result = NULL, *p; - size_t len; - + va_list vp; + gchar *result = NULL, *p; + size_t len; + va_start (vp, format); len = g_printf_string_upper_bound (format, vp); va_end (vp); @@ -56,9 +53,7 @@ make_smtp_error (rspamd_mempool_t *pool, gboolean -parse_smtp_command (struct smtp_session *session, - f_str_t *line, - struct smtp_command **cmd) +parse_smtp_command (struct smtp_session *session, f_str_t *line, struct smtp_command **cmd) { enum { SMTP_PARSE_START = 0, @@ -66,11 +61,11 @@ parse_smtp_command (struct smtp_session *session, SMTP_PARSE_ARGUMENT, SMTP_PARSE_DONE } state; - gchar *p, *c, ch, cmd_buf[4]; - guint i; - f_str_t *arg = NULL; - struct smtp_command *pcmd; - + gchar *p, *c, ch, cmd_buf[4]; + guint i; + f_str_t *arg = NULL; + struct smtp_command *pcmd; + if (line->len == 0) { return FALSE; } @@ -81,129 +76,125 @@ parse_smtp_command (struct smtp_session *session, *cmd = rspamd_mempool_alloc0 (session->pool, sizeof (struct smtp_command)); pcmd = *cmd; - for (i = 0; i < line->len; i++, p++) { + for (i = 0; i < line->len; i ++, p ++) { ch = *p; switch (state) { - case SMTP_PARSE_START: - if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i == - line->len - 1) { - if (i == line->len - 1) { - p++; - } - if (p - c == 4) { - cmd_buf[0] = g_ascii_toupper (c[0]); - cmd_buf[1] = g_ascii_toupper (c[1]); - cmd_buf[2] = g_ascii_toupper (c[2]); - cmd_buf[3] = g_ascii_toupper (c[3]); - - if (memcmp (cmd_buf, "HELO", 4) == 0) { - pcmd->command = SMTP_COMMAND_HELO; - } - else if (memcmp (cmd_buf, "EHLO", 4) == 0) { - pcmd->command = SMTP_COMMAND_EHLO; - } - else if (memcmp (cmd_buf, "MAIL", 4) == 0) { - pcmd->command = SMTP_COMMAND_MAIL; + case SMTP_PARSE_START: + if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i == line->len - 1) { + if (i == line->len - 1) { + p ++; } - else if (memcmp (cmd_buf, "RCPT", 4) == 0) { - pcmd->command = SMTP_COMMAND_RCPT; + if (p - c == 4) { + cmd_buf[0] = g_ascii_toupper (c[0]); + cmd_buf[1] = g_ascii_toupper (c[1]); + cmd_buf[2] = g_ascii_toupper (c[2]); + cmd_buf[3] = g_ascii_toupper (c[3]); + + if (memcmp (cmd_buf, "HELO", 4) == 0) { + pcmd->command = SMTP_COMMAND_HELO; + } + else if (memcmp (cmd_buf, "EHLO", 4) == 0) { + pcmd->command = SMTP_COMMAND_EHLO; + } + else if (memcmp (cmd_buf, "MAIL", 4) == 0) { + pcmd->command = SMTP_COMMAND_MAIL; + } + else if (memcmp (cmd_buf, "RCPT", 4) == 0) { + pcmd->command = SMTP_COMMAND_RCPT; + } + else if (memcmp (cmd_buf, "DATA", 4) == 0) { + pcmd->command = SMTP_COMMAND_DATA; + } + else if (memcmp (cmd_buf, "QUIT", 4) == 0) { + pcmd->command = SMTP_COMMAND_QUIT; + } + else if (memcmp (cmd_buf, "NOOP", 4) == 0) { + pcmd->command = SMTP_COMMAND_NOOP; + } + else if (memcmp (cmd_buf, "EXPN", 4) == 0) { + pcmd->command = SMTP_COMMAND_EXPN; + } + else if (memcmp (cmd_buf, "RSET", 4) == 0) { + pcmd->command = SMTP_COMMAND_RSET; + } + else if (memcmp (cmd_buf, "HELP", 4) == 0) { + pcmd->command = SMTP_COMMAND_HELP; + } + else if (memcmp (cmd_buf, "VRFY", 4) == 0) { + pcmd->command = SMTP_COMMAND_VRFY; + } + else { + msg_info ("invalid command: %*s", 4, cmd_buf); + return FALSE; + } } - else if (memcmp (cmd_buf, "DATA", 4) == 0) { - pcmd->command = SMTP_COMMAND_DATA; - } - else if (memcmp (cmd_buf, "QUIT", 4) == 0) { - pcmd->command = SMTP_COMMAND_QUIT; - } - else if (memcmp (cmd_buf, "NOOP", 4) == 0) { - pcmd->command = SMTP_COMMAND_NOOP; - } - else if (memcmp (cmd_buf, "EXPN", 4) == 0) { - pcmd->command = SMTP_COMMAND_EXPN; + else { + /* Invalid command */ + msg_info ("invalid command: %*s", 4, c); + return FALSE; } - else if (memcmp (cmd_buf, "RSET", 4) == 0) { - pcmd->command = SMTP_COMMAND_RSET; + /* Now check what we have */ + if (ch == ' ' || ch == ':') { + state = SMTP_PARSE_SPACES; } - else if (memcmp (cmd_buf, "HELP", 4) == 0) { - pcmd->command = SMTP_COMMAND_HELP; + else if (ch == CR) { + state = SMTP_PARSE_DONE; } - else if (memcmp (cmd_buf, "VRFY", 4) == 0) { - pcmd->command = SMTP_COMMAND_VRFY; - } - else { - msg_info ("invalid command: %*s", 4, cmd_buf); - return FALSE; + else if (ch == LF) { + return TRUE; } } - else { - /* Invalid command */ - msg_info ("invalid command: %*s", 4, c); + else if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { + msg_info ("invalid letter code in SMTP command: %d", (gint)ch); return FALSE; } - /* Now check what we have */ - if (ch == ' ' || ch == ':') { - state = SMTP_PARSE_SPACES; - } - else if (ch == CR) { + break; + case SMTP_PARSE_SPACES: + if (ch == CR) { state = SMTP_PARSE_DONE; } else if (ch == LF) { - return TRUE; + goto end; } - } - else if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { - msg_info ("invalid letter code in SMTP command: %d", (gint)ch); - return FALSE; - } - break; - case SMTP_PARSE_SPACES: - if (ch == CR) { - state = SMTP_PARSE_DONE; - } - else if (ch == LF) { - goto end; - } - else if (ch != ' ' && ch != ':') { - state = SMTP_PARSE_ARGUMENT; - arg = rspamd_mempool_alloc (session->pool, sizeof (f_str_t)); - c = p; - } - break; - case SMTP_PARSE_ARGUMENT: - if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i == - line->len - 1) { - if (i == line->len - 1 && (ch != ' ' && ch != CR && ch != LF)) { - p++; - } - arg->len = p - c; - arg->begin = rspamd_mempool_alloc (session->pool, arg->len); - memcpy (arg->begin, c, arg->len); - pcmd->args = g_list_prepend (pcmd->args, arg); - if (ch == ' ' || ch == ':') { - state = SMTP_PARSE_SPACES; - } - else if (ch == CR) { - state = SMTP_PARSE_DONE; + else if (ch != ' ' && ch != ':') { + state = SMTP_PARSE_ARGUMENT; + arg = rspamd_mempool_alloc (session->pool, sizeof (f_str_t)); + c = p; } - else { + break; + case SMTP_PARSE_ARGUMENT: + if (ch == ' ' || ch == ':' || ch == CR || ch == LF || i == line->len - 1) { + if (i == line->len - 1 && (ch != ' ' && ch != CR && ch != LF)) { + p ++; + } + arg->len = p - c; + arg->begin = rspamd_mempool_alloc (session->pool, arg->len); + memcpy (arg->begin, c, arg->len); + pcmd->args = g_list_prepend (pcmd->args, arg); + if (ch == ' ' || ch == ':') { + state = SMTP_PARSE_SPACES; + } + else if (ch == CR) { + state = SMTP_PARSE_DONE; + } + else { + goto end; + } + } + break; + case SMTP_PARSE_DONE: + if (ch == LF) { goto end; } - } - break; - case SMTP_PARSE_DONE: - if (ch == LF) { - goto end; - } - msg_info ("CR without LF in SMTP command"); - return FALSE; + msg_info ("CR without LF in SMTP command"); + return FALSE; } } end: if (pcmd->args) { pcmd->args = g_list_reverse (pcmd->args); - rspamd_mempool_add_destructor (session->pool, - (rspamd_mempool_destruct_t)g_list_free, - pcmd->args); + rspamd_mempool_add_destructor (session->pool, (rspamd_mempool_destruct_t)g_list_free, pcmd->args); } return TRUE; } @@ -211,14 +202,14 @@ end: static gboolean check_smtp_path (f_str_t *path) { - guint i; - gchar *p; + guint i; + gchar *p; p = path->begin; if (*p != '<' || path->len < 2) { return FALSE; } - for (i = 0; i < path->len; i++, p++) { + for (i = 0; i < path->len; i++, p ++) { if (*p == '>' && i != path->len - 1) { return FALSE; } @@ -230,7 +221,7 @@ check_smtp_path (f_str_t *path) gboolean parse_smtp_helo (struct smtp_session *session, struct smtp_command *cmd) { - f_str_t *arg; + f_str_t *arg; if (cmd->args == NULL) { session->error = SMTP_ERROR_BAD_ARGUMENTS; @@ -265,8 +256,8 @@ parse_smtp_helo (struct smtp_session *session, struct smtp_command *cmd) gboolean parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd) { - f_str_t *arg; - GList *cur = cmd->args; + f_str_t *arg; + GList *cur = cmd->args; if (cmd->args == NULL) { session->error = SMTP_ERROR_BAD_ARGUMENTS; @@ -275,10 +266,10 @@ parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd) arg = cur->data; /* First argument MUST be FROM */ if (arg->len != 4 || ( - g_ascii_toupper (arg->begin[0]) != 'F' || - g_ascii_toupper (arg->begin[1]) != 'R' || - g_ascii_toupper (arg->begin[2]) != 'O' || - g_ascii_toupper (arg->begin[3]) != 'M')) { + g_ascii_toupper (arg->begin[0]) != 'F' || + g_ascii_toupper (arg->begin[1]) != 'R' || + g_ascii_toupper (arg->begin[2]) != 'O' || + g_ascii_toupper (arg->begin[3]) != 'M')) { session->error = SMTP_ERROR_BAD_ARGUMENTS; return FALSE; } @@ -303,8 +294,8 @@ parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd) gboolean parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd) { - f_str_t *arg; - GList *cur = cmd->args; + f_str_t *arg; + GList *cur = cmd->args; if (cmd->args == NULL) { session->error = SMTP_ERROR_BAD_ARGUMENTS; @@ -313,8 +304,8 @@ parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd) arg = cur->data; /* First argument MUST be FROM */ if (arg->len != 2 || ( - g_ascii_toupper (arg->begin[0]) != 'T' || - g_ascii_toupper (arg->begin[1]) != 'O')) { + g_ascii_toupper (arg->begin[0]) != 'T' || + g_ascii_toupper (arg->begin[1]) != 'O')) { session->error = SMTP_ERROR_BAD_ARGUMENTS; return FALSE; } @@ -341,7 +332,7 @@ parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd) static gint check_smtp_ustream_reply (f_str_t *in, gchar success_code) { - gchar *p; + gchar *p; /* Check for 250 at the begin of line */ if (in->len >= sizeof ("220 ") - 1) { @@ -366,13 +357,13 @@ check_smtp_ustream_reply (f_str_t *in, gchar success_code) size_t smtp_upstream_write_list (GList *args, gchar *buf, size_t buflen) { - GList *cur = args; - size_t r = 0; - f_str_t *arg; + GList *cur = args; + size_t r = 0; + f_str_t *arg; while (cur && r < buflen - 3) { arg = cur->data; - r += rspamd_snprintf (buf + r, buflen - r, " %V", arg); + r += rspamd_snprintf (buf + r, buflen - r, " %V", arg); cur = g_list_next (cur); } @@ -383,351 +374,288 @@ smtp_upstream_write_list (GList *args, gchar *buf, size_t buflen) return r; } -gboolean +gboolean smtp_upstream_write_socket (void *arg) { - struct smtp_session *session = arg; - + struct smtp_session *session = arg; + if (session->upstream_state == SMTP_STATE_IN_SENDFILE) { session->upstream_state = SMTP_STATE_AFTER_DATA; - return rspamd_dispatcher_write (session->upstream_dispatcher, - CRLF DATA_END_TRAILER, - sizeof (CRLF DATA_END_TRAILER) - 1, - FALSE, - TRUE); + return rspamd_dispatcher_write (session->upstream_dispatcher, CRLF DATA_END_TRAILER, sizeof (CRLF DATA_END_TRAILER) - 1, FALSE, TRUE); } return TRUE; } -gboolean +gboolean smtp_upstream_read_socket (f_str_t * in, void *arg) { - struct smtp_session *session = arg; - gchar outbuf[BUFSIZ]; - gint r; - + struct smtp_session *session = arg; + gchar outbuf[BUFSIZ]; + gint r; + msg_debug ("in: %V, state: %d", in, session->upstream_state); switch (session->upstream_state) { - case SMTP_STATE_GREETING: - r = check_smtp_ustream_reply (in, '2'); - if (r == -1) { - session->error = rspamd_mempool_alloc (session->pool, in->len + 1); - rspamd_strlcpy (session->error, in->begin, in->len + 1); - /* XXX: assume upstream errors as critical errors */ - session->state = SMTP_STATE_CRITICAL_ERROR; - rspamd_dispatcher_restore (session->dispatcher); - if (!rspamd_dispatcher_write (session->dispatcher, session->error, - in->len, FALSE, TRUE)) { - goto err; + case SMTP_STATE_GREETING: + r = check_smtp_ustream_reply (in, '2'); + if (r == -1) { + session->error = rspamd_mempool_alloc (session->pool, in->len + 1); + rspamd_strlcpy (session->error, in->begin, in->len + 1); + /* XXX: assume upstream errors as critical errors */ + session->state = SMTP_STATE_CRITICAL_ERROR; + rspamd_dispatcher_restore (session->dispatcher); + if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) { + goto err; + } + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { + goto err; + } + destroy_session (session->s); + return FALSE; } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, - sizeof (CRLF) - 1, FALSE, TRUE)) { - goto err; + else if (r == 1) { + if (session->ctx->use_xclient) { + r = rspamd_snprintf (outbuf, sizeof (outbuf), "XCLIENT NAME=%s ADDR=%s" CRLF, + session->resolved ? session->hostname : "[UNDEFINED]", + inet_ntoa (session->client_addr)); + session->upstream_state = SMTP_STATE_HELO; + return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE); + } + else { + session->upstream_state = SMTP_STATE_FROM; + if (session->helo) { + r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF, + session->esmtp ? "EHLO" : "HELO", + session->helo); + } + else { + return smtp_upstream_read_socket (in, arg); + } + return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE); + } } - destroy_session (session->s); - return FALSE; - } - else if (r == 1) { - if (session->ctx->use_xclient) { - r = rspamd_snprintf (outbuf, - sizeof (outbuf), - "XCLIENT NAME=%s ADDR=%s" CRLF, - session->resolved ? session->hostname : "[UNDEFINED]", - inet_ntoa (session->client_addr)); - session->upstream_state = SMTP_STATE_HELO; - return rspamd_dispatcher_write (session->upstream_dispatcher, - outbuf, - r, - FALSE, - FALSE); + break; + case SMTP_STATE_HELO: + r = check_smtp_ustream_reply (in, '2'); + if (r == -1) { + session->error = rspamd_mempool_alloc (session->pool, in->len + 1); + rspamd_strlcpy (session->error, in->begin, in->len + 1); + /* XXX: assume upstream errors as critical errors */ + session->state = SMTP_STATE_CRITICAL_ERROR; + rspamd_dispatcher_restore (session->dispatcher); + if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) { + goto err; + } + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { + goto err; + } + destroy_session (session->s); + return FALSE; } - else { + else if (r == 1) { session->upstream_state = SMTP_STATE_FROM; if (session->helo) { - r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF, - session->esmtp ? "EHLO" : "HELO", - session->helo); + r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF, + session->esmtp ? "EHLO" : "HELO", + session->helo); } else { return smtp_upstream_read_socket (in, arg); } - return rspamd_dispatcher_write (session->upstream_dispatcher, - outbuf, - r, - FALSE, - FALSE); + return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE); } - } - break; - case SMTP_STATE_HELO: - r = check_smtp_ustream_reply (in, '2'); - if (r == -1) { - session->error = rspamd_mempool_alloc (session->pool, in->len + 1); - rspamd_strlcpy (session->error, in->begin, in->len + 1); - /* XXX: assume upstream errors as critical errors */ - session->state = SMTP_STATE_CRITICAL_ERROR; - rspamd_dispatcher_restore (session->dispatcher); - if (!rspamd_dispatcher_write (session->dispatcher, session->error, - in->len, FALSE, TRUE)) { - goto err; - } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, - sizeof (CRLF) - 1, FALSE, TRUE)) { - goto err; - } - destroy_session (session->s); - return FALSE; - } - else if (r == 1) { - session->upstream_state = SMTP_STATE_FROM; - if (session->helo) { - r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s %s" CRLF, - session->esmtp ? "EHLO" : "HELO", - session->helo); - } - else { - return smtp_upstream_read_socket (in, arg); - } - return rspamd_dispatcher_write (session->upstream_dispatcher, - outbuf, - r, - FALSE, - FALSE); - } - break; - case SMTP_STATE_FROM: - r = check_smtp_ustream_reply (in, '2'); - if (r == -1) { - session->error = rspamd_mempool_alloc (session->pool, in->len + 1); - rspamd_strlcpy (session->error, in->begin, in->len + 1); - /* XXX: assume upstream errors as critical errors */ - session->state = SMTP_STATE_CRITICAL_ERROR; - rspamd_dispatcher_restore (session->dispatcher); - if (!rspamd_dispatcher_write (session->dispatcher, session->error, - in->len, FALSE, TRUE)) { - goto err; - } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, - sizeof (CRLF) - 1, FALSE, TRUE)) { - goto err; - } - destroy_session (session->s); - return FALSE; - } - else if (r == 1) { - r = rspamd_snprintf (outbuf, sizeof (outbuf), "MAIL FROM: "); - r += - smtp_upstream_write_list (session->from, - outbuf + r, - sizeof (outbuf) - r); - session->upstream_state = SMTP_STATE_RCPT; - return rspamd_dispatcher_write (session->upstream_dispatcher, - outbuf, - r, - FALSE, - FALSE); - } - break; - case SMTP_STATE_RCPT: - r = check_smtp_ustream_reply (in, '2'); - if (r == -1) { - session->error = rspamd_mempool_alloc (session->pool, in->len + 1); - rspamd_strlcpy (session->error, in->begin, in->len + 1); - /* XXX: assume upstream errors as critical errors */ - session->state = SMTP_STATE_CRITICAL_ERROR; - rspamd_dispatcher_restore (session->dispatcher); - if (!rspamd_dispatcher_write (session->dispatcher, session->error, - in->len, FALSE, TRUE)) { - goto err; - } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, - sizeof (CRLF) - 1, FALSE, TRUE)) { - goto err; - } - destroy_session (session->s); - return FALSE; - } - else if (r == 1) { - r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: "); - session->cur_rcpt = g_list_first (session->rcpt); - r += smtp_upstream_write_list (session->cur_rcpt->data, - outbuf + r, - sizeof (outbuf) - r); - session->cur_rcpt = g_list_next (session->cur_rcpt); - session->upstream_state = SMTP_STATE_BEFORE_DATA; - return rspamd_dispatcher_write (session->upstream_dispatcher, - outbuf, - r, - FALSE, - FALSE); - } - break; - case SMTP_STATE_BEFORE_DATA: - r = check_smtp_ustream_reply (in, '2'); - if (r == -1) { - session->error = rspamd_mempool_alloc (session->pool, in->len + 1); - rspamd_strlcpy (session->error, in->begin, in->len + 1); - rspamd_dispatcher_restore (session->dispatcher); - if (!rspamd_dispatcher_write (session->dispatcher, session->error, - in->len, FALSE, TRUE)) { - goto err; - } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, - sizeof (CRLF) - 1, FALSE, TRUE)) { - goto err; + break; + case SMTP_STATE_FROM: + r = check_smtp_ustream_reply (in, '2'); + if (r == -1) { + session->error = rspamd_mempool_alloc (session->pool, in->len + 1); + rspamd_strlcpy (session->error, in->begin, in->len + 1); + /* XXX: assume upstream errors as critical errors */ + session->state = SMTP_STATE_CRITICAL_ERROR; + rspamd_dispatcher_restore (session->dispatcher); + if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) { + goto err; + } + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { + goto err; + } + destroy_session (session->s); + return FALSE; } - if (session->cur_rcpt) { - session->rcpt = g_list_delete_link (session->rcpt, - session->cur_rcpt); + else if (r == 1) { + r = rspamd_snprintf (outbuf, sizeof (outbuf), "MAIL FROM: "); + r += smtp_upstream_write_list (session->from, outbuf + r, sizeof (outbuf) - r); + session->upstream_state = SMTP_STATE_RCPT; + return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE); } - else { - session->rcpt = - g_list_delete_link (session->rcpt, session->rcpt); + break; + case SMTP_STATE_RCPT: + r = check_smtp_ustream_reply (in, '2'); + if (r == -1) { + session->error = rspamd_mempool_alloc (session->pool, in->len + 1); + rspamd_strlcpy (session->error, in->begin, in->len + 1); + /* XXX: assume upstream errors as critical errors */ + session->state = SMTP_STATE_CRITICAL_ERROR; + rspamd_dispatcher_restore (session->dispatcher); + if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) { + goto err; + } + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { + goto err; + } + destroy_session (session->s); + return FALSE; } - session->errors++; - session->state = SMTP_STATE_RCPT; - return TRUE; - } - else if (r == 1) { - if (session->cur_rcpt != NULL) { + else if (r == 1) { r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: "); - r += smtp_upstream_write_list (session->cur_rcpt, - outbuf + r, - sizeof (outbuf) - r); + session->cur_rcpt = g_list_first (session->rcpt); + r += smtp_upstream_write_list (session->cur_rcpt->data, outbuf + r, sizeof (outbuf) - r); session->cur_rcpt = g_list_next (session->cur_rcpt); - if (!rspamd_dispatcher_write (session->upstream_dispatcher, - outbuf, r, FALSE, FALSE)) { + session->upstream_state = SMTP_STATE_BEFORE_DATA; + return rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE); + } + break; + case SMTP_STATE_BEFORE_DATA: + r = check_smtp_ustream_reply (in, '2'); + if (r == -1) { + session->error = rspamd_mempool_alloc (session->pool, in->len + 1); + rspamd_strlcpy (session->error, in->begin, in->len + 1); + rspamd_dispatcher_restore (session->dispatcher); + if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) { goto err; } + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { + goto err; + } + if (session->cur_rcpt) { + session->rcpt = g_list_delete_link (session->rcpt, session->cur_rcpt); + } + else { + session->rcpt = g_list_delete_link (session->rcpt, session->rcpt); + } + session->errors ++; + session->state = SMTP_STATE_RCPT; + return TRUE; + } + else if (r == 1) { + if (session->cur_rcpt != NULL) { + r = rspamd_snprintf (outbuf, sizeof (outbuf), "RCPT TO: "); + r += smtp_upstream_write_list (session->cur_rcpt, outbuf + r, sizeof (outbuf) - r); + session->cur_rcpt = g_list_next (session->cur_rcpt); + if (! rspamd_dispatcher_write (session->upstream_dispatcher, outbuf, r, FALSE, FALSE)) { + goto err; + } + } + else { + session->upstream_state = SMTP_STATE_DATA; + rspamd_dispatcher_pause (session->upstream_dispatcher); + } + session->error = rspamd_mempool_alloc (session->pool, in->len + 1); + rspamd_strlcpy (session->error, in->begin, in->len + 1); + /* Write to client */ + if (! rspamd_dispatcher_write (session->dispatcher, session->error, in->len, FALSE, TRUE)) { + goto err; + } + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { + goto err; + } + if (session->state == SMTP_STATE_WAIT_UPSTREAM) { + rspamd_dispatcher_restore (session->dispatcher); + session->state = SMTP_STATE_RCPT; + } } - else { - session->upstream_state = SMTP_STATE_DATA; - rspamd_dispatcher_pause (session->upstream_dispatcher); - } - session->error = rspamd_mempool_alloc (session->pool, in->len + 1); - rspamd_strlcpy (session->error, in->begin, in->len + 1); - /* Write to client */ - if (!rspamd_dispatcher_write (session->dispatcher, session->error, - in->len, FALSE, TRUE)) { - goto err; - } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, - sizeof (CRLF) - 1, FALSE, TRUE)) { - goto err; + break; + case SMTP_STATE_DATA: + r = check_smtp_ustream_reply (in, '3'); + if (r == -1) { + session->error = rspamd_mempool_alloc (session->pool, in->len + 1); + rspamd_strlcpy (session->error, in->begin, in->len + 1); + /* XXX: assume upstream errors as critical errors */ + session->state = SMTP_STATE_CRITICAL_ERROR; + rspamd_dispatcher_restore (session->dispatcher); + if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) { + goto err; + } + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { + goto err; + } + destroy_session (session->s); + return FALSE; } - if (session->state == SMTP_STATE_WAIT_UPSTREAM) { + else if (r == 1) { + 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)) { + goto err; + } + destroy_session (session->s); + return FALSE; + } + session->state = SMTP_STATE_AFTER_DATA; + session->error = SMTP_ERROR_DATA_OK; rspamd_dispatcher_restore (session->dispatcher); - session->state = SMTP_STATE_RCPT; + if (! rspamd_dispatcher_write (session->dispatcher, session->error, 0, FALSE, TRUE)) { + goto err; + } + rspamd_dispatcher_pause (session->upstream_dispatcher); + rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_LINE, 0); + session->dispatcher->strip_eol = FALSE; + return TRUE; } - } - break; - case SMTP_STATE_DATA: - r = check_smtp_ustream_reply (in, '3'); - if (r == -1) { + break; + case SMTP_STATE_AFTER_DATA: session->error = rspamd_mempool_alloc (session->pool, in->len + 1); rspamd_strlcpy (session->error, in->begin, in->len + 1); - /* XXX: assume upstream errors as critical errors */ - session->state = SMTP_STATE_CRITICAL_ERROR; + session->state = SMTP_STATE_DATA; 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; } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, - sizeof (CRLF) - 1, FALSE, TRUE)) { + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { goto err; } - destroy_session (session->s); - return FALSE; - } - else if (r == 1) { - if (!make_smtp_tempfile (session)) { - session->error = SMTP_ERROR_FILE; + if (! rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, sizeof ("QUIT" CRLF) - 1, FALSE, TRUE)) { + goto err; + } + session->upstream_state = SMTP_STATE_END; + return TRUE; + break; + case SMTP_STATE_END: + r = check_smtp_ustream_reply (in, '5'); + if (r == -1) { + session->error = rspamd_mempool_alloc (session->pool, in->len + 1); + rspamd_strlcpy (session->error, in->begin, in->len + 1); + /* XXX: assume upstream errors as critical errors */ 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; + } + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { goto err; } destroy_session (session->s); return FALSE; } - session->state = SMTP_STATE_AFTER_DATA; - session->error = SMTP_ERROR_DATA_OK; - rspamd_dispatcher_restore (session->dispatcher); - if (!rspamd_dispatcher_write (session->dispatcher, session->error, - 0, FALSE, TRUE)) { - goto err; + else { + remove_normal_event (session->s, (event_finalizer_t)smtp_upstream_finalize_connection, session); } - rspamd_dispatcher_pause (session->upstream_dispatcher); - rspamd_set_dispatcher_policy (session->dispatcher, BUFFER_LINE, 0); - session->dispatcher->strip_eol = FALSE; - return TRUE; - } - break; - case SMTP_STATE_AFTER_DATA: - session->error = rspamd_mempool_alloc (session->pool, in->len + 1); - rspamd_strlcpy (session->error, in->begin, in->len + 1); - session->state = SMTP_STATE_DATA; - rspamd_dispatcher_restore (session->dispatcher); - if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, - FALSE, TRUE)) { - goto err; - } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - - 1, FALSE, TRUE)) { - goto err; - } - if (!rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, - sizeof ("QUIT" CRLF) - 1, FALSE, TRUE)) { - goto err; - } - session->upstream_state = SMTP_STATE_END; - return TRUE; - break; - case SMTP_STATE_END: - r = check_smtp_ustream_reply (in, '5'); - if (r == -1) { - session->error = rspamd_mempool_alloc (session->pool, in->len + 1); - rspamd_strlcpy (session->error, in->begin, in->len + 1); - /* XXX: assume upstream errors as critical errors */ + return FALSE; + break; + default: + msg_err ("got upstream reply at unexpected state: %d, reply: %V", session->upstream_state, in); 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; } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, - sizeof (CRLF) - 1, FALSE, TRUE)) { + if (! rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE, TRUE)) { goto err; } destroy_session (session->s); return FALSE; - } - else { - remove_normal_event (session->s, - (event_finalizer_t)smtp_upstream_finalize_connection, - session); - } - return FALSE; - break; - default: - msg_err ("got upstream reply at unexpected state: %d, reply: %V", - session->upstream_state, - in); - session->state = SMTP_STATE_CRITICAL_ERROR; - rspamd_dispatcher_restore (session->dispatcher); - if (!rspamd_dispatcher_write (session->dispatcher, session->error, 0, - FALSE, TRUE)) { - goto err; - } - if (!rspamd_dispatcher_write (session->dispatcher, CRLF, sizeof (CRLF) - - 1, FALSE, TRUE)) { - goto err; - } - destroy_session (session->s); - return FALSE; } return TRUE; @@ -736,24 +664,20 @@ err: return FALSE; } -void +void smtp_upstream_err_socket (GError *err, void *arg) { - struct smtp_session *session = arg; + struct smtp_session *session = arg; - msg_info ("abnormally closing connection with upstream %s, error: %s", - session->upstream->name, - err->message); + msg_info ("abnormally closing connection with upstream %s, error: %s", session->upstream->name, err->message); session->error = SMTP_ERROR_UPSTREAM; session->state = SMTP_STATE_CRITICAL_ERROR; /* XXX: assume upstream errors as critical errors */ 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)) { return; } - 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; } upstream_fail (&session->upstream->up, session->session_time); @@ -763,11 +687,10 @@ smtp_upstream_err_socket (GError *err, void *arg) void smtp_upstream_finalize_connection (gpointer data) { - struct smtp_session *session = data; - + struct smtp_session *session = data; + if (session->state != SMTP_STATE_CRITICAL_ERROR) { - if (!rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, - 0, FALSE, TRUE)) { + if (! rspamd_dispatcher_write (session->upstream_dispatcher, "QUIT" CRLF, 0, FALSE, TRUE)) { msg_warn ("cannot send correctly closing message to upstream"); } } diff --git a/src/libmime/smtp_proto.h b/src/libmime/smtp_proto.h index 7c5787926..42fecd255 100644 --- a/src/libmime/smtp_proto.h +++ b/src/libmime/smtp_proto.h @@ -6,14 +6,12 @@ /* SMTP errors */ #define SMTP_ERROR_BAD_COMMAND "500 Syntax error, command unrecognized" CRLF -#define SMTP_ERROR_BAD_ARGUMENTS "501 Syntax error in parameters or arguments" \ - CRLF +#define SMTP_ERROR_BAD_ARGUMENTS "501 Syntax error in parameters or arguments" CRLF #define SMTP_ERROR_SEQUENCE "503 Bad sequence of commands" CRLF #define SMTP_ERROR_RECIPIENTS "554 No valid recipients" CRLF #define SMTP_ERROR_UNIMPLIMENTED "502 Command not implemented" CRLF #define SMTP_ERROR_LIMIT "505 Too many errors. Aborting." CRLF -#define SMTP_ERROR_UPSTREAM \ - "421 Service not available, closing transmission channel" CRLF +#define SMTP_ERROR_UPSTREAM "421 Service not available, closing transmission channel" CRLF #define SMTP_ERROR_FILE "420 Service not available, filesystem error" CRLF #define SMTP_ERROR_OK "250 Requested mail action okay, completed" CRLF #define SMTP_ERROR_DATA_OK "354 Start mail input; end with <CRLF>.<CRLF>" CRLF @@ -45,35 +43,27 @@ struct smtp_command { /* * Generate SMTP error message */ -gchar * make_smtp_error (rspamd_mempool_t *pool, - gint error_code, - const gchar *format, - ...); +gchar * make_smtp_error (rspamd_mempool_t *pool, gint error_code, const gchar *format, ...); /* * Parse a single SMTP command */ -gboolean parse_smtp_command (struct smtp_session *session, - f_str_t *line, - struct smtp_command **cmd); +gboolean parse_smtp_command (struct smtp_session *session, f_str_t *line, struct smtp_command **cmd); /* * Parse HELO command */ -gboolean parse_smtp_helo (struct smtp_session *session, - struct smtp_command *cmd); +gboolean parse_smtp_helo (struct smtp_session *session, struct smtp_command *cmd); /* * Parse MAIL command */ -gboolean parse_smtp_from (struct smtp_session *session, - struct smtp_command *cmd); +gboolean parse_smtp_from (struct smtp_session *session, struct smtp_command *cmd); /* * Parse RCPT command */ -gboolean parse_smtp_rcpt (struct smtp_session *session, - struct smtp_command *cmd); +gboolean parse_smtp_rcpt (struct smtp_session *session, struct smtp_command *cmd); /* Upstream SMTP */ diff --git a/src/libmime/smtp_utils.c b/src/libmime/smtp_utils.c index a4fb4582e..8ed169fa7 100644 --- a/src/libmime/smtp_utils.c +++ b/src/libmime/smtp_utils.c @@ -22,15 +22,15 @@ */ #include "config.h" -#include "filter.h" #include "main.h" +#include "filter.h" #include "smtp.h" #include "smtp_proto.h" void free_smtp_session (gpointer arg) { - struct smtp_session *session = arg; + struct smtp_session *session = arg; if (session) { if (session->task) { @@ -60,17 +60,12 @@ 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; @@ -79,32 +74,19 @@ 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; } @@ -116,8 +98,7 @@ 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; } @@ -126,8 +107,7 @@ 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); @@ -135,35 +115,32 @@ 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; @@ -175,10 +152,8 @@ 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) { @@ -190,70 +165,42 @@ 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)); @@ -267,28 +214,23 @@ 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); @@ -296,26 +238,22 @@ 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); @@ -328,11 +266,7 @@ 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; @@ -341,26 +275,21 @@ 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); @@ -373,8 +302,7 @@ 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); @@ -382,33 +310,29 @@ 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')) { @@ -425,15 +349,15 @@ parse_upstreams_line (rspamd_mempool_t *pool, 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) ++; } } diff --git a/src/libmime/smtp_utils.h b/src/libmime/smtp_utils.h index c09729180..652b6759f 100644 --- a/src/libmime/smtp_utils.h +++ b/src/libmime/smtp_utils.h @@ -58,9 +58,6 @@ void free_smtp_session (gpointer arg); * @param count targeted count * @return */ -gboolean parse_upstreams_line (rspamd_mempool_t *pool, - struct smtp_upstream *upstreams, - const gchar *line, - gsize *count); +gboolean parse_upstreams_line (rspamd_mempool_t *pool, struct smtp_upstream *upstreams, const gchar *line, gsize *count); #endif /* SMTP_UTILS_H_ */ |