From: Vsevolod Stakhov Date: Sun, 24 Apr 2016 12:10:05 +0000 (+0100) Subject: [Feature] Start moving to the new email address structure X-Git-Tag: 1.3.0~647 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f40a090c9e01963d121861fb5cddf0f951dd2de1;p=rspamd.git [Feature] Start moving to the new email address structure --- diff --git a/src/libmime/message.c b/src/libmime/message.c index a234e43be..2f3656eb8 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -21,6 +21,7 @@ #include "libutil/regexp.h" #include "html.h" #include "images.h" +#include "email_addr.h" #include "utlist.h" #include "tokenizers/tokenizers.h" @@ -1475,14 +1476,21 @@ rspamd_message_from_data (struct rspamd_task *task, GByteArray *data, const char *mb = NULL; gchar *mid; rspamd_ftok_t srch, *tok; + struct rspamd_email_address *addr; g_assert (data != NULL); message = g_mime_message_new (TRUE); task->message = message; if (task->from_envelope) { - g_mime_message_set_sender (task->message, - rspamd_task_get_sender (task)); + addr = rspamd_task_get_sender (task); + + if (addr->addr_len > 0) { + srch.begin = addr->addr; + srch.len = addr->addr_len; + g_mime_message_set_sender (task->message, + rspamd_mempool_ftokdup (task->task_pool, &srch)); + } } srch.begin = "Content-Type"; @@ -1764,18 +1772,8 @@ rspamd_message_parse (struct rspamd_task *task) if (first) { rh = first->data; - task->from_envelope = internet_address_list_parse_string (rh->value); - if (task->from_envelope) { -#ifdef GMIME24 - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_object_unref, - task->from_envelope); -#else - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) internet_address_list_destroy, - task->from_envelope); -#endif - } + task->from_envelope = rspamd_email_address_from_smtp (rh->decoded, + strlen (rh->decoded)); } } diff --git a/src/libmime/mime_expressions.c b/src/libmime/mime_expressions.c index ea8af2dcd..fcea95bb2 100644 --- a/src/libmime/mime_expressions.c +++ b/src/libmime/mime_expressions.c @@ -20,6 +20,7 @@ #include "message.h" #include "mime_expressions.h" #include "html.h" +#include "email_addr.h" #include "lua/lua_common.h" gboolean rspamd_compare_encoding (struct rspamd_task *task, @@ -1424,7 +1425,7 @@ rspamd_raw_header_exists (struct rspamd_task *task, GArray * args, void *unused) static gboolean match_smtp_data (struct rspamd_task *task, struct expression_argument *arg, - const gchar *what) + const gchar *what, gsize len) { rspamd_regexp_t *re; gint r; @@ -1438,12 +1439,12 @@ match_smtp_data (struct rspamd_task *task, } - r = rspamd_regexp_search (re, what, 0, NULL, NULL, FALSE, NULL); + r = rspamd_regexp_search (re, what, len, NULL, NULL, FALSE, NULL); return r; } else if (arg->type == EXPRESSION_ARGUMENT_NORMAL && - g_ascii_strcasecmp (arg->data, what) == 0) { + g_ascii_strncasecmp (arg->data, what, len) == 0) { return TRUE; } @@ -1454,9 +1455,10 @@ static gboolean rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused) { struct expression_argument *arg; - InternetAddressList *ia = NULL; - const gchar *type, *what = NULL; - gint i, ialen; + struct rspamd_email_address *addr; + GPtrArray *rcpts; + const gchar *type, *str = NULL; + guint i; if (args == NULL) { msg_warn_task ("no parameters to function"); @@ -1475,7 +1477,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused) case 'f': case 'F': if (g_ascii_strcasecmp (type, "from") == 0) { - what = rspamd_task_get_sender (task); + addr = rspamd_task_get_sender (task); } else { msg_warn_task ("bad argument to function: %s", type); @@ -1485,7 +1487,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused) case 'h': case 'H': if (g_ascii_strcasecmp (type, "helo") == 0) { - what = task->helo; + str = task->helo; } else { msg_warn_task ("bad argument to function: %s", type); @@ -1495,7 +1497,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused) case 'u': case 'U': if (g_ascii_strcasecmp (type, "user") == 0) { - what = task->user; + str = task->user; } else { msg_warn_task ("bad argument to function: %s", type); @@ -1505,7 +1507,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused) case 's': case 'S': if (g_ascii_strcasecmp (type, "subject") == 0) { - what = task->subject; + str = task->subject; } else { msg_warn_task ("bad argument to function: %s", type); @@ -1515,7 +1517,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused) case 'r': case 'R': if (g_ascii_strcasecmp (type, "rcpt") == 0) { - ia = task->rcpt_mime; + rcpts = task->rcpt_envelope; } else { msg_warn_task ("bad argument to function: %s", type); @@ -1528,7 +1530,7 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused) } } - if (what == NULL && ia == NULL) { + if (str == NULL && addr == NULL && rcpts == NULL) { /* Not enough data so regexp would NOT be found anyway */ return FALSE; } @@ -1536,22 +1538,22 @@ rspamd_check_smtp_data (struct rspamd_task *task, GArray * args, void *unused) /* We would process only one more argument, others are ignored */ if (args->len >= 2) { arg = &g_array_index (args, struct expression_argument, 1); + if (arg) { - if (what != NULL) { - return match_smtp_data (task, arg, what); + if (str != NULL) { + return match_smtp_data (task, arg, str, strlen (str)); + } + else if (addr != NULL && addr->addr) { + return match_smtp_data (task, arg, addr->addr, addr->addr_len); } else { - if (ia != NULL) { - ialen = internet_address_list_length(ia); - for (i = 0; i < ialen; i ++) { - InternetAddress *iaelt = - internet_address_list_get_address(ia, i); - InternetAddressMailbox *iamb = - INTERNET_ADDRESS_IS_MAILBOX(iaelt) ? - INTERNET_ADDRESS_MAILBOX (iaelt) : NULL; - if (iamb && + if (rcpts != NULL) { + for (i = 0; i < rcpts->len; i ++) { + addr = g_ptr_array_index (rcpts, i); + + if (addr && addr->addr && match_smtp_data (task, arg, - internet_address_mailbox_get_addr(iamb))) { + addr->addr, addr->addr_len)) { return TRUE; } } diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index e32dfc6e5..e95321966 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -21,6 +21,7 @@ #include "message.h" #include "utlist.h" #include "http.h" +#include "email_addr.h" #include "worker_private.h" /* Max line size */ @@ -268,6 +269,7 @@ rspamd_protocol_handle_headers (struct rspamd_task *task, rspamd_ftok_t *hn_tok, *hv_tok, srch; gboolean fl, has_ip = FALSE; struct rspamd_http_header *h; + struct rspamd_email_address *addr; LL_FOREACH (msg->headers, h) { @@ -305,8 +307,9 @@ rspamd_protocol_handle_headers (struct rspamd_task *task, case 'f': case 'F': IF_HEADER (FROM_HEADER) { - if (!rspamd_task_add_sender (task, - rspamd_mempool_ftokdup (task->task_pool, hv_tok))) { + task->from_envelope = rspamd_email_address_from_smtp (hv->str, + hv->len); + if (!task->from_envelope) { msg_err_task ("bad from header: '%V'", hv); } } @@ -343,8 +346,12 @@ rspamd_protocol_handle_headers (struct rspamd_task *task, case 'r': case 'R': IF_HEADER (RCPT_HEADER) { - if (!rspamd_task_add_recipient (task, - rspamd_mempool_ftokdup (task->task_pool, hv_tok))) { + addr = rspamd_email_address_from_smtp (hv->str, hv->len); + + if (addr) { + g_ptr_array_add (task->rcpt_envelope, addr); + } + else { msg_err_task ("bad from header: '%T'", h->value); } debug_task ("read rcpt header, value: %V", hv); @@ -656,15 +663,7 @@ urls_protocol_cb (gpointer key, gpointer value, gpointer ud) has_user = TRUE; } else if (task->from_envelope) { - InternetAddress *ia; - - ia = internet_address_list_get_address (task->from_envelope, 0); - - if (ia && INTERNET_ADDRESS_IS_MAILBOX (ia)) { - InternetAddressMailbox *iamb = INTERNET_ADDRESS_MAILBOX (ia); - - user_field = iamb->addr; - } + user_field = task->from_envelope->addr; } msg_info_task ("<%s> %s: %s; ip: %s; URL: %*s", diff --git a/src/libserver/task.c b/src/libserver/task.c index 492a69d72..d1adbcd0b 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -19,6 +19,7 @@ #include "protocol.h" #include "message.h" #include "lua/lua_common.h" +#include "email_addr.h" #include "composites.h" #include "stat_api.h" #include "unix-std.h" @@ -162,6 +163,7 @@ rspamd_task_free (struct rspamd_task *task) { struct mime_part *p; struct mime_text_part *tp; + struct rspamd_email_address *addr; guint i; if (task) { @@ -188,6 +190,15 @@ rspamd_task_free (struct rspamd_task *task) } } + for (i = 0; i < task->rcpt_envelope->len; i ++) { + addr = g_ptr_array_index (task->rcpt_envelope, i); + rspamd_email_address_unref (addr); + } + + if (task->from_envelope) { + rspamd_email_address_unref (task->from_envelope); + } + if (task->images) { g_list_free (task->images); } @@ -530,48 +541,22 @@ rspamd_task_process (struct rspamd_task *task, guint stages) return ret; } -const gchar * +struct rspamd_email_address* rspamd_task_get_sender (struct rspamd_task *task) { - InternetAddress *iaelt = NULL; -#ifdef GMIME24 - InternetAddressMailbox *imb; - - if (task->from_envelope != NULL) { - iaelt = internet_address_list_get_address (task->from_envelope, 0); - } - else if (task->from_mime != NULL) { - iaelt = internet_address_list_get_address (task->from_mime, 0); - } - imb = INTERNET_ADDRESS_IS_MAILBOX(iaelt) ? - INTERNET_ADDRESS_MAILBOX (iaelt) : NULL; - - return (imb ? internet_address_mailbox_get_addr (imb) : NULL); -#else - if (task->from_envelope != NULL) { - iaelt = internet_address_list_get_address (task->from_envelope); - } - else if (task->from_mime != NULL) { - iaelt = internet_address_list_get_address (task->from_mime); - } - - return (iaelt != NULL ? internet_address_get_addr (iaelt) : NULL); -#endif + return task->from_envelope; } static const gchar * rspamd_task_cache_principal_recipient (struct rspamd_task *task, - const gchar *rcpt) + const gchar *rcpt, gsize len) { gchar *rcpt_lc; - gsize len; if (rcpt == NULL) { return NULL; } - len = strlen (rcpt); - rcpt_lc = rspamd_mempool_alloc (task->task_pool, len + 1); rspamd_strlcpy (rcpt_lc, rcpt, len + 1); rspamd_str_lc (rcpt_lc, len); @@ -586,6 +571,7 @@ rspamd_task_get_principal_recipient (struct rspamd_task *task) { InternetAddress *iaelt = NULL; const gchar *val; + struct rspamd_email_address *addr; val = rspamd_mempool_get_variable (task->task_pool, "recipient"); @@ -594,16 +580,22 @@ rspamd_task_get_principal_recipient (struct rspamd_task *task) } if (task->deliver_to) { - return rspamd_task_cache_principal_recipient (task, task->deliver_to); + return rspamd_task_cache_principal_recipient (task, task->deliver_to, + strlen (task->deliver_to)); + } + if (task->rcpt_envelope != NULL) { + addr = g_ptr_array_index (task->rcpt_envelope, 0); + + if (addr->addr) { + return rspamd_task_cache_principal_recipient (task, addr->addr, + addr->addr_len); + } } #ifdef GMIME24 InternetAddressMailbox *imb; - if (task->rcpt_envelope != NULL) { - iaelt = internet_address_list_get_address (task->rcpt_envelope, 0); - } - else if (task->rcpt_mime != NULL) { + if (task->rcpt_mime != NULL) { iaelt = internet_address_list_get_address (task->rcpt_mime, 0); } @@ -613,99 +605,23 @@ rspamd_task_get_principal_recipient (struct rspamd_task *task) if (imb) { val = internet_address_mailbox_get_addr (imb); - return rspamd_task_cache_principal_recipient (task, val); + return rspamd_task_cache_principal_recipient (task, val, strlen (val)); } #else - if (task->rcpt_envelope != NULL) { - iaelt = internet_address_list_get_address (task->rcpt_envelope); - } - else if (task->rcpt_mime != NULL) { + if (task->rcpt_mime != NULL) { iaelt = internet_address_list_get_address (task->rcpt_mime); } if (iaelt) { val = internet_address_get_addr (iaelt); - return rspamd_task_cache_principal_recipient (task, val); + return rspamd_task_cache_principal_recipient (task, val, strlen (val)); } #endif return NULL; } -gboolean -rspamd_task_add_recipient (struct rspamd_task *task, const gchar *rcpt) -{ - InternetAddressList *tmp_addr; - - if (task->rcpt_envelope == NULL) { - task->rcpt_envelope = internet_address_list_new (); -#ifdef GMIME24 - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_object_unref, - task->rcpt_envelope); -#else - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) internet_address_list_destroy, - task->rcpt_envelope); -#endif - } - tmp_addr = internet_address_list_parse_string (rcpt); - - if (tmp_addr) { - internet_address_list_append (task->rcpt_envelope, tmp_addr); -#ifdef GMIME24 - g_object_unref (tmp_addr); -#else - internet_address_list_destroy (tmp_addr); -#endif - return TRUE; - } - - return FALSE; -} - -gboolean -rspamd_task_add_sender (struct rspamd_task *task, const gchar *sender) -{ - InternetAddressList *tmp_addr; - - if (task->from_envelope == NULL) { - task->from_envelope = internet_address_list_new (); -#ifdef GMIME24 - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_object_unref, - task->from_envelope); -#else - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) internet_address_list_destroy, - task->from_envelope); -#endif - } - - if (strcmp (sender, "<>") == 0) { - /* Workaround for gmime */ - internet_address_list_add (task->from_envelope, - internet_address_mailbox_new ("", "")); - return TRUE; - } - else { - tmp_addr = internet_address_list_parse_string (sender); - - if (tmp_addr) { - internet_address_list_append (task->from_envelope, tmp_addr); -#ifdef GMIME24 - g_object_unref (tmp_addr); -#else - internet_address_list_destroy (tmp_addr); -#endif - return TRUE; - } - } - - return FALSE; -} - gboolean rspamd_learn_task_spam (struct rspamd_task *task, gboolean is_spam, @@ -753,12 +669,7 @@ rspamd_task_log_check_condition (struct rspamd_task *task, break; case RSPAMD_LOG_SMTP_RCPT: case RSPAMD_LOG_SMTP_RCPTS: - if (task->rcpt_envelope && - internet_address_list_length (task->rcpt_envelope) > 0) { - ret = TRUE; - } - else if (task->rcpt_mime && - internet_address_list_length (task->rcpt_mime) > 0) { + if (task->rcpt_envelope && task->rcpt_envelope->len > 0) { ret = TRUE; } break; @@ -770,12 +681,7 @@ rspamd_task_log_check_condition (struct rspamd_task *task, } break; case RSPAMD_LOG_SMTP_FROM: - if (task->from_envelope && - internet_address_list_length (task->from_envelope) > 0) { - ret = TRUE; - } - else if (task->from_mime && - internet_address_list_length (task->from_mime) > 0) { + if (task->from_envelope) { ret = TRUE; } break; @@ -965,6 +871,49 @@ rspamd_task_write_ialist (struct rspamd_task *task, return res; } +static rspamd_fstring_t * +rspamd_task_write_addr_list (struct rspamd_task *task, + GPtrArray *addrs, gint lim, + struct rspamd_log_format *lf, + rspamd_fstring_t *logbuf) +{ + rspamd_fstring_t *res = logbuf, *varbuf; + rspamd_ftok_t var = {.begin = NULL, .len = 0}; + struct rspamd_email_address *addr; + gint i; + + if (lim <= 0) { + lim = addrs->len; + } + + varbuf = rspamd_fstring_new (); + + for (i = 0; i < lim; i++) { + addr = g_ptr_array_index (addrs, i); + + if (addr->addr) { + varbuf = rspamd_fstring_append (varbuf, addr->addr, addr->addr_len); + } + + if (varbuf->len > 0) { + if (i != lim - 1) { + varbuf = rspamd_fstring_append (varbuf, ",", 1); + } + } + } + + if (varbuf->len > 0) { + var.begin = varbuf->str; + var.len = varbuf->len; + res = rspamd_task_log_write_var (task, logbuf, + &var, (const rspamd_ftok_t *) lf->data); + } + + rspamd_fstring_free (varbuf); + + return res; +} + static rspamd_fstring_t * rspamd_task_log_variable (struct rspamd_task *task, struct rspamd_log_format *lf, rspamd_fstring_t *logbuf) @@ -1040,12 +989,8 @@ rspamd_task_log_variable (struct rspamd_task *task, /* InternetAddress vars */ case RSPAMD_LOG_SMTP_FROM: if (task->from_envelope) { - return rspamd_task_write_ialist (task, task->from_envelope, 1, lf, - logbuf); - } - else if (task->from_mime) { - return rspamd_task_write_ialist (task, task->from_mime, 1, lf, - logbuf); + var.begin = task->from_envelope->addr; + var.len = task->from_envelope->addr_len; } break; case RSPAMD_LOG_MIME_FROM: @@ -1056,11 +1001,7 @@ rspamd_task_log_variable (struct rspamd_task *task, break; case RSPAMD_LOG_SMTP_RCPT: if (task->rcpt_envelope) { - return rspamd_task_write_ialist (task, task->rcpt_envelope, 1, lf, - logbuf); - } - else if (task->rcpt_mime) { - return rspamd_task_write_ialist (task, task->rcpt_mime, 1, lf, + return rspamd_task_write_addr_list (task, task->rcpt_envelope, 1, lf, logbuf); } break; @@ -1072,11 +1013,7 @@ rspamd_task_log_variable (struct rspamd_task *task, break; case RSPAMD_LOG_SMTP_RCPTS: if (task->rcpt_envelope) { - return rspamd_task_write_ialist (task, task->rcpt_envelope, -1, lf, - logbuf); - } - else if (task->rcpt_mime) { - return rspamd_task_write_ialist (task, task->rcpt_mime, -1, lf, + return rspamd_task_write_addr_list (task, task->rcpt_envelope, -1, lf, logbuf); } break; diff --git a/src/libserver/task.h b/src/libserver/task.h index 1f4e8eeea..8aeb7dc6b 100644 --- a/src/libserver/task.h +++ b/src/libserver/task.h @@ -151,17 +151,11 @@ struct rspamd_task { GHashTable *results; /**< hash table of metric_result indexed by * metric's name */ GPtrArray *tokens; /**< statistics tokens */ -#if 0 - GPtrArray *rcpt_mime; /**< list of all recipients (rspamd_email_address) */ - GPtrArray *rcpt_envelope; /**< list of all recipients (rspamd_email_address) */ - struct rspamd_email_address *from_mime; - struct rspamd_email_address *from_envelope; -#else + InternetAddressList *rcpt_mime; - InternetAddressList *rcpt_envelope; + GPtrArray *rcpt_envelope; /**< array of rspamd_email_address */ InternetAddressList *from_mime; - InternetAddressList *from_envelope; -#endif + struct rspamd_email_address *from_envelope; GList *messages; /**< list of messages that would be reported */ struct rspamd_re_runtime *re_rt; /**< regexp runtime */ @@ -237,7 +231,7 @@ gboolean rspamd_task_process (struct rspamd_task *task, guint stages); * @param task * @return */ -const gchar *rspamd_task_get_sender (struct rspamd_task *task); +struct rspamd_email_address* rspamd_task_get_sender (struct rspamd_task *task); /** * Return addresses in the following precendence: @@ -256,13 +250,6 @@ const gchar *rspamd_task_get_principal_recipient (struct rspamd_task *task); * @return TRUE if an address has been parsed and added */ gboolean rspamd_task_add_recipient (struct rspamd_task *task, const gchar *rcpt); -/** - * Add a sender for a task - * @param task task object - * @param sender string representation of sender's address - * @return TRUE if an address has been parsed and added - */ -gboolean rspamd_task_add_sender (struct rspamd_task *task, const gchar *sender); /** * Learn specified statfile with message in a task