]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Add R_DKIM_PERMFAIL symbol 936/head
authorAndrew Lewis <nerf@judo.za.org>
Mon, 19 Sep 2016 14:56:16 +0000 (16:56 +0200)
committerAndrew Lewis <nerf@judo.za.org>
Mon, 19 Sep 2016 18:59:25 +0000 (20:59 +0200)
conf/composites.conf
conf/metrics.conf
src/libserver/dkim.c
src/libserver/dkim.h
src/plugins/dkim_check.c

index b642014944bd46c6d0a6c04419bb0d0674f68357..40b4959186adcc9719bb16a3927a37e635e9f91b 100644 (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"
index 7ece1c542412d310d2c5c34e20fb1a3f3c11c601..8d228a5ba916117bdd883c9aaed1346ceb6a03a4 100644 (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;
index 3c4d7ed36e96805c36d88afffbee6d4e29a1fd94..33ac2cb966e87cfe945c416c5d47b9c775410769 100644 (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));
index 35f2988075274387b2bcf13fbda2e1d3d702de89..b2ff151ade225a6ff991a7d2e7b16b83f238a17c 100644 (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 */
index 58ae6486f85f8c8db3caab95703a0c6014a1a9ce..9911a8291e3a6486737ac1b2009adde9da3e5c29 100644 (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;
+                       }
                }
        }