aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-03-18 21:21:25 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-03-18 21:21:25 +0000
commit385b83245d1de73130da8ff3bf16915d0e393e07 (patch)
treea19a7fdf860a270e92bd3398d0e10a6caff4a1c3 /src
parent237ccf43be5d534ecc9550c27a1e8e66d41d6629 (diff)
downloadrspamd-385b83245d1de73130da8ff3bf16915d0e393e07.tar.gz
rspamd-385b83245d1de73130da8ff3bf16915d0e393e07.zip
Fix references.
Diffstat (limited to 'src')
-rw-r--r--src/libserver/spf.c66
-rw-r--r--src/plugins/spf.c1
2 files changed, 38 insertions, 29 deletions
diff --git a/src/libserver/spf.c b/src/libserver/spf.c
index b51bcf7dc..8999402d6 100644
--- a/src/libserver/spf.c
+++ b/src/libserver/spf.c
@@ -113,7 +113,8 @@ struct spf_dns_cb {
} \
} while (0) \
-static gboolean start_spf_parse (struct spf_record *rec, gchar *begin);
+static gboolean start_spf_parse (struct spf_record *rec,
+ struct spf_resolved_element *resolved, gchar *begin);
/* Determine spf mech */
static spf_mech_t
@@ -171,7 +172,7 @@ rspamd_spf_free_addr (gpointer a)
}
}
-static void
+static struct spf_resolved_element *
rspamd_spf_new_addr_list (struct spf_record *rec, const gchar *domain)
{
struct spf_resolved_element resolved;
@@ -181,6 +182,9 @@ rspamd_spf_new_addr_list (struct spf_record *rec, const gchar *domain)
resolved.elts = g_ptr_array_new_full (8, rspamd_spf_free_addr);
g_array_append_val (rec->resolved, resolved);
+
+ return &g_array_index (rec->resolved, struct spf_resolved_element,
+ rec->resolved->len - 1);
}
/* Debugging function that dumps spf record in log */
@@ -247,7 +251,21 @@ rspamd_spf_process_reference (struct spf_resolved *target,
}
while (elt->redirected) {
- cur = g_ptr_array_index (elt->elts, 0);
+ g_assert (elt->elts->len > 0);
+
+ for (i = 0; i < elt->elts->len; i ++) {
+ cur = g_ptr_array_index (elt->elts, i);
+ if (cur->flags & RSPAMD_SPF_FLAG_PARSED) {
+ break;
+ }
+ }
+
+ if (!(cur->flags & RSPAMD_SPF_FLAG_PARSED)) {
+ /* Unresolved redirect */
+ msg_info ("redirect to %s cannot be resolved", cur->spf_string);
+ return;
+ }
+
g_assert (cur->flags & RSPAMD_SPF_FLAG_REFRENCE);
g_assert (cur->m.idx < rec->resolved->len);
elt = &g_array_index (rec->resolved, struct spf_resolved_element,
@@ -494,7 +512,7 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
case SPF_RESOLVE_REDIRECT:
if (elt_data->type == RDNS_REQUEST_TXT) {
begin = elt_data->content.txt.data;
- ret = start_spf_parse (cb->rec, begin);
+ ret = start_spf_parse (cb->rec, cb->resolved, begin);
if (ret) {
cb->addr->flags |= RSPAMD_SPF_FLAG_PARSED;
@@ -507,7 +525,7 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
case SPF_RESOLVE_INCLUDE:
if (elt_data->type == RDNS_REQUEST_TXT) {
begin = elt_data->content.txt.data;
- ret = start_spf_parse (cb->rec, begin);
+ ret = start_spf_parse (cb->rec, cb->resolved, begin);
if (ret) {
cb->addr->flags |= RSPAMD_SPF_FLAG_PARSED;
@@ -568,6 +586,7 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
task->message_id,
cb->rec->sender_domain,
cb->resolved->cur_domain);
+ cb->addr->flags &= ~RSPAMD_SPF_FLAG_PARSED;
break;
case SPF_RESOLVE_INCLUDE:
msg_info (
@@ -575,6 +594,7 @@ spf_record_dns_callback (struct rdns_reply *reply, gpointer arg)
task->message_id,
cb->rec->sender_domain,
cb->resolved->cur_domain);
+ cb->addr->flags &= ~RSPAMD_SPF_FLAG_PARSED;
break;
case SPF_RESOLVE_EXP:
break;
@@ -956,10 +976,6 @@ parse_spf_include (struct spf_record *rec, struct spf_addr *addr)
struct spf_dns_cb *cb;
const gchar *domain;
struct rspamd_task *task = rec->task;
- struct spf_resolved_element *resolved;
-
- resolved = &g_array_index (rec->resolved, struct spf_resolved_element,
- rec->resolved->len - 1);
CHECK_REC (rec);
domain = strchr (addr->spf_string, ':');
@@ -976,11 +992,10 @@ parse_spf_include (struct spf_record *rec, struct spf_addr *addr)
cb->rec = rec;
cb->addr = addr;
cb->cur_action = SPF_RESOLVE_INCLUDE;
- cb->resolved = resolved;
+ addr->m.idx = rec->resolved->len;
+ cb->resolved = rspamd_spf_new_addr_list (rec, domain);
/* Set reference */
addr->flags |= RSPAMD_SPF_FLAG_REFRENCE;
- addr->m.idx = rec->resolved->len;
- rspamd_spf_new_addr_list (rec, domain);
msg_debug ("resolve include %s", domain);
if (make_dns_request (task->resolver, task->s, task->task_pool,
@@ -1005,18 +1020,15 @@ parse_spf_exp (struct spf_record *rec, struct spf_addr *addr)
}
static gboolean
-parse_spf_redirect (struct spf_record *rec, struct spf_addr *addr)
+parse_spf_redirect (struct spf_record *rec,
+ struct spf_resolved_element *resolved, struct spf_addr *addr)
{
struct spf_dns_cb *cb;
const gchar *domain;
- struct spf_resolved_element *resolved;
struct spf_addr *cur;
struct rspamd_task *task = rec->task;
guint i;
- resolved = &g_array_index (rec->resolved, struct spf_resolved_element,
- rec->resolved->len - 1);
-
CHECK_REC (rec);
domain = strchr (addr->spf_string, '=');
@@ -1035,7 +1047,7 @@ parse_spf_redirect (struct spf_record *rec, struct spf_addr *addr)
cur = g_ptr_array_index (resolved->elts, i);
if (cur != addr) {
- g_ptr_array_remove_index_fast (resolved->elts, i);
+ cur->flags &= ~RSPAMD_SPF_FLAG_PARSED;
}
}
@@ -1043,12 +1055,11 @@ parse_spf_redirect (struct spf_record *rec, struct spf_addr *addr)
/* Set reference */
addr->flags |= RSPAMD_SPF_FLAG_REFRENCE;
addr->m.idx = rec->resolved->len;
- rspamd_spf_new_addr_list (rec, domain);
cb->rec = rec;
cb->addr = addr;
cb->cur_action = SPF_RESOLVE_REDIRECT;
- cb->resolved = resolved;
+ cb->resolved = rspamd_spf_new_addr_list (rec, domain);
msg_debug ("resolve redirect %s", domain);
if (make_dns_request (task->resolver, task->s, task->task_pool,
@@ -1495,7 +1506,7 @@ 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, addr);
+ res = parse_spf_redirect (rec, resolved, addr);
}
else {
msg_info ("<%s>: spf error for domain %s: bad spf command %s",
@@ -1549,10 +1560,10 @@ parse_spf_scopes (struct spf_record *rec, gchar **begin)
}
static gboolean
-start_spf_parse (struct spf_record *rec, gchar *begin)
+start_spf_parse (struct spf_record *rec, struct spf_resolved_element *resolved,
+ gchar *begin)
{
gchar **elts, **cur_elt;
- struct spf_resolved_element *resolved;
/* Skip spaces */
while (g_ascii_isspace (*begin)) {
@@ -1593,8 +1604,6 @@ start_spf_parse (struct spf_record *rec, gchar *begin)
begin++;
}
- resolved = &g_array_index (rec->resolved, struct spf_resolved_element,
- rec->resolved->len - 1);
elts = g_strsplit_set (begin, " ", 0);
if (elts) {
@@ -1618,16 +1627,19 @@ spf_dns_callback (struct rdns_reply *reply, gpointer arg)
{
struct spf_record *rec = arg;
struct rdns_reply_entry *elt;
+ struct spf_resolved_element *resolved;
rec->requests_inflight--;
+
if (reply->code == RDNS_RC_NOERROR) {
+ resolved = rspamd_spf_new_addr_list (rec, rec->sender_domain);
if (rec->resolved->len == 1) {
/* Top level resolved element */
rec->ttl = reply->entries->ttl;
}
LL_FOREACH (reply->entries, elt) {
- if (start_spf_parse (rec, elt->content.txt.data)) {
+ if (start_spf_parse (rec, resolved, elt->content.txt.data)) {
break;
}
}
@@ -1670,8 +1682,6 @@ resolve_spf (struct rspamd_task *task, spf_cb_t callback)
rec->resolved = g_array_sized_new (FALSE, FALSE,
sizeof (struct spf_resolved_element), 8);
- rspamd_spf_new_addr_list (rec, rec->sender_domain);
-
/* Add destructor */
rspamd_mempool_add_destructor (task->task_pool,
(rspamd_mempool_destruct_t)spf_record_destructor,
diff --git a/src/plugins/spf.c b/src/plugins/spf.c
index caeb9365b..908e097ab 100644
--- a/src/plugins/spf.c
+++ b/src/plugins/spf.c
@@ -281,7 +281,6 @@ spf_check_list (struct spf_resolved *rec, struct rspamd_task *task)
for (i = 0; i < rec->elts->len; i ++) {
addr = &g_array_index (rec->elts, struct spf_addr, i);
-
if (spf_check_element (addr, task)) {
break;
}