]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
[Rework] Start rework of mime addresses
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 22 Dec 2016 21:25:47 +0000 (21:25 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 22 Dec 2016 21:25:47 +0000 (21:25 +0000)
src/libmime/message.c
src/libmime/mime_headers.c
src/libserver/task.h

index 72f148e1e623e5623126391acf4d1900faa345fa..eba213898512790379cc37b7ee7f70abceb27462 100644 (file)
@@ -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);
 
index 9b65f1ecfe8ba6c0cb656b37fc70143d42fdf33d..eaee0a5aeacb07d5378c79eefd0e00f8813a50f8 100644 (file)
 #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 * */
index e7df6371918476b84b711cfe26cea2741373c66b..7e56ded79fc7d6e2aa35225495cf78823d513a05 100644 (file)
@@ -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      */