diff options
Diffstat (limited to 'src/view.c')
-rw-r--r-- | src/view.c | 393 |
1 files changed, 0 insertions, 393 deletions
diff --git a/src/view.c b/src/view.c deleted file mode 100644 index f3534f84c..000000000 --- a/src/view.c +++ /dev/null @@ -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; -} |