]> source.dussan.org Git - rspamd.git/commitdiff
* Fix cores in spf code (partially)
authorcebka@lenovo-laptop <cebka@lenovo-laptop>
Sat, 27 Feb 2010 15:59:05 +0000 (18:59 +0300)
committercebka@lenovo-laptop <cebka@lenovo-laptop>
Sat, 27 Feb 2010 15:59:05 +0000 (18:59 +0300)
* Add support for spf 2.0 (Sender ID policy)
* Add support of MAP_NOCORE to systems that supports it (FreeBSD for example)

CMakeLists.txt
config.h.in
src/plugins/fuzzy_check.c
src/spf.c
src/statfile.c

index 58a823c29a23aee916efa6652f9cda163a6d0603..22d2c21f0e78c3cec2fb4c0874a9a0113b262509 100644 (file)
@@ -272,6 +272,7 @@ CHECK_SYMBOL_EXISTS(PATH_MAX limits.h HAVE_PATH_MAX)
 CHECK_SYMBOL_EXISTS(MAXPATHLEN sys/param.h HAVE_MAXPATHLEN)
 CHECK_SYMBOL_EXISTS(MAP_SHARED sys/mman.h HAVE_MMAP_SHARED)
 CHECK_SYMBOL_EXISTS(MAP_ANON sys/mman.h HAVE_MMAP_ANON)
+CHECK_SYMBOL_EXISTS(MAP_NOCORE sys/mman.h HAVE_MMAP_NOCORE)
 CHECK_SYMBOL_EXISTS(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN)
 CHECK_SYMBOL_EXISTS(CLOCK_PROCESS_CPUTIME_ID time.h HAVE_CLOCK_PROCESS_CPUTIME_ID)
 CHECK_SYMBOL_EXISTS(SA_SIGINFO signal.h HAVE_SA_SIGINFO)
index 468e5d6d4d7fdaecf6a8fbe3773c6b85fd424014..cdb5680f1b1795dd73fdeba988eb360bacb656b7 100644 (file)
@@ -82,6 +82,8 @@
 
 #cmakedefine HAVE_MMAP_ANON      1
 
+#cmakedefine HAVE_MMAP_NOCORE    1
+
 #cmakedefine HAVE_COMPATIBLE_QUEUE_H    1
 
 #cmakedefine HAVE_SC_NPROCESSORS_ONLN 1
index 40b1aaa79de88d3a9c6374381e3267899b475ddf..0b5c43a575271dbe294ae0845fdc68fb4a2083e5 100644 (file)
@@ -246,6 +246,7 @@ fuzzy_io_callback (int fd, short what, void *arg)
        if (what == EV_WRITE) {
                /* Send command to storage */
                cmd.blocksize = session->h->block_size;
+               cmd.value = 0;
                memcpy (cmd.hash, session->h->hash_pipe, sizeof (cmd.hash));
                cmd.cmd = FUZZY_CHECK;
                if (write (fd, &cmd, sizeof (struct fuzzy_cmd)) == -1) {
index 50ad3176e9a8085972222bba61786663d6699ae9..798803a027030b4204ba591b200b3e7371e08938 100644 (file)
--- a/src/spf.c
+++ b/src/spf.c
 #include "message.h"
 #include "filter.h"
 
-#define SPF_VER_STR "v=spf1"
+#define SPF_VER1_STR "v=spf1"
+#define SPF_VER2_STR "spf2."
+#define SPF_SCOPE_PRA "pra"
+#define SPF_SCOPE_MFROM "mfrom"
 #define SPF_ALL "all"
 #define SPF_A "a"
 #define SPF_IP4 "ip4"
@@ -70,6 +73,7 @@ struct spf_dns_cb {
        struct spf_record *rec;
        struct spf_addr *addr;
        spf_action_t cur_action;
+       gboolean in_include;
 };
 
 #define CHECK_REC(rec)                                                                         \
@@ -259,7 +263,8 @@ spf_record_dns_callback (int result, char type, int count, int ttl, void *addres
                                        if (type == DNS_TXT) {
                                                if (addresses != NULL) {
                                                        begin = *(char **)addresses;
-                                                       if (cb->rec->addrs) {
+
+                                                       if (!cb->in_include && cb->rec->addrs) {
                                                                g_list_free (cb->rec->addrs);
                                                                cb->rec->addrs = NULL;
                                                        }
@@ -288,7 +293,6 @@ spf_record_dns_callback (int result, char type, int count, int ttl, void *addres
                                                                        if (elt->prev == NULL && elt->next == NULL) {
                                                                                g_list_free1 (elt);
                                                                        }
-
                                                                        else {
 
                                                                                if (elt->prev) {
@@ -297,13 +301,18 @@ spf_record_dns_callback (int result, char type, int count, int ttl, void *addres
                                                                                else {
                                                                                        /* Elt is the first element, so we need to shift temporary list */
                                                                                        tmp = elt->next;
+                                                                                       tmp->prev = NULL;
                                                                                }
                                                                                if (elt->next) {
                                                                                        elt->next->prev = last;
-                                                                                       last->next = elt->next;
+                                                                                       if (last != NULL) {
+                                                                                               last->next = elt->next;
+                                                                                       }
+                                                                               }
+                                                                               
+                                                                               if (cb->rec->addrs != NULL) {
+                                                                                       cb->rec->addrs->prev = elt->prev;
                                                                                }
-
-                                                                               cb->rec->addrs->prev = elt->prev;
 
                                                                                cb->rec->addrs = tmp;
                                                                                g_list_free1 (elt);
@@ -395,6 +404,7 @@ parse_spf_a (struct worker_task *task, const char *begin, struct spf_record *rec
        cb->rec = rec;
        cb->addr = addr;
        cb->cur_action = SPF_RESOLVE_A;
+       cb->in_include = rec->in_include;
 
        if (evdns_resolve_ipv4 (host, DNS_QUERY_NO_SEARCH, spf_record_dns_callback, (void *)cb) == 0) {
                task->save.saved++;
@@ -442,6 +452,7 @@ parse_spf_mx (struct worker_task *task, const char *begin, struct spf_record *re
        cb->rec = rec;
        cb->addr = addr;
        cb->cur_action = SPF_RESOLVE_MX;
+       cb->in_include = rec->in_include;
 
        if (evdns_resolve_mx (host, DNS_QUERY_NO_SEARCH, spf_record_dns_callback, (void *)cb) == 0) {
                task->save.saved++;
@@ -497,6 +508,7 @@ parse_spf_include (struct worker_task *task, const char *begin, struct spf_recor
        cb->rec = rec;
        cb->addr = addr;
        cb->cur_action = SPF_RESOLVE_INCLUDE;
+       cb->in_include = rec->in_include;
        domain = memory_pool_strdup (task->task_pool, begin);
 
        if (evdns_resolve_txt (domain, DNS_QUERY_NO_SEARCH, spf_record_dns_callback, (void *)cb) == 0) {
@@ -535,7 +547,8 @@ parse_spf_redirect (struct worker_task *task, const char *begin, struct spf_reco
        cb = memory_pool_alloc (task->task_pool, sizeof (struct spf_dns_cb));
        cb->rec = rec;
        cb->addr = addr;
-       cb->cur_action = SPF_RESOLVE_INCLUDE;
+       cb->cur_action = SPF_RESOLVE_REDIRECT;
+       cb->in_include = rec->in_include;
        domain = memory_pool_strdup (task->task_pool, begin);
 
        if (evdns_resolve_txt (domain, DNS_QUERY_NO_SEARCH, spf_record_dns_callback, (void *)cb) == 0) {
@@ -567,6 +580,7 @@ parse_spf_exists (struct worker_task *task, const char *begin, struct spf_record
        cb->rec = rec;
        cb->addr = addr;
        cb->cur_action = SPF_RESOLVE_EXISTS;
+       cb->in_include = rec->in_include;
        host = memory_pool_strdup (task->task_pool, begin);
 
        if (evdns_resolve_ipv4 (host, DNS_QUERY_NO_SEARCH, spf_record_dns_callback, (void *)cb) == 0) {
@@ -850,6 +864,11 @@ parse_spf_record (struct worker_task *task, struct spf_record *rec)
        if (rec->cur_elt == NULL) {
                return FALSE;
        }
+       else if (*rec->cur_elt == '\0') {
+               /* Silently skip empty elements */
+               rec->elt_num ++;
+               return TRUE;
+       }
        else {
                begin = expand_spf_macro (task, rec, rec->cur_elt);
                if (*begin == '?' || *begin == '+' || *begin == '-' || *begin == '~') {
@@ -960,15 +979,67 @@ parse_spf_record (struct worker_task *task, struct spf_record *rec)
 }
 #undef NEW_ADDR
 
+static void
+parse_spf_scopes (struct spf_record *rec, char **begin)
+{
+       for (;;) {
+               if (g_ascii_strncasecmp (*begin, SPF_SCOPE_PRA, sizeof (SPF_SCOPE_PRA) - 1) == 0) {
+                       *begin += sizeof (SPF_SCOPE_PRA) - 1;
+                       /* XXX: Implement actual PRA check */
+                       /* extract_pra_info (rec); */
+                       continue;
+               }
+               else if (g_ascii_strncasecmp (*begin, SPF_SCOPE_MFROM, sizeof (SPF_SCOPE_MFROM) - 1) == 0) {
+                       /* mfrom is standart spf1 check */
+                       *begin += sizeof (SPF_SCOPE_MFROM) - 1;
+                       continue;
+               }
+               else if (**begin != ',') {
+                       break;
+               }
+               (*begin) ++;
+       }
+}
+
 static void
 start_spf_parse (struct spf_record *rec, char *begin)
 {
-       if (strncmp (begin, SPF_VER_STR, sizeof (SPF_VER_STR) - 1) == 0) {
-               begin += sizeof (SPF_VER_STR) - 1;
+       /* Skip spaces */
+       while (g_ascii_isspace (*begin)) {
+               begin ++;
+       }
+
+       if (g_ascii_strncasecmp (begin, SPF_VER1_STR, sizeof (SPF_VER1_STR) - 1) == 0) {
+               begin += sizeof (SPF_VER1_STR) - 1;
+               while (g_ascii_isspace (*begin) && *begin) {
+                       begin ++;
+               }
+               rec->elts = g_strsplit_set (begin, " ", 0);
+               rec->elt_num = 0;
+               if (rec->elts) {
+                       memory_pool_add_destructor (rec->task->task_pool, (pool_destruct_func)g_strfreev, rec->elts);
+                       rec->cur_elt = rec->elts[0];
+                       while (parse_spf_record (rec->task, rec));
+                       if (rec->addrs) {
+                               rec->addrs = g_list_reverse (rec->addrs);
+                       }
+               }
+       }
+       else if (g_ascii_strncasecmp (begin, SPF_VER2_STR, sizeof (SPF_VER2_STR) - 1) == 0) {
+               /* Skip one number of record, so no we are here spf2.0/ */
+               begin += sizeof (SPF_VER2_STR);
+               if (*begin != '/') {
+                       msg_info ("sender id string has not valid skope");
+               }
+               else {
+                       begin ++;
+                       parse_spf_scopes (rec, &begin);
+               }
+               /* Now common spf record */
                while (g_ascii_isspace (*begin) && *begin) {
                        begin ++;
                }
-               rec->elts = g_strsplit (begin, " ", 0);
+               rec->elts = g_strsplit_set (begin, " ", 0);
                rec->elt_num = 0;
                if (rec->elts) {
                        memory_pool_add_destructor (rec->task->task_pool, (pool_destruct_func)g_strfreev, rec->elts);
@@ -980,7 +1051,7 @@ start_spf_parse (struct spf_record *rec, char *begin)
                }
        }
        else {
-               msg_info ("bad spf record version: %*s", sizeof (SPF_VER_STR) - 1, begin);
+               msg_info ("bad spf record version: %*s", sizeof (SPF_VER1_STR) - 1, begin);
        }
 }
 
index c3313e47ab628b5f2d64716965ea242509211f6f..1e47b3ec7245fc9ad925190bf74839af7924bffc 100644 (file)
@@ -104,7 +104,11 @@ convert_statfile_10 (stat_file_t * file)
        /* Unmap old memory and map new */
        munmap (file->map, file->len);
        file->len = file->len + sizeof (struct stat_file_header) - sizeof (struct stat_file_header_10);
+#ifdef HAVE_MMAP_NOCORE
+       if ((file->map = mmap (NULL, file->len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_NOCORE, file->fd, 0)) == MAP_FAILED) {
+#else
        if ((file->map = mmap (NULL, file->len, PROT_READ | PROT_WRITE, MAP_SHARED, file->fd, 0)) == MAP_FAILED) {
+#endif
                msg_info ("cannot mmap file %s, error %d, %s", file->filename, errno, strerror (errno));
                return FALSE;
        }