@@ -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 |
@@ -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; | |||
} |
@@ -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; |
@@ -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; |
@@ -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") |
@@ -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; |
@@ -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 |