aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/uthash/utlist.h26
-rw-r--r--src/libmime/email_addr.h2
-rw-r--r--src/libmime/message.c101
-rw-r--r--src/libmime/message.h72
-rw-r--r--src/libmime/mime_headers.c136
-rw-r--r--src/libmime/mime_headers.h34
-rw-r--r--src/libmime/smtp_parsers.h2
-rw-r--r--src/lua/lua_task.c2
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;