Browse code

parse CNAME aliases

git-svn: trunk@4551

aCaB authored on 2008/12/11 21:04:07
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Thu Dec 11 13:08:20 CET 2008 (acab)
2
+-----------------------------------
3
+ * freshclam/dns.c: add support for TXT aliases
4
+
1 5
 Wed Dec 10 20:09:00 CET 2008 (tk)
2 6
 ---------------------------------
3 7
  * libclamav: add CL_FLEVEL_DCONF (bb#1313)
... ...
@@ -16,9 +16,6 @@
16 16
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 17
  *  MA 02110-1301, USA.
18 18
  */
19
-#ifdef	_MSC_VER
20
-#include <winsock.h>
21
-#endif
22 19
 
23 20
 #if HAVE_CONFIG_H
24 21
 #include "clamav-config.h"
... ...
@@ -45,9 +42,10 @@
45 45
 
46 46
 char *txtquery(const char *domain, unsigned int *ttl)
47 47
 {
48
-	unsigned char answer[PACKETSZ], *pt;
48
+	unsigned char answer[PACKETSZ], *answend, *pt;
49 49
 	char *txt, host[128];
50
-	int len, exp, cttl, size, txtlen, type, qtype;
50
+	int len, type, qtype;
51
+	unsigned int cttl, size, txtlen = 0;
51 52
 
52 53
 
53 54
     *ttl = 0;
... ...
@@ -60,7 +58,7 @@ char *txtquery(const char *domain, unsigned int *ttl)
60 60
 
61 61
     memset(answer, 0, PACKETSZ);
62 62
     qtype = T_TXT;
63
-    if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0) {
63
+    if((len = res_query(domain, C_IN, qtype, answer, PACKETSZ)) < 0 || len > PACKETSZ) {
64 64
 #ifdef FRESHCLAM_DNS_FIX
65 65
 	/*  The DNS server in the SpeedTouch Alcatel 510 modem can't
66 66
 	 *  handle a TXT-query, but it can resolve an ANY-query to a
... ...
@@ -79,14 +77,19 @@ char *txtquery(const char *domain, unsigned int *ttl)
79 79
 #endif
80 80
     }
81 81
 
82
+    answend = answer + len;
82 83
     pt = answer + sizeof(HEADER);
83 84
 
84
-    if((exp = dn_expand(answer, answer + len, pt, host, sizeof(host))) < 0) {
85
+    if((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) {
85 86
 	logg("^dn_expand failed\n");
86 87
 	return NULL;
87 88
     }
88 89
 
89
-    pt += exp;
90
+    pt += len;
91
+    if(pt > answend-4) {
92
+	logg("^Bad (too short) DNS reply\n");
93
+	return NULL;
94
+    }
90 95
 
91 96
     GETSHORT(type, pt);
92 97
     if(type != qtype) {
... ...
@@ -95,25 +98,34 @@ char *txtquery(const char *domain, unsigned int *ttl)
95 95
     }
96 96
 
97 97
     pt += INT16SZ; /* class */
98
+    size = 0;
99
+    do { /* recurse through CNAME rr's */
100
+	pt += size;
101
+    	if((len = dn_expand(answer, answend, pt, host, sizeof(host))) < 0) {
102
+	    logg("^second dn_expand failed\n");
103
+	    return NULL;
104
+	}
105
+	pt += len;
106
+	if(pt > answend-10) {
107
+	    logg("^Bad (too short) DNS reply\n");
108
+	    return NULL;
109
+	}
110
+	GETSHORT(type, pt);
111
+	pt += INT16SZ; /* class */
112
+	GETLONG(cttl, pt);
113
+	GETSHORT(size, pt);
114
+	if(pt + size < answer || pt + size >= answend) {
115
+	    logg("^DNS rr overflow\n");
116
+	    return NULL;
117
+	}
118
+    } while(type == T_CNAME);
98 119
 
99
-    if((exp = dn_expand(answer, answer + len, pt, host, sizeof(host))) < 0) {
100
-	logg("^second dn_expand failed\n");
101
-	return NULL;
102
-    }
103
-
104
-    pt += exp;
105
-    GETSHORT(type, pt);
106 120
     if(type != T_TXT) {
107 121
 	logg("^Not a TXT record\n");
108 122
 	return NULL;
109 123
     }
110 124
 
111
-    pt += INT16SZ; /* class */
112
-    GETLONG(cttl, pt);
113
-    GETSHORT(size, pt);
114
-    txtlen = *pt;
115
-
116
-    if(txtlen >= size || !txtlen) {
125
+    if(!size || (txtlen = *pt) >= size || !txtlen) {
117 126
 	logg("^Broken TXT record (txtlen = %d, size = %d)\n", txtlen, size);
118 127
 	return NULL;
119 128
     }
... ...
@@ -121,8 +133,7 @@ char *txtquery(const char *domain, unsigned int *ttl)
121 121
     if(!(txt = (char *) malloc(txtlen + 1)))
122 122
 	return NULL;
123 123
 
124
-    pt++;
125
-    memcpy(txt, pt, txtlen);
124
+    memcpy(txt, pt+1, txtlen);
126 125
     txt[txtlen] = 0;
127 126
     *ttl = cttl;
128 127
 
... ...
@@ -136,7 +147,7 @@ char *txtquery(const char *domain, unsigned int *ttl)
136 136
  * The dll behind this library is available from Windows 2000 onward.
137 137
  * Written by Mark Pizzolato
138 138
  */
139
-
139
+#include <winsock.h>
140 140
 #include <string.h>
141 141
 #include <windows.h>
142 142
 #include <windns.h>