From: Vsevolod Stakhov Date: Tue, 3 Jan 2017 17:05:57 +0000 (+0000) Subject: [Feature] Ignore too wide elements in SPF X-Git-Tag: 1.5.0~431 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=96909e01b93eb2f89ffd3c50d833b48c7f45fec4;p=rspamd.git [Feature] Ignore too wide elements in SPF Issue: #216 Reported by: @fatalbanana --- 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; diff --git a/src/libserver/spf.h b/src/libserver/spf.h index a8f0cf10e..2a844e998 100644 --- a/src/libserver/spf.h +++ b/src/libserver/spf.h @@ -34,7 +34,7 @@ typedef enum spf_action_e { #define RSPAMD_SPF_FLAG_PROCESSED (1 << 2) #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_INVALID (1 << 5) #define RSPAMD_SPF_FLAG_REFERENCE (1 << 6) #define RSPAMD_SPF_FLAG_REDIRECT (1 << 7) #define RSPAMD_SPF_FLAG_TEMPFAIL (1 << 8)