diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-03-18 17:21:33 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-03-18 17:21:33 +0000 |
commit | f7b2b8e8bf205da930c1aa14704428600e3453ba (patch) | |
tree | a4f8c0e86ecbe5f202cf0025b6dfec673f498991 /src | |
parent | 020d5565adc3653ba4b674bb4c72dea6442a32c3 (diff) | |
download | rspamd-f7b2b8e8bf205da930c1aa14704428600e3453ba.tar.gz rspamd-f7b2b8e8bf205da930c1aa14704428600e3453ba.zip |
Fix spf plugin.
Diffstat (limited to 'src')
-rw-r--r-- | src/libserver/spf.c | 1 | ||||
-rw-r--r-- | src/libserver/spf.h | 1 | ||||
-rw-r--r-- | src/plugins/spf.c | 126 |
3 files changed, 27 insertions, 101 deletions
diff --git a/src/libserver/spf.c b/src/libserver/spf.c index e9c0ebc71..eae35d352 100644 --- a/src/libserver/spf.c +++ b/src/libserver/spf.c @@ -301,6 +301,7 @@ rspamd_spf_record_flatten (struct spf_record *rec) res->elts = g_array_sized_new (FALSE, FALSE, sizeof (struct spf_addr), rec->resolved->len); res->domain = g_strdup (rec->sender_domain); + res->ttl = rec->ttl; REF_INIT_RETAIN (res, rspamd_flatten_record_dtor); top = &g_array_index (rec->resolved, struct spf_resolved_element, 0); diff --git a/src/libserver/spf.h b/src/libserver/spf.h index db220e03a..473eff086 100644 --- a/src/libserver/spf.h +++ b/src/libserver/spf.h @@ -51,6 +51,7 @@ struct spf_addr { struct spf_resolved { gchar *domain; + guint ttl; GArray *elts; /* Flat list of struct spf_addr */ ref_entry_t ref; /* Refcounting */ }; diff --git a/src/plugins/spf.c b/src/plugins/spf.c index 6bcb8626f..08e4ec9c3 100644 --- a/src/plugins/spf.c +++ b/src/plugins/spf.c @@ -166,8 +166,8 @@ spf_module_config (struct rspamd_config *cfg) spf_module_ctx->spf_hash = rspamd_lru_hash_new ( cache_size, cache_expire, - g_free, - spf_record_destroy); + NULL, + (GDestroyNotify)spf_record_unref); return res; } @@ -188,12 +188,10 @@ static gboolean spf_check_element (struct spf_addr *addr, struct rspamd_task *task) { gboolean res = FALSE; - guint8 *s, *d; + const guint8 *s, *d; gchar *spf_result; guint af, mask, bmask, addrlen; const gchar *spf_message, *spf_symbol; - struct in_addr in4s; - struct in6_addr in6s; GList *opts = NULL; if (task->from_addr == NULL) { @@ -202,23 +200,20 @@ spf_check_element (struct spf_addr *addr, struct rspamd_task *task) af = rspamd_inet_address_get_af (task->from_addr); /* Basic comparing algorithm */ - if ((addr->data.normal.ipv6 && af == AF_INET6) || - (!addr->data.normal.ipv6 && af == AF_INET)) { + if (((addr->flags & RSPAMD_SPF_FLAG_IPV6) && af == AF_INET6) || + ((addr->flags & RSPAMD_SPF_FLAG_IPV4) && af == AF_INET)) { d = rspamd_inet_address_get_radix_key (task->from_addr, &addrlen); - if (addr->data.normal.ipv6) { - memcpy (&in6s, &addr->data.normal.d.in6, - sizeof (struct in6_addr)); - s = (guint8 *)&in6s; + if (af == AF_INET6) { + s = (const guint8 *)addr->addr6; + mask = addr->m.dual.mask_v6; } else { - memcpy (&in4s, &addr->data.normal.d.in4, - sizeof (struct in_addr)); - s = (guint8 *)&in4s; + s = (const guint8 *)addr->addr4; + mask = addr->m.dual.mask_v4; } /* Compare the first bytes */ - mask = addr->data.normal.mask; bmask = mask / CHAR_BIT; if (bmask > addrlen) { msg_info ("bad mask length: %d", mask); @@ -240,7 +235,7 @@ spf_check_element (struct spf_addr *addr, struct rspamd_task *task) } } else { - if (addr->data.normal.addr_any) { + if (addr->flags & RSPAMD_SPF_FLAG_ANY) { res = TRUE; } else { @@ -280,47 +275,35 @@ spf_check_element (struct spf_addr *addr, struct rspamd_task *task) return FALSE; } -static gboolean -spf_check_list (GList *list, struct rspamd_task *task) +static void +spf_check_list (struct spf_resolved *rec, struct rspamd_task *task) { - GList *cur; + guint i; struct spf_addr *addr; - cur = list; + for (i = 0; i < rec->elts->len; i ++) { + addr = &g_array_index (rec->elts, struct spf_addr, i); - while (cur) { - addr = cur->data; - if (addr->is_list) { - /* Recursive call */ - if (spf_check_list (addr->data.list, task)) { - return TRUE; - } - } - else { - if (spf_check_element (addr, task)) { - return TRUE; - } + if (spf_check_element (addr, task)) { + break; } - cur = g_list_next (cur); } - - return FALSE; } static void -spf_plugin_callback (struct spf_record *record, struct rspamd_task *task) +spf_plugin_callback (struct spf_resolved *record, struct rspamd_task *task) { - GList *l; + struct spf_resolved *l; - if (record && record->addrs && record->sender_domain) { + if (record && record->elts->len > 0 && record->domain) { if ((l = rspamd_lru_hash_lookup (spf_module_ctx->spf_hash, - record->sender_domain, task->tv.tv_sec)) == NULL) { - l = spf_record_copy (record->addrs); + record->domain, task->tv.tv_sec)) == NULL) { + rspamd_lru_hash_insert (spf_module_ctx->spf_hash, - g_strdup (record->sender_domain), - l, task->tv.tv_sec, record->ttl); + record->domain, + record, task->tv.tv_sec, record->ttl); } spf_check_list (l, task); } @@ -348,62 +331,3 @@ spf_symbol_callback (struct rspamd_task *task, void *unused) } } } - -/* - * Make a deep copy of list, note copy is REVERSED - */ -static GList * -spf_record_copy (GList *addrs) -{ - GList *cur, *newl = NULL; - struct spf_addr *addr, *newa; - - cur = addrs; - - while (cur) { - addr = cur->data; - newa = g_malloc (sizeof (struct spf_addr)); - memcpy (newa, addr, sizeof (struct spf_addr)); - if (addr->is_list) { - /* Recursive call */ - newa->data.list = spf_record_copy (addr->data.list); - } - else { - if (addr->spf_string) { - newa->spf_string = g_strdup (addr->spf_string); - } - } - newl = g_list_prepend (newl, newa); - cur = g_list_next (cur); - } - - return newl; -} - -/* - * Destroy allocated spf list - */ - - -static void -spf_record_destroy (gpointer list) -{ - GList *cur = list; - struct spf_addr *addr; - - while (cur) { - addr = cur->data; - if (addr->is_list) { - spf_record_destroy (addr->data.list); - } - else { - if (addr->spf_string) { - g_free (addr->spf_string); - } - } - g_free (addr); - cur = g_list_next (cur); - } - - g_list_free (list); -} |