aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver/spf.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2017-01-03 17:05:57 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2017-01-03 17:07:18 +0000
commit96909e01b93eb2f89ffd3c50d833b48c7f45fec4 (patch)
tree01d75e78e1aae07b20ffaaa61082fceacd597bea /src/libserver/spf.c
parentfb2cc650c62de4f5fd077649bdaa1a8bc1e04595 (diff)
downloadrspamd-96909e01b93eb2f89ffd3c50d833b48c7f45fec4.tar.gz
rspamd-96909e01b93eb2f89ffd3c50d833b48c7f45fec4.zip
[Feature] Ignore too wide elements in SPF
Issue: #216 Reported by: @fatalbanana
Diffstat (limited to 'src/libserver/spf.c')
-rw-r--r--src/libserver/spf.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/libserver/spf.c b/src/libserver/spf.c
index 5eb8dbd1c..39c7c232b 100644
--- a/src/libserver/spf.c
+++ b/src/libserver/spf.c
@@ -339,6 +339,10 @@ rspamd_spf_process_reference (struct spf_resolved *target,
target->na = TRUE;
continue;
}
+ if (cur->flags & RSPAMD_SPF_FLAG_INVALID) {
+ /* Ignore invalid elements */
+ continue;
+ }
if ((cur->flags & (RSPAMD_SPF_FLAG_PARSED|RSPAMD_SPF_FLAG_RESOLVED)) !=
(RSPAMD_SPF_FLAG_RESOLVED|RSPAMD_SPF_FLAG_PARSED)) {
/* Ignore unparsed addrs */
@@ -1094,6 +1098,13 @@ parse_spf_all (struct spf_record *rec, struct spf_addr *addr)
addr->flags |= RSPAMD_SPF_FLAG_ANY|RSPAMD_SPF_FLAG_RESOLVED;
msg_debug_spf ("parsed all elt");
+ /* Disallow +all */
+ if (addr->mech == SPF_PASS) {
+ addr->flags |= RSPAMD_SPF_FLAG_INVALID;
+ msg_info_spf ("allow any SPF record for %s, ignore it",
+ rec->sender_domain);
+ }
+
return TRUE;
}
@@ -1105,6 +1116,7 @@ parse_spf_ip4 (struct spf_record *rec, struct spf_addr *addr)
gsize len;
gchar ipbuf[INET_ADDRSTRLEN + 1];
guint32 mask;
+ static const guint32 min_valid_mask = 8;
semicolon = strchr (addr->spf_string, ':');
@@ -1133,7 +1145,15 @@ parse_spf_ip4 (struct spf_record *rec, struct spf_addr *addr)
if (mask > 32) {
return FALSE;
}
+
addr->m.dual.mask_v4 = mask;
+
+ if (mask < min_valid_mask) {
+ addr->flags |= RSPAMD_SPF_FLAG_INVALID;
+ msg_info_spf ("too wide SPF record for %s: %s/%d",
+ rec->sender_domain,
+ ipbuf, addr->m.dual.mask_v4);
+ }
}
else {
addr->m.dual.mask_v4 = 32;
@@ -1153,6 +1173,7 @@ parse_spf_ip6 (struct spf_record *rec, struct spf_addr *addr)
gsize len;
gchar ipbuf[INET6_ADDRSTRLEN + 1];
guint32 mask;
+ static const guint32 min_valid_mask = 8;
semicolon = strchr (addr->spf_string, ':');
@@ -1181,7 +1202,15 @@ parse_spf_ip6 (struct spf_record *rec, struct spf_addr *addr)
if (mask > 128) {
return FALSE;
}
+
addr->m.dual.mask_v6 = mask;
+
+ if (mask < min_valid_mask) {
+ addr->flags |= RSPAMD_SPF_FLAG_INVALID;
+ msg_info_spf ("too wide SPF record for %s: %s/%d",
+ rec->sender_domain,
+ ipbuf, addr->m.dual.mask_v6);
+ }
}
else {
addr->m.dual.mask_v6 = 128;