/*
* 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
#include "cfg_file.h"
#include "lua/lua_common.h"
#include "expressions.h"
+#include "view.h"
#include "classifiers/classifiers.h"
#include "tokenizers/tokenizers.h"
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
* 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;
}
}
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;
* 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;
/* 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;
}
}
}
}
- *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) {
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;
* @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")
}
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;
}
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;
}
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;
}
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;
}
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;
* @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);
/**
* @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
* @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
* @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
* @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