aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-05-15 14:21:41 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-05-15 14:21:41 +0100
commitf57c6e2c50e05aebbc9020fc9fe58b647b15b9dd (patch)
tree53f4d90ce06efaabf776586bdd8e038744b33a5f
parent1d2cb297a1cd882e6b0ea75ca5c081f844742c18 (diff)
downloadrspamd-f57c6e2c50e05aebbc9020fc9fe58b647b15b9dd.tar.gz
rspamd-f57c6e2c50e05aebbc9020fc9fe58b647b15b9dd.zip
[Feature] Allow multiple groups for symbols
-rw-r--r--src/libmime/filter.c4
-rw-r--r--src/libserver/cfg_file.h26
-rw-r--r--src/libserver/cfg_rcl.c34
-rw-r--r--src/libserver/cfg_utils.c101
-rw-r--r--src/lua/lua_config.c65
-rw-r--r--src/lua/lua_task.c12
-rw-r--r--src/plugins/dkim_check.c3
-rw-r--r--src/plugins/regexp.c16
8 files changed, 237 insertions, 24 deletions
diff --git a/src/libmime/filter.c b/src/libmime/filter.c
index f7d4e3410..c9367514f 100644
--- a/src/libmime/filter.c
+++ b/src/libmime/filter.c
@@ -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) {
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index 7a6cc1c8a..5a846a1f5 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -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
diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c
index 47e730af0..d4aa5314b 100644
--- a/src/libserver/cfg_rcl.c
+++ b/src/libserver/cfg_rcl.c
@@ -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");
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index ed9876b8d..bf63b2188 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -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) {
@@ -1593,6 +1615,57 @@ rspamd_config_add_symbol (struct rspamd_config *cfg,
}
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)
{
diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c
index a42f33b37..6e502d6e7 100644
--- a/src/lua/lua_config.c
+++ b/src/lua/lua_config.c
@@ -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);
diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c
index 17aee10b8..3aa24e88b 100644
--- a/src/lua/lua_task.c
+++ b/src/lua/lua_task.c
@@ -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");
diff --git a/src/plugins/dkim_check.c b/src/plugins/dkim_check.c
index d666289ec..8f63a167d 100644
--- a/src/plugins/dkim_check.c
+++ b/src/plugins/dkim_check.c
@@ -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 "
diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c
index 03dd21734..57b8e524e 100644
--- a/src/plugins/regexp.c
+++ b/src/plugins/regexp.c
@@ -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 {