]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Allow multiple groups for symbols
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 15 May 2018 13:21:41 +0000 (14:21 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 15 May 2018 13:21:41 +0000 (14:21 +0100)
src/libmime/filter.c
src/libserver/cfg_file.h
src/libserver/cfg_rcl.c
src/libserver/cfg_utils.c
src/lua/lua_config.c
src/lua/lua_task.c
src/plugins/dkim_check.c
src/plugins/regexp.c

index f7d4e3410537e06150a93d35a214be57f18eda04..c9367514f44c95513bfe4c5fce552be9f11c3d12 100644 (file)
@@ -92,6 +92,7 @@ insert_metric_result (struct rspamd_task *task,
        struct rspamd_symbols_group *gr = NULL;
        const ucl_object_t *mobj, *sobj;
        gint max_shots;
+       guint i;
        gboolean single = !!(flags & RSPAMD_SYMBOL_INSERT_SINGLE);
 
        metric_res = rspamd_create_metric_result (task);
@@ -113,9 +114,8 @@ insert_metric_result (struct rspamd_task *task,
        }
        else {
                final_score = (*sdef->weight_ptr) * weight;
-               gr = sdef->gr;
 
-               if (gr != NULL) {
+               PTR_ARRAY_FOREACH (sdef->groups, i, gr) {
                        gr_score = g_hash_table_lookup (metric_res->sym_groups, gr);
 
                        if (gr_score == NULL) {
index 7a6cc1c8a5a9e353139afb6138c8dcbc9c5aca42..5a846a1f52fb879ea96f575802373bba977e866c 100644 (file)
@@ -123,8 +123,8 @@ struct rspamd_symbol {
        gdouble *weight_ptr;
        gdouble score;
        guint priority;
-       struct rspamd_symbols_group *gr;
-       GList *groups;
+       struct rspamd_symbols_group *gr; /* Main group */
+       GPtrArray *groups; /* Other groups */
        guint flags;
        gint nshots;
 };
@@ -585,10 +585,24 @@ gboolean rspamd_init_filters (struct rspamd_config *cfg, bool reconfig);
  * @return TRUE if symbol has been inserted or FALSE if symbol already exists with higher priority
  */
 gboolean rspamd_config_add_symbol (struct rspamd_config *cfg,
-               const gchar *symbol, gdouble score, const gchar *description,
-               const gchar *group, guint flags,
-               guint priority,
-               gint nshots);
+                                                                  const gchar *symbol,
+                                                                  gdouble score,
+                                                                  const gchar *description,
+                                                                  const gchar *group,
+                                                                  guint flags,
+                                                                  guint priority,
+                                                                  gint nshots);
+
+/**
+ * Adds new group for a symbol
+ * @param cfg
+ * @param symbol
+ * @param group
+ * @return
+ */
+gboolean rspamd_config_add_symbol_group (struct rspamd_config *cfg,
+                                                                                const gchar *symbol,
+                                                                                const gchar *group);
 
 /**
  * Sets action score for a specified metric with the specified priority
index 47e730af0bb53e68d86eae5836b7006891c39fec..d4aa5314b988e5e68eaa6b8178c0df9e4ddc3169 100644 (file)
@@ -438,6 +438,22 @@ rspamd_rcl_symbol_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
                                description, NULL, flags, priority, nshots);
        }
 
+       elt = ucl_object_lookup (obj, "groups");
+
+       if (elt) {
+               ucl_object_iter_t gr_it;
+               const ucl_object_t *cur_gr;
+
+               gr_it = ucl_object_iterate_new (elt);
+
+               while ((cur_gr = ucl_object_iterate_safe (gr_it, true)) != NULL) {
+                       rspamd_config_add_symbol_group (cfg, key,
+                                       ucl_object_tostring (cur_gr));
+               }
+
+               ucl_object_iterate_free (gr_it);
+       }
+
        return TRUE;
 }
 
@@ -1423,7 +1439,7 @@ rspamd_rcl_composite_handler (rspamd_mempool_t *pool,
        struct rspamd_rcl_section *section,
        GError **err)
 {
-       const ucl_object_t *val;
+       const ucl_object_t *val, *elt;
        struct rspamd_expression *expr;
        struct rspamd_config *cfg = ud;
        struct rspamd_composite *composite;
@@ -1500,6 +1516,22 @@ rspamd_rcl_composite_handler (rspamd_mempool_t *pool,
                rspamd_config_add_symbol (cfg, composite_name, score,
                                description, group, FALSE, FALSE,
                                1);
+
+               elt = ucl_object_lookup (obj, "groups");
+
+               if (elt) {
+                       ucl_object_iter_t gr_it;
+                       const ucl_object_t *cur_gr;
+
+                       gr_it = ucl_object_iterate_new (elt);
+
+                       while ((cur_gr = ucl_object_iterate_safe (gr_it, true)) != NULL) {
+                               rspamd_config_add_symbol_group (cfg, key,
+                                               ucl_object_tostring (cur_gr));
+                       }
+
+                       ucl_object_iterate_free (gr_it);
+               }
        }
 
        val = ucl_object_lookup (obj, "policy");
index ed9876b8d43a72d927eba5d386398d3547afacb4..bf63b2188aeebfcc0d66f92fadbb8599fc2873e1 100644 (file)
@@ -1470,6 +1470,9 @@ rspamd_config_new_symbol (struct rspamd_config *cfg, const gchar *symbol,
        sym_def->priority = priority;
        sym_def->flags = flags;
        sym_def->nshots = nshots;
+       sym_def->groups = g_ptr_array_sized_new (1);
+       rspamd_mempool_add_destructor (cfg->cfg_pool, rspamd_ptr_array_free_hard,
+                       sym_def->groups);
 
        if (description) {
                sym_def->description = rspamd_mempool_strdup (cfg->cfg_pool, description);
@@ -1502,30 +1505,49 @@ rspamd_config_new_symbol (struct rspamd_config *cfg, const gchar *symbol,
 
 gboolean
 rspamd_config_add_symbol (struct rspamd_config *cfg,
-               const gchar *symbol,
-               gdouble score, const gchar *description, const gchar *group,
-               guint flags, guint priority, gint nshots)
+                                                 const gchar *symbol,
+                                                 gdouble score, const gchar *description,
+                                                 const gchar *group,
+                                                 guint flags, guint priority, gint nshots)
 {
        struct rspamd_symbol *sym_def;
+       struct rspamd_symbols_group *sym_group;
+       guint i;
+
        g_assert (cfg != NULL);
        g_assert (symbol != NULL);
-       struct rspamd_symbols_group *sym_group;
 
        sym_def = g_hash_table_lookup (cfg->symbols, symbol);
 
        if (sym_def != NULL) {
-               if (sym_def->flags & RSPAMD_SYMBOL_FLAG_UNGROUPPED && group != NULL) {
-                       /* Non-empty group has a priority over non-groupped one */
-                       sym_group = g_hash_table_lookup (cfg->groups, group);
-
-                       if (sym_group == NULL) {
-                               /* Create new group */
-                               sym_group = rspamd_config_new_group (cfg, group);
+               if (group != NULL) {
+                       gboolean has_group = FALSE;
+
+                       PTR_ARRAY_FOREACH (sym_def->groups, i, sym_group) {
+                               if (g_ascii_strcasecmp (sym_group->name, group) == 0) {
+                                       /* Group is already here */
+                                       has_group = TRUE;
+                                       break;
+                               }
                        }
 
-                       sym_def->gr = sym_group;
-                       g_hash_table_insert (sym_group->symbols, sym_def->name, sym_def);
-                       sym_def->flags &= ~(RSPAMD_SYMBOL_FLAG_UNGROUPPED);
+                       if (!has_group) {
+                               /* Non-empty group has a priority over non-groupped one */
+                               sym_group = g_hash_table_lookup (cfg->groups, group);
+
+                               if (sym_group == NULL) {
+                                       /* Create new group */
+                                       sym_group = rspamd_config_new_group (cfg, group);
+                               }
+
+                               if (!sym_def->gr) {
+                                       sym_def->gr = sym_group;
+                               }
+
+                               g_hash_table_insert (sym_group->symbols, sym_def->name, sym_def);
+                               sym_def->flags &= ~(RSPAMD_SYMBOL_FLAG_UNGROUPPED);
+                               g_ptr_array_add (sym_def->groups, sym_group);
+                       }
                }
 
                if (sym_def->priority > priority) {
@@ -1592,6 +1614,57 @@ rspamd_config_add_symbol (struct rspamd_config *cfg,
        return TRUE;
 }
 
+gboolean
+rspamd_config_add_symbol_group (struct rspamd_config *cfg,
+                                                               const gchar *symbol,
+                                                               const gchar *group)
+{
+       struct rspamd_symbol *sym_def;
+       struct rspamd_symbols_group *sym_group;
+       guint i;
+
+       g_assert (cfg != NULL);
+       g_assert (symbol != NULL);
+       g_assert (group != NULL);
+
+       sym_def = g_hash_table_lookup (cfg->symbols, symbol);
+
+       if (sym_def != NULL) {
+               gboolean has_group = FALSE;
+
+               PTR_ARRAY_FOREACH (sym_def->groups, i, sym_group) {
+                       if (g_ascii_strcasecmp (sym_group->name, group) == 0) {
+                               /* Group is already here */
+                               has_group = TRUE;
+                               break;
+                       }
+               }
+
+               if (!has_group) {
+                       /* Non-empty group has a priority over non-groupped one */
+                       sym_group = g_hash_table_lookup (cfg->groups, group);
+
+                       if (sym_group == NULL) {
+                               /* Create new group */
+                               sym_group = rspamd_config_new_group (cfg, group);
+                       }
+
+                       if (!sym_def->gr) {
+                               sym_def->gr = sym_group;
+                       }
+
+                       g_hash_table_insert (sym_group->symbols, sym_def->name, sym_def);
+                       sym_def->flags &= ~(RSPAMD_SYMBOL_FLAG_UNGROUPPED);
+                       g_ptr_array_add (sym_def->groups, sym_group);
+
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+
 gboolean
 rspamd_config_is_module_enabled (struct rspamd_config *cfg,
                const gchar *module_name)
index a42f33b37ace7cda065a3a53844718b2cafa0177..6e502d6e713db570452e3867cb3b7dc66a06a8fc 100644 (file)
@@ -1641,6 +1641,23 @@ lua_config_register_symbol (lua_State * L)
                        rspamd_config_add_symbol (cfg, name,
                                        score, description, group, flags,
                                        (guint) priority, nshots);
+
+                       lua_pushstring (L, "groups");
+                       lua_gettable (L, 2);
+
+                       if (lua_istable (L, -1)) {
+                               for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) {
+                                       if (lua_isstring (L, -1)) {
+                                               rspamd_config_add_symbol_group (cfg, name,
+                                                               lua_tostring (L, -1));
+                                       }
+                                       else {
+                                               return luaL_error (L, "invalid groups element");
+                                       }
+                               }
+                       }
+
+                       lua_pop (L, 1);
                }
        }
        else {
@@ -1997,6 +2014,25 @@ lua_config_set_metric_symbol (lua_State * L)
 
                rspamd_config_add_symbol (cfg, name,
                                weight, description, group, flags, (guint) priority, nshots);
+
+
+               if (lua_type (L, 2) == LUA_TTABLE) {
+                       lua_pushstring (L, "groups");
+                       lua_gettable (L, 2);
+
+                       if (lua_istable (L, -1)) {
+                               for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) {
+                                       if (lua_isstring (L, -1)) {
+                                               rspamd_config_add_symbol_group (cfg, name,
+                                                               lua_tostring (L, -1));
+                                       } else {
+                                               return luaL_error (L, "invalid groups element");
+                                       }
+                               }
+                       }
+
+                       lua_pop (L, 1);
+               }
        }
        else {
                return luaL_error (L, "invalid arguments, rspamd_config expected");
@@ -2011,6 +2047,8 @@ lua_config_get_metric_symbol (lua_State * L)
        struct rspamd_config *cfg = lua_check_config (L, 1);
        const gchar *sym_name = luaL_checkstring (L, 2);
        struct rspamd_symbol *sym_def;
+       struct rspamd_symbols_group *sym_group;
+       guint i;
 
        if (cfg && sym_name) {
                sym_def = g_hash_table_lookup (cfg->symbols, sym_name);
@@ -2035,6 +2073,16 @@ lua_config_get_metric_symbol (lua_State * L)
                                lua_pushstring (L, sym_def->gr->name);
                                lua_settable (L, -3);
                        }
+
+                       lua_pushstring (L, "groups");
+                       lua_createtable (L, sym_def->groups->len, 0);
+
+                       PTR_ARRAY_FOREACH (sym_def->groups, i, sym_group) {
+                               lua_pushstring (L, sym_group->name);
+                               lua_rawseti (L, -2, i + 1);
+                       }
+
+                       lua_settable (L, -3);
                }
        }
        else {
@@ -2376,6 +2424,23 @@ lua_config_newindex (lua_State *L)
                                         */
                                        rspamd_config_add_symbol (cfg, name, score,
                                                        description, group, flags, 0, nshots);
+
+                                       lua_pushstring (L, "groups");
+                                       lua_gettable (L, -2);
+
+                                       if (lua_istable (L, -1)) {
+                                               for (lua_pushnil (L); lua_next (L, -2); lua_pop (L, 1)) {
+                                                       if (lua_isstring (L, -1)) {
+                                                               rspamd_config_add_symbol_group (cfg, name,
+                                                                               lua_tostring (L, -1));
+                                                       }
+                                                       else {
+                                                               return luaL_error (L, "invalid groups element");
+                                                       }
+                                               }
+                                       }
+
+                                       lua_pop (L, 1);
                                }
                                else {
                                        lua_pop (L, 1);
index 17aee10b844b33118707d570f7c2dca7ea4e7c48..3aa24e88b731f630a8d26d7fa11e6aedadd7bdae 100644 (file)
@@ -3053,6 +3053,8 @@ lua_push_symbol_result (lua_State *L,
        struct rspamd_metric_result *metric_res;
        struct rspamd_symbol_result *s = NULL;
        struct rspamd_symbol_option *opt;
+       struct rspamd_symbols_group *sym_group;
+       guint i;
        gint j = 1, e = 4;
 
        if (!symbol_result) {
@@ -3089,6 +3091,16 @@ lua_push_symbol_result (lua_State *L,
                        lua_pushstring (L, "group");
                        lua_pushstring (L, s->sym->gr->name);
                        lua_settable (L, -3);
+
+                       lua_pushstring (L, "groups");
+                       lua_createtable (L, s->sym->groups->len, 0);
+
+                       PTR_ARRAY_FOREACH (s->sym->groups, i, sym_group) {
+                               lua_pushstring (L, sym_group->name);
+                               lua_rawseti (L, -2, i + 1);
+                       }
+
+                       lua_settable (L, -3);
                }
                else {
                        lua_pushstring (L, "group");
index d666289ec17eaed902ac8e856a21d4594b115698..8f63a167d599137927ff93daa21a1991f89edc4b 100644 (file)
@@ -559,7 +559,8 @@ dkim_module_config (struct rspamd_config *cfg)
                                        rspamd_config_add_symbol (cfg,
                                                        "DKIM_TRACE", 0.0, "DKIM trace symbol",
                                                        "policies", RSPAMD_SYMBOL_FLAG_IGNORE, 1, 1);
-
+                                       rspamd_config_add_symbol_group (cfg, "DKIM_SIGN", "dkim");
+                                       rspamd_config_add_symbol_group (cfg, "DKIM_TRACE", "dkim");
                                }
                                else {
                                        msg_err_config ("lua script must return "
index 03dd21734a874a0a8633eb3a11cd543adb309057..57b8e524e7a659f2b5346451c6670e172367a336 100644 (file)
@@ -305,6 +305,22 @@ regexp_module_config (struct rspamd_config *cfg)
 
                                rspamd_config_add_symbol (cfg, cur_item->symbol,
                                                score, description, group, flags, priority, nshots);
+
+                               elt = ucl_object_lookup (value, "groups");
+
+                               if (elt) {
+                                       ucl_object_iter_t gr_it;
+                                       const ucl_object_t *cur_gr;
+
+                                       gr_it = ucl_object_iterate_new (elt);
+
+                                       while ((cur_gr = ucl_object_iterate_safe (gr_it, true)) != NULL) {
+                                               rspamd_config_add_symbol_group (cfg, cur_item->symbol,
+                                                               ucl_object_tostring (cur_gr));
+                                       }
+
+                                       ucl_object_iterate_free (gr_it);
+                               }
                        }
                }
                else {