]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Ignore SPF results in case of DNS failure
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 15 Jan 2016 22:06:27 +0000 (22:06 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 15 Jan 2016 22:06:27 +0000 (22:06 +0000)
src/libserver/spf.c
src/libserver/spf.h
src/plugins/spf.c

index 31dba5d89a65d8887e724d878548ee44884f5b95..fde0030d370979c51041034033ef65cea647e635 100644 (file)
@@ -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);
 }
index 9e875b5155e149e557c75f4c2000a9b7447c31a7..25905f894b584e90f4140ca32d5736071e66518c 100644 (file)
@@ -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 */
 };
index d7f1031c7dbf6177bea96015e57468c533fdb248..583a46a44100d55db76b2e6b0347a2cece42d702 100644 (file)
@@ -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