summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2010-07-15 15:08:31 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2010-07-15 15:08:31 +0400
commit99cd57ba7f0e6b9178ccacc6987b0854ed137d83 (patch)
tree1e1cb2993f5b8f1965925180be43f24b31477902 /src
parent44e9a2cda785d6630b30c90707b7a00deb6b2b35 (diff)
downloadrspamd-99cd57ba7f0e6b9178ccacc6987b0854ed137d83.tar.gz
rspamd-99cd57ba7f0e6b9178ccacc6987b0854ed137d83.zip
* Add ability to make views by recipient
Diffstat (limited to 'src')
-rw-r--r--src/cfg_xml.c22
-rw-r--r--src/cfg_xml.h1
-rw-r--r--src/view.c95
-rw-r--r--src/view.h4
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
@@ -382,6 +382,12 @@ static struct xml_parser_rule grammar[] = {
NULL
},
{
+ "rcpt",
+ handle_view_rcpt,
+ 0,
+ NULL
+ },
+ {
"symbols",
handle_view_symbols,
0,
@@ -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
@@ -65,6 +65,22 @@ add_view_from (struct rspamd_view * view, char *line)
}
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)
{
struct rspamd_regexp *re = NULL;
@@ -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);