From 99cd57ba7f0e6b9178ccacc6987b0854ed137d83 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Thu, 15 Jul 2010 15:08:31 +0400 Subject: [PATCH] * Add ability to make views by recipient --- src/cfg_xml.c | 22 ++++++++++-- src/cfg_xml.h | 1 + src/view.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/view.h | 4 +++ 4 files changed, 117 insertions(+), 5 deletions(-) diff --git a/src/cfg_xml.c b/src/cfg_xml.c index 030ec9b34..aeb64d1ae 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -381,6 +381,12 @@ static struct xml_parser_rule grammar[] = { 0, NULL }, + { + "rcpt", + handle_view_rcpt, + 0, + NULL + }, { "symbols", handle_view_symbols, @@ -913,19 +919,31 @@ handle_view_from (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHas struct rspamd_view *view = ctx->section_pointer; if (!add_view_from (view, data)) { - msg_err ("invalid from line in view definition: ip = '%s'", data); + msg_err ("invalid from line in view definition: from = '%s'", data); return FALSE; } return TRUE; } gboolean +handle_view_rcpt (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset) +{ + struct rspamd_view *view = ctx->section_pointer; + + if (!add_view_rcpt (view, data)) { + msg_err ("invalid from line in view definition: rcpt = '%s'", data); + return FALSE; + } + + return TRUE; +} +gboolean handle_view_symbols (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset) { struct rspamd_view *view = ctx->section_pointer; if (!add_view_symbols (view, data)) { - msg_err ("invalid symbols line in view definition: ip = '%s'", data); + msg_err ("invalid symbols line in view definition: symbols = '%s'", data); return FALSE; } cfg->domain_settings_str = memory_pool_strdup (cfg->cfg_pool, data); diff --git a/src/cfg_xml.h b/src/cfg_xml.h index 50fa7ac3f..b61c2f825 100644 --- a/src/cfg_xml.h +++ b/src/cfg_xml.h @@ -108,6 +108,7 @@ gboolean handle_composite (struct config_file *cfg, struct rspamd_xml_userdata * gboolean handle_view_ip (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); gboolean handle_view_client_ip (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); gboolean handle_view_from (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); +gboolean handle_view_rcpt (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); gboolean handle_view_symbols (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); gboolean handle_user_settings (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, int offset); diff --git a/src/view.c b/src/view.c index 9a191fe80..13de5e8a9 100644 --- a/src/view.c +++ b/src/view.c @@ -64,6 +64,22 @@ add_view_from (struct rspamd_view * view, char *line) return FALSE; } +gboolean +add_view_rcpt (struct rspamd_view * view, char *line) +{ + struct rspamd_regexp *re = NULL; + + if (add_map (line, 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, char *line) { @@ -190,6 +206,77 @@ find_view_by_from (GList * views, struct worker_task *task) return NULL; } +G_INLINE_FUNC gboolean +check_view_rcpt (struct rspamd_view *v, struct worker_task *task) +{ + GList *cur, *cur_re; + char rcpt_user[256], *p; + gint l; + struct rspamd_regexp *re; + + cur = task->rcpt; + while (cur) { + if ((p = strchr (cur->data, '@')) != NULL) { + l = MIN (sizeof (rcpt_user) - 1, p - (char *)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) { + 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) { + 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) { + 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) { + 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 worker_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 char *symbol) { @@ -236,9 +323,11 @@ check_view (GList * views, const char *symbol, struct worker_task * task) 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) { - /* No matching view for this task */ - task->view_checked = TRUE; - return TRUE; + if ((selected = find_view_by_rcpt (views, task)) == NULL) { + /* No matching view for this task */ + task->view_checked = TRUE; + return TRUE; + } } } } diff --git a/src/view.h b/src/view.h index ea15149bd..0b3412c85 100644 --- a/src/view.h +++ b/src/view.h @@ -9,6 +9,9 @@ struct rspamd_view { 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; @@ -22,6 +25,7 @@ struct rspamd_view { struct rspamd_view* init_view (memory_pool_t *pool); gboolean add_view_from (struct rspamd_view *view, char *line); +gboolean add_view_rcpt (struct rspamd_view *view, char *line); gboolean add_view_ip (struct rspamd_view *view, char *line); gboolean add_view_client_ip (struct rspamd_view *view, char *line); gboolean add_view_symbols (struct rspamd_view *view, char *line); -- 2.39.5