From 6ef35e3b2219338be95a1f1fc31f77c5c8cbed29 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 15 Jan 2016 22:06:27 +0000 Subject: [PATCH] Ignore SPF results in case of DNS failure --- src/libserver/spf.c | 18 ++++++++++++++++-- src/libserver/spf.h | 2 ++ src/plugins/spf.c | 14 ++++++++++---- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/libserver/spf.c b/src/libserver/spf.c index 31dba5d89..fde0030d3 100644 --- a/src/libserver/spf.c +++ b/src/libserver/spf.c @@ -299,7 +299,11 @@ rspamd_spf_process_reference (struct spf_resolved *target, for (i = 0; i < elt->elts->len; i++) { cur = g_ptr_array_index (elt->elts, i); - if (!(cur->flags & RSPAMD_SPF_FLAG_PARSED)) { + if (cur->flags & RSPAMD_SPF_FLAG_TEMPFAIL) { + target->failed = TRUE; + continue; + } + else if (!(cur->flags & RSPAMD_SPF_FLAG_PARSED)) { /* Ignore unparsed addrs */ continue; } @@ -337,7 +341,7 @@ rspamd_spf_record_flatten (struct spf_record *rec) g_assert (rec != NULL); - res = g_slice_alloc (sizeof (*res)); + res = g_slice_alloc0 (sizeof (*res)); res->elts = g_array_sized_new (FALSE, FALSE, sizeof (struct spf_addr), rec->resolved->len); res->domain = g_strdup (rec->sender_domain); @@ -673,6 +677,16 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg) break; } } + else { + cb->addr->flags |= RSPAMD_SPF_FLAG_TEMPFAIL; + msg_info_spf ( + "<%s>: spf error for domain %s: cannot resolve DNS record for" + " %s: %s", + task->message_id, + cb->rec->sender_domain, + cb->resolved->cur_domain, + rdns_strerror (reply->code)); + } rspamd_spf_maybe_return (cb->rec); } diff --git a/src/libserver/spf.h b/src/libserver/spf.h index 9e875b515..25905f894 100644 --- a/src/libserver/spf.h +++ b/src/libserver/spf.h @@ -36,6 +36,7 @@ typedef enum spf_action_e { #define RSPAMD_SPF_FLAG_VALID (1 << 5) #define RSPAMD_SPF_FLAG_REFRENCE (1 << 6) #define RSPAMD_SPF_FLAG_REDIRECT (1 << 7) +#define RSPAMD_SPF_FLAG_TEMPFAIL (1 << 8) struct spf_addr { guchar addr6[sizeof (struct in6_addr)]; @@ -56,6 +57,7 @@ struct spf_addr { struct spf_resolved { gchar *domain; guint ttl; + gboolean failed; 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 d7f1031c7..583a46a44 100644 --- a/src/plugins/spf.c +++ b/src/plugins/spf.c @@ -386,12 +386,18 @@ spf_check_list (struct spf_resolved *rec, struct rspamd_task *task) guint i; struct spf_addr *addr; - for (i = 0; i < rec->elts->len; i ++) { - addr = &g_array_index (rec->elts, struct spf_addr, i); - if (spf_check_element (addr, task)) { - break; + if (!rec->failed) { + for (i = 0; i < rec->elts->len; i ++) { + addr = &g_array_index (rec->elts, struct spf_addr, i); + if (spf_check_element (addr, task)) { + break; + } } } + else { + msg_info_task ("<%s>: ignore spf results due to DNS failure", + task->message_id); + } } static void -- 2.39.5