diff options
-rw-r--r-- | contrib/uthash/utlist.h | 26 | ||||
-rw-r--r-- | src/libmime/email_addr.h | 2 | ||||
-rw-r--r-- | src/libmime/message.c | 101 | ||||
-rw-r--r-- | src/libmime/message.h | 72 | ||||
-rw-r--r-- | src/libmime/mime_headers.c | 136 | ||||
-rw-r--r-- | src/libmime/mime_headers.h | 34 | ||||
-rw-r--r-- | src/libmime/smtp_parsers.h | 2 | ||||
-rw-r--r-- | src/lua/lua_task.c | 2 |
8 files changed, 154 insertions, 221 deletions
diff --git a/contrib/uthash/utlist.h b/contrib/uthash/utlist.h index c82dd916e..e4d9a4c23 100644 --- a/contrib/uthash/utlist.h +++ b/contrib/uthash/utlist.h @@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <assert.h> -/* +/* * This file contains macros to manipulate singly and doubly-linked lists. * * 1. LL_ macros: singly-linked lists. @@ -38,7 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * To use singly-linked lists, your structure must have a "next" pointer. * To use doubly-linked lists, your structure must "prev" and "next" pointers. * Either way, the pointer to the head of the list must be initialized to NULL. - * + * * ----------------.EXAMPLE ------------------------- * struct item { * int id; @@ -88,7 +88,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } #define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } #define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } -#else +#else #define _SV(elt,list) #define _NEXT(elt,list,next) ((elt)->next) #define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to) @@ -312,7 +312,7 @@ do { #define LL_PREPEND2(head,add,next) \ do { \ (add)->next = head; \ - head = add; \ + (head) = (add); \ } while (0) #define LL_CONCAT(head1,head2) \ @@ -445,7 +445,7 @@ do { LL_FOREACH2(head,out,next) { \ if ((out)->field == (val)) break; \ } \ -} while(0) +} while(0) #define LL_SEARCH(head,out,elt,cmp) \ LL_SEARCH2(head,out,elt,cmp,next) @@ -455,7 +455,7 @@ do { LL_FOREACH2(head,out,next) { \ if ((cmp(out,elt))==0) break; \ } \ -} while(0) +} while(0) #define LL_REPLACE_ELEM(head, el, add) \ do { \ @@ -531,7 +531,7 @@ do { (head)->prev = (head); \ (head)->next = NULL; \ } \ -} while (0) +} while (0) #define DL_CONCAT(head1,head2) \ DL_CONCAT2(head1,head2,prev,next) @@ -549,7 +549,7 @@ do { (head1)=(head2); \ } \ } \ -} while (0) +} while (0) #define DL_DELETE(head,del) \ DL_DELETE2(head,del,prev,next) @@ -570,7 +570,7 @@ do { (head)->prev = (del)->prev; \ } \ } \ -} while (0) +} while (0) #define DL_COUNT(head,el,counter) \ DL_COUNT2(head,el,counter,next) \ @@ -674,7 +674,7 @@ do { (del)->prev->next = (del)->next; \ if ((del) == (head)) (head)=(del)->next; \ } \ -} while (0) +} while (0) #define CDL_COUNT(head,el,counter) \ CDL_COUNT2(head,el,counter,next) \ @@ -689,7 +689,7 @@ do { CDL_FOREACH2(head,el,next) #define CDL_FOREACH2(head,el,next) \ - for(el=head;el;el=((el)->next==head ? 0L : (el)->next)) + for(el=head;el;el=((el)->next==head ? 0L : (el)->next)) #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) @@ -707,7 +707,7 @@ do { CDL_FOREACH2(head,out,next) { \ if ((out)->field == (val)) break; \ } \ -} while(0) +} while(0) #define CDL_SEARCH(head,out,elt,cmp) \ CDL_SEARCH2(head,out,elt,cmp,next) @@ -717,7 +717,7 @@ do { CDL_FOREACH2(head,out,next) { \ if ((cmp(out,elt))==0) break; \ } \ -} while(0) +} while(0) #define CDL_REPLACE_ELEM(head, el, add) \ do { \ diff --git a/src/libmime/email_addr.h b/src/libmime/email_addr.h index 69aa2aa00..13e94f7cc 100644 --- a/src/libmime/email_addr.h +++ b/src/libmime/email_addr.h @@ -58,7 +58,7 @@ struct rspamd_email_address { guint flags; }; -struct received_header; +struct rspamd_received_header; struct rspamd_task; /** diff --git a/src/libmime/message.c b/src/libmime/message.c index 1d9da26f2..500590e02 100644 --- a/src/libmime/message.c +++ b/src/libmime/message.c @@ -1110,7 +1110,7 @@ rspamd_message_new (struct rspamd_task *task) gboolean rspamd_message_parse (struct rspamd_task *task) { - struct received_header *recv, *trecv; + struct rspamd_received_header *recv, *trecv; const gchar *p; gsize len; guint i; @@ -1247,7 +1247,7 @@ rspamd_message_parse (struct rspamd_task *task) " not ours, prepend it with fake one"); trecv = rspamd_mempool_alloc0 (task->task_pool, - sizeof (struct received_header)); + sizeof (struct rspamd_received_header)); trecv->flags |= RSPAMD_RECEIVED_FLAG_ARTIFICIAL; if (task->flags & RSPAMD_TASK_FLAG_SSL) { @@ -1515,101 +1515,6 @@ rspamd_message_process (struct rspamd_task *task) } -GPtrArray * -rspamd_message_get_header_from_hash (GHashTable *htb, - rspamd_mempool_t *pool, - const gchar *field, - gboolean strong) -{ - GPtrArray *ret, *ar; - struct rspamd_mime_header *cur; - guint i; - - ar = g_hash_table_lookup (htb, field); - - if (ar == NULL) { - return NULL; - } - - if (strong && pool != NULL) { - /* Need to filter what we have */ - ret = g_ptr_array_sized_new (ar->len); - - PTR_ARRAY_FOREACH (ar, i, cur) { - if (strcmp (cur->name, field) != 0) { - continue; - } - - g_ptr_array_add (ret, cur); - } - - rspamd_mempool_add_destructor (pool, - (rspamd_mempool_destruct_t)rspamd_ptr_array_free_hard, ret); - } - else { - ret = ar; - } - - return ret; -} - -GPtrArray * -rspamd_message_get_header_array (struct rspamd_task *task, - const gchar *field, - gboolean strong) -{ - return rspamd_message_get_header_from_hash (task->raw_headers, - task->task_pool, field, strong); -} - -GPtrArray * -rspamd_message_get_mime_header_array (struct rspamd_task *task, - const gchar *field, - gboolean strong) -{ - GPtrArray *ret, *ar; - struct rspamd_mime_header *cur; - guint nelems = 0, i, j; - struct rspamd_mime_part *mp; - - for (i = 0; i < task->parts->len; i ++) { - mp = g_ptr_array_index (task->parts, i); - ar = g_hash_table_lookup (mp->raw_headers, field); - - if (ar == NULL) { - continue; - } - - nelems += ar->len; - } - - if (nelems == 0) { - return NULL; - } - - ret = g_ptr_array_sized_new (nelems); - - for (i = 0; i < task->parts->len; i ++) { - mp = g_ptr_array_index (task->parts, i); - ar = g_hash_table_lookup (mp->raw_headers, field); - - PTR_ARRAY_FOREACH (ar, j, cur) { - if (strong) { - if (strcmp (cur->name, field) != 0) { - continue; - } - } - - g_ptr_array_add (ret, cur); - } - } - - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t)rspamd_ptr_array_free_hard, ret); - - return ret; -} - struct rspamd_message * rspamd_message_ref (struct rspamd_message *msg) { @@ -1618,5 +1523,5 @@ rspamd_message_ref (struct rspamd_message *msg) void rspamd_message_unref (struct rspamd_message *msg) { - REF_RELEASE (msg);s + REF_RELEASE (msg); } diff --git a/src/libmime/message.h b/src/libmime/message.h index 7d58fa88f..880645c0a 100644 --- a/src/libmime/message.h +++ b/src/libmime/message.h @@ -7,11 +7,12 @@ #define RSPAMD_MESSAGE_H #include "config.h" -#include "email_addr.h" -#include "addr.h" -#include "cryptobox.h" -#include "mime_headers.h" -#include "content_type.h" + +#include "libmime/email_addr.h" +#include "libutil/addr.h" +#include "libcryptobox/cryptobox.h" +#include "libmime/mime_headers.h" +#include "libmime/content_type.h" #include "libutil/ref.h" #include "libutil/str_util.h" @@ -60,8 +61,8 @@ struct rspamd_mime_part { rspamd_ftok_t parsed_data; struct rspamd_mime_part *parent_part; - GQueue *headers_order; - GHashTable *raw_headers; + struct rspamd_mime_header *headers_order; + khash_t(rspamd_mime_headers_htb) *raw_headers; gchar *raw_headers_str; gsize raw_headers_len; @@ -141,24 +142,25 @@ struct rspamd_message { const gchar *begin; gsize len; const gchar *body_start; - } raw_headers_content; /**< list of raw headers */ - GPtrArray *received; /**< list of received headers */ - GHashTable *urls; /**< list of parsed urls */ - GHashTable *emails; /**< list of parsed emails */ - GHashTable *raw_headers; /**< list of raw headers */ - GQueue *headers_order; /**< order of raw headers */ + } raw_headers_content; /**< list of raw headers */ + struct rspamd_received_header *received; /**< list of received headers */ + GHashTable *urls; /**< list of parsed urls */ + GHashTable *emails; /**< list of parsed emails */ + khash_t(rspamd_mime_headers_htb) *raw_headers; /**< list of raw headers */ + struct rspamd_mime_header *headers_order; /**< inversed order of raw headers */ GPtrArray *rcpt_mime; GPtrArray *from_mime; - enum rspamd_newlines_type nlines_type; /**< type of newlines (detected on most of headers */ + enum rspamd_newlines_type nlines_type; /**< type of newlines (detected on most of headers */ ref_entry_t ref; }; #ifndef FULL_DEBUG -#define MESSAGE_FIELD(task, field) ((task)->message->(field)) +#define MESSAGE_FIELD(task, field) ((task)->message->field) #else -#define MESSAGE_FIELD(task, field) do { \ - if (!task->message) {msg_err_task("no message when getting field %s", #field); g_assert(0);} \ - } while(0), ((task)->message->(field)) +#define MESSAGE_FIELD(task, field) + ((!(task)->message) ? \ + (msg_err_task("no message when getting field %s", #field), g_assert(0)) : \ + ((task)->message->field)) #endif /** @@ -174,40 +176,6 @@ gboolean rspamd_message_parse (struct rspamd_task *task); */ void rspamd_message_process (struct rspamd_task *task); -/** - * Get an array of header's values with specified header's name using raw headers - * @param task worker task structure - * @param field header's name - * @param strong if this flag is TRUE header's name is case sensitive, otherwise it is not - * @return An array of header's values or NULL. It is NOT permitted to free array or values. - */ -GPtrArray *rspamd_message_get_header_array (struct rspamd_task *task, - const gchar *field, - gboolean strong); - -/** - * Get an array of mime parts header's values with specified header's name using raw headers - * @param task worker task structure - * @param field header's name - * @param strong if this flag is TRUE header's name is case sensitive, otherwise it is not - * @return An array of header's values or NULL. It is NOT permitted to free array or values. - */ -GPtrArray *rspamd_message_get_mime_header_array (struct rspamd_task *task, - const gchar *field, - gboolean strong); - -/** - * Get an array of header's values with specified header's name using raw headers - * @param htb hash table indexed by header name (caseless) with ptr arrays as elements - * @param field header's name - * @param strong if this flag is TRUE header's name is case sensitive, otherwise it is not - * @return An array of header's values or NULL. It is NOT permitted to free array or values. - */ -GPtrArray *rspamd_message_get_header_from_hash (GHashTable *htb, - rspamd_mempool_t *pool, - const gchar *field, - gboolean strong); - /** * Converts string to cte diff --git a/src/libmime/mime_headers.c b/src/libmime/mime_headers.c index 952a163b9..7ffa5453c 100644 --- a/src/libmime/mime_headers.c +++ b/src/libmime/mime_headers.c @@ -20,14 +20,18 @@ #include "contrib/uthash/utlist.h" #include "libserver/mempool_vars_internal.h" #include "libserver/url.h" +#include "libutil/util.h" #include <unicode/utf8.h> +__KHASH_IMPL (rspamd_mime_headers_htb, static inline, gchar *, + struct rspamd_mime_header *, 1, rspamd_strcase_hash, rspamd_strcase_equal); + static void rspamd_mime_header_check_special (struct rspamd_task *task, struct rspamd_mime_header *rh) { guint64 h; - struct received_header *recv; + struct rspamd_received_header *recv; const gchar *p, *end; gchar *id; @@ -36,35 +40,39 @@ rspamd_mime_header_check_special (struct rspamd_task *task, switch (h) { case 0x88705DC4D9D61ABULL: /* received */ recv = rspamd_mempool_alloc0 (task->task_pool, - sizeof (struct received_header)); + sizeof (struct rspamd_received_header)); recv->hdr = rh; if (rspamd_smtp_received_parse (task, rh->decoded, strlen (rh->decoded), recv) != -1) { - g_ptr_array_add (task->received, recv); + DL_APPEND (MESSAGE_FIELD (task, received), recv); } - rh->flags = RSPAMD_HEADER_RECEIVED; + rh->flags |= RSPAMD_HEADER_RECEIVED; break; case 0x76F31A09F4352521ULL: /* to */ - task->rcpt_mime = rspamd_email_address_from_mime (task->task_pool, - rh->decoded, strlen (rh->decoded), task->rcpt_mime); - rh->flags = RSPAMD_HEADER_TO|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE; + MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool, + rh->decoded, strlen (rh->decoded), + MESSAGE_FIELD (task, rcpt_mime)); + rh->flags |= RSPAMD_HEADER_TO|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE; break; case 0x7EB117C1480B76ULL: /* cc */ - task->rcpt_mime = rspamd_email_address_from_mime (task->task_pool, - rh->decoded, strlen (rh->decoded), task->rcpt_mime); - rh->flags = RSPAMD_HEADER_CC|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE; + MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool, + rh->decoded, strlen (rh->decoded), + MESSAGE_FIELD (task, rcpt_mime)); + rh->flags |= RSPAMD_HEADER_CC|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE; break; case 0xE4923E11C4989C8DULL: /* bcc */ - task->rcpt_mime = rspamd_email_address_from_mime (task->task_pool, - rh->decoded, strlen (rh->decoded), task->rcpt_mime); - rh->flags = RSPAMD_HEADER_BCC|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE; + MESSAGE_FIELD (task, rcpt_mime) = rspamd_email_address_from_mime (task->task_pool, + rh->decoded, strlen (rh->decoded), + MESSAGE_FIELD (task, rcpt_mime)); + rh->flags |= RSPAMD_HEADER_BCC|RSPAMD_HEADER_RCPT|RSPAMD_HEADER_UNIQUE; break; case 0x41E1985EDC1CBDE4ULL: /* from */ - task->from_mime = rspamd_email_address_from_mime (task->task_pool, - rh->decoded, strlen (rh->decoded), task->from_mime); - rh->flags = RSPAMD_HEADER_FROM|RSPAMD_HEADER_SENDER|RSPAMD_HEADER_UNIQUE; + MESSAGE_FIELD (task, from_mime) = rspamd_email_address_from_mime (task->task_pool, + rh->decoded, strlen (rh->decoded), + MESSAGE_FIELD (task, from_mime)); + rh->flags |= RSPAMD_HEADER_FROM|RSPAMD_HEADER_SENDER|RSPAMD_HEADER_UNIQUE; break; case 0x43A558FC7C240226ULL: /* message-id */ { @@ -98,14 +106,14 @@ rspamd_mime_header_check_special (struct rspamd_task *task, *d = '\0'; - task->message_id = id; + MESSAGE_FIELD (task, message_id) = id; } break; } case 0xB91D3910358E8212ULL: /* subject */ - if (task->subject == NULL) { - task->subject = rh->decoded; + if (MESSAGE_FIELD (task, subject) == NULL) { + MESSAGE_FIELD (task, subject) = rh->decoded; } rh->flags = RSPAMD_HEADER_SUBJECT|RSPAMD_HEADER_UNIQUE; break; @@ -135,24 +143,28 @@ rspamd_mime_header_check_special (struct rspamd_task *task, static void rspamd_mime_header_add (struct rspamd_task *task, - GHashTable *target, GQueue *order, - struct rspamd_mime_header *rh, - gboolean check_special) + khash_t(rspamd_mime_headers_htb) *target, + struct rspamd_mime_header **order_ptr, + struct rspamd_mime_header *rh, + gboolean check_special) { - GPtrArray *ar; + khiter_t k; + struct rspamd_mime_header *ex; + int res; + + k = kh_put (rspamd_mime_headers_htb, target, rh->name, &res); - if ((ar = g_hash_table_lookup (target, rh->name)) != NULL) { - g_ptr_array_add (ar, rh); + if (res == 0) { + ex = kh_value (target, k); + DL_APPEND (ex, rh); msg_debug_task ("append raw header %s: %s", rh->name, rh->value); } else { - ar = g_ptr_array_sized_new (2); - g_ptr_array_add (ar, rh); - g_hash_table_insert (target, rh->name, ar); + kh_value (target, k) = rh; msg_debug_task ("add new raw header %s: %s", rh->name, rh->value); } - g_queue_push_tail (order, rh); + LL_PREPEND2 (*order_ptr, rh, ord_next); if (check_special) { rspamd_mime_header_check_special (task, rh); @@ -162,8 +174,9 @@ rspamd_mime_header_add (struct rspamd_task *task, /* Convert raw headers to a list of struct raw_header * */ void -rspamd_mime_headers_process (struct rspamd_task *task, GHashTable *target, - GQueue *order, +rspamd_mime_headers_process (struct rspamd_task *task, + khash_t(rspamd_mime_headers_htb) *target, + struct rspamd_mime_header **order_ptr, const gchar *in, gsize len, gboolean check_newlines) { @@ -205,7 +218,7 @@ rspamd_mime_headers_process (struct rspamd_task *task, GHashTable *target, tmp = rspamd_mempool_alloc (task->task_pool, l + 1); rspamd_null_safe_copy (c, l, tmp, l + 1); nh->name = tmp; - nh->empty_separator = TRUE; + nh->flags |= RSPAMD_HEADER_EMPTY_SEPARATOR; nh->raw_value = c; nh->raw_len = p - c; /* Including trailing ':' */ p++; @@ -225,12 +238,12 @@ rspamd_mime_headers_process (struct rspamd_task *task, GHashTable *target, case 2: /* We got header's name, so skip any \t or spaces */ if (*p == '\t') { - nh->tab_separated = TRUE; - nh->empty_separator = FALSE; + nh->flags &= ~RSPAMD_HEADER_EMPTY_SEPARATOR; + nh->flags |= RSPAMD_HEADER_TAB_SEPARATED; p++; } else if (*p == ' ') { - nh->empty_separator = FALSE; + nh->flags &= ~RSPAMD_HEADER_EMPTY_SEPARATOR; p++; } else if (*p == '\n' || *p == '\r') { @@ -464,7 +477,7 @@ rspamd_mime_headers_process (struct rspamd_task *task, GHashTable *target, } } - task->nlines_type = sel; + MESSAGE_FIELD (task, nlines_type) = sel; cur = order->head; rspamd_cryptobox_hash_init (&hs, NULL, 0); @@ -1287,7 +1300,7 @@ rspamd_smtp_received_process_rdns (struct rspamd_task *task, static gboolean rspamd_smtp_received_process_host_tcpinfo (struct rspamd_task *task, - struct received_header *rh, + struct rspamd_received_header *rh, const gchar *data, gsize len) { @@ -1373,7 +1386,7 @@ rspamd_smtp_received_process_host_tcpinfo (struct rspamd_task *task, static void rspamd_smtp_received_process_from (struct rspamd_task *task, struct rspamd_received_part *rpart, - struct received_header *rh) + struct rspamd_received_header *rh) { if (rpart->dlen > 0) { /* We have seen multiple cases: @@ -1457,7 +1470,7 @@ int rspamd_smtp_received_parse (struct rspamd_task *task, const char *data, size_t len, - struct received_header *rh) + struct rspamd_received_header *rh) { goffset date_pos = -1; struct rspamd_received_part *head, *cur; @@ -1469,7 +1482,7 @@ rspamd_smtp_received_parse (struct rspamd_task *task, return -1; } - rh->type = RSPAMD_RECEIVED_UNKNOWN; + rh->flags = RSPAMD_RECEIVED_UNKNOWN; DL_FOREACH (head, cur) { switch (cur->type) { @@ -1490,7 +1503,7 @@ rspamd_smtp_received_parse (struct rspamd_task *task, RSPAMD_FTOK_ASSIGN (&t2, "smtp"); if (rspamd_ftok_cmp (&t1, &t2) == 0) { - rh->type = RSPAMD_RECEIVED_SMTP; + rh->flags = RSPAMD_RECEIVED_SMTP; } RSPAMD_FTOK_ASSIGN (&t2, "esmtp"); @@ -1501,11 +1514,11 @@ rspamd_smtp_received_parse (struct rspamd_task *task, */ if (t1.len == t2.len + 1) { if (t1.begin[t2.len] == 'a') { - rh->type = RSPAMD_RECEIVED_ESMTPA; + rh->flags = RSPAMD_RECEIVED_ESMTPA; rh->flags |= RSPAMD_RECEIVED_FLAG_AUTHENTICATED; } else if (t1.begin[t2.len] == 's') { - rh->type = RSPAMD_RECEIVED_ESMTPS; + rh->flags = RSPAMD_RECEIVED_ESMTPS; rh->flags |= RSPAMD_RECEIVED_FLAG_SSL; } continue; @@ -1513,14 +1526,14 @@ rspamd_smtp_received_parse (struct rspamd_task *task, else if (t1.len == t2.len + 2) { if (t1.begin[t2.len] == 's' && t1.begin[t2.len + 1] == 'a') { - rh->type = RSPAMD_RECEIVED_ESMTPSA; + rh->flags = RSPAMD_RECEIVED_ESMTPSA; rh->flags |= RSPAMD_RECEIVED_FLAG_AUTHENTICATED; rh->flags |= RSPAMD_RECEIVED_FLAG_SSL; } continue; } else if (t1.len == t2.len) { - rh->type = RSPAMD_RECEIVED_ESMTP; + rh->flags = RSPAMD_RECEIVED_ESMTP; continue; } } @@ -1528,21 +1541,21 @@ rspamd_smtp_received_parse (struct rspamd_task *task, RSPAMD_FTOK_ASSIGN (&t2, "lmtp"); if (rspamd_ftok_cmp (&t1, &t2) == 0) { - rh->type = RSPAMD_RECEIVED_LMTP; + rh->flags = RSPAMD_RECEIVED_LMTP; continue; } RSPAMD_FTOK_ASSIGN (&t2, "imap"); if (rspamd_ftok_cmp (&t1, &t2) == 0) { - rh->type = RSPAMD_RECEIVED_IMAP; + rh->flags = RSPAMD_RECEIVED_IMAP; continue; } RSPAMD_FTOK_ASSIGN (&t2, "local"); if (rspamd_ftok_cmp (&t1, &t2) == 0) { - rh->type = RSPAMD_RECEIVED_LOCAL; + rh->flags = RSPAMD_RECEIVED_LOCAL; continue; } @@ -1551,12 +1564,12 @@ rspamd_smtp_received_parse (struct rspamd_task *task, if (rspamd_ftok_starts_with (&t1, &t2)) { if (t1.len == t2.len + 1) { if (t1.begin[t2.len] == 's') { - rh->type = RSPAMD_RECEIVED_HTTP; + rh->flags = RSPAMD_RECEIVED_HTTP; rh->flags |= RSPAMD_RECEIVED_FLAG_SSL; } } else if (t1.len == t2.len) { - rh->type = RSPAMD_RECEIVED_HTTP; + rh->flags = RSPAMD_RECEIVED_HTTP; } continue; @@ -1584,4 +1597,27 @@ rspamd_smtp_received_parse (struct rspamd_task *task, } return 0; +} + +struct rspamd_mime_header * +rspamd_message_get_header_from_hash (khash_t(rspamd_mime_headers_htb) *htb, + const gchar *field) +{ + khiter_t k; + + k = kh_get (rspamd_mime_headers_htb, htb, (gchar *)field); + + if (k == kh_end (htb)) { + return NULL; + } + + return kh_value (htb, k); +} + +struct rspamd_mime_header * +rspamd_message_get_header_array (struct rspamd_task *task, + const gchar *field) +{ + return rspamd_message_get_header_from_hash (MESSAGE_FIELD (task, raw_headers), + field); }
\ No newline at end of file diff --git a/src/libmime/mime_headers.h b/src/libmime/mime_headers.h index 60fd7b697..7c17b8ddd 100644 --- a/src/libmime/mime_headers.h +++ b/src/libmime/mime_headers.h @@ -19,6 +19,7 @@ #include "config.h" #include "libutil/mem_pool.h" #include "libutil/addr.h" +#include "khash.h" #ifdef __cplusplus extern "C" { @@ -50,7 +51,7 @@ enum rspamd_mime_header_flags { }; struct rspamd_mime_header { - gchar *name; + gchar *name; /* Also used for key */ gchar *value; const gchar *raw_value; /* As it is in the message (unfolded and unparsed) */ gsize raw_len; @@ -59,9 +60,12 @@ struct rspamd_mime_header { gchar *separator; gchar *decoded; struct rspamd_mime_header *prev, *next; /* Headers with the same name */ - struct rspamd_mime_header *ord_prev, *ord_next; /* Overall order of headers */ + struct rspamd_mime_header *ord_next; /* Overall order of headers, slist */ }; +/* Define hash type */ +__KHASH_TYPE (rspamd_mime_headers_htb, gchar *, struct rspamd_mime_header *) + enum rspamd_received_type { RSPAMD_RECEIVED_SMTP = 0, RSPAMD_RECEIVED_ESMTP = 1u << 0u, @@ -79,7 +83,7 @@ enum rspamd_received_type { RSPAMD_RECEIVED_FLAG_AUTHENTICATED = (1u << 12u), }; -struct received_header { +struct rspamd_received_header { const gchar *from_hostname; const gchar *from_ip; const gchar *real_hostname; @@ -90,7 +94,7 @@ struct received_header { struct rspamd_mime_header *hdr; time_t timestamp; gint flags; /* See enum rspamd_received_type */ - struct received_header *prev, *next; + struct rspamd_received_header *prev, *next; }; /** @@ -102,7 +106,7 @@ struct received_header { * @param check_newlines */ void rspamd_mime_headers_process (struct rspamd_task *task, - GHashTable *target, + khash_t(rspamd_mime_headers_htb) *target, struct rspamd_mime_header **order_ptr, const gchar *in, gsize len, gboolean check_newlines); @@ -132,6 +136,26 @@ gchar *rspamd_mime_header_encode (const gchar *in, gsize len); */ gchar *rspamd_mime_message_id_generate (const gchar *fqdn); +/** + * Get an array of header's values with specified header's name using raw headers + * @param task worker task structure + * @param field header's name + * @return An array of header's values or NULL. It is NOT permitted to free array or values. + */ +struct rspamd_mime_header * +rspamd_message_get_header_array (struct rspamd_task *task, + const gchar *field); + +/** + * Get an array of header's values with specified header's name using raw headers + * @param htb hash table indexed by header name (caseless) with ptr arrays as elements + * @param field header's name + * @return An array of header's values or NULL. It is NOT permitted to free array or values. + */ +struct rspamd_mime_header * +rspamd_message_get_header_from_hash (khash_t(rspamd_mime_headers_htb) *htb, + const gchar *field); + #ifdef __cplusplus } #endif diff --git a/src/libmime/smtp_parsers.h b/src/libmime/smtp_parsers.h index b4fb825b4..3a52f1dd6 100644 --- a/src/libmime/smtp_parsers.h +++ b/src/libmime/smtp_parsers.h @@ -29,7 +29,7 @@ extern "C" { int rspamd_smtp_received_parse (struct rspamd_task *task, const char *data, size_t len, - struct received_header *rh); + struct rspamd_received_header *rh); int rspamd_smtp_addr_parse (const char *data, size_t len, struct rspamd_email_address *addr); diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index 99faa4b3e..3f69adfcc 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -2514,7 +2514,7 @@ lua_task_get_received_headers (lua_State * L) { LUA_TRACE_POINT; struct rspamd_task *task = lua_check_task (L, 1); - struct received_header *rh; + struct rspamd_received_header *rh; const gchar *proto; guint i, k = 1; |