summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/spf.c36
-rw-r--r--src/spf.c26
2 files changed, 47 insertions, 15 deletions
diff --git a/src/plugins/spf.c b/src/plugins/spf.c
index 1823f3407..dae3cb471 100644
--- a/src/plugins/spf.c
+++ b/src/plugins/spf.c
@@ -135,6 +135,36 @@ spf_module_reconfig (struct config_file *cfg)
static void
spf_plugin_callback (struct spf_record *record, struct worker_task *task)
{
+ GList *cur;
+ struct spf_addr *addr;
+ uint32_t s, m;
+
+ if (record) {
+ record->addrs = g_list_reverse (record->addrs);
+ cur = g_list_first (record->addrs);
+ s = ntohl (task->from_addr.s_addr);
+ while (cur) {
+ addr = cur->data;
+ m = (1 << addr->mask) - 1;
+ if ((s & m) == (addr->addr & m)) {
+ switch (addr->mech) {
+ case SPF_FAIL:
+ insert_result (task, spf_module_ctx->metric, spf_module_ctx->symbol_fail, 1, NULL);
+ break;
+ case SPF_SOFT_FAIL:
+ case SPF_NEUTRAL:
+ insert_result (task, spf_module_ctx->metric, spf_module_ctx->symbol_softfail, 1, NULL);
+ break;
+ default:
+ insert_result (task, spf_module_ctx->metric, spf_module_ctx->symbol_allow, 1, NULL);
+ break;
+ }
+ /* Stop parsing */
+ break;
+ }
+ cur = g_list_next (cur);
+ }
+ }
if (task->save.saved == 0) {
/* Call other filters */
task->save.saved = 1;
@@ -146,7 +176,9 @@ spf_plugin_callback (struct spf_record *record, struct worker_task *task)
static void
spf_symbol_callback (struct worker_task *task, void *unused)
{
- if (!resolve_spf (task, spf_plugin_callback)) {
- msg_info ("spf_symbol_callback: cannot make spf request for [%s]", task->message_id);
+ if (task->from_addr.s_addr != INADDR_NONE && task->from_addr.s_addr != INADDR_ANY) {
+ if (!resolve_spf (task, spf_plugin_callback)) {
+ msg_info ("spf_symbol_callback: cannot make spf request for [%s]", task->message_id);
+ }
}
}
diff --git a/src/spf.c b/src/spf.c
index b175d9498..bfd6da483 100644
--- a/src/spf.c
+++ b/src/spf.c
@@ -90,7 +90,7 @@ check_spf_mech (const char *elt, gboolean *need_shift)
g_assert (elt != NULL);
*need_shift = TRUE;
-
+
switch (*elt) {
case '-':
return SPF_FAIL;
@@ -170,10 +170,10 @@ parse_spf_ipmask (const char *begin, struct spf_addr *addr)
if (!inet_aton (ip_buf, &in)) {
return FALSE;
}
- addr->addr = in.s_addr;
+ addr->addr = ntohl (in.s_addr);
if (state == 2) {
/* Also parse mask */
- addr->mask = mask_buf[0] * 10 + mask_buf[1];
+ addr->mask = (mask_buf[0] - '0') * 10 + mask_buf[1] - '0';
if (addr->mask > 32) {
return FALSE;
}
@@ -242,13 +242,13 @@ spf_record_dns_callback (int result, char type, int count, int ttl, void *addres
}
else if (type == DNS_IPv4_A) {
/* XXX: process only one record */
- cb->addr->addr = *((uint32_t *)addresses);
+ cb->addr->addr = ntohl (*((uint32_t *)addresses));
}
break;
case SPF_RESOLVE_A:
if (type == DNS_IPv4_A) {
/* XXX: process only one record */
- cb->addr->addr = *((uint32_t *)addresses);
+ cb->addr->addr = ntohl (*((uint32_t *)addresses));
}
break;
case SPF_RESOLVE_PTR:
@@ -274,7 +274,7 @@ spf_record_dns_callback (int result, char type, int count, int ttl, void *addres
case SPF_RESOLVE_EXISTS:
if (type == DNS_IPv4_A) {
/* If specified address resolves, we can accept connection from every IP */
- cb->addr->addr = INADDR_ANY;
+ cb->addr->addr = ntohl (INADDR_ANY);
}
break;
}
@@ -437,7 +437,7 @@ parse_spf_redirect (struct worker_task *task, const char *begin, struct spf_reco
CHECK_REC (rec);
- if (begin == NULL || *begin != ':') {
+ if (begin == NULL || *begin != '=') {
return FALSE;
}
begin ++;
@@ -499,7 +499,7 @@ parse_spf_record (struct worker_task *task, struct spf_record *rec)
rec->cur_elt = rec->elts[rec->elt_num];
if (rec->cur_elt == NULL) {
- return TRUE;
+ return FALSE;
}
else {
/* Check spf mech */
@@ -515,14 +515,14 @@ parse_spf_record (struct worker_task *task, struct spf_record *rec)
switch (*begin) {
case 'a':
/* all or a */
- if (strncmp (begin, SPF_A, sizeof (SPF_A) - 1) == 0) {
- begin += sizeof (SPF_A) - 1;
- res = parse_spf_a (task, begin, rec, new);
- }
- else if (strncmp (begin, SPF_ALL, sizeof (SPF_ALL) - 1) == 0) {
+ if (strncmp (begin, SPF_ALL, sizeof (SPF_ALL) - 1) == 0) {
begin += sizeof (SPF_ALL) - 1;
res = parse_spf_all (task, begin, rec, new);
}
+ else if (strncmp (begin, SPF_A, sizeof (SPF_A) - 1) == 0) {
+ begin += sizeof (SPF_A) - 1;
+ res = parse_spf_a (task, begin, rec, new);
+ }
else {
msg_info ("parse_spf_record: bad spf command: %s", begin);
}