aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lewis <nerf@judo.za.org>2016-09-19 16:56:16 +0200
committerAndrew Lewis <nerf@judo.za.org>2016-09-19 20:59:25 +0200
commitb0e378af1d574d2745e676acdb2cf180a7338886 (patch)
tree37ece6ccf1d806c8f52cba7895e594c5f6153c6d
parent4a09a0c772b6f73dda7c44d637771fd2596f1acc (diff)
downloadrspamd-b0e378af1d574d2745e676acdb2cf180a7338886.tar.gz
rspamd-b0e378af1d574d2745e676acdb2cf180a7338886.zip
[Feature] Add R_DKIM_PERMFAIL symbol
-rw-r--r--conf/composites.conf5
-rw-r--r--conf/metrics.conf1
-rw-r--r--src/libserver/dkim.c9
-rw-r--r--src/libserver/dkim.h3
-rw-r--r--src/plugins/dkim_check.c106
5 files changed, 79 insertions, 45 deletions
diff --git a/conf/composites.conf b/conf/composites.conf
index b64201494..40b495918 100644
--- a/conf/composites.conf
+++ b/conf/composites.conf
@@ -47,6 +47,11 @@ composite "AUTH_NA" {
score = 1.0;
policy = "remove_weight";
}
+composite {
+ name = "DKIM_MIXED";
+ expression = "-R_DKIM_ALLOW & (R_DKIM_DNSFAIL | R_DKIM_PERMFAIL | R_DKIM_REJECT)"
+ policy = "remove_weight";
+}
.include(try=true; priority=1; duplicate=merge) "$LOCAL_CONFDIR/local.d/composites.conf"
.include(try=true; priority=10) "$LOCAL_CONFDIR/override.d/composites.conf"
diff --git a/conf/metrics.conf b/conf/metrics.conf
index 7ece1c542..8d228a5ba 100644
--- a/conf/metrics.conf
+++ b/conf/metrics.conf
@@ -327,6 +327,7 @@ metric {
symbol "R_DKIM_REJECT" {
weight = 1.0;
description = "DKIM verification failed";
+ one_shot = true;
}
symbol "R_DKIM_TEMPFAIL" {
weight = 0.0;
diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c
index 3c4d7ed36..33ac2cb96 100644
--- a/src/libserver/dkim.c
+++ b/src/libserver/dkim.c
@@ -1111,9 +1111,16 @@ rspamd_dkim_dns_cb (struct rdns_reply *reply, gpointer arg)
gsize keylen = 0;
if (reply->code != RDNS_RC_NOERROR) {
+ gint err_code = DKIM_SIGERROR_NOKEY;
+ if (reply->code == RDNS_RC_NOREC) {
+ err_code = DKIM_SIGERROR_NOREC;
+ }
+ else if (reply->code == RDNS_RC_NXDOMAIN) {
+ err_code = DKIM_SIGERROR_NOREC;
+ }
g_set_error (&err,
DKIM_ERROR,
- DKIM_SIGERROR_NOKEY,
+ err_code,
"dns request to %s failed: %s",
cbdata->ctx->dns_key,
rdns_strerror (reply->code));
diff --git a/src/libserver/dkim.h b/src/libserver/dkim.h
index 35f298807..b2ff151ad 100644
--- a/src/libserver/dkim.h
+++ b/src/libserver/dkim.h
@@ -36,7 +36,7 @@
#define DKIM_SIGERROR_EXPIRED 3 /* signature expired */
#define DKIM_SIGERROR_FUTURE 4 /* signature in the future */
#define DKIM_SIGERROR_TIMESTAMPS 5 /* x= < t= */
-#define DKIM_SIGERROR_UNUSED 6 /* OBSOLETE */
+#define DKIM_SIGERROR_NOREC 6 /* No record */
#define DKIM_SIGERROR_INVALID_HC 7 /* c= invalid (header) */
#define DKIM_SIGERROR_INVALID_BC 8 /* c= invalid (body) */
#define DKIM_SIGERROR_MISSING_A 9 /* a= missing */
@@ -83,6 +83,7 @@
#define DKIM_TRYAGAIN 2 /* try again later */
#define DKIM_NOTFOUND 3 /* requested record not found */
#define DKIM_RECORD_ERROR 4 /* error requesting record */
+#define DKIM_PERM_ERROR 5 /* permanent error */
#define DKIM_CANON_SIMPLE 0 /* as specified in DKIM spec */
#define DKIM_CANON_RELAXED 1 /* as specified in DKIM spec */
diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c
index 58ae6486f..9911a8291 100644
--- a/src/plugins/dkim_check.c
+++ b/src/plugins/dkim_check.c
@@ -20,6 +20,7 @@
* - symbol_allow (string): symbol to insert in case of allow (default: 'R_DKIM_ALLOW')
* - symbol_reject (string): symbol to insert (default: 'R_DKIM_REJECT')
* - symbol_tempfail (string): symbol to insert in case of temporary fail (default: 'R_DKIM_TEMPFAIL')
+ * - symbol_permfail (string): symbol to insert in case of permanent failure (default: 'R_DKIM_PERMFAIL')
* - symbol_na (string): symbol to insert in case of no signing (default: 'R_DKIM_NA')
* - whitelist (map): map of whitelisted networks
* - domains (map): map of domains to check
@@ -42,6 +43,7 @@
#define DEFAULT_SYMBOL_TEMPFAIL "R_DKIM_TEMPFAIL"
#define DEFAULT_SYMBOL_ALLOW "R_DKIM_ALLOW"
#define DEFAULT_SYMBOL_NA "R_DKIM_NA"
+#define DEFAULT_SYMBOL_PERMFAIL "R_DKIM_PERMFAIL"
#define DEFAULT_CACHE_SIZE 2048
#define DEFAULT_CACHE_MAXAGE 86400
#define DEFAULT_TIME_JITTER 60
@@ -53,6 +55,7 @@ struct dkim_ctx {
const gchar *symbol_tempfail;
const gchar *symbol_allow;
const gchar *symbol_na;
+ const gchar *symbol_permfail;
rspamd_mempool_t *dkim_pool;
radix_compressed_t *whitelist_ip;
@@ -177,6 +180,15 @@ dkim_module_init (struct rspamd_config *cfg, struct module_ctx **ctx)
0);
rspamd_rcl_add_doc_by_path (cfg,
"dkim",
+ "Symbol that is added if permanent failure encountered",
+ "symbol_permfail",
+ UCL_STRING,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ rspamd_rcl_add_doc_by_path (cfg,
+ "dkim",
"Size of DKIM keys cache",
"dkim_cache_size",
UCL_INT,
@@ -304,6 +316,13 @@ dkim_module_config (struct rspamd_config *cfg)
dkim_module_ctx->symbol_na = DEFAULT_SYMBOL_NA;
}
if ((value =
+ rspamd_config_get_module_opt (cfg, "dkim", "symbol_permfail")) != NULL) {
+ dkim_module_ctx->symbol_permfail = ucl_obj_tostring (value);
+ }
+ else {
+ dkim_module_ctx->symbol_permfail = DEFAULT_SYMBOL_PERMFAIL;
+ }
+ if ((value =
rspamd_config_get_module_opt (cfg, "dkim",
"dkim_cache_size")) != NULL) {
cache_size = ucl_obj_toint (value);
@@ -402,6 +421,12 @@ dkim_module_config (struct rspamd_config *cfg)
SYMBOL_TYPE_VIRTUAL|SYMBOL_TYPE_FINE,
cb_id);
rspamd_symbols_cache_add_symbol (cfg->cache,
+ dkim_module_ctx->symbol_permfail,
+ 0,
+ NULL, NULL,
+ SYMBOL_TYPE_VIRTUAL|SYMBOL_TYPE_FINE,
+ cb_id);
+ rspamd_symbols_cache_add_symbol (cfg->cache,
dkim_module_ctx->symbol_tempfail,
0,
NULL, NULL,
@@ -533,9 +558,9 @@ dkim_module_parse_strict (const gchar *value, gint *allow, gint *deny)
static void
dkim_module_check (struct dkim_check_result *res)
{
- gboolean all_done = TRUE, got_allow = FALSE;
+ gboolean all_done = TRUE;
const gchar *strict_value;
- struct dkim_check_result *first, *cur, *sel = NULL;
+ struct dkim_check_result *first, *cur = NULL;
first = res->first;
@@ -560,8 +585,13 @@ dkim_module_check (struct dkim_check_result *res)
}
}
}
+ }
- if (cur->res == -1 || cur->key == NULL) {
+ DL_FOREACH (first, cur) {
+ if (cur->ctx == NULL) {
+ continue;
+ }
+ if (cur->res == -1) {
/* Still need a key */
all_done = FALSE;
}
@@ -569,51 +599,36 @@ dkim_module_check (struct dkim_check_result *res)
if (all_done) {
DL_FOREACH (first, cur) {
+ const gchar *symbol = NULL;
+ GList *messages = NULL;
+ int symbol_weight = 1;
if (cur->ctx == NULL) {
continue;
}
-
- if (cur->res == DKIM_CONTINUE) {
- rspamd_task_insert_result (cur->task,
- dkim_module_ctx->symbol_allow,
- cur->mult_allow * 1.0,
- g_list_prepend (NULL,
- rspamd_mempool_strdup (cur->task->task_pool,
- rspamd_dkim_get_domain (cur->ctx))));
- got_allow = TRUE;
- sel = NULL;
+ if (cur->res == DKIM_REJECT) {
+ symbol = dkim_module_ctx->symbol_reject;
+ symbol_weight = cur->mult_deny * 1.0;
}
- else if (!got_allow) {
- if (sel == NULL) {
- sel = cur;
- }
- else if (sel->res == DKIM_TRYAGAIN && cur->res != DKIM_TRYAGAIN) {
- sel = cur;
- }
+ else if (cur->res == DKIM_CONTINUE) {
+ symbol = dkim_module_ctx->symbol_allow;
+ symbol_weight = cur->mult_allow * 1.0;
+ }
+ else if (cur->res == DKIM_PERM_ERROR) {
+ symbol = dkim_module_ctx->symbol_permfail;
+ }
+ else if (cur->res == DKIM_TRYAGAIN) {
+ symbol = dkim_module_ctx->symbol_tempfail;
+ }
+ if (symbol != NULL) {
+ messages = g_list_prepend (messages,
+ rspamd_mempool_strdup (cur->task->task_pool,
+ rspamd_dkim_get_domain (cur->ctx)));
+ rspamd_task_insert_result (cur->task,
+ symbol,
+ 1.0,
+ messages);
}
}
- }
-
- if (sel != NULL) {
- if (sel->res == DKIM_REJECT) {
- rspamd_task_insert_result (sel->task,
- dkim_module_ctx->symbol_reject,
- sel->mult_deny * 1.0,
- g_list_prepend (NULL,
- rspamd_mempool_strdup (sel->task->task_pool,
- rspamd_dkim_get_domain (sel->ctx))));
- }
- else {
- rspamd_task_insert_result (sel->task,
- dkim_module_ctx->symbol_tempfail,
- 1.0,
- g_list_prepend (NULL,
- rspamd_mempool_strdup (sel->task->task_pool,
- rspamd_dkim_get_domain (sel->ctx))));
- }
- }
-
- if (all_done) {
rspamd_session_watcher_pop (res->task->s, res->w);
}
}
@@ -650,7 +665,12 @@ dkim_module_key_handler (rspamd_dkim_key_t *key,
rspamd_dkim_get_dns_key (ctx), err);
if (err != NULL) {
- res->res = DKIM_TRYAGAIN;
+ if (err->code == DKIM_SIGERROR_NOKEY) {
+ res->res = DKIM_TRYAGAIN;
+ }
+ else {
+ res->res = DKIM_PERM_ERROR;
+ }
}
}