]> source.dussan.org Git - rspamd.git/commitdiff
* Add ability to specify 'S' flag to regexp that means that headers checks must be...
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 15 Feb 2011 15:26:27 +0000 (18:26 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 15 Feb 2011 15:26:27 +0000 (18:26 +0300)
* Add lua function message:get_header_strong

src/cfg_file.h
src/controller.c
src/expressions.c
src/filter.c
src/lua/lua_message.c
src/message.c
src/message.h
src/plugins/regexp.c
src/spf.c

index e33b1585a767b6d5492063f2bc861d141222bad9..09eea39766d9c926e45ad04d4e960c3169eb8d6f 100644 (file)
@@ -93,6 +93,7 @@ struct rspamd_regexp {
        gchar *header;                                                                  /**< header name for header regexps                                             */
        gboolean is_test;                                                               /**< true if this expression must be tested                             */
        gboolean is_raw;                                                                /**< true if this regexp is done by raw matching                */
+       gboolean is_strong;                                                             /**< true if headers search must be case sensitive              */
 };
 
 /**
index e4dea60f7c2491db6c4450ef633d74b99b83f9e1..162217828b88e9c37d7b044cb60d22b657fbb98e 100644 (file)
@@ -800,7 +800,7 @@ controller_read_socket (f_str_t * in, void *arg)
                        return FALSE;
                }
                if ((s = g_hash_table_lookup (session->learn_classifier->opts, "header")) != NULL) {
-                       cur = message_get_header (task->task_pool, task->message, s);
+                       cur = message_get_header (task->task_pool, task->message, s, FALSE);
                        if (cur) {
                                memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_list_free, cur);
                        }
index c3b45ef7cf5791bdbb6fd3c0a839c6980790aec9..87ce5933754d835c75ea0a32118d8120c309fc9c 100644 (file)
@@ -245,6 +245,7 @@ is_regexp_flag (gchar a)
        case 'U':
        case 'X':
        case 'T':
+       case 'S':
                return TRUE;
        default:
                return FALSE;
@@ -680,6 +681,10 @@ parse_regexp (memory_pool_t * pool, gchar *line, gboolean raw_mode)
                        result->is_test = TRUE;
                        p ++;
                        break;
+               case 'S':
+                       result->is_strong = TRUE;
+                       p ++;
+                       break;
                        /* Stop flags parsing */
                default:
                        p = NULL;
@@ -913,7 +918,7 @@ rspamd_header_exists (struct worker_task * task, GList * args, void *unused)
        }
 
        debug_task ("try to get header %s", (gchar *)arg->data);
-       headerlist = message_get_header (task->task_pool, task->message, (gchar *)arg->data);
+       headerlist = message_get_header (task->task_pool, task->message, (gchar *)arg->data, FALSE);
        if (headerlist) {
                g_list_free (headerlist);
                return TRUE;
index 1091de0ca5256330b817e9cc9b7f080bfa3b29b1..91b0196d4b94c827e1de7d4b4f5b519fc0a728ed 100644 (file)
@@ -493,7 +493,7 @@ classifiers_callback (gpointer value, void *arg)
        gchar                           *header = NULL;
        
        if ((header = g_hash_table_lookup (cl->opts, "header")) != NULL) {
-               cur = message_get_header (task->task_pool, task->message, header);
+               cur = message_get_header (task->task_pool, task->message, header, FALSE);
                if (cur) {
                        memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_list_free, cur);
                }
index 04adec24a2502d21848cb9469c9684ad6acd85eb..2848e082ffa8dba65f0712229a671b2415bb5c14 100644 (file)
@@ -66,6 +66,7 @@ LUA_FUNCTION_DEF (message, set_sender);
 LUA_FUNCTION_DEF (message, get_reply_to);
 LUA_FUNCTION_DEF (message, set_reply_to);
 LUA_FUNCTION_DEF (message, get_header);
+LUA_FUNCTION_DEF (message, get_header_strong);
 LUA_FUNCTION_DEF (message, set_header);
 
 static const struct luaL_reg    msglib_m[] = {
@@ -78,6 +79,7 @@ static const struct luaL_reg    msglib_m[] = {
        LUA_INTERFACE_DEF (message, get_reply_to),
        LUA_INTERFACE_DEF (message, set_reply_to),
        LUA_INTERFACE_DEF (message, get_header),
+       LUA_INTERFACE_DEF (message, get_header_strong),
        LUA_INTERFACE_DEF (message, set_header),
        {"__tostring", lua_class_tostring},
        {NULL, NULL}
@@ -106,7 +108,7 @@ LUA_GMIME_BRIDGE_GET (message, get_reply_to, Message)
 LUA_GMIME_BRIDGE_SET (message, set_reply_to, Message)
 
 static gint
-lua_message_get_header (lua_State * L)
+lua_message_get_header_common (lua_State * L, gboolean strong)
 {
        const gchar                     *headern;
        GMimeMessage                   *obj = lua_check_message (L);
@@ -116,7 +118,7 @@ lua_message_get_header (lua_State * L)
        if (obj != NULL) {
                headern = luaL_checkstring (L, 2);
                if (headern) {
-                       res = message_get_header (NULL, obj, headern);
+                       res = message_get_header (NULL, obj, headern, strong);
                        if (res) {
                                cur = res;
                                lua_newtable (L);
@@ -143,6 +145,17 @@ lua_message_get_header (lua_State * L)
        return 1;
 }
 
+static gint
+lua_message_get_header (lua_State * L)
+{
+       return lua_message_get_header_common (L, FALSE);
+}
+
+static gint
+lua_message_get_header_strong (lua_State * L)
+{
+       return lua_message_get_header_common (L, TRUE);
+}
 
 static gint
 lua_message_set_header (lua_State * L)
index 83ce3b91d1b17bb56f6457ed114a61531d080fb7..323dd33a0fe01ad1d8e8df84e34ddb076aa3a1c8 100644 (file)
@@ -816,7 +816,7 @@ process_message (struct worker_task *task)
 #endif
 
                /* Parse received headers */
-               first = message_get_header (task->task_pool, message, "Received");
+               first = message_get_header (task->task_pool, message, "Received", FALSE);
                cur = first;
                while (cur) {
                        recv = memory_pool_alloc0 (task->task_pool, sizeof (struct received_header));
@@ -927,15 +927,27 @@ enum {
 
 #ifndef GMIME24
 static void
-header_iterate (memory_pool_t * pool, struct raw_header *h, GList ** ret, const gchar *field)
+header_iterate (memory_pool_t * pool, struct raw_header *h, GList ** ret, const gchar *field, gboolean strong)
 {
        while (h) {
-               if (h->value && !g_strncasecmp (field, h->name, strlen (field))) {
-                       if (pool != NULL) {
-                               *ret = g_list_prepend (*ret, memory_pool_strdup (pool, h->value));
+               if (G_LIKELY (!strong)) {
+                       if (h->value && !g_strncasecmp (field, h->name, strlen (field))) {
+                               if (pool != NULL) {
+                                       *ret = g_list_prepend (*ret, memory_pool_strdup (pool, h->value));
+                               }
+                               else {
+                                       *ret = g_list_prepend (*ret, g_strdup (h->value));
+                               }
                        }
-                       else {
-                               *ret = g_list_prepend (*ret, g_strdup (h->value));
+               }
+               else {
+                       if (h->value && !strncmp (field, h->name, strlen (field))) {
+                               if (pool != NULL) {
+                                       *ret = g_list_prepend (*ret, memory_pool_strdup (pool, h->value));
+                               }
+                               else {
+                                       *ret = g_list_prepend (*ret, g_strdup (h->value));
+                               }
                        }
                }
                h = h->next;
@@ -943,7 +955,7 @@ header_iterate (memory_pool_t * pool, struct raw_header *h, GList ** ret, const
 }
 #else
 static void
-header_iterate (memory_pool_t * pool, GMimeHeaderList * ls, GList ** ret, const gchar *field)
+header_iterate (memory_pool_t * pool, GMimeHeaderList * ls, GList ** ret, const gchar *field, gboolean strong)
 {
        GMimeHeaderIter                *iter;
        const gchar                     *name;
@@ -957,12 +969,24 @@ header_iterate (memory_pool_t * pool, GMimeHeaderList * ls, GList ** ret, const
        if (g_mime_header_list_get_iter (ls, iter) && g_mime_header_iter_first (iter)) {
                while (g_mime_header_iter_is_valid (iter)) {
                        name = g_mime_header_iter_get_name (iter);
-                       if (!g_strncasecmp (field, name, strlen (name))) {
-                               if (pool != NULL) {
-                                       *ret = g_list_prepend (*ret, memory_pool_strdup (pool, g_mime_header_iter_get_value (iter)));
+                       if (G_LIKELY (!strong)) {
+                               if (!g_strncasecmp (field, name, strlen (name))) {
+                                       if (pool != NULL) {
+                                               *ret = g_list_prepend (*ret, memory_pool_strdup (pool, g_mime_header_iter_get_value (iter)));
+                                       }
+                                       else {
+                                               *ret = g_list_prepend (*ret, g_strdup (g_mime_header_iter_get_value (iter)));
+                                       }
                                }
-                               else {
-                                       *ret = g_list_prepend (*ret, g_strdup (g_mime_header_iter_get_value (iter)));
+                       }
+                       else {
+                               if (!strncmp (field, name, strlen (name))) {
+                                       if (pool != NULL) {
+                                               *ret = g_list_prepend (*ret, memory_pool_strdup (pool, g_mime_header_iter_get_value (iter)));
+                                       }
+                                       else {
+                                               *ret = g_list_prepend (*ret, g_strdup (g_mime_header_iter_get_value (iter)));
+                                       }
                                }
                        }
                        if (!g_mime_header_iter_next (iter)) {
@@ -980,6 +1004,7 @@ struct multipart_cb_data {
        memory_pool_t                  *pool;
        const gchar                     *field;
        gboolean                        try_search;
+       gboolean                        strong;
        gint                            rec;
 };
 
@@ -1003,10 +1028,10 @@ multipart_iterate (GMimeObject * part, gpointer user_data)
                GMimeHeaderList                *ls;
 
                ls = g_mime_object_get_header_list (GMIME_OBJECT (part));
-               header_iterate (data->pool, ls, &l, data->field);
+               header_iterate (data->pool, ls, &l, data->field, data->strong);
 #else
                h = part->headers->headers;
-               header_iterate (data->pool, h, &l, data->field);
+               header_iterate (data->pool, h, &l, data->field, data->strong);
 #endif
                if (l == NULL) {
                        /* Header not found, abandon search results */
@@ -1031,7 +1056,7 @@ multipart_iterate (GMimeObject * part, gpointer user_data)
 }
 
 static GList                   *
-local_message_get_header (memory_pool_t * pool, GMimeMessage * message, const gchar *field)
+local_message_get_header (memory_pool_t * pool, GMimeMessage * message, const gchar *field, gboolean strong)
 {
        GList                          *gret = NULL;
        GMimeObject                    *part;
@@ -1042,6 +1067,7 @@ local_message_get_header (memory_pool_t * pool, GMimeMessage * message, const gc
        };
        cb.pool = pool;
        cb.field = field;
+       cb.strong = strong;
 
 #ifndef GMIME24
        struct raw_header              *h;
@@ -1052,7 +1078,7 @@ local_message_get_header (memory_pool_t * pool, GMimeMessage * message, const gc
 
        msg_debug ("iterate over headers to find header %s", field);
        h = GMIME_OBJECT (message)->headers->headers;
-       header_iterate (pool, h, &gret, field);
+       header_iterate (pool, h, &gret, field, strong);
 
        if (gret == NULL) {
                /* Try to iterate with mime part headers */
@@ -1060,7 +1086,7 @@ local_message_get_header (memory_pool_t * pool, GMimeMessage * message, const gc
                part = g_mime_message_get_mime_part (message);
                if (part) {
                        h = part->headers->headers;
-                       header_iterate (pool, h, &gret, field);
+                       header_iterate (pool, h, &gret, field, strong);
                        if (gret == NULL && GMIME_IS_MULTIPART (part)) {
                                msg_debug ("iterate over headers of each multipart's subparts %s", field);
                                g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, &cb);
@@ -1079,13 +1105,13 @@ local_message_get_header (memory_pool_t * pool, GMimeMessage * message, const gc
        GMimeHeaderList                *ls;
 
        ls = g_mime_object_get_header_list (GMIME_OBJECT (message));
-       header_iterate (pool, ls, &gret, field);
+       header_iterate (pool, ls, &gret, field, strong);
        if (gret == NULL) {
                /* Try to iterate with mime part headers */
                part = g_mime_message_get_mime_part (message);
                if (part) {
                        ls = g_mime_object_get_header_list (GMIME_OBJECT (part));
-                       header_iterate (pool, ls, &gret, field);
+                       header_iterate (pool, ls, &gret, field, strong);
                        if (gret == NULL && GMIME_IS_MULTIPART (part)) {
                                g_mime_multipart_foreach (GMIME_MULTIPART (part), multipart_iterate, &cb);
                                if (cb.ret != NULL) {
@@ -1202,7 +1228,7 @@ local_message_get_recipients_##type (GMimeMessage *message, const gchar *unused)
 /* different declarations for different types of set and get functions */
   typedef const gchar             *(*GetFunc) (GMimeMessage * message);
   typedef InternetAddressList    *(*GetRcptFunc) (GMimeMessage * message, const gchar *type);
-  typedef GList                  *(*GetListFunc) (memory_pool_t * pool, GMimeMessage * message, const gchar *type);
+  typedef GList                  *(*GetListFunc) (memory_pool_t * pool, GMimeMessage * message, const gchar *type, gboolean strong);
   typedef void                    (*SetFunc) (GMimeMessage * message, const gchar *value);
   typedef void                    (*SetListFunc) (GMimeMessage * message, const gchar *field, const gchar *value);
 
@@ -1306,7 +1332,7 @@ message_set_header (GMimeMessage * message, const gchar *field, const gchar *val
 * You should free the GList list by yourself.
 **/
 GList                          *
-message_get_header (memory_pool_t * pool, GMimeMessage * message, const gchar *field)
+message_get_header (memory_pool_t * pool, GMimeMessage * message, const gchar *field, gboolean strong)
 {
        gint                            i;
        gchar                           *ret = NULL, *ia_string;
@@ -1347,7 +1373,7 @@ message_get_header (memory_pool_t * pool, GMimeMessage * message, const gchar *f
 #endif
                                break;
                        case FUNC_LIST:
-                               gret = (*(fieldfunc[i].getlistfunc)) (pool, message, field);
+                               gret = (*(fieldfunc[i].getlistfunc)) (pool, message, field, strong);
                                break;
                        }
                        break;
index d8be944e33937544e829604a64583cb67acfe2de..a57571987e0b2184ca3e849d3bd36fa4dda094ad 100644 (file)
@@ -54,6 +54,6 @@ struct received_header {
 gint process_message (struct worker_task *task);
 
 void message_set_header (GMimeMessage *message, const gchar *field, const gchar *value);
-GList* message_get_header (memory_pool_t *pool, GMimeMessage *message, const gchar *field);
+GList* message_get_header (memory_pool_t *pool, GMimeMessage *message, const gchar *field, gboolean strong);
 
 #endif
index 4ae056beec6698bfc9c46e797a51f364442ca4f7..68c91f976d04cb2b5986dc4a5e960e39b5476aa9 100644 (file)
@@ -661,7 +661,7 @@ process_regexp (struct rspamd_regexp *re, struct worker_task *task, const gchar
                }
                debug_task ("checking header regexp: %s = %s", re->header, re->regexp_text);
 
-               headerlist = message_get_header (task->task_pool, task->message, re->header);
+               headerlist = message_get_header (task->task_pool, task->message, re->header, re->is_strong);
                if (headerlist == NULL) {
                        if (G_UNLIKELY (re->is_test)) {
                                msg_info ("process test regexp %s for header %s returned FALSE: no header found", re->regexp_text, re->header);
index 63a3fed99b801738a5eca03e02ade0579c78b677..8e60604ac37dda04cefddc4e330a4818d8bd3e48 100644 (file)
--- a/src/spf.c
+++ b/src/spf.c
@@ -1152,7 +1152,7 @@ resolve_spf (struct worker_task *task, spf_cb_t callback)
                }
        }
        else {
-               domains = message_get_header (task->task_pool, task->message, "From");
+               domains = message_get_header (task->task_pool, task->message, "From", FALSE);
 
                if (domains != NULL) {
                        rec->cur_domain = memory_pool_strdup (task->task_pool, domains->data);