Browse Source

[Feature] Add R_DKIM_PERMFAIL symbol

tags/1.4.0
Andrew Lewis 7 years ago
parent
commit
b0e378af1d
5 changed files with 79 additions and 45 deletions
  1. 5
    0
      conf/composites.conf
  2. 1
    0
      conf/metrics.conf
  3. 8
    1
      src/libserver/dkim.c
  4. 2
    1
      src/libserver/dkim.h
  5. 63
    43
      src/plugins/dkim_check.c

+ 5
- 0
conf/composites.conf View File

@@ -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"

+ 1
- 0
conf/metrics.conf View File

@@ -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;

+ 8
- 1
src/libserver/dkim.c View File

@@ -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));

+ 2
- 1
src/libserver/dkim.h View File

@@ -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 */

+ 63
- 43
src/plugins/dkim_check.c View File

@@ -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;
@@ -175,6 +178,15 @@ dkim_module_init (struct rspamd_config *cfg, struct module_ctx **ctx)
0,
NULL,
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",
@@ -303,6 +315,13 @@ dkim_module_config (struct rspamd_config *cfg)
else {
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) {
@@ -401,6 +420,12 @@ dkim_module_config (struct rspamd_config *cfg)
NULL, NULL,
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,
@@ -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;
}
}
}


Loading…
Cancel
Save