]> source.dussan.org Git - rspamd.git/commitdiff
Handle views in ucl.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 14 Nov 2013 16:12:57 +0000 (16:12 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 14 Nov 2013 16:12:57 +0000 (16:12 +0000)
src/cfg_file.h
src/cfg_rcl.c
src/cfg_utils.c
src/expressions.c
src/expressions.h
src/view.c
src/view.h

index 9dec61bc3c7418f061abc7fa76d1fadb9648b9c3..b4cc4ded14b2bee977289808800160f4eadd027f 100644 (file)
@@ -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
index 557c532e88162bc5bdbb2f15ab07e881fc367f29..633dac99cdedadc81e04272bd15ba2f86f7edecb 100644 (file)
@@ -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;
 }
index dd6b00dcd92e3c148292b6ff98b15fea05b866b2..711c045ab6d53a1e7c498f2cc720e37b9fddd1bd 100644 (file)
@@ -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;
index c8247e40d646cb1a5e43a4453379242b89241c70..df98b5a509a5c20438187bebdc21139e06d1adc9 100644 (file)
@@ -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;
index 1ec3106c0011ffd85e7e598438269764fe2e0e0e..da55c250cd66b1ec04b4f86adec8a3ab03702484 100644 (file)
@@ -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")
index a59f3eb0b1c0578ac59e7f926af9bdbd0fd97fb4..2743e6a363666e021dde2baa6300a8da78997c66 100644 (file)
@@ -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;
index f36f2e1b45cfd3648751af4dbb43a89214fd275c..89de824b3695663752403b9d1108c1929000e001 100644 (file)
@@ -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