aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lewis <nerf@judo.za.org>2016-09-27 14:19:21 +0200
committerAndrew Lewis <nerf@judo.za.org>2016-09-27 15:28:42 +0200
commit8afaa80ad5eb23d2b9feb575f9ef4d7bef7b1e85 (patch)
tree22cd1646855d2a57122b6a4d9472cd1820554845
parent3c564548962ae4bca2fbc565acac68023170d94b (diff)
downloadrspamd-8afaa80ad5eb23d2b9feb575f9ef4d7bef7b1e85.tar.gz
rspamd-8afaa80ad5eb23d2b9feb575f9ef4d7bef7b1e85.zip
[Minor] Really fix SPF PERMFAIL/DNSFAIL behaviour on failed redirect
-rw-r--r--src/libserver/spf.c49
-rw-r--r--src/libserver/spf.h2
2 files changed, 39 insertions, 12 deletions
diff --git a/src/libserver/spf.c b/src/libserver/spf.c
index 41f31bfb0..362c96255 100644
--- a/src/libserver/spf.c
+++ b/src/libserver/spf.c
@@ -314,10 +314,9 @@ rspamd_spf_process_reference (struct spf_resolved *target,
if (!(cur->flags & RSPAMD_SPF_FLAG_PARSED)) {
/* Unresolved redirect */
msg_info_spf ("redirect to %s cannot be resolved", cur->spf_string);
- cur->flags |= RSPAMD_SPF_FLAG_TEMPFAIL;
}
else {
- g_assert (cur->flags & RSPAMD_SPF_FLAG_REFRENCE);
+ g_assert (cur->flags & RSPAMD_SPF_FLAG_REFERENCE);
g_assert (cur->m.idx < rec->resolved->len);
relt = g_ptr_array_index (rec->resolved, cur->m.idx);
msg_debug_spf ("domain %s is redirected to %s", elt->cur_domain,
@@ -344,7 +343,7 @@ rspamd_spf_process_reference (struct spf_resolved *target,
/* Ignore unparsed addrs */
continue;
}
- if (cur->flags & RSPAMD_SPF_FLAG_REFRENCE) {
+ if (cur->flags & RSPAMD_SPF_FLAG_REFERENCE) {
/* Process reference */
if (cur->flags & RSPAMD_SPF_FLAG_REDIRECT) {
/* Stop on redirected domain */
@@ -665,11 +664,18 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
break;
case SPF_RESOLVE_REDIRECT:
if (elt_data->type == RDNS_REQUEST_TXT) {
- if (spf_process_txt_record (rec, cb->resolved, reply)) {
- cb->addr->flags |= RSPAMD_SPF_FLAG_PARSED;
+ if (reply->code == RDNS_RC_NOERROR || reply->code == RDNS_RC_NXDOMAIN || reply->code == RDNS_RC_NOREC) {
+ if (spf_process_txt_record (rec, cb->resolved, reply)) {
+ cb->addr->flags |= RSPAMD_SPF_FLAG_PARSED;
+ }
+ else {
+ cb->addr->flags &= ~RSPAMD_SPF_FLAG_PARSED;
+ cb->addr->flags |= RSPAMD_SPF_FLAG_PERMFAIL;
+ }
}
else {
cb->addr->flags &= ~RSPAMD_SPF_FLAG_PARSED;
+ cb->addr->flags |= RSPAMD_SPF_FLAG_TEMPFAIL;
}
}
@@ -759,7 +765,13 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
else if ((cb->cur_action == SPF_RESOLVE_INCLUDE ||
cb->cur_action == SPF_RESOLVE_REDIRECT) ||
reply->code == RDNS_RC_TIMEOUT) {
- cb->addr->flags |= RSPAMD_SPF_FLAG_TEMPFAIL;
+ if ((cb->cur_action == SPF_RESOLVE_INCLUDE || cb->cur_action == SPF_RESOLVE_REDIRECT) &&
+ (reply->code == RDNS_RC_NOREC && reply->code == RDNS_RC_NXDOMAIN)) {
+ cb->addr->flags |= RSPAMD_SPF_FLAG_PERMFAIL;
+ }
+ else {
+ cb->addr->flags |= RSPAMD_SPF_FLAG_TEMPFAIL;
+ }
msg_info_spf (
"<%s>: spf error for domain %s: cannot resolve %s DNS record for"
" %s: %s",
@@ -1166,7 +1178,7 @@ parse_spf_include (struct spf_record *rec, struct spf_addr *addr)
cb->resolved = rspamd_spf_new_addr_list (rec, domain);
cb->ptr_host = domain;
/* Set reference */
- addr->flags |= RSPAMD_SPF_FLAG_REFRENCE;
+ addr->flags |= RSPAMD_SPF_FLAG_REFERENCE;
msg_debug_spf ("resolve include %s", domain);
if (make_dns_request_task_forced (task,
@@ -1210,7 +1222,7 @@ parse_spf_redirect (struct spf_record *rec,
cb = rspamd_mempool_alloc (task->task_pool, sizeof (struct spf_dns_cb));
/* Set reference */
- addr->flags |= RSPAMD_SPF_FLAG_REFRENCE | RSPAMD_SPF_FLAG_REDIRECT;
+ addr->flags |= RSPAMD_SPF_FLAG_REFERENCE | RSPAMD_SPF_FLAG_REDIRECT;
addr->m.idx = rec->resolved->len;
cb->rec = rec;
@@ -1818,11 +1830,26 @@ spf_dns_callback (struct rdns_reply *reply, gpointer arg)
if (resolved) {
if (!spf_process_txt_record (rec, resolved, reply)) {
- if (rec->dns_requests == 0) {
- resolved = g_ptr_array_index(rec->resolved, 0);
+ resolved = g_ptr_array_index(rec->resolved, 0);
+ if (rec->resolved->len > 1) {
+ addr = g_ptr_array_index(resolved->elts, 0);
+ if ((reply->code == RDNS_RC_NOREC || reply->code == RDNS_RC_NXDOMAIN)
+ && addr->flags & RSPAMD_SPF_FLAG_REDIRECT) {
+ addr->flags |= RSPAMD_SPF_FLAG_PERMFAIL;
+ } else {
+ addr->flags |= RSPAMD_SPF_FLAG_TEMPFAIL;
+ }
+ }
+ else {
addr = g_slice_alloc0 (sizeof(*addr));
addr->flags = 0;
- addr->flags |= RSPAMD_SPF_FLAG_NA;
+ if (reply->code == RDNS_RC_NOREC || reply->code == RDNS_RC_NXDOMAIN
+ || reply->code == RDNS_RC_NOERROR) {
+ addr->flags |= RSPAMD_SPF_FLAG_NA;
+ }
+ else {
+ addr->flags |= RSPAMD_SPF_FLAG_TEMPFAIL;
+ }
g_ptr_array_insert (resolved->elts, 0, addr);
}
}
diff --git a/src/libserver/spf.h b/src/libserver/spf.h
index ab2d0bc53..271056d87 100644
--- a/src/libserver/spf.h
+++ b/src/libserver/spf.h
@@ -35,7 +35,7 @@ typedef enum spf_action_e {
#define RSPAMD_SPF_FLAG_ANY (1 << 3)
#define RSPAMD_SPF_FLAG_PARSED (1 << 4)
#define RSPAMD_SPF_FLAG_VALID (1 << 5)
-#define RSPAMD_SPF_FLAG_REFRENCE (1 << 6)
+#define RSPAMD_SPF_FLAG_REFERENCE (1 << 6)
#define RSPAMD_SPF_FLAG_REDIRECT (1 << 7)
#define RSPAMD_SPF_FLAG_TEMPFAIL (1 << 8)
#define RSPAMD_SPF_FLAG_NA (1 << 9)