@@ -36,8 +36,7 @@ SET(LIBRSPAMDSERVERSRC | |||
statfile_sync.c | |||
symbols_cache.c | |||
task.c | |||
url.c | |||
view.c) | |||
url.c) | |||
# Librspamd mime | |||
SET(LIBRSPAMDMIMESRC |
@@ -337,7 +337,6 @@ struct config_file { | |||
GList *statfiles; /**< list of all statfiles in config file order */ | |||
GHashTable *classifiers_symbols; /**< hashtable indexed by symbol name of classifiers */ | |||
GHashTable* cfg_params; /**< all cfg params indexed by its name in this structure */ | |||
GList *views; /**< views */ | |||
GList *pre_filters; /**< list of pre-processing lua filters */ | |||
GList *post_filters; /**< list of post-processing lua filters */ | |||
gchar *dynamic_conf; /**< path to dynamic configuration */ |
@@ -27,7 +27,6 @@ | |||
#include "cfg_file.h" | |||
#include "lua/lua_common.h" | |||
#include "expressions.h" | |||
#include "view.h" | |||
#include "classifiers/classifiers.h" | |||
#include "tokenizers/tokenizers.h" | |||
@@ -903,73 +902,6 @@ rspamd_rcl_composite_handler (struct config_file *cfg, const ucl_object_t *obj, | |||
return TRUE; | |||
} | |||
static gboolean | |||
rspamd_rcl_view_handler (struct config_file *cfg, const ucl_object_t *obj, | |||
gpointer ud, struct rspamd_rcl_section *section, GError **err) | |||
{ | |||
const 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 | |||
@@ -1155,12 +1087,6 @@ rspamd_rcl_config_init (void) | |||
sub = rspamd_rcl_add_section (&new, "composite", rspamd_rcl_composite_handler, UCL_OBJECT, | |||
FALSE, TRUE); | |||
/** | |||
* Views handler | |||
*/ | |||
sub = rspamd_rcl_add_section (&new, "view", rspamd_rcl_view_handler, UCL_OBJECT, | |||
FALSE, TRUE); | |||
return new; | |||
} | |||
@@ -31,7 +31,6 @@ | |||
#include "util.h" | |||
#include "expressions.h" | |||
#include "settings.h" | |||
#include "view.h" | |||
#include "binlog.h" | |||
#include "diff.h" | |||
#include "classifiers/classifiers.h" | |||
@@ -266,14 +265,6 @@ process_filters (struct rspamd_task *task) | |||
struct metric *metric; | |||
gpointer item = NULL; | |||
/* Check want spam setting */ | |||
if (check_skip (task->cfg->views, task) || check_want_spam (task)) { | |||
task->is_skipped = TRUE; | |||
task->state = WRITE_REPLY; | |||
msg_info ("disable check for message id <%s>, user wants spam", task->message_id); | |||
return 1; | |||
} | |||
/* Process metrics symbols */ | |||
while (call_symbol_callback (task, task->cfg->cache, &item)) { | |||
/* Check reject actions */ |
@@ -70,7 +70,6 @@ struct tokenizer; | |||
struct classifier; | |||
struct classifier_config; | |||
struct mime_part; | |||
struct rspamd_view; | |||
struct rspamd_dns_resolver; | |||
struct rspamd_task; | |||
@@ -36,7 +36,6 @@ | |||
#include "message.h" | |||
#include "cfg_file.h" | |||
#include "expressions.h" | |||
#include "view.h" | |||
#define DEFAULT_SYMBOL "R_CHARSET_MIXED" | |||
#define DEFAULT_THRESHOLD 0.1 | |||
@@ -202,15 +201,13 @@ chartable_symbol_callback (struct rspamd_task *task, void *unused) | |||
GList *cur; | |||
struct mime_text_part *part; | |||
if (check_view (task->cfg->views, chartable_module_ctx->symbol, task)) { | |||
cur = g_list_first (task->text_parts); | |||
while (cur) { | |||
part = cur->data; | |||
if (!part->is_empty && check_part (part, task->cfg->raw_mode)) { | |||
insert_result (task, chartable_module_ctx->symbol, 1, NULL); | |||
} | |||
cur = g_list_next (cur); | |||
cur = g_list_first (task->text_parts); | |||
while (cur) { | |||
part = cur->data; | |||
if (!part->is_empty && check_part (part, task->cfg->raw_mode)) { | |||
insert_result (task, chartable_module_ctx->symbol, 1, NULL); | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
} |
@@ -43,7 +43,6 @@ | |||
#include "cfg_file.h" | |||
#include "expressions.h" | |||
#include "util.h" | |||
#include "view.h" | |||
#include "map.h" | |||
#include "dkim.h" | |||
#include "hash.h" | |||
@@ -315,12 +314,9 @@ dkim_symbol_callback (struct rspamd_task *task, void *unused) | |||
if (hlist != NULL) { | |||
/* Check whitelist */ | |||
msg_debug ("dkim signature found"); | |||
#ifdef HAVE_INET_PTON | |||
if (!task->from_addr.has_addr || | |||
radix32tree_find (dkim_module_ctx->whitelist_ip, ntohl (task->from_addr.d.in4.s_addr)) == RADIX_NO_VALUE) { | |||
#else | |||
if (radix32tree_find (dkim_module_ctx->whitelist_ip, ntohl (task->from_addr.s_addr)) == RADIX_NO_VALUE) { | |||
#endif | |||
if (task->from_addr.af == AF_INET || | |||
radix32tree_find (dkim_module_ctx->whitelist_ip, | |||
ntohl (task->from_addr.addr.s4.sin_addr.s_addr)) == RADIX_NO_VALUE) { | |||
/* Parse signature */ | |||
msg_debug ("create dkim signature"); | |||
/* |
@@ -45,7 +45,6 @@ | |||
#include "cfg_file.h" | |||
#include "expressions.h" | |||
#include "util.h" | |||
#include "view.h" | |||
#include "map.h" | |||
#include "images.h" | |||
#include "fuzzy_storage.h" | |||
@@ -823,8 +822,9 @@ fuzzy_symbol_callback (struct rspamd_task *task, void *unused) | |||
/* Check whitelist */ | |||
#ifdef HAVE_INET_PTON | |||
if (fuzzy_module_ctx->whitelist && !task->from_addr.ipv6 && task->from_addr.d.in4.s_addr != INADDR_NONE) { | |||
if (radix32tree_find (fuzzy_module_ctx->whitelist, ntohl ((guint32) task->from_addr.d.in4.s_addr)) != RADIX_NO_VALUE) { | |||
if (fuzzy_module_ctx->whitelist && task->from_addr.af == AF_INET) { | |||
if (radix32tree_find (fuzzy_module_ctx->whitelist, | |||
ntohl (task->from_addr.addr.s4.sin_addr.s_addr)) != RADIX_NO_VALUE) { | |||
msg_info ("<%s>, address %s is whitelisted, skip fuzzy check", | |||
task->message_id, inet_ntoa (task->from_addr.d.in4)); | |||
return; |
@@ -34,7 +34,6 @@ | |||
#include "map.h" | |||
#include "util.h" | |||
#include "expressions.h" | |||
#include "view.h" | |||
#include "lua/lua_common.h" | |||
#include "json/jansson.h" | |||
@@ -38,7 +38,6 @@ | |||
#include "cfg_file.h" | |||
#include "expressions.h" | |||
#include "util.h" | |||
#include "view.h" | |||
#include "map.h" | |||
#include "spf.h" | |||
#include "hash.h" |
@@ -47,7 +47,6 @@ | |||
#include "cfg_file.h" | |||
#include "expressions.h" | |||
#include "util.h" | |||
#include "view.h" | |||
#include "map.h" | |||
#include "dns.h" | |||
#include "hash.h" | |||
@@ -634,31 +633,26 @@ make_surbl_requests (struct uri *url, struct rspamd_task *task, | |||
f.begin = url->host; | |||
f.len = url->hostlen; | |||
if (check_view (task->cfg->views, suffix->symbol, task)) { | |||
if ((surbl_req = format_surbl_request (task->task_pool, &f, suffix, TRUE, | |||
&err, forced, tree)) != NULL) { | |||
param = rspamd_mempool_alloc (task->task_pool, sizeof (struct dns_param)); | |||
param->url = url; | |||
param->task = task; | |||
param->suffix = suffix; | |||
param->host_resolve = rspamd_mempool_strdup (task->task_pool, surbl_req); | |||
debug_task ("send surbl dns request %s", surbl_req); | |||
if (make_dns_request (task->resolver, task->s, task->task_pool, dns_callback, | |||
(void *)param, RDNS_REQUEST_A, surbl_req)) { | |||
task->dns_requests ++; | |||
} | |||
} | |||
else if (err != NULL && err->code != WHITELIST_ERROR && err->code != DUPLICATE_ERROR) { | |||
msg_info ("cannot format url string for surbl %s, %s", struri (url), err->message); | |||
g_error_free (err); | |||
return; | |||
} | |||
else if (err != NULL) { | |||
g_error_free (err); | |||
if ((surbl_req = format_surbl_request (task->task_pool, &f, suffix, TRUE, | |||
&err, forced, tree)) != NULL) { | |||
param = rspamd_mempool_alloc (task->task_pool, sizeof (struct dns_param)); | |||
param->url = url; | |||
param->task = task; | |||
param->suffix = suffix; | |||
param->host_resolve = rspamd_mempool_strdup (task->task_pool, surbl_req); | |||
debug_task ("send surbl dns request %s", surbl_req); | |||
if (make_dns_request (task->resolver, task->s, task->task_pool, dns_callback, | |||
(void *)param, RDNS_REQUEST_A, surbl_req)) { | |||
task->dns_requests ++; | |||
} | |||
} | |||
else { | |||
debug_task ("skipping symbol that is not in view: %s", suffix->symbol); | |||
else if (err != NULL && err->code != WHITELIST_ERROR && err->code != DUPLICATE_ERROR) { | |||
msg_info ("cannot format url string for surbl %s, %s", struri (url), err->message); | |||
g_error_free (err); | |||
return; | |||
} | |||
else if (err != NULL) { | |||
g_error_free (err); | |||
} | |||
} | |||
@@ -27,7 +27,6 @@ | |||
#include "main.h" | |||
#include "message.h" | |||
#include "symbols_cache.h" | |||
#include "view.h" | |||
#include "cfg_file.h" | |||
#define WEIGHT_MULT 4.0 | |||
@@ -1003,7 +1002,7 @@ call_symbol_callback (struct rspamd_task * task, struct symbols_cache * cache, g | |||
if (!item) { | |||
return FALSE; | |||
} | |||
if (!item->is_virtual && check_view (task->cfg->views, item->s->symbol, task)) { | |||
if (!item->is_virtual) { | |||
#ifdef HAVE_CLOCK_GETTIME | |||
# ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID | |||
clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts1); |
@@ -58,8 +58,6 @@ struct custom_command { | |||
protocol_reply_func func; | |||
}; | |||
struct rspamd_view; | |||
/** | |||
* Worker task structure | |||
*/ | |||
@@ -122,9 +120,7 @@ struct rspamd_task { | |||
struct timespec ts; /**< time of connection */ | |||
#endif | |||
struct timeval tv; /**< time of connection */ | |||
struct rspamd_view *view; /**< matching view */ | |||
guint32 scan_milliseconds; /**< how much milliseconds passed */ | |||
gboolean view_checked; | |||
gboolean pass_all_filters; /**< pass task throught every rule */ | |||
gboolean no_log; /**< do not log or write this task to the history */ | |||
guint32 parser_recursion; /**< for avoiding recursion stack overflow */ |
@@ -1,393 +0,0 @@ | |||
/* | |||
* Copyright (c) 2009-2012, Vsevolod Stakhov | |||
* All rights reserved. | |||
* | |||
* Redistribution and use in source and binary forms, with or without | |||
* modification, are permitted provided that the following conditions are met: | |||
* * Redistributions of source code must retain the above copyright | |||
* notice, this list of conditions and the following disclaimer. | |||
* * Redistributions in binary form must reproduce the above copyright | |||
* notice, this list of conditions and the following disclaimer in the | |||
* documentation and/or other materials provided with the distribution. | |||
* | |||
* THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY | |||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
* DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY | |||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
*/ | |||
#include "config.h" | |||
#include "main.h" | |||
#include "util.h" | |||
#include "view.h" | |||
#include "expressions.h" | |||
#include "cfg_file.h" | |||
#include "map.h" | |||
struct rspamd_view * | |||
init_view (struct config_file *cfg, rspamd_mempool_t * pool) | |||
{ | |||
struct rspamd_view *new; | |||
new = rspamd_mempool_alloc0 (pool, sizeof (struct rspamd_view)); | |||
new->pool = pool; | |||
new->from_hash = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); | |||
new->symbols_hash = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); | |||
new->rcpt_hash = g_hash_table_new (rspamd_strcase_hash, rspamd_strcase_equal); | |||
new->ip_tree = radix_tree_create (); | |||
new->client_ip_tree = radix_tree_create (); | |||
new->cfg = cfg; | |||
rspamd_mempool_add_destructor (new->pool, (rspamd_mempool_destruct_t) g_hash_table_destroy, new->symbols_hash); | |||
return new; | |||
} | |||
gboolean | |||
add_view_from (struct rspamd_view * view, const gchar *line) | |||
{ | |||
struct rspamd_regexp *re = NULL; | |||
if (add_map (view->cfg, line, "SMTP From view", read_host_list, fin_host_list, (void **)&view->from_hash)) { | |||
return TRUE; | |||
} | |||
else if ((re = parse_regexp (view->pool, line, TRUE)) != NULL) { | |||
view->from_re_list = g_list_prepend (view->from_re_list, re); | |||
return TRUE; | |||
} | |||
return FALSE; | |||
} | |||
gboolean | |||
add_view_rcpt (struct rspamd_view * view, const gchar *line) | |||
{ | |||
struct rspamd_regexp *re = NULL; | |||
if (add_map (view->cfg, line, "Recipients view", read_host_list, fin_host_list, (void **)&view->rcpt_hash)) { | |||
return TRUE; | |||
} | |||
else if ((re = parse_regexp (view->pool, line, TRUE)) != NULL) { | |||
view->rcpt_re_list = g_list_prepend (view->rcpt_re_list, re); | |||
return TRUE; | |||
} | |||
return FALSE; | |||
} | |||
gboolean | |||
add_view_symbols (struct rspamd_view * view, const gchar *line) | |||
{ | |||
struct rspamd_regexp *re = NULL; | |||
GList *symbols; | |||
if (add_map (view->cfg, line, "Symbols view", read_host_list, fin_host_list, (void **)&view->symbols_hash)) { | |||
return TRUE; | |||
} | |||
else if ((re = parse_regexp (view->pool, line, TRUE)) != NULL) { | |||
view->symbols_re_list = g_list_prepend (view->symbols_re_list, re); | |||
return TRUE; | |||
} | |||
else { | |||
/* Try to parse symbols line as comma separated list */ | |||
symbols = parse_comma_list (view->pool, line); | |||
while (symbols) { | |||
g_hash_table_insert (view->symbols_hash, (gchar *)symbols->data, symbols->data); | |||
/* Symbols list would be free at pool destruction */ | |||
symbols = g_list_next (symbols); | |||
} | |||
} | |||
return FALSE; | |||
} | |||
gboolean | |||
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; | |||
} | |||
return FALSE; | |||
} | |||
gboolean | |||
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; | |||
} | |||
return FALSE; | |||
} | |||
static struct rspamd_view * | |||
find_view_by_ip (GList * views, struct rspamd_task *task) | |||
{ | |||
GList *cur; | |||
struct rspamd_view *v; | |||
#ifdef HAVE_INET_PTON | |||
if (task->from_addr.ipv6 || task->from_addr.d.in4.s_addr == INADDR_NONE) { | |||
return NULL; | |||
} | |||
cur = views; | |||
while (cur) { | |||
v = cur->data; | |||
if (radix32tree_find (v->ip_tree, ntohl (task->from_addr.d.in4.s_addr)) != RADIX_NO_VALUE) { | |||
return v; | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
return NULL; | |||
#else | |||
if (task->from_addr.s_addr == INADDR_NONE) { | |||
return NULL; | |||
} | |||
cur = views; | |||
while (cur) { | |||
v = cur->data; | |||
if (radix32tree_find (v->ip_tree, ntohl (task->from_addr.s_addr)) != RADIX_NO_VALUE) { | |||
return v; | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
return NULL; | |||
#endif | |||
} | |||
static struct rspamd_view * | |||
find_view_by_client_ip (GList * views, struct rspamd_task *task) | |||
{ | |||
GList *cur; | |||
struct rspamd_view *v; | |||
if (task->client_addr.s_addr == INADDR_NONE) { | |||
return NULL; | |||
} | |||
cur = views; | |||
while (cur) { | |||
v = cur->data; | |||
if (radix32tree_find (v->client_ip_tree, ntohl (task->client_addr.s_addr)) != RADIX_NO_VALUE) { | |||
msg_info ("found view for client ip %s", inet_ntoa (task->client_addr)); | |||
return v; | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
return NULL; | |||
} | |||
static struct rspamd_view * | |||
find_view_by_from (GList * views, struct rspamd_task *task) | |||
{ | |||
GList *cur, *cur_re; | |||
struct rspamd_view *v; | |||
struct rspamd_regexp *re; | |||
gchar *from_domain; | |||
if (task->from == NULL) { | |||
return NULL; | |||
} | |||
cur = views; | |||
while (cur) { | |||
v = cur->data; | |||
/* First try to lookup in hashtable domain name */ | |||
if ((from_domain = strchr (task->from, '@')) != NULL) { | |||
from_domain ++; | |||
if (g_hash_table_lookup (v->from_hash, from_domain) != NULL) { | |||
msg_info ("found view for client from %s", task->from); | |||
return v; | |||
} | |||
} | |||
if (g_hash_table_lookup (v->from_hash, task->from) != NULL) { | |||
msg_info ("found view for client from %s", task->from); | |||
return v; | |||
} | |||
/* Then try to match re */ | |||
cur_re = v->from_re_list; | |||
while (cur_re) { | |||
re = cur_re->data; | |||
if (g_regex_match (re->regexp, task->from, 0, NULL) == TRUE) { | |||
msg_info ("found view for client from %s", task->from); | |||
return v; | |||
} | |||
cur_re = g_list_next (cur_re); | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
return NULL; | |||
} | |||
static inline gboolean | |||
check_view_rcpt (struct rspamd_view *v, struct rspamd_task *task) | |||
{ | |||
GList *cur, *cur_re; | |||
gchar rcpt_user[256], *p; | |||
gint l; | |||
struct rspamd_regexp *re; | |||
cur = task->rcpt; | |||
while (cur) { | |||
if ((p = strchr (cur->data, '@')) != NULL) { | |||
l = MIN ((gint)sizeof (rcpt_user) - 1, p - (gchar *)cur->data); | |||
memcpy (rcpt_user, cur->data, l); | |||
rcpt_user[l] = '\0'; | |||
/* First try to lookup in hashtable */ | |||
if (g_hash_table_lookup (v->rcpt_hash, rcpt_user) != NULL) { | |||
msg_info ("found view for client rcpt %s", rcpt_user); | |||
return TRUE; | |||
} | |||
/* Then try to match re */ | |||
cur_re = v->rcpt_re_list; | |||
while (cur_re) { | |||
re = cur_re->data; | |||
if (g_regex_match (re->regexp, rcpt_user, 0, NULL) == TRUE) { | |||
msg_info ("found view for client rcpt %s", rcpt_user); | |||
return TRUE; | |||
} | |||
cur_re = g_list_next (cur_re); | |||
} | |||
} | |||
/* Now check the whole recipient */ | |||
if (g_hash_table_lookup (v->rcpt_hash, cur->data) != NULL) { | |||
msg_info ("found view for client rcpt %s", rcpt_user); | |||
return TRUE; | |||
} | |||
/* Then try to match re */ | |||
cur_re = v->rcpt_re_list; | |||
while (cur_re) { | |||
re = cur_re->data; | |||
if (g_regex_match (re->regexp, cur->data, 0, NULL) == TRUE) { | |||
msg_info ("found view for client rcpt %s", rcpt_user); | |||
return TRUE; | |||
} | |||
cur_re = g_list_next (cur_re); | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
return FALSE; | |||
} | |||
static struct rspamd_view * | |||
find_view_by_rcpt (GList * views, struct rspamd_task *task) | |||
{ | |||
GList *cur; | |||
struct rspamd_view *v; | |||
if (task->from == NULL) { | |||
return NULL; | |||
} | |||
cur = views; | |||
while (cur) { | |||
v = cur->data; | |||
if (check_view_rcpt (v, task)) { | |||
return v; | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
return NULL; | |||
} | |||
static gboolean | |||
match_view_symbol (struct rspamd_view *v, const gchar *symbol) | |||
{ | |||
GList *cur; | |||
struct rspamd_regexp *re; | |||
/* Special case */ | |||
if (symbol == NULL) { | |||
return TRUE; | |||
} | |||
/* First try to lookup in hashtable */ | |||
if (g_hash_table_lookup (v->symbols_hash, symbol) != NULL) { | |||
return TRUE; | |||
} | |||
/* Then try to match re */ | |||
cur = v->symbols_re_list; | |||
while (cur) { | |||
re = cur->data; | |||
if (g_regex_match (re->regexp, symbol, 0, NULL) == TRUE) { | |||
return TRUE; | |||
} | |||
cur = g_list_next (cur); | |||
} | |||
return FALSE; | |||
} | |||
gboolean | |||
check_view (GList * views, const gchar *symbol, struct rspamd_task * task) | |||
{ | |||
struct rspamd_view *selected = NULL; | |||
if (views == NULL || (task->view == NULL && task->view_checked == TRUE)) { | |||
/* If now views defined just return TRUE to check each symbol */ | |||
return TRUE; | |||
} | |||
if (task->view != NULL) { | |||
goto check_symbol; | |||
} | |||
if ((selected = find_view_by_ip (views, task)) == NULL) { | |||
if ((selected = find_view_by_client_ip (views, task)) == NULL) { | |||
if ((selected = find_view_by_from (views, task)) == NULL) { | |||
if ((selected = find_view_by_rcpt (views, task)) == NULL) { | |||
/* No matching view for this task */ | |||
task->view_checked = TRUE; | |||
return TRUE; | |||
} | |||
} | |||
} | |||
} | |||
task->view_checked = TRUE; | |||
task->view = selected; | |||
check_symbol: | |||
/* selected is now not NULL */ | |||
if (task->view->skip_check) { | |||
return FALSE; | |||
} | |||
if (match_view_symbol (task->view, symbol)) { | |||
return TRUE; | |||
} | |||
return FALSE; | |||
} | |||
gboolean | |||
check_skip (GList * views, struct rspamd_task * task) | |||
{ | |||
if (check_view (views, NULL, task) == FALSE) { | |||
return TRUE; | |||
} | |||
return FALSE; | |||
} |
@@ -1,95 +0,0 @@ | |||
/** @file view.h **/ | |||
#ifndef RSPAMD_VIEW_H | |||
#define RSPAMD_VIEW_H | |||
#include "config.h" | |||
#include "main.h" | |||
#include "radix.h" | |||
struct config_file; | |||
struct rspamd_view { | |||
struct config_file *cfg; | |||
GList *from_re_list; | |||
GHashTable *from_hash; | |||
GList *rcpt_re_list; | |||
GHashTable *rcpt_hash; | |||
radix_tree_t *ip_tree; | |||
radix_tree_t *client_ip_tree; | |||
GHashTable *symbols_hash; | |||
GList *symbols_re_list; | |||
gboolean skip_check; | |||
rspamd_mempool_t *pool; | |||
}; | |||
/** | |||
* Init a new view | |||
* @param pool pool for view | |||
* @return | |||
*/ | |||
struct rspamd_view* init_view (struct config_file *cfg, rspamd_mempool_t *pool); | |||
/** | |||
* Add from option for this view | |||
* @param view view | |||
* @param line from line for this view | |||
* @return | |||
*/ | |||
gboolean add_view_from (struct rspamd_view *view, const gchar *line); | |||
/** | |||
* Add recipient for this view | |||
* @param view view object | |||
* @param line recipient description | |||
* @return | |||
*/ | |||
gboolean add_view_rcpt (struct rspamd_view *view, const gchar *line); | |||
/** | |||
* Add ip option for this view | |||
* @param view view object | |||
* @param line ip description | |||
* @return | |||
*/ | |||
gboolean add_view_ip (struct rspamd_view *view, const gchar *line); | |||
/** | |||
* Add client ip option for this view | |||
* @param view view object | |||
* @param line ip description | |||
* @return | |||
*/ | |||
gboolean add_view_client_ip (struct rspamd_view *view, const gchar *line); | |||
/** | |||
* Add symbols option for this view | |||
* @param view view object | |||
* @param line symbols description | |||
* @return | |||
*/ | |||
gboolean add_view_symbols (struct rspamd_view *view, const gchar *line); | |||
/** | |||
* Check view for this task for specified symbol | |||
* @param views list of defined views | |||
* @param symbol symbol to check | |||
* @param task task object | |||
* @return whether to check this symbol for this task | |||
*/ | |||
gboolean check_view (GList *views, const gchar *symbol, struct rspamd_task *task); | |||
/** | |||
* Check whether this task should be skipped from checks | |||
* @param views list of defined views | |||
* @param task task object | |||
* @return | |||
*/ | |||
gboolean check_skip (GList *views, struct rspamd_task *task); | |||
#endif |
@@ -56,7 +56,6 @@ construct_task (struct rspamd_worker *worker) | |||
if (worker) { | |||
new_task->cfg = worker->srv->cfg; | |||
} | |||
new_task->view_checked = FALSE; | |||
#ifdef HAVE_CLOCK_GETTIME | |||
# ifdef HAVE_CLOCK_PROCESS_CPUTIME_ID | |||
clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &new_task->ts); | |||
@@ -155,15 +154,6 @@ free_task (struct rspamd_task *task, gboolean is_soft) | |||
if (task->received) { | |||
g_list_free (task->received); | |||
} | |||
if (task->dispatcher) { | |||
if (is_soft) { | |||
/* Plan dispatcher shutdown */ | |||
task->dispatcher->wanna_die = 1; | |||
} | |||
else { | |||
rspamd_remove_dispatcher (task->dispatcher); | |||
} | |||
} | |||
if (task->http_conn != NULL) { | |||
rspamd_http_connection_unref (task->http_conn); | |||
} |