diff options
-rw-r--r-- | src/libmime/message.c | 185 | ||||
-rw-r--r-- | src/libmime/mime_headers.c | 77 | ||||
-rw-r--r-- | src/libserver/task.h | 4 |
3 files changed, 126 insertions, 140 deletions
diff --git a/src/libmime/message.c b/src/libmime/message.c index 72f148e1e..eba213898 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -670,43 +670,10 @@ rspamd_message_parse (struct rspamd_task *task) } - /* Save message id for future use */ - hdrs = rspamd_message_get_header_array (task, "Message-ID", FALSE); - - if (hdrs) { - gchar *p, *end; - - rh = g_ptr_array_index (hdrs, 0); - - p = rh->decoded; - end = p + strlen (p); - - if (*p == '<') { - p ++; - - if (end > p && *(end - 1) == '>') { - *(end - 1) = '\0'; - p = rspamd_mempool_strdup (task->task_pool, p); - *(end - 1) = '>'; - } - } - - task->message_id = p; - } - if (task->message_id == NULL) { task->message_id = "undef"; } - if (!task->subject) { - hdrs = rspamd_message_get_header_array (task, "Subject", FALSE); - - if (hdrs) { - rh = g_ptr_array_index (hdrs, 0); - task->subject = rh->decoded; - } - } - debug_task ("found %ud parts in message", task->parts->len); if (task->queue_id == NULL) { task->queue_id = "undef"; @@ -725,62 +692,70 @@ rspamd_message_parse (struct rspamd_task *task) rspamd_images_process (task); rspamd_archives_process (task); - /* Parse received headers */ - hdrs = rspamd_message_get_header_array (task, "Received", FALSE); + if (task->received && task->received->len > 0) { + gboolean need_recv_correction = FALSE; + rspamd_inet_addr_t *raddr; - PTR_ARRAY_FOREACH (hdrs, i, rh) { - recv = rspamd_mempool_alloc0 (task->task_pool, - sizeof (struct received_header)); - rspamd_smtp_recieved_parse (task, rh->decoded, strlen (rh->decoded), recv); + recv = g_ptr_array_index (task->received, 0); /* * For the first header we must ensure that * received is consistent with the IP that we obtain through * client. */ - if (i == 0) { - gboolean need_recv_correction = FALSE; - rspamd_inet_addr_t *raddr = recv->addr; - if (recv->real_ip == NULL || (task->cfg && task->cfg->ignore_received)) { + raddr = recv->addr; + if (recv->real_ip == NULL || (task->cfg && task->cfg->ignore_received)) { + need_recv_correction = TRUE; + } + else if (!(task->flags & RSPAMD_TASK_FLAG_NO_IP) && task->from_addr) { + if (!raddr) { need_recv_correction = TRUE; } - else if (!(task->flags & RSPAMD_TASK_FLAG_NO_IP) && task->from_addr) { - if (!raddr) { + else { + if (rspamd_inet_address_compare (raddr, task->from_addr) != 0) { need_recv_correction = TRUE; } - else { - if (rspamd_inet_address_compare (raddr, task->from_addr) != 0) { - need_recv_correction = TRUE; - } - } + } + } + if (need_recv_correction && !(task->flags & RSPAMD_TASK_FLAG_NO_IP) + && task->from_addr) { + msg_debug_task ("the first received seems to be" + " not ours, replace it with fake one"); + + trecv = rspamd_mempool_alloc0 (task->task_pool, + sizeof (struct received_header)); + trecv->real_ip = rspamd_mempool_strdup (task->task_pool, + rspamd_inet_address_to_string (task->from_addr)); + trecv->from_ip = trecv->real_ip; + trecv->addr = rspamd_inet_address_copy (task->from_addr); + rspamd_mempool_add_destructor (task->task_pool, + (rspamd_mempool_destruct_t)rspamd_inet_address_destroy, + trecv->addr); + + if (task->hostname) { + trecv->real_hostname = task->hostname; + trecv->from_hostname = trecv->real_hostname; } - if (need_recv_correction && !(task->flags & RSPAMD_TASK_FLAG_NO_IP) - && task->from_addr) { - msg_debug_task ("the first received seems to be" - " not ours, replace it with fake one"); - - trecv = rspamd_mempool_alloc0 (task->task_pool, - sizeof (struct received_header)); - trecv->real_ip = rspamd_mempool_strdup (task->task_pool, - rspamd_inet_address_to_string (task->from_addr)); - trecv->from_ip = trecv->real_ip; - trecv->addr = rspamd_inet_address_copy (task->from_addr); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t)rspamd_inet_address_destroy, - trecv->addr); - - if (task->hostname) { - trecv->real_hostname = task->hostname; - trecv->from_hostname = trecv->real_hostname; - } +#ifdef GLIB_VERSION_2_40 + g_ptr_array_insert (task->received, 0, trecv); +#else + /* + * Unfortunately, before glib 2.40 we cannot insert element into a + * ptr array + */ + GPtrArray *nar = g_ptr_array_sized_new (task->received->len + 1); - g_ptr_array_add (task->received, trecv); + g_ptr_array_add (nar, trecv); + PTR_ARRAY_FOREACH (task->received, i, recv) { + g_ptr_array_add (nar, recv); } + rspamd_mempool_add_destructor (task->task_pool, + rspamd_ptr_array_free_hard, nar); + task->received = nar; +#endif } - - g_ptr_array_add (task->received, recv); } /* Extract data from received header if we were not given IP */ @@ -801,72 +776,6 @@ rspamd_message_parse (struct rspamd_task *task) } } - if (task->from_envelope == NULL) { - hdrs = rspamd_message_get_header_array (task, "Return-Path", FALSE); - - if (hdrs && hdrs->len > 0) { - rh = g_ptr_array_index (hdrs, 0); - task->from_envelope = rspamd_email_address_from_smtp (rh->decoded, - strlen (rh->decoded)); - } - } - - if (task->deliver_to == NULL) { - hdrs = rspamd_message_get_header_array (task, "Delivered-To", FALSE); - - if (hdrs && hdrs->len > 0) { - rh = g_ptr_array_index (hdrs, 0); - task->deliver_to = rspamd_mempool_strdup (task->task_pool, rh->decoded); - } - } - - /* Set mime recipients and sender for the task */ - /* TODO: kill it with fire */ - task->rcpt_mime = internet_address_list_new (); - - static const gchar *to_hdrs[] = {"To", "Cc", "Bcc"}; - - for (int k = 0; k < G_N_ELEMENTS (to_hdrs); k ++) { - hdrs = rspamd_message_get_header_array (task, to_hdrs[k], FALSE); - if (hdrs && hdrs->len > 0) { - - InternetAddressList *tia; - - for (i = 0; i < hdrs->len; i ++) { - rh = g_ptr_array_index (hdrs, i); - - tia = internet_address_list_parse_string (rh->decoded); - - if (tia) { - internet_address_list_append (task->rcpt_mime, tia); - g_object_unref (tia); - } - } - } - } - - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_object_unref, - task->rcpt_mime); - - hdrs = rspamd_message_get_header_array (task, "From", FALSE); - - if (hdrs && hdrs->len > 0) { - rh = g_ptr_array_index (hdrs, 0); - task->from_mime = internet_address_list_parse_string (rh->value); - if (task->from_mime) { -#ifdef GMIME24 - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) g_object_unref, - task->from_mime); -#else - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) internet_address_list_destroy, - task->from_mime); -#endif - } - } - /* Parse urls inside Subject header */ hdrs = rspamd_message_get_header_array (task, "Subject", FALSE); diff --git a/src/libmime/mime_headers.c b/src/libmime/mime_headers.c index 9b65f1ecf..eaee0a5ae 100644 --- a/src/libmime/mime_headers.c +++ b/src/libmime/mime_headers.c @@ -17,15 +17,90 @@ #include "mime_headers.h" #include "smtp_parsers.h" #include "mime_encoding.h" +#include "email_addr.h" #include "task.h" +#include "cryptobox.h" #include "contrib/libottery/ottery.h" static void +rspamd_mime_header_check_special (struct rspamd_task *task, + struct rspamd_mime_header *rh) +{ + guint64 h; + struct received_header *recv; + + h = rspamd_icase_hash (rh->name, strlen (rh->name), 0xdeadbabe); + + switch (h) { + case 0x88705DC4D9D61ABULL: /* received */ + recv = rspamd_mempool_alloc0 (task->task_pool, + sizeof (struct received_header)); + rspamd_smtp_recieved_parse (task, rh->decoded, + strlen (rh->decoded), recv); + g_ptr_array_add (task->received, recv); + break; + case 0x76F31A09F4352521ULL: /* to */ + task->rcpt_mime = rspamd_email_address_from_mime (task->task_pool, + rh->value, strlen (rh->value), task->rcpt_mime); + break; + case 0x7EB117C1480B76ULL: /* cc */ + task->rcpt_mime = rspamd_email_address_from_mime (task->task_pool, + rh->value, strlen (rh->value), task->rcpt_mime); + break; + case 0xE4923E11C4989C8DULL: /* bcc */ + task->rcpt_mime = rspamd_email_address_from_mime (task->task_pool, + rh->value, strlen (rh->value), task->rcpt_mime); + break; + case 0x41E1985EDC1CBDE4ULL: /* from */ + task->from_mime = rspamd_email_address_from_mime (task->task_pool, + rh->value, strlen (rh->value), task->from_mime); + break; + case 0x43A558FC7C240226ULL: /* message-id */ { + gchar *p, *end; + + p = rh->decoded; + end = p + strlen (p); + + if (*p == '<') { + p ++; + + if (end > p && *(end - 1) == '>') { + *(end - 1) = '\0'; + p = rspamd_mempool_strdup (task->task_pool, p); + *(end - 1) = '>'; + } + } + + task->message_id = p; + break; + } + case 0xB91D3910358E8212ULL: /* subject */ + if (task->subject == NULL) { + task->subject = rh->decoded; + } + break; + case 0xEE4AA2EAAC61D6F4ULL: /* return-path */ + if (task->from_envelope == NULL) { + task->from_envelope = rspamd_email_address_from_smtp (rh->decoded, + strlen (rh->decoded)); + } + break; + case 0xB9EEFAD2E93C2161ULL: /* delivered-to */ + if (task->deliver_to == NULL) { + task->deliver_to = rh->decoded; + } + break; + } +} + +static void rspamd_mime_header_add (struct rspamd_task *task, GHashTable *target, struct rspamd_mime_header *rh) { GPtrArray *ar; + rspamd_mime_header_check_special (task, rh); + if ((ar = g_hash_table_lookup (target, rh->name)) != NULL) { g_ptr_array_add (ar, rh); msg_debug_task ("append raw header %s: %s", rh->name, rh->value); @@ -36,6 +111,8 @@ rspamd_mime_header_add (struct rspamd_task *task, g_hash_table_insert (target, rh->name, ar); msg_debug_task ("add new raw header %s: %s", rh->name, rh->value); } + + rspamd_mime_header_check_special (task, rh); } /* Convert raw headers to a list of struct raw_header * */ diff --git a/src/libserver/task.h b/src/libserver/task.h index e7df63719..7e56ded79 100644 --- a/src/libserver/task.h +++ b/src/libserver/task.h @@ -156,9 +156,9 @@ struct rspamd_task { * metric's name */ GPtrArray *tokens; /**< statistics tokens */ - InternetAddressList *rcpt_mime; + GPtrArray *rcpt_mime; GPtrArray *rcpt_envelope; /**< array of rspamd_email_address */ - InternetAddressList *from_mime; + GPtrArray *from_mime; struct rspamd_email_address *from_envelope; enum rspamd_newlines_type nlines_type; /**< type of newlines (detected on most of headers */ |