aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libmime/message.c185
-rw-r--r--src/libmime/mime_headers.c77
-rw-r--r--src/libserver/task.h4
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 */