From 3848994dbe0eb3775387960b396be75962de72dc Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 18 Aug 2014 14:20:48 +0100 Subject: [PATCH] Unify from/rcpt processing. --- src/libmime/message.c | 56 ++++++++++++++++++++-------------------- src/libserver/protocol.c | 33 +++++++++++++++++------ src/libserver/task.c | 34 ++++++++++++------------ src/libserver/task.h | 18 ++++++++++--- 4 files changed, 84 insertions(+), 57 deletions(-) diff --git a/src/libmime/message.c b/src/libmime/message.c index f2dac687b..9f3df14e2 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -1231,20 +1231,6 @@ process_message (struct rspamd_task *task) 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); -#else - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t) internet_address_list_destroy, - task->rcpts); -#endif - } - - /* free the parser (and the stream) */ g_object_unref (parser); } @@ -1252,8 +1238,9 @@ process_message (struct rspamd_task *task) /* We got only message, no mime headers or anything like this */ /* Construct fake message for it */ task->message = g_mime_message_new (TRUE); - if (task->from) { - g_mime_message_set_sender (task->message, task->from); + if (task->from_envelope) { + g_mime_message_set_sender (task->message, + rspamd_task_get_sender (task)); } /* Construct part for it */ part = g_mime_part_new_with_type ("text", "html"); @@ -1292,19 +1279,32 @@ process_message (struct rspamd_task *task) if (task->subject) { g_mime_message_set_subject (task->message, task->subject); } + } - /* Add recipients */ -#ifndef GMIME24 - if (task->rcpt) { - cur = task->rcpt; - while (cur) { - g_mime_message_add_recipient (task->message, - GMIME_RECIPIENT_TYPE_TO, - NULL, - (gchar *)cur->data); - cur = g_list_next (cur); - } - } + /* Set mime recipients and sender for the task */ + task->rcpt_mime = g_mime_message_get_all_recipients (message); + if (task->rcpt_mime) { +#ifdef GMIME24 + rspamd_mempool_add_destructor (task->task_pool, + (rspamd_mempool_destruct_t) g_object_unref, + task->rcpt_mime); +#else + rspamd_mempool_add_destructor (task->task_pool, + (rspamd_mempool_destruct_t) internet_address_list_destroy, + task->rcpt_mime); +#endif + } + task->from_mime = internet_address_list_parse_string( + g_mime_message_get_sender (message)); + 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 } diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index 650becbe4..e7be5a1c3 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -232,6 +232,7 @@ rspamd_protocol_handle_headers (struct rspamd_task *task, gchar *headern, *err, *tmp; gboolean res = TRUE, validh; struct rspamd_http_header *h; + InternetAddressList *tmp; LL_FOREACH (msg->headers, h) { @@ -269,8 +270,20 @@ rspamd_protocol_handle_headers (struct rspamd_task *task, case 'f': case 'F': if (g_ascii_strcasecmp (headern, FROM_HEADER) == 0) { - task->from = rspamd_protocol_escape_braces (h->value); - debug_task ("read from header, value: %s", task->from); + task->from_envelope = internet_address_list_parse_string ( + h->value->str); + 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 + } + debug_task ("read from header, value: %v", h->value); } else { debug_task ("wrong header: %s", headern); @@ -301,14 +314,18 @@ rspamd_protocol_handle_headers (struct rspamd_task *task, case 'r': case 'R': if (g_ascii_strcasecmp (headern, RCPT_HEADER) == 0) { - tmp = rspamd_protocol_escape_braces (h->value); - task->rcpt = g_list_prepend (task->rcpt, tmp); + if (task->rcpt_envelope == NULL) { + task->rcpt_envelope = internet_address_list_new (); + } + tmp = internet_address_list_parse_string (h->value->str); + internet_address_list_append (task->rcpt_envelope, tmp); +#ifdef GMIME24 + g_object_unref (tmp); +#else + internet_address_list_destroy (tmp); +#endif debug_task ("read rcpt header, value: %s", tmp); } - else if (g_ascii_strcasecmp (headern, NRCPT_HEADER) == 0) { - task->nrcpt = strtoul (h->value->str, &err, 10); - debug_task ("read rcpt header, value: %d", (gint)task->nrcpt); - } else { msg_info ("wrong header: %s", headern); validh = FALSE; diff --git a/src/libserver/task.c b/src/libserver/task.c index cc70afd97..860bb2b03 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -28,20 +28,6 @@ #include "message.h" #include "lua/lua_common.h" -/* - * Destructor for recipients list in a task - */ -static void -rcpt_destruct (void *pointer) -{ - struct rspamd_task *task = (struct rspamd_task *) pointer; - - if (task->rcpt) { - g_list_free (task->rcpt); - } -} - - static void gstring_destruct (gpointer ptr) { @@ -81,9 +67,6 @@ rspamd_task_new (struct rspamd_worker *worker) new_task->task_pool = rspamd_mempool_new (rspamd_mempool_suggest_size ()); - /* Add destructor for recipients list (it would be better to use anonymous function here */ - rspamd_mempool_add_destructor (new_task->task_pool, - (rspamd_mempool_destruct_t) rcpt_destruct, new_task); new_task->results = g_hash_table_new (rspamd_str_hash, rspamd_str_equal); rspamd_mempool_add_destructor (new_task->task_pool, (rspamd_mempool_destruct_t) g_hash_table_unref, @@ -364,3 +347,20 @@ rspamd_task_process (struct rspamd_task *task, return TRUE; } + +const gchar * +rspamd_task_get_sender (struct rspamd_task *task) +{ + InternetAddressMailbox *imb = NULL; + + if (task->from_envelope != NULL) { + imb = INTERNET_ADDRESS_MAILBOX(internet_address_list_get_address ( + task->from_envelope, 0)); + } + else if (task->from_mime != NULL) { + imb = INTERNET_ADDRESS_MAILBOX(internet_address_list_get_address ( + task->from_mime, 0)); + } + + return internet_address_mailbox_get_addr (imb); +} diff --git a/src/libserver/task.h b/src/libserver/task.h index 84262af6f..bf14d2174 100644 --- a/src/libserver/task.h +++ b/src/libserver/task.h @@ -80,11 +80,9 @@ struct rspamd_task { gboolean is_skipped; /**< whether message was skipped by configuration */ gchar *helo; /**< helo header value */ - gchar *from; /**< from header value */ gchar *queue_id; /**< queue id if specified */ const gchar *message_id; /**< message id */ - GList *rcpt; /**< recipients list */ - guint nrcpt; /**< number of recipients */ + rspamd_inet_addr_t from_addr; /**< from addr for a task */ rspamd_inet_addr_t client_addr; /**< address of connected socket */ gchar *deliver_to; /**< address to deliver */ @@ -99,7 +97,6 @@ struct rspamd_task { gint parts_count; /**< mime parts count */ GMimeMessage *message; /**< message, parsed with GMime */ GMimeObject *parser_parent_part; /**< current parent part */ - InternetAddressList *rcpts; /**< list of all recipients */ GList *parts; /**< list of parsed parts */ GList *text_parts; /**< list of text parts */ gchar *raw_headers_str; /**< list of raw headers */ @@ -112,6 +109,12 @@ struct rspamd_task { * metric's name */ GHashTable *tokens; /**< hash table of tokens indexed by tokenizer * pointer */ + + InternetAddressList *rcpt_mime; /**< list of all recipients */ + InternetAddressList *rcpt_envelope; /**< list of all recipients */ + InternetAddressList *from_mime; + InternetAddressList *from_envelope; + GList *messages; /**< list of messages that would be reported */ GHashTable *re_cache; /**< cache for matched or not matched regexps */ struct rspamd_config *cfg; /**< pointer to config object */ @@ -178,4 +181,11 @@ gboolean rspamd_task_process (struct rspamd_task *task, struct rspamd_http_message *msg, GThreadPool *classify_pool, gboolean process_extra_filters); +/** + * Return address of sender or NULL + * @param task + * @return + */ +const gchar *rspamd_task_get_sender (struct rspamd_task *task); + #endif /* TASK_H_ */ -- 2.39.5