aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2011-02-15 18:26:27 +0300
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2011-02-15 18:26:27 +0300
commit17a938b2aeffb3448c8d61f3d8dd7d012eb910cc (patch)
tree066cebe8b625a8b728ba17f1b3be8f2e80dce9c1
parentbeab78097de6a53430bb16310e41b93d74546cb9 (diff)
downloadrspamd-17a938b2aeffb3448c8d61f3d8dd7d012eb910cc.tar.gz
rspamd-17a938b2aeffb3448c8d61f3d8dd7d012eb910cc.zip
* Add ability to specify 'S' flag to regexp that means that headers checks must be case sensitive
* Add lua function message:get_header_strong
-rw-r--r--src/cfg_file.h1
-rw-r--r--src/controller.c2
-rw-r--r--src/expressions.c7
-rw-r--r--src/filter.c2
-rw-r--r--src/lua/lua_message.c17
-rw-r--r--src/message.c72
-rw-r--r--src/message.h2
-rw-r--r--src/plugins/regexp.c2
-rw-r--r--src/spf.c2
9 files changed, 76 insertions, 31 deletions
diff --git a/src/cfg_file.h b/src/cfg_file.h
index e33b1585a..09eea3976 100644
--- a/src/cfg_file.h
+++ b/src/cfg_file.h
@@ -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 */
};
/**
diff --git a/src/controller.c b/src/controller.c
index e4dea60f7..162217828 100644
--- a/src/controller.c
+++ b/src/controller.c
@@ -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);
}
diff --git a/src/expressions.c b/src/expressions.c
index c3b45ef7c..87ce59337 100644
--- a/src/expressions.c
+++ b/src/expressions.c
@@ -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;
diff --git a/src/filter.c b/src/filter.c
index 1091de0ca..91b0196d4 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -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);
}
diff --git a/src/lua/lua_message.c b/src/lua/lua_message.c
index 04adec24a..2848e082f 100644
--- a/src/lua/lua_message.c
+++ b/src/lua/lua_message.c
@@ -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)
diff --git a/src/message.c b/src/message.c
index 83ce3b91d..323dd33a0 100644
--- a/src/message.c
+++ b/src/message.c
@@ -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;
diff --git a/src/message.h b/src/message.h
index d8be944e3..a57571987 100644
--- a/src/message.h
+++ b/src/message.h
@@ -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
diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c
index 4ae056bee..68c91f976 100644
--- a/src/plugins/regexp.c
+++ b/src/plugins/regexp.c
@@ -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);
diff --git a/src/spf.c b/src/spf.c
index 63a3fed99..8e60604ac 100644
--- 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);