aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-12-17 15:11:03 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-12-17 15:11:03 +0000
commit99aaa9bbb378dd6f902901230dbe9ce9ae3ac038 (patch)
tree383c04a20760425a30c64226331adf106e7db8a2 /src
parent50e53039c4259a66124ec2bf481da8fc85d551b7 (diff)
downloadrspamd-99aaa9bbb378dd6f902901230dbe9ce9ae3ac038.tar.gz
rspamd-99aaa9bbb378dd6f902901230dbe9ce9ae3ac038.zip
[Minor] Spf: Ignore redirect if `all` is also in a record
Diffstat (limited to 'src')
-rw-r--r--src/libserver/spf.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/libserver/spf.c b/src/libserver/spf.c
index 762f77a75..ef542a7f5 100644
--- a/src/libserver/spf.c
+++ b/src/libserver/spf.c
@@ -2100,8 +2100,10 @@ expand_spf_macro (struct spf_record *rec, struct spf_resolved_element *resolved,
/* Read current element and try to parse record */
static gboolean
-parse_spf_record (struct spf_record *rec, struct spf_resolved_element *resolved,
- const gchar *elt)
+spf_process_element (struct spf_record *rec,
+ struct spf_resolved_element *resolved,
+ const gchar *elt,
+ const gchar **elts)
{
struct spf_addr *addr = NULL;
gboolean res = FALSE;
@@ -2197,7 +2199,35 @@ parse_spf_record (struct spf_record *rec, struct spf_resolved_element *resolved,
/* redirect */
if (g_ascii_strncasecmp (begin, SPF_REDIRECT,
sizeof (SPF_REDIRECT) - 1) == 0) {
- res = parse_spf_redirect (rec, resolved, addr);
+ /*
+ * According to https://tools.ietf.org/html/rfc7208#section-6.1
+ * There must be no ALL element anywhere in the record,
+ * redirect must be ignored
+ */
+ gboolean ignore_redirect = FALSE;
+
+ for (const gchar **tmp = elts; *tmp != NULL; tmp ++) {
+ if (g_ascii_strcasecmp ((*tmp) + 1, "all") == 0) {
+ ignore_redirect = TRUE;
+ break;
+ }
+ }
+
+ if (!ignore_redirect) {
+ res = parse_spf_redirect (rec, resolved, addr);
+ }
+ else {
+ msg_info_spf ("ignore SPF redirect (%s) for domain %s as there is also all element",
+ begin, rec->sender_domain);
+
+ /* Pop the current addr as it is ignored */
+ g_free (addr->spf_string);
+ g_ptr_array_remove_index_fast (resolved->elts,
+ resolved->elts->len - 1);
+ g_free (addr);
+
+ return TRUE;
+ }
}
else {
msg_info_spf ("spf error for domain %s: bad spf command %s",
@@ -2306,7 +2336,7 @@ start_spf_parse (struct spf_record *rec, struct spf_resolved_element *resolved,
cur_elt = elts;
while (*cur_elt) {
- parse_spf_record (rec, resolved, *cur_elt);
+ spf_process_element (rec, resolved, *cur_elt, (const gchar **)elts);
cur_elt++;
}