From 7347509ead19b66f951194147d12c9d769a90c20 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 14 Nov 2013 16:12:57 +0000 Subject: [PATCH] Handle views in ucl. --- src/cfg_file.h | 2 +- src/cfg_rcl.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- src/cfg_utils.c | 5 ++-- src/expressions.c | 31 ++++++++++--------- src/expressions.h | 2 +- src/view.c | 10 +++---- src/view.h | 10 +++---- 7 files changed, 105 insertions(+), 31 deletions(-) diff --git a/src/cfg_file.h b/src/cfg_file.h index 9dec61bc3..b4cc4ded1 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -507,7 +507,7 @@ void unescape_quotes (gchar *line); /* * Convert comma separated string to a list of strings */ -GList* parse_comma_list (memory_pool_t *pool, gchar *line); +GList* parse_comma_list (memory_pool_t *pool, const gchar *line); /* * Return a new classifier_config structure, setting default and non-conflicting attributes diff --git a/src/cfg_rcl.c b/src/cfg_rcl.c index 557c532e8..633dac99c 100644 --- a/src/cfg_rcl.c +++ b/src/cfg_rcl.c @@ -27,6 +27,7 @@ #include "cfg_file.h" #include "lua/lua_common.h" #include "expressions.h" +#include "view.h" #include "classifiers/classifiers.h" #include "tokenizers/tokenizers.h" @@ -853,6 +854,73 @@ rspamd_rcl_composite_handler (struct config_file *cfg, ucl_object_t *obj, return TRUE; } +static gboolean +rspamd_rcl_view_handler (struct config_file *cfg, ucl_object_t *obj, + gpointer ud, struct rspamd_rcl_section *section, GError **err) +{ + ucl_object_t *val, *cur; + struct rspamd_view *view; + const gchar *view_ip, *view_client_ip, *view_symbols, + *view_rcpt, *view_from; + bool skip_check = false; + + view = init_view (cfg, cfg->cfg_pool); + + val = ucl_object_find_key (obj, "ip"); + LL_FOREACH (val, cur) { + if (cur != NULL && ucl_object_tostring_safe (cur, &view_ip)) { + if (!add_view_ip (view, view_ip)) { + g_set_error (err, CFG_RCL_ERROR, EINVAL, "cannot parse view ip: %s", view_ip); + return FALSE; + } + } + } + val = ucl_object_find_key (obj, "client_ip"); + LL_FOREACH (val, cur) { + if (cur != NULL && ucl_object_tostring_safe (cur, &view_client_ip)) { + if (!add_view_client_ip (view, view_client_ip)) { + g_set_error (err, CFG_RCL_ERROR, EINVAL, "cannot parse view client ip: %s", view_client_ip); + return FALSE; + } + } + } + val = ucl_object_find_key (obj, "symbols"); + LL_FOREACH (val, cur) { + if (cur != NULL && ucl_object_tostring_safe (cur, &view_symbols)) { + if (!add_view_symbols (view, view_symbols)) { + g_set_error (err, CFG_RCL_ERROR, EINVAL, "cannot parse view client symbols: %s", view_symbols); + return FALSE; + } + } + } + val = ucl_object_find_key (obj, "rcpt"); + LL_FOREACH (val, cur) { + if (cur != NULL && ucl_object_tostring_safe (cur, &view_rcpt)) { + if (!add_view_rcpt (view, view_rcpt)) { + g_set_error (err, CFG_RCL_ERROR, EINVAL, "cannot parse view recipient: %s", view_rcpt); + return FALSE; + } + } + } + val = ucl_object_find_key (obj, "from"); + LL_FOREACH (val, cur) { + if (cur != NULL && ucl_object_tostring_safe (cur, &view_from)) { + if (!add_view_from (view, view_from)) { + g_set_error (err, CFG_RCL_ERROR, EINVAL, "cannot parse view from: %s", view_from); + return FALSE; + } + } + } + val = ucl_object_find_key (obj, "skip_check"); + if (val != NULL && ucl_object_toboolean_safe (val, &skip_check)) { + view->skip_check = skip_check; + } + + cfg->views = g_list_prepend (cfg->views, view); + + return TRUE; +} + /** * Fake handler to parse default options only, uses struct cfg_file as pointer * for default handlers @@ -1034,7 +1102,13 @@ rspamd_rcl_config_init (void) * Composites handler */ sub = rspamd_rcl_add_section (&new, "composite", rspamd_rcl_composite_handler, UCL_OBJECT, - FALSE, TRUE); + FALSE, TRUE); + + /** + * Views handler + */ + sub = rspamd_rcl_add_section (&new, "view", rspamd_rcl_view_handler, UCL_OBJECT, + FALSE, TRUE); return new; } diff --git a/src/cfg_utils.c b/src/cfg_utils.c index dd6b00dcd..711c045ab 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -750,10 +750,11 @@ unescape_quotes (gchar *line) } GList * -parse_comma_list (memory_pool_t * pool, gchar *line) +parse_comma_list (memory_pool_t * pool, const gchar *line) { GList *res = NULL; - gchar *c, *p, *str; + const gchar *c, *p; + gchar *str; c = line; p = c; diff --git a/src/expressions.c b/src/expressions.c index c8247e40d..df98b5a50 100644 --- a/src/expressions.c +++ b/src/expressions.c @@ -587,9 +587,10 @@ parse_expression (memory_pool_t * pool, gchar *line) * Rspamd regexp utility functions */ struct rspamd_regexp * -parse_regexp (memory_pool_t * pool, gchar *line, gboolean raw_mode) +parse_regexp (memory_pool_t * pool, const gchar *line, gboolean raw_mode) { - gchar *begin, *end, *p, *src, *start; + const gchar *begin, *end, *p, *src, *start; + gchar *dbegin, *dend; struct rspamd_regexp *result, *check; gint regexp_flags = G_REGEX_OPTIMIZE | G_REGEX_NO_AUTO_CAPTURE; GError *err = NULL; @@ -613,14 +614,11 @@ parse_regexp (memory_pool_t * pool, gchar *line, gboolean raw_mode) /* First try to find header name */ begin = strchr (line, '/'); if (begin != NULL) { - *begin = '\0'; - end = strchr (line, '='); - *begin = '/'; + end = strrchr (begin, '='); if (end) { - *end = '\0'; - result->header = memory_pool_strdup (pool, line); + result->header = memory_pool_alloc (pool, end - line + 1); + rspamd_strlcpy (result->header, line, end - line + 1); result->type = REGEXP_HEADER; - *end = '='; line = end; } } @@ -735,14 +733,17 @@ parse_regexp (memory_pool_t * pool, gchar *line, gboolean raw_mode) } } - *end = '\0'; + result->regexp_text = memory_pool_strdup (pool, start); + dbegin = result->regexp_text + (begin - start); + dend = result->regexp_text + (end - start); + *dend = '\0'; if (raw_mode) { regexp_flags |= G_REGEX_RAW; } /* Avoid multiply regexp structures for similar regexps */ - if ((check = (struct rspamd_regexp *)re_cache_check (begin, pool)) != NULL) { + if ((check = (struct rspamd_regexp *)re_cache_check (result->regexp_text, pool)) != NULL) { /* Additional check for headers */ if (result->type == REGEXP_HEADER || result->type == REGEXP_RAW_HEADER) { if (result->header && check->header) { @@ -755,25 +756,23 @@ parse_regexp (memory_pool_t * pool, gchar *line, gboolean raw_mode) return check; } } - result->regexp = g_regex_new (begin, regexp_flags, 0, &err); + result->regexp = g_regex_new (dbegin, regexp_flags, 0, &err); if ((regexp_flags & G_REGEX_RAW) != 0) { result->raw_regexp = result->regexp; } else { - result->raw_regexp = g_regex_new (begin, regexp_flags | G_REGEX_RAW, 0, &err); + result->raw_regexp = g_regex_new (dbegin, regexp_flags | G_REGEX_RAW, 0, &err); memory_pool_add_destructor (pool, (pool_destruct_func) g_regex_unref, (void *)result->raw_regexp); } - *end = '/'; - result->regexp_text = memory_pool_strdup (pool, start); memory_pool_add_destructor (pool, (pool_destruct_func) g_regex_unref, (void *)result->regexp); + *dend = '/'; + if (result->regexp == NULL || err != NULL) { - *end = '/'; msg_warn ("could not read regexp: %s while reading regexp %s", err->message, src); return NULL; } - if (result->raw_regexp == NULL || err != NULL) { msg_warn ("could not read raw regexp: %s while reading regexp %s", err->message, src); return NULL; diff --git a/src/expressions.h b/src/expressions.h index 1ec3106c0..da55c250c 100644 --- a/src/expressions.h +++ b/src/expressions.h @@ -59,7 +59,7 @@ typedef gboolean (*rspamd_internal_func_t)(struct worker_task *, GList *args, vo * @param line incoming line * @return regexp structure or NULL in case of error */ -struct rspamd_regexp* parse_regexp (memory_pool_t *pool, gchar *line, gboolean raw_mode); +struct rspamd_regexp* parse_regexp (memory_pool_t *pool, const gchar *line, gboolean raw_mode); /** * Parse composites line to composites structure (eg. "SYMBOL1&SYMBOL2|!SYMBOL3") diff --git a/src/view.c b/src/view.c index a59f3eb0b..2743e6a36 100644 --- a/src/view.c +++ b/src/view.c @@ -51,7 +51,7 @@ init_view (struct config_file *cfg, memory_pool_t * pool) } gboolean -add_view_from (struct rspamd_view * view, gchar *line) +add_view_from (struct rspamd_view * view, const gchar *line) { struct rspamd_regexp *re = NULL; @@ -67,7 +67,7 @@ add_view_from (struct rspamd_view * view, gchar *line) } gboolean -add_view_rcpt (struct rspamd_view * view, gchar *line) +add_view_rcpt (struct rspamd_view * view, const gchar *line) { struct rspamd_regexp *re = NULL; @@ -83,7 +83,7 @@ add_view_rcpt (struct rspamd_view * view, gchar *line) } gboolean -add_view_symbols (struct rspamd_view * view, gchar *line) +add_view_symbols (struct rspamd_view * view, const gchar *line) { struct rspamd_regexp *re = NULL; GList *symbols; @@ -110,7 +110,7 @@ add_view_symbols (struct rspamd_view * view, gchar *line) } gboolean -add_view_ip (struct rspamd_view * view, gchar *line) +add_view_ip (struct rspamd_view * view, const gchar *line) { if (add_map (view->cfg, line, "IP view", read_radix_list, fin_radix_list, (void **)&view->ip_tree)) { return TRUE; @@ -120,7 +120,7 @@ add_view_ip (struct rspamd_view * view, gchar *line) } gboolean -add_view_client_ip (struct rspamd_view * view, gchar *line) +add_view_client_ip (struct rspamd_view * view, const gchar *line) { if (add_map (view->cfg, line, "Client IP view", read_radix_list, fin_radix_list, (void **)&view->client_ip_tree)) { return TRUE; diff --git a/src/view.h b/src/view.h index f36f2e1b4..89de824b3 100644 --- a/src/view.h +++ b/src/view.h @@ -40,7 +40,7 @@ struct rspamd_view* init_view (struct config_file *cfg, memory_pool_t *pool); * @param line from line for this view * @return */ -gboolean add_view_from (struct rspamd_view *view, gchar *line); +gboolean add_view_from (struct rspamd_view *view, const gchar *line); /** @@ -49,7 +49,7 @@ gboolean add_view_from (struct rspamd_view *view, gchar *line); * @param line recipient description * @return */ -gboolean add_view_rcpt (struct rspamd_view *view, gchar *line); +gboolean add_view_rcpt (struct rspamd_view *view, const gchar *line); /** * Add ip option for this view @@ -57,7 +57,7 @@ gboolean add_view_rcpt (struct rspamd_view *view, gchar *line); * @param line ip description * @return */ -gboolean add_view_ip (struct rspamd_view *view, gchar *line); +gboolean add_view_ip (struct rspamd_view *view, const gchar *line); /** * Add client ip option for this view @@ -65,7 +65,7 @@ gboolean add_view_ip (struct rspamd_view *view, gchar *line); * @param line ip description * @return */ -gboolean add_view_client_ip (struct rspamd_view *view, gchar *line); +gboolean add_view_client_ip (struct rspamd_view *view, const gchar *line); /** * Add symbols option for this view @@ -73,7 +73,7 @@ gboolean add_view_client_ip (struct rspamd_view *view, gchar *line); * @param line symbols description * @return */ -gboolean add_view_symbols (struct rspamd_view *view, gchar *line); +gboolean add_view_symbols (struct rspamd_view *view, const gchar *line); /** * Check view for this task for specified symbol -- 2.39.5