]> source.dussan.org Git - rspamd.git/commitdiff
* Small improvement of lua style
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Sat, 17 Oct 2009 01:50:38 +0000 (05:50 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Sat, 17 Oct 2009 01:50:38 +0000 (05:50 +0400)
* Add ibility to process A records in spf parser
* Add recursion limit to spf parser

src/plugins/lua/forged_recipients.lua
src/spf.c
src/spf.h

index 82f53dd73d5fa59fac5ef944d3096e4d6ef567a9..d5fda34bbe158d0da955ebde0b8b03525924f97d 100644 (file)
@@ -26,7 +26,7 @@ function check_forged_headers(task)
                else
                        -- Find pair for each smtp recipient recipient in To or Cc headers
                        for _,sr in ipairs(smtp_rcpt) do
-                               if string.byte(sr, 1) == string.byte('<') then
+                               if sr:byte(1) == utf8.ltsym then
                                        -- Trim brackets
                                        sr = string.sub(sr, 2, -2)
                                end
index 695eaaea46d6700a027f30cccd8fb7555961c32c..c72698bc182caa283f30d45869a87ec91fcda3d9 100644 (file)
--- a/src/spf.c
+++ b/src/spf.c
 struct spf_dns_cb {
        struct spf_record *rec;
        struct spf_addr *addr;
+       spf_action_t cur_action;
 };
 
+#define CHECK_REC(rec)                                                                         \
+do {                                                                                                           \
+       if ((rec)->nested > SPF_MAX_NESTING ||                                  \
+               (rec)->dns_requests > SPF_MAX_DNS_REQUESTS) {           \
+               return FALSE;                                                                           \
+       }                                                                                                               \
+} while (0)                                                                                                    \
+       
+
 /* Determine spf mech */
 static spf_mech_t
 check_spf_mech (const char *elt, gboolean *need_shift)
@@ -174,10 +184,86 @@ parse_spf_ipmask (const char *begin, struct spf_addr *addr)
 
 }
 
+static void
+spf_record_dns_callback (int result, char type, int count, int ttl, void *addresses, void *data)
+{
+       struct spf_dns_cb *cb = data;
+       char *begin;
+
+       if (result == DNS_ERR_NONE) {
+               if (addresses != NULL) {
+                       /* Add all logic for all DNS states here */
+                       switch (cb->cur_action) {
+                               case SPF_RESOLVE_MX:
+                                       break;
+                               case SPF_RESOLVE_A:
+                                       if (type == DNS_IPv4_A) {
+                                               /* XXX: process only one record */
+                                               cb->addr->addr = *((uint32_t *)addresses);
+                                       }
+                                       break;
+                               case SPF_RESOLVE_PTR:
+                                       break;
+                               case SPF_RESOLVE_REDIRECT:
+                                       break;
+                               case SPF_RESOLVE_INCLUDE:
+                                       break;
+                               case SPF_RESOLVE_EXP:
+                                       break;
+                       }
+               }
+       }
+
+       cb->rec->task->save.saved--;
+       if (cb->rec->task->save.saved == 0 && cb->rec->callback) {
+               cb->rec->callback (cb->rec, cb->rec->task);
+       }
+       remove_forced_event (cb->rec->task->s, (event_finalizer_t) spf_record_dns_callback);
+
+}
+
 static gboolean
 parse_spf_a (struct worker_task *task, const char *begin, struct spf_record *rec, struct spf_addr *addr)
 {
        struct spf_dns_cb *cb;
+       char *host, *p,  mask_buf[3];
+       int hostlen;
+       
+       CHECK_REC (rec);
+
+       bzero (mask_buf, sizeof (mask_buf));
+       p = strchr (begin, '/');
+       if (p != NULL) {
+               /* Extract mask */
+               g_strlcpy (mask_buf, p + 1, sizeof (mask_buf));
+               addr->mask = mask_buf[0] * 10 + mask_buf[1];
+               if (addr->mask > 32) {
+                       return FALSE;
+               }
+               hostlen = p - begin;
+               host = memory_pool_alloc (task->task_pool, hostlen);
+               g_strlcpy (host, begin, hostlen);
+       }
+       else {
+               addr->mask = 32;
+               g_strlcpy (host, begin, strlen (begin));
+       }
+       
+       rec->dns_requests ++;
+       cb = memory_pool_alloc (task->task_pool, sizeof (struct spf_dns_cb));
+       cb->rec = rec;
+       cb->addr = addr;
+       cb->cur_action = SPF_RESOLVE_A;
+
+       if (evdns_resolve_ipv4 (host, DNS_QUERY_NO_SEARCH, spf_record_dns_callback, (void *)cb) == 0) {
+               task->save.saved++;
+               register_async_event (task->s, (event_finalizer_t) spf_record_dns_callback, NULL, TRUE);
+               
+               return TRUE;
+       }
+
+       return FALSE;
+
 }
 
 static gboolean
@@ -185,6 +271,8 @@ parse_spf_ptr (struct worker_task *task, const char *begin, struct spf_record *r
 {
        struct spf_dns_cb *cb;
 
+       CHECK_REC (rec);
+
 }
 
 static gboolean
@@ -192,6 +280,8 @@ parse_spf_mx (struct worker_task *task, const char *begin, struct spf_record *re
 {
        struct spf_dns_cb *cb;
 
+       CHECK_REC (rec);
+
 }
 
 static gboolean
@@ -207,6 +297,7 @@ parse_spf_ip4 (struct worker_task *task, const char *begin, struct spf_record *r
 {
        /* ip4:addr[/mask] */
 
+       CHECK_REC (rec);
        return parse_spf_ipmask (begin, addr);
 }
 
@@ -215,6 +306,8 @@ parse_spf_include (struct worker_task *task, const char *begin, struct spf_recor
 {
        struct spf_dns_cb *cb;
 
+       CHECK_REC (rec);
+
 }
 
 static gboolean
@@ -222,6 +315,7 @@ parse_spf_exp (struct worker_task *task, const char *begin, struct spf_record *r
 {
        struct spf_dns_cb *cb;
 
+       CHECK_REC (rec);
 }
 
 static gboolean
@@ -229,6 +323,7 @@ parse_spf_redirect (struct worker_task *task, const char *begin, struct spf_reco
 {
        struct spf_dns_cb *cb;
 
+       CHECK_REC (rec);
 }
 
 static gboolean
@@ -236,6 +331,7 @@ parse_spf_exists (struct worker_task *task, const char *begin, struct spf_record
 {
        struct spf_dns_cb *cb;
 
+       CHECK_REC (rec);
 }
 
 /* Read current element and try to parse record */
index 6c98f85efaeb35d361db64ab7f5a0b1af0b87bba..b3198095865b3273b2abbaca3a44649074d6dbb0 100644 (file)
--- a/src/spf.h
+++ b/src/spf.h
@@ -34,7 +34,8 @@ struct spf_record {
        char **elts;
 
        char **cur_elt;
-       spf_action_t cur_action;
+       int nested;
+       int dns_requests;
 
        GList *addrs;
        char *cur_domain;