]> source.dussan.org Git - rspamd.git/commitdiff
* Add ability to make views by recipient
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 15 Jul 2010 11:08:31 +0000 (15:08 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Thu, 15 Jul 2010 11:08:31 +0000 (15:08 +0400)
src/cfg_xml.c
src/cfg_xml.h
src/view.c
src/view.h

index 030ec9b34d7f3374d886b18046223763a4736c78..aeb64d1aeec4729fd12406dbfe1f3ab6d2ae1a57 100644 (file)
@@ -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);
index 50fa7ac3f3bffec0f577cee7f8d74b31aa724aa7..b61c2f825c3677eaccf78d124bb5974d15cca6af 100644 (file)
@@ -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);
index 9a191fe80014d116c61eb6cf9817075aecf78d7d..13de5e8a93b4cab8979fb228cc9d1fedfb748779 100644 (file)
@@ -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;
+                               }
                        }
                }
        }
index ea15149bd1e68830f0982b1801929c162630fdd2..0b3412c85278ad79155cc3a344670ac114c300ab 100644 (file)
@@ -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);