From d70836c1a799962f2b25a320d72a960748b76645 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 7 Nov 2014 16:00:59 +0000 Subject: [PATCH] Another fix for PTR records in SPF. --- src/libserver/spf.c | 81 +++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/src/libserver/spf.c b/src/libserver/spf.c index c30d893d1..df5426b1d 100644 --- a/src/libserver/spf.c +++ b/src/libserver/spf.c @@ -488,47 +488,51 @@ spf_check_ptr_host (struct spf_dns_cb *cb, const char *name) if (name == NULL) { return FALSE; } - if (cb->ptr_host == NULL) { - /* We need to check whether `cur_domain` is a subdomain for `name` */ + if (cb->ptr_host != NULL) { + dstart = cb->ptr_host; + + } + else { dstart = cb->rec->cur_domain; - dend = dstart + strlen (dstart) - 1; - nstart = name; - nend = nstart + strlen (nstart) - 1; + } - if (nend == nstart || dend == dstart) { + msg_debug ("check ptr %s vs %s", name, dstart); + + /* We need to check whether `cur_domain` is a subdomain for `name` */ + dend = dstart + strlen (dstart) - 1; + nstart = name; + nend = nstart + strlen (nstart) - 1; + + if (nend == nstart || dend == dstart) { + return FALSE; + } + /* Strip last '.' from names */ + if (*nend == '.') { + nend --; + } + if (*dend == '.') { + dend --; + } + + /* Now compare from end to start */ + for (;;) { + if (g_ascii_tolower (*dend) != g_ascii_tolower (*nend)) { + msg_debug ("ptr records missmatch: %s and %s", dend, nend); return FALSE; } - /* Strip last '.' from names */ - if (*nend == '.') { - nend --; - } - if (*dend == '.') { - dend --; - } - - /* Now compare from end to start */ - for (;;) { - if (g_ascii_tolower (*dend) != g_ascii_tolower (*nend)) { - return FALSE; - } - if (dend == dstart) { - break; - } - if (nend == nstart) { - /* Name is shorter than cur_domain */ - return FALSE; - } - nend --; - dend --; + if (dend == dstart) { + break; } - if (nend != nstart && *(nend - 1) != '.') { - /* Not a subdomain */ + if (nend == nstart) { + /* Name is shorter than cur_domain */ return FALSE; } + nend --; + dend --; } - else { - dstart = cb->rec->cur_domain; - return rspamd_strcase_equal (dstart, name); + if (nend != nstart && *(nend - 1) != '.') { + /* Not a subdomain */ + return FALSE; } return TRUE; @@ -555,6 +559,8 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg) case SPF_RESOLVE_MX: if (elt_data->type == RDNS_REQUEST_MX) { /* Now resolve A record for this MX */ + msg_debug ("resolve %s after resolving of MX", + elt_data->content.mx.name); if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, RDNS_REQUEST_A, @@ -582,6 +588,8 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg) if (elt_data->type == RDNS_REQUEST_PTR) { /* Validate returned records prior to making A requests */ if (spf_check_ptr_host (cb, elt_data->content.ptr.name)) { + msg_debug ("resolve %s after resolving of PTR", + elt_data->content.ptr.name); if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, @@ -766,6 +774,7 @@ parse_spf_a (struct rspamd_task *task, cb->addr = addr; cb->cur_action = SPF_RESOLVE_A; cb->in_include = rec->in_include; + msg_debug ("resolve a %s", host); if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, RDNS_REQUEST_A, host)) { task->dns_requests++; @@ -816,6 +825,7 @@ parse_spf_ptr (struct rspamd_task *task, return FALSE; } rspamd_mempool_add_destructor (task->task_pool, free, ptr); + msg_debug ("resolve ptr %s for %s", ptr, host); if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, RDNS_REQUEST_PTR, ptr)) { task->dns_requests++; @@ -857,6 +867,7 @@ parse_spf_mx (struct rspamd_task *task, cb->addr = addr; cb->cur_action = SPF_RESOLVE_MX; cb->in_include = rec->in_include; + msg_debug ("resolve mx for %s", host); if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, RDNS_REQUEST_MX, host)) { task->dns_requests++; @@ -939,6 +950,8 @@ parse_spf_include (struct rspamd_task *task, addr->is_list = TRUE; addr->data.list = NULL; domain = rspamd_mempool_strdup (task->task_pool, begin); + msg_debug ("resolve include %s", domain); + if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, RDNS_REQUEST_TXT, domain)) { task->dns_requests++; @@ -986,6 +999,7 @@ parse_spf_redirect (struct rspamd_task *task, cb->cur_action = SPF_RESOLVE_REDIRECT; cb->in_include = rec->in_include; domain = rspamd_mempool_strdup (task->task_pool, begin); + msg_debug ("resolve redirect %s", domain); if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, RDNS_REQUEST_TXT, domain)) { task->dns_requests++; @@ -1022,6 +1036,7 @@ parse_spf_exists (struct rspamd_task *task, cb->in_include = rec->in_include; host = rspamd_mempool_strdup (task->task_pool, begin); + msg_debug ("resolve exists %s", host); if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, RDNS_REQUEST_A, host)) { task->dns_requests++; -- 2.39.5