diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-08-01 17:05:21 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-08-01 17:05:21 +0100 |
commit | 8ba42e555bade7b69676bff1f78ee37c8ee8a371 (patch) | |
tree | 2e5cb484cfe6fc84723d2b98fe07e740c7505eec /src/plugins/spf.c | |
parent | c75906d95cbda6828fbfe4e282a98a3e77d50c42 (diff) | |
download | rspamd-8ba42e555bade7b69676bff1f78ee37c8ee8a371.tar.gz rspamd-8ba42e555bade7b69676bff1f78ee37c8ee8a371.zip |
[Feature] Add a special symbol for SPF DNS errors: R_SPF_DNSFAIL
Diffstat (limited to 'src/plugins/spf.c')
-rw-r--r-- | src/plugins/spf.c | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/src/plugins/spf.c b/src/plugins/spf.c index 691f50964..4af4d15bb 100644 --- a/src/plugins/spf.c +++ b/src/plugins/spf.c @@ -35,6 +35,7 @@ #define DEFAULT_SYMBOL_SOFTFAIL "R_SPF_SOFTFAIL" #define DEFAULT_SYMBOL_NEUTRAL "R_SPF_NEUTRAL" #define DEFAULT_SYMBOL_ALLOW "R_SPF_ALLOW" +#define DEFAULT_SYMBOL_DNSFAIL "R_SPF_DNSFAIL" #define DEFAULT_CACHE_SIZE 2048 #define DEFAULT_CACHE_MAXAGE 86400 @@ -44,6 +45,7 @@ struct spf_ctx { const gchar *symbol_softfail; const gchar *symbol_neutral; const gchar *symbol_allow; + const gchar *symbol_dnsfail; rspamd_mempool_t *spf_pool; radix_compressed_t *whitelist_ip; @@ -134,6 +136,15 @@ spf_module_init (struct rspamd_config *cfg, struct module_ctx **ctx) 0); rspamd_rcl_add_doc_by_path (cfg, "spf", + "Symbol that is added if SPF policy is failed due to DNS failure", + "symbol_dnsfail", + UCL_STRING, + NULL, + 0, + NULL, + 0); + rspamd_rcl_add_doc_by_path (cfg, + "spf", "Size of SPF parsed records cache", "spf_cache_size", UCL_INT, @@ -188,6 +199,13 @@ spf_module_config (struct rspamd_config *cfg) spf_module_ctx->symbol_allow = DEFAULT_SYMBOL_ALLOW; } if ((value = + rspamd_config_get_module_opt (cfg, "spf", "symbol_dnsfail")) != NULL) { + spf_module_ctx->symbol_dnsfail = ucl_obj_tostring (value); + } + else { + spf_module_ctx->symbol_dnsfail = DEFAULT_SYMBOL_DNSFAIL; + } + if ((value = rspamd_config_get_module_opt (cfg, "spf", "spf_cache_size")) != NULL) { cache_size = ucl_obj_toint (value); } @@ -223,6 +241,11 @@ spf_module_config (struct rspamd_config *cfg) NULL, NULL, SYMBOL_TYPE_VIRTUAL, cb_id); + rspamd_symbols_cache_add_symbol (cfg->cache, + spf_module_ctx->symbol_dnsfail, 0, + NULL, NULL, + SYMBOL_TYPE_VIRTUAL, + cb_id); spf_module_ctx->spf_hash = rspamd_lru_hash_new ( cache_size, @@ -250,7 +273,8 @@ spf_module_reconfig (struct rspamd_config *cfg) } static gboolean -spf_check_element (struct spf_addr *addr, struct rspamd_task *task) +spf_check_element (struct spf_resolved *rec, struct spf_addr *addr, + struct rspamd_task *task) { gboolean res = FALSE; const guint8 *s, *d; @@ -263,6 +287,11 @@ spf_check_element (struct spf_addr *addr, struct rspamd_task *task) return FALSE; } + if (addr->flags & RSPAMD_SPF_FLAG_TEMPFAIL) { + /* Ignore failed addresses */ + return FALSE; + } + af = rspamd_inet_address_get_af (task->from_addr); /* Basic comparing algorithm */ if (((addr->flags & RSPAMD_SPF_FLAG_IPV6) && af == AF_INET6) || @@ -311,14 +340,32 @@ spf_check_element (struct spf_addr *addr, struct rspamd_task *task) if (res) { spf_result = rspamd_mempool_strdup (task->task_pool, addr->spf_string); opts = g_list_prepend (opts, spf_result); + switch (addr->mech) { case SPF_FAIL: spf_symbol = spf_module_ctx->symbol_fail; spf_message = "(SPF): spf fail"; + if (addr->flags & RSPAMD_SPF_FLAG_ANY) { + if (rec->failed) { + msg_info_task ("do not apply SPF failed policy, as we have " + "some addresses unresolved"); + spf_symbol = spf_module_ctx->symbol_dnsfail; + spf_message = "(SPF): spf DNS fail"; + } + } break; case SPF_SOFT_FAIL: spf_symbol = spf_module_ctx->symbol_softfail; spf_message = "(SPF): spf softfail"; + + if (addr->flags & RSPAMD_SPF_FLAG_ANY) { + if (rec->failed) { + msg_info_task ("do not apply SPF failed policy, as we have " + "some addresses unresolved"); + spf_symbol = spf_module_ctx->symbol_dnsfail; + spf_message = "(SPF): spf DNS fail"; + } + } break; case SPF_NEUTRAL: spf_symbol = spf_module_ctx->symbol_neutral; @@ -329,6 +376,7 @@ spf_check_element (struct spf_addr *addr, struct rspamd_task *task) spf_message = "(SPF): spf allow"; break; } + rspamd_task_insert_result (task, spf_symbol, 1, @@ -346,18 +394,12 @@ spf_check_list (struct spf_resolved *rec, struct rspamd_task *task) guint i; struct spf_addr *addr; - if (!rec->failed) { - 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; - } + for (i = 0; i < rec->elts->len; i ++) { + addr = &g_array_index (rec->elts, struct spf_addr, i); + if (spf_check_element (rec, addr, task)) { + break; } } - else { - msg_info_task ("<%s>: ignore spf results due to DNS failure", - task->message_id); - } } static void |