diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-03-17 12:25:23 +0300 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-03-17 12:25:23 +0300 |
commit | 8cc22288806b9ff7115cb8f30349029714e2d89a (patch) | |
tree | bc569c0dc56263b07906987ae22b8379cfb5325e | |
parent | cfd2ff7bb58b81b7c0713b423a5b3397579610e7 (diff) | |
download | rspamd-8cc22288806b9ff7115cb8f30349029714e2d89a.tar.gz rspamd-8cc22288806b9ff7115cb8f30349029714e2d89a.zip |
* Add ability to match raw headers
* Update documentation
-rw-r--r-- | README.utf8.txt | 11 | ||||
-rw-r--r-- | src/cfg_file.h | 3 | ||||
-rw-r--r-- | src/cfg_utils.c | 6 | ||||
-rw-r--r-- | src/main.h | 1 | ||||
-rw-r--r-- | src/message.c | 10 | ||||
-rw-r--r-- | src/plugins/regexp.c | 47 |
6 files changed, 73 insertions, 5 deletions
diff --git a/README.utf8.txt b/README.utf8.txt index c49da2476..c5bc293c0 100644 --- a/README.utf8.txt +++ b/README.utf8.txt @@ -89,6 +89,10 @@ Queue-ID - идентификатор очереди .module 'regexp' { SYMBOL = "regexp_expression"; }; +header_filters = "regexp"; + +Обратите внимание, что модуль regexp надо регистрировать как header filter, так как иначе он не будет работать. +Эту проблему надо исправлять, но это не первоочередная задача. Формат регэкспов такой: /pattern/flags @@ -98,14 +102,19 @@ headername=/pattern/flags Флаги регэскпов: i, m, s, x, u, o - такие же, как у perl/pcre H - ищет по заголовкам -M - ищет по всему сообщению +M - ищет по всему сообщению (в "сыром" виде) P - ищет по всем mime частям U - ищет по url +X - ищет по "сырым" хедерам (тут нужно учитывать фолдинг и ставить, где надо, /m для multiline матчинга) + Выражение регэкспов может содержать сложные выражения из нескольких регэкспов, операторов логики и скобок: SOME_SYMBOL = "To=/blah@blah/H & !(From=/blah@blah/H | Subject=/blah/H)" + Также можно использовать переменные: $to_blah = "To=/blah@blah/H"; $from_blah = "From=/blah@blah/H"; $subject_blah = "Subject=/blah/H"; + тогда предыдущее выражение будет таким + SOME_SYMBOL = "${to_blah} & !(${from_blah} | ${subject_blah})" diff --git a/src/cfg_file.h b/src/cfg_file.h index b484d5b0d..cc31f7a0c 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -50,7 +50,7 @@ enum rspamd_cred_type { }; /** - * Regexp type: /H - header, /M - mime, /U - url + * Regexp type: /H - header, /M - mime, /U - url /X - raw header */ enum rspamd_regexp_type { REGEXP_NONE = 0, @@ -58,6 +58,7 @@ enum rspamd_regexp_type { REGEXP_MIME, REGEXP_MESSAGE, REGEXP_URL, + REGEXP_RAW_HEADER, }; /** diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 3d2ce611c..204ed65f6 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -656,6 +656,12 @@ parse_regexp (memory_pool_t *pool, char *line) } p ++; break; + case 'X': + if (result->type == REGEXP_NONE || result->type == REGEXP_HEADER) { + result->type = REGEXP_RAW_HEADER; + } + p ++; + break; /* Stop flags parsing */ default: p = NULL; diff --git a/src/main.h b/src/main.h index 7b7c221ca..a13866657 100644 --- a/src/main.h +++ b/src/main.h @@ -185,6 +185,7 @@ struct worker_task { int parts_count; /**< mime parts count */ GMimeMessage *message; /**< message, parsed with GMime */ GList *parts; /**< list of parsed parts */ + char *raw_headers; /**< list of raw headers */ TAILQ_HEAD (uriq, uri) urls; /**< list of parsed urls */ GHashTable *results; /**< hash table of metric_result indexed by * metric's name */ diff --git a/src/message.c b/src/message.c index 4780a11ff..76743f7de 100644 --- a/src/message.c +++ b/src/message.c @@ -371,6 +371,16 @@ process_message (struct worker_task *task) task->message_id = "undef"; } +#ifdef GMIME24 + task->raw_headers = g_mime_object_get_headers (GMIME_OBJECT (task->message)); +#else + task->raw_headers = g_mime_message_get_headers (task->message); +#endif + + if (task->raw_headers) { + memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_free, task->raw_headers); + } + task->worker->srv->stat->messages_scanned ++; /* free the parser (and the stream) */ diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c index 06da6932f..9ef4e1ce3 100644 --- a/src/plugins/regexp.c +++ b/src/plugins/regexp.c @@ -138,7 +138,7 @@ regexp_module_reconfig (struct config_file *cfg) static gsize process_regexp (struct rspamd_regexp *re, struct worker_task *task) { - char *headerv; + char *headerv, *c, t; struct mime_part *part; GList *cur; struct uri *url; @@ -190,19 +190,60 @@ process_regexp (struct rspamd_regexp *re, struct worker_task *task) } return 0; case REGEXP_MESSAGE: - msg_debug ("process_message: checking message regexp: /%s/", re->regexp_text); + msg_debug ("process_regexp: checking message regexp: /%s/", re->regexp_text); if (g_regex_match_full (re->regexp, task->msg->begin, task->msg->len, 0, 0, NULL, NULL) == TRUE) { return 1; } return 0; case REGEXP_URL: - msg_debug ("process_url: checking url regexp: /%s/", re->regexp_text); + msg_debug ("process_regexp: checking url regexp: /%s/", re->regexp_text); TAILQ_FOREACH (url, &task->urls, next) { if (g_regex_match (re->regexp, struri (url), 0, NULL) == TRUE) { return 1; } } return 0; + case REGEXP_RAW_HEADER: + msg_debug ("process_regexp: checking for raw header: %s with regexp: /%s/", re->header, re->regexp_text); + if (task->raw_headers == NULL) { + msg_debug ("process_regexp: cannot check for raw header in message, no headers found"); + return 0; + } + if ((headerv = strstr (task->raw_headers, re->header)) == NULL) { + /* No header was found */ + return 0; + } + /* Skip header name and start matching after regexp */ + headerv += strlen (re->header) + 1; + /* Now the main problem is to find position of end of raw header */ + c = headerv; + while (*c) { + /* We need to handle all types of line end */ + if ((*c == '\r' && *(c + 1) == '\n')) { + c ++; + /* Check for folding */ + if (!g_ascii_isspace (*(c + 1))) { + c ++; + break; + } + } + else if (*c == '\r' || *c == '\n') { + if (!g_ascii_isspace (*(c + 1))) { + c ++; + break; + } + } + c ++; + } + /* Temporary null terminate this part of string */ + t = *c; + *c = '\0'; + if (g_regex_match (re->regexp, headerv, 0, NULL) == TRUE) { + *c = t; + return 1; + } + *c = t; + return 0; } /* Not reached */ |