]> source.dussan.org Git - rspamd.git/commitdiff
Fix parsing of DNS records :(
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 25 Feb 2011 14:14:56 +0000 (17:14 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Fri, 25 Feb 2011 14:14:56 +0000 (17:14 +0300)
Fix parsing several mx addrs in spf parser [1]

Reported by: Victor Ustugov

src/dns.c
src/dns.h
src/spf.c

index e11d035820b2e7bd2c69ee41c37ed62a1b1de887..d29ea5696d3d154767f2e7ae421161c840ab196e 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -572,8 +572,8 @@ dns_fin_cb (gpointer arg)
 static guint8 *
 decompress_label (guint8 *begin, guint16 *len, guint16 max)
 {
-       guint16 offset;
-       offset = ntohs ((*len) ^ DNS_COMPRESSION_BITS);
+       guint16 offset = DNS_COMPRESSION_BITS;
+       offset = (*len) ^ (offset << 8);
 
        if (offset > max) {
                return NULL;
@@ -610,7 +610,7 @@ dns_request_reply_cmp (struct rspamd_dns_request *req, guint8 *in, gint len)
                }
                /* This may be compressed, so we need to decompress it */
                if (len1 & DNS_COMPRESSION_BITS) {
-                       memcpy (&len1, p, sizeof (guint16));
+                       len1 = ((*p) << 8) + *(p + 1);
                        l1 = decompress_label (in, &len1, len);
                        if (l1 == NULL) {
                                msg_info ("invalid DNS pointer");
@@ -625,7 +625,7 @@ dns_request_reply_cmp (struct rspamd_dns_request *req, guint8 *in, gint len)
                        p += len1;
                }
                if (len2 & DNS_COMPRESSION_BITS) {
-                       memcpy (&len2, p, sizeof (guint16));
+                       len2 = ((*p) << 8) + *(p + 1);
                        l2 = decompress_label (req->packet, &len2, len);
                        if (l2 == NULL) {
                                msg_info ("invalid DNS pointer");
@@ -686,7 +686,7 @@ dns_parse_labels (guint8 *in, gchar **target, guint8 **pos, struct rspamd_dns_re
                }
                else if (llen & DNS_COMPRESSION_BITS) {
                        ptrs ++;
-                       memcpy (&llen, p, sizeof (guint16));
+                       llen = ((*p) << 8) + *(p + 1);
                        l = decompress_label (in, &llen, end - in);
                        if (l == NULL) {
                                msg_info ("invalid DNS pointer");
@@ -728,7 +728,7 @@ dns_parse_labels (guint8 *in, gchar **target, guint8 **pos, struct rspamd_dns_re
                        break;
                }
                else if (llen & DNS_COMPRESSION_BITS) {
-                       memcpy (&llen, p, sizeof (guint16));
+                       llen = ((*p) << 8) + *(p + 1);
                        l = decompress_label (in, &llen, end - in);
                        begin = l;
                        length = end - begin;
@@ -747,7 +747,7 @@ dns_parse_labels (guint8 *in, gchar **target, guint8 **pos, struct rspamd_dns_re
        *(t - 1) = '\0';
 end:
        if (offset < 0) {
-               offset = p - begin;
+               offset = p - begin + 1;
        }
        *remain -= offset;
        *pos += offset;
@@ -815,6 +815,7 @@ dns_parse_rr (guint8 *in, union rspamd_reply_element *elt, guint8 **pos, struct
                }
                else {
                        GET16 (elt->mx.priority);
+                       datalen -= sizeof (guint16);
                        if (! dns_parse_labels (in, &elt->mx.name, &p, rep, remain, TRUE)) {
                                msg_info ("invalid labels in MX record");
                                return -1;
index 57877748b100848d5eafc24ff895f3a651550a81..9896a6fa445711dc01057407c4bf73b385327e72 100644 (file)
--- a/src/dns.h
+++ b/src/dns.h
@@ -11,7 +11,7 @@
 #define DNS_D_MAXLABEL 63      /* + 1 '\0' */
 #define DNS_D_MAXNAME  255     /* + 1 '\0' */
 
-#define MAX_ADDRS 4
+#define MAX_ADDRS 1
 
 struct rspamd_dns_reply;
 struct config_file;
index 8e60604ac37dda04cefddc4e330a4818d8bd3e48..212bd0074ef48c0d874cbabe122fe7d96f571aa2 100644 (file)
--- a/src/spf.c
+++ b/src/spf.c
@@ -265,11 +265,13 @@ parse_spf_hostmask (struct worker_task *task, const gchar *begin, struct spf_add
 static void
 spf_record_dns_callback (struct rspamd_dns_reply *reply, gpointer arg)
 {
-       struct spf_dns_cb *cb = arg;
+       struct spf_dns_cb               *cb = arg;
        gchar                           *begin;
-       union rspamd_reply_element *elt_data;
-       GList *tmp = NULL, *tmp1, *elt, *last;
-       struct worker_task *task;
+       union rspamd_reply_element      *elt_data;
+       GList                           *tmp = NULL, *tmp1,
+                                               *elt, *last;
+       struct worker_task              *task;
+       struct spf_addr                 *new_addr;
 
        task = cb->rec->task;
 
@@ -288,8 +290,23 @@ spf_record_dns_callback (struct rspamd_dns_reply *reply, gpointer arg)
                                                }
                                        }
                                        else if (reply->type == DNS_REQUEST_A) {
-                                               /* XXX: process only one record */
-                                               cb->addr->addr = ntohl (elt_data->a.addr[0].s_addr);
+                                               if (cb->addr->addr == 0) {
+                                                       cb->addr->addr = ntohl (elt_data->a.addr[0].s_addr);
+                                               }
+                                               else {
+                                                       /* Insert one more address */
+                                                       tmp = g_list_find (cb->rec->addrs, cb->addr);
+                                                       if (tmp) {
+                                                               new_addr = memory_pool_alloc (task->task_pool, sizeof (struct spf_addr));
+                                                               memcpy (new_addr, cb->addr, sizeof (struct spf_addr));
+                                                               new_addr->addr = ntohl (elt_data->a.addr[0].s_addr);
+                                                               cb->rec->addrs = g_list_insert_before (cb->rec->addrs, tmp, new_addr);
+                                                       }
+                                                       else {
+                                                               msg_info ("wrong address list");
+                                                       }
+                                               }
+
                                        }
                                        break;
                                case SPF_RESOLVE_A:
@@ -496,6 +513,7 @@ parse_spf_mx (struct worker_task *task, const gchar *begin, struct spf_record *r
        cb = memory_pool_alloc (task->task_pool, sizeof (struct spf_dns_cb));
        cb->rec = rec;
        cb->addr = addr;
+       addr->addr = 0;
        cb->cur_action = SPF_RESOLVE_MX;
        cb->in_include = rec->in_include;
        if (make_dns_request (task->resolver, task->s, task->task_pool, spf_record_dns_callback, (void *)cb, DNS_REQUEST_MX, host)) {