diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-01-03 17:05:57 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2017-01-03 17:07:18 +0000 |
commit | 96909e01b93eb2f89ffd3c50d833b48c7f45fec4 (patch) | |
tree | 01d75e78e1aae07b20ffaaa61082fceacd597bea /src/libserver/spf.c | |
parent | fb2cc650c62de4f5fd077649bdaa1a8bc1e04595 (diff) | |
download | rspamd-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.c | 29 |
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; |