From 730d2740eb77ff757cbeca6bc56151327cfa1ed0 Mon Sep 17 00:00:00 2001 From: "cebka@lenovo-laptop" Date: Sat, 27 Feb 2010 18:59:05 +0300 Subject: [PATCH] * Fix cores in spf code (partially) * Add support for spf 2.0 (Sender ID policy) * Add support of MAP_NOCORE to systems that supports it (FreeBSD for example) --- CMakeLists.txt | 1 + config.h.in | 2 + src/plugins/fuzzy_check.c | 1 + src/spf.c | 93 ++++++++++++++++++++++++++++++++++----- src/statfile.c | 4 ++ 5 files changed, 90 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58a823c29..22d2c21f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/config.h.in b/config.h.in index 468e5d6d4..cdb5680f1 100644 --- a/config.h.in +++ b/config.h.in @@ -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 diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c index 40b1aaa79..0b5c43a57 100644 --- a/src/plugins/fuzzy_check.c +++ b/src/plugins/fuzzy_check.c @@ -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) { diff --git a/src/spf.c b/src/spf.c index 50ad3176e..798803a02 100644 --- a/src/spf.c +++ b/src/spf.c @@ -29,7 +29,10 @@ #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); } } diff --git a/src/statfile.c b/src/statfile.c index c3313e47a..1e47b3ec7 100644 --- a/src/statfile.c +++ b/src/statfile.c @@ -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; } -- 2.39.5