]>
Commit | Line | Data |
---|---|---|
c6ce1e7e MT |
1 | From 1e153945def3c50d1e59ceea6a768db0ac770f98 Mon Sep 17 00:00:00 2001 |
2 | From: Simon Kelley <simon@thekelleys.org.uk> | |
3 | Date: Sat, 28 Mar 2015 21:34:07 +0000 | |
888c41de | 4 | Subject: [PATCH 64/98] DNSSEC fix for non-ascii characters in labels. |
c6ce1e7e MT |
5 | |
6 | --- | |
7 | src/dnssec.c | 34 +++++++++++++++++----------------- | |
8 | src/rfc1035.c | 5 +++-- | |
9 | 2 files changed, 20 insertions(+), 19 deletions(-) | |
10 | ||
11 | diff --git a/src/dnssec.c b/src/dnssec.c | |
12 | index 14bae7e9bf75..8bd5294ce773 100644 | |
13 | --- a/src/dnssec.c | |
14 | +++ b/src/dnssec.c | |
15 | @@ -552,7 +552,7 @@ static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, | |
16 | ||
17 | (*desc)++; | |
18 | ||
19 | - if (d == 0 && extract_name(header, plen, p, buff, 1, 0)) | |
20 | + if (d == 0 && extract_name(header, plen, p, buff, 2, 0)) | |
21 | /* domain-name, canonicalise */ | |
22 | return to_wire(buff); | |
23 | else | |
24 | @@ -811,7 +811,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in | |
25 | GETLONG(sig_inception, p); | |
26 | GETSHORT(key_tag, p); | |
27 | ||
28 | - if (!extract_name(header, plen, &p, keyname, 1, 0)) | |
29 | + if (!extract_name(header, plen, &p, keyname, 2, 0)) | |
30 | return STAT_BOGUS; | |
31 | ||
32 | /* RFC 4035 5.3.1 says that the Signer's Name field MUST equal | |
33 | @@ -866,7 +866,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in | |
34 | u16 len, *dp; | |
35 | ||
36 | p = rrset[i]; | |
37 | - if (!extract_name(header, plen, &p, name, 1, 10)) | |
38 | + if (!extract_name(header, plen, &p, name, 2, 10)) | |
39 | return STAT_BOGUS; | |
40 | ||
41 | name_start = name; | |
42 | @@ -923,7 +923,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in | |
43 | ||
44 | /* namebuff used for workspace above, restore to leave unchanged on exit */ | |
45 | p = (unsigned char*)(rrset[0]); | |
46 | - extract_name(header, plen, &p, name, 1, 0); | |
47 | + extract_name(header, plen, &p, name, 2, 0); | |
48 | ||
49 | if (key) | |
50 | { | |
51 | @@ -963,7 +963,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch | |
52 | struct all_addr a; | |
53 | ||
54 | if (ntohs(header->qdcount) != 1 || | |
55 | - !extract_name(header, plen, &p, name, 1, 4)) | |
56 | + !extract_name(header, plen, &p, name, 2, 4)) | |
57 | return STAT_BOGUS; | |
58 | ||
59 | GETSHORT(qtype, p); | |
60 | @@ -1202,7 +1202,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char | |
61 | val = STAT_BOGUS; | |
62 | ||
63 | p = (unsigned char *)(header+1); | |
64 | - extract_name(header, plen, &p, name, 1, 4); | |
65 | + extract_name(header, plen, &p, name, 2, 4); | |
66 | p += 4; /* qtype, qclass */ | |
67 | ||
68 | if (!(p = skip_section(p, ntohs(header->ancount), header, plen))) | |
69 | @@ -1419,12 +1419,12 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi | |
70 | for (i = 0; i < nsec_count; i++) | |
71 | { | |
72 | p = nsecs[i]; | |
73 | - if (!extract_name(header, plen, &p, workspace1, 1, 10)) | |
74 | + if (!extract_name(header, plen, &p, workspace1, 2, 10)) | |
75 | return STAT_BOGUS; | |
76 | p += 8; /* class, type, TTL */ | |
77 | GETSHORT(rdlen, p); | |
78 | psave = p; | |
79 | - if (!extract_name(header, plen, &p, workspace2, 1, 10)) | |
80 | + if (!extract_name(header, plen, &p, workspace2, 2, 10)) | |
81 | return STAT_BOGUS; | |
82 | ||
83 | rc = hostname_cmp(workspace1, name); | |
84 | @@ -1553,7 +1553,7 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige | |
85 | for (i = 0; i < nsec_count; i++) | |
86 | if ((p = nsecs[i])) | |
87 | { | |
88 | - if (!extract_name(header, plen, &p, workspace1, 1, 0) || | |
89 | + if (!extract_name(header, plen, &p, workspace1, 2, 0) || | |
90 | !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2))) | |
91 | return 0; | |
92 | ||
93 | @@ -1730,7 +1730,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns | |
94 | for (i = 0; i < nsec_count; i++) | |
95 | if ((p = nsecs[i])) | |
96 | { | |
97 | - if (!extract_name(header, plen, &p, workspace1, 1, 0) || | |
98 | + if (!extract_name(header, plen, &p, workspace1, 2, 0) || | |
99 | !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2))) | |
100 | return STAT_BOGUS; | |
101 | ||
102 | @@ -1796,7 +1796,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch | |
103 | ||
104 | qname = p1 = (unsigned char *)(header+1); | |
105 | ||
106 | - if (!extract_name(header, plen, &p1, name, 1, 4)) | |
107 | + if (!extract_name(header, plen, &p1, name, 2, 4)) | |
108 | return STAT_BOGUS; | |
109 | ||
110 | GETSHORT(qtype, p1); | |
111 | @@ -1836,7 +1836,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch | |
112 | qname = p1; | |
113 | ||
114 | /* looped CNAMES */ | |
115 | - if (!cname_count-- || !extract_name(header, plen, &p1, name, 1, 0)) | |
116 | + if (!cname_count-- || !extract_name(header, plen, &p1, name, 2, 0)) | |
117 | return STAT_BOGUS; | |
118 | ||
119 | p1 = ans_start; | |
120 | @@ -1857,7 +1857,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch | |
121 | ||
122 | for (p1 = ans_start, i = 0; i < ntohs(header->ancount) + ntohs(header->nscount); i++) | |
123 | { | |
124 | - if (!extract_name(header, plen, &p1, name, 1, 10)) | |
125 | + if (!extract_name(header, plen, &p1, name, 2, 10)) | |
126 | return STAT_BOGUS; /* bad packet */ | |
127 | ||
128 | GETSHORT(type1, p1); | |
129 | @@ -2039,7 +2039,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch | |
130 | an unsigned zone. Return STAT_NO_SIG to cause this to be proved. */ | |
131 | ||
132 | /* Get name of missing answer */ | |
133 | - if (!extract_name(header, plen, &qname, name, 1, 0)) | |
134 | + if (!extract_name(header, plen, &qname, name, 2, 0)) | |
135 | return STAT_BOGUS; | |
136 | ||
137 | if (nsec_type == T_NSEC) | |
138 | @@ -2061,7 +2061,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char | |
139 | int cname_count = CNAME_CHAIN; | |
140 | ||
141 | /* Get question */ | |
142 | - if (!extract_name(header, plen, &p, name, 1, 4)) | |
143 | + if (!extract_name(header, plen, &p, name, 2, 4)) | |
144 | return STAT_BOGUS; | |
145 | ||
146 | p +=2; /* type */ | |
147 | @@ -2102,7 +2102,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char | |
148 | ||
149 | /* Loop down CNAME chain/ */ | |
150 | if (!cname_count-- || | |
151 | - !extract_name(header, plen, &p, name, 1, 0) || | |
152 | + !extract_name(header, plen, &p, name, 2, 0) || | |
153 | !(p = skip_questions(header, plen))) | |
154 | return STAT_BOGUS; | |
155 | ||
156 | @@ -2419,7 +2419,7 @@ unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name | |
157 | ||
158 | for (q = ntohs(header->qdcount); q != 0; q--) | |
159 | { | |
160 | - if (!extract_name(header, plen, &p, name, 1, 4)) | |
161 | + if (!extract_name(header, plen, &p, name, 2, 4)) | |
162 | break; /* bad packet */ | |
163 | ||
164 | len = to_wire(name); | |
165 | diff --git a/src/rfc1035.c b/src/rfc1035.c | |
166 | index 5ef5ddb7485e..10832a3d5d2e 100644 | |
167 | --- a/src/rfc1035.c | |
168 | +++ b/src/rfc1035.c | |
169 | @@ -16,6 +16,7 @@ | |
170 | ||
171 | #include "dnsmasq.h" | |
172 | ||
173 | +/* isExtract == 2 -> DNSSEC mode, no bitstrings, no ascii checks. */ | |
174 | int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, | |
175 | char *name, int isExtract, int extrabytes) | |
176 | { | |
177 | @@ -86,7 +87,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, | |
178 | if ((l & 0x3f) != 1) | |
179 | return 0; /* we only understand bitstrings */ | |
180 | ||
181 | - if (!isExtract) | |
182 | + if (isExtract != 1) | |
183 | return 0; /* Cannot compare bitsrings */ | |
184 | ||
185 | count = *p++; | |
186 | @@ -128,7 +129,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, | |
187 | if (isExtract) | |
188 | { | |
189 | unsigned char c = *p; | |
190 | - if (isascii(c) && !iscntrl(c) && c != '.') | |
191 | + if ((isExtract == 2 || (isascii(c) && !iscntrl(c))) && c != '.') | |
192 | *cp++ = *p; | |
193 | else | |
194 | return 0; | |
195 | -- | |
196 | 2.1.0 | |
197 |