]>
Commit | Line | Data |
---|---|---|
fbcc3cb7 MF |
1 | From 93be5b1e023b0c661e1ec2cd6d811a8ec9055c49 Mon Sep 17 00:00:00 2001 |
2 | From: Simon Kelley <simon@thekelleys.org.uk> | |
3 | Date: Tue, 15 Dec 2015 12:04:40 +0000 | |
4 | Subject: [PATCH] Abandon caching RRSIGs and returning them from cache. | |
5 | ||
6 | The list of exceptions to being able to locally answer | |
7 | cached data for validated records when DNSSEC data is requested | |
8 | was getting too long, so don't ever do that. This means | |
9 | that the cache no longer has to hold RRSIGS and allows | |
10 | us to lose lots of code. Note that cached validated | |
11 | answers are still returned as long as do=0 | |
12 | --- | |
13 | src/cache.c | 38 ++--------- | |
14 | src/dnsmasq.h | 10 +-- | |
15 | src/dnssec.c | 94 ++++----------------------- | |
16 | src/rfc1035.c | 197 ++++++--------------------------------------------------- | |
17 | 4 files changed, 42 insertions(+), 297 deletions(-) | |
18 | ||
19 | diff --git a/src/cache.c b/src/cache.c | |
20 | index 1b76b67..51ba7cc 100644 | |
21 | --- a/src/cache.c | |
22 | +++ b/src/cache.c | |
23 | @@ -189,12 +189,7 @@ static void cache_hash(struct crec *crecp) | |
24 | static void cache_blockdata_free(struct crec *crecp) | |
25 | { | |
26 | if (crecp->flags & F_DNSKEY) | |
27 | - { | |
28 | - if (crecp->flags & F_DS) | |
29 | - blockdata_free(crecp->addr.sig.keydata); | |
30 | - else | |
31 | - blockdata_free(crecp->addr.key.keydata); | |
32 | - } | |
33 | + blockdata_free(crecp->addr.key.keydata); | |
34 | else if ((crecp->flags & F_DS) && !(crecp->flags & F_NEG)) | |
35 | blockdata_free(crecp->addr.ds.keydata); | |
36 | } | |
37 | @@ -369,13 +364,8 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no | |
38 | } | |
39 | ||
40 | #ifdef HAVE_DNSSEC | |
41 | - /* Deletion has to be class-sensitive for DS, DNSKEY, RRSIG, also | |
42 | - type-covered sensitive for RRSIG */ | |
43 | - if ((flags & (F_DNSKEY | F_DS)) && | |
44 | - (flags & (F_DNSKEY | F_DS)) == (crecp->flags & (F_DNSKEY | F_DS)) && | |
45 | - crecp->uid == addr->addr.dnssec.class && | |
46 | - (!((flags & (F_DS | F_DNSKEY)) == (F_DS | F_DNSKEY)) || | |
47 | - crecp->addr.sig.type_covered == addr->addr.dnssec.type)) | |
48 | + /* Deletion has to be class-sensitive for DS and DNSKEY */ | |
49 | + if ((flags & crecp->flags & (F_DNSKEY | F_DS)) && crecp->uid == addr->addr.dnssec.class) | |
50 | { | |
51 | if (crecp->flags & F_CONFIG) | |
52 | return crecp; | |
53 | @@ -532,13 +522,9 @@ struct crec *cache_insert(char *name, struct all_addr *addr, | |
54 | struct all_addr free_addr = new->addr.addr;; | |
55 | ||
56 | #ifdef HAVE_DNSSEC | |
57 | - /* For DNSSEC records, addr holds class and type_covered for RRSIG */ | |
58 | + /* For DNSSEC records, addr holds class. */ | |
59 | if (new->flags & (F_DS | F_DNSKEY)) | |
60 | - { | |
61 | - free_addr.addr.dnssec.class = new->uid; | |
62 | - if ((new->flags & (F_DS | F_DNSKEY)) == (F_DS | F_DNSKEY)) | |
63 | - free_addr.addr.dnssec.type = new->addr.sig.type_covered; | |
64 | - } | |
65 | + free_addr.addr.dnssec.class = new->uid; | |
66 | #endif | |
67 | ||
68 | free_avail = 1; /* Must be free space now. */ | |
69 | @@ -653,9 +639,6 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsi | |
70 | if (!is_expired(now, crecp) && !is_outdated_cname_pointer(crecp)) | |
71 | { | |
72 | if ((crecp->flags & F_FORWARD) && | |
73 | -#ifdef HAVE_DNSSEC | |
74 | - (((crecp->flags & (F_DNSKEY | F_DS)) == (prot & (F_DNSKEY | F_DS))) || (prot & F_NSIGMATCH)) && | |
75 | -#endif | |
76 | (crecp->flags & prot) && | |
77 | hostname_isequal(cache_get_name(crecp), name)) | |
78 | { | |
79 | @@ -713,9 +696,6 @@ struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsi | |
80 | ||
81 | if (ans && | |
82 | (ans->flags & F_FORWARD) && | |
83 | -#ifdef HAVE_DNSSEC | |
84 | - (((ans->flags & (F_DNSKEY | F_DS)) == (prot & (F_DNSKEY | F_DS))) || (prot & F_NSIGMATCH)) && | |
85 | -#endif | |
86 | (ans->flags & prot) && | |
87 | hostname_isequal(cache_get_name(ans), name)) | |
88 | return ans; | |
89 | @@ -1472,11 +1452,7 @@ void dump_cache(time_t now) | |
90 | #ifdef HAVE_DNSSEC | |
91 | else if (cache->flags & F_DS) | |
92 | { | |
93 | - if (cache->flags & F_DNSKEY) | |
94 | - /* RRSIG */ | |
95 | - sprintf(a, "%5u %3u %s", cache->addr.sig.keytag, | |
96 | - cache->addr.sig.algo, querystr("", cache->addr.sig.type_covered)); | |
97 | - else if (!(cache->flags & F_NEG)) | |
98 | + if (!(cache->flags & F_NEG)) | |
99 | sprintf(a, "%5u %3u %3u", cache->addr.ds.keytag, | |
100 | cache->addr.ds.algo, cache->addr.ds.digest); | |
101 | } | |
102 | @@ -1502,8 +1478,6 @@ void dump_cache(time_t now) | |
103 | else if (cache->flags & F_CNAME) | |
104 | t = "C"; | |
105 | #ifdef HAVE_DNSSEC | |
106 | - else if ((cache->flags & (F_DS | F_DNSKEY)) == (F_DS | F_DNSKEY)) | |
107 | - t = "G"; /* DNSKEY and DS set -> RRISG */ | |
108 | else if (cache->flags & F_DS) | |
109 | t = "S"; | |
110 | else if (cache->flags & F_DNSKEY) | |
111 | diff --git a/src/dnsmasq.h b/src/dnsmasq.h | |
112 | index 023a1cf..4344cae 100644 | |
113 | --- a/src/dnsmasq.h | |
114 | +++ b/src/dnsmasq.h | |
115 | @@ -398,14 +398,9 @@ struct crec { | |
116 | unsigned char algo; | |
117 | unsigned char digest; | |
118 | } ds; | |
119 | - struct { | |
120 | - struct blockdata *keydata; | |
121 | - unsigned short keylen, type_covered, keytag; | |
122 | - char algo; | |
123 | - } sig; | |
124 | } addr; | |
125 | time_t ttd; /* time to die */ | |
126 | - /* used as class if DNSKEY/DS/RRSIG, index to source for F_HOSTS */ | |
127 | + /* used as class if DNSKEY/DS, index to source for F_HOSTS */ | |
128 | unsigned int uid; | |
129 | unsigned short flags; | |
130 | union { | |
131 | @@ -445,8 +440,7 @@ struct crec { | |
132 | #define F_SECSTAT (1u<<24) | |
133 | #define F_NO_RR (1u<<25) | |
134 | #define F_IPSET (1u<<26) | |
135 | -#define F_NSIGMATCH (1u<<27) | |
136 | -#define F_NOEXTRA (1u<<28) | |
137 | +#define F_NOEXTRA (1u<<27) | |
138 | ||
139 | /* Values of uid in crecs with F_CONFIG bit set. */ | |
140 | #define SRC_INTERFACE 0 | |
141 | diff --git a/src/dnssec.c b/src/dnssec.c | |
142 | index de7b335..1ae03a6 100644 | |
143 | --- a/src/dnssec.c | |
144 | +++ b/src/dnssec.c | |
145 | @@ -1004,7 +1004,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch | |
146 | { | |
147 | unsigned char *psave, *p = (unsigned char *)(header+1); | |
148 | struct crec *crecp, *recp1; | |
149 | - int rc, j, qtype, qclass, ttl, rdlen, flags, algo, valid, keytag, type_covered; | |
150 | + int rc, j, qtype, qclass, ttl, rdlen, flags, algo, valid, keytag; | |
151 | struct blockdata *key; | |
152 | struct all_addr a; | |
153 | ||
154 | @@ -1115,7 +1115,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch | |
155 | ||
156 | if (valid) | |
157 | { | |
158 | - /* DNSKEY RRset determined to be OK, now cache it and the RRsigs that sign it. */ | |
159 | + /* DNSKEY RRset determined to be OK, now cache it. */ | |
160 | cache_start_insert(); | |
161 | ||
162 | p = skip_questions(header, plen); | |
163 | @@ -1155,7 +1155,10 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch | |
164 | if ((key = blockdata_alloc((char*)p, rdlen - 4))) | |
165 | { | |
166 | if (!(recp1 = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK))) | |
167 | - blockdata_free(key); | |
168 | + { | |
169 | + blockdata_free(key); | |
170 | + return STAT_BOGUS; | |
171 | + } | |
172 | else | |
173 | { | |
174 | a.addr.keytag = keytag; | |
175 | @@ -1169,38 +1172,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch | |
176 | } | |
177 | } | |
178 | } | |
179 | - else if (qtype == T_RRSIG) | |
180 | - { | |
181 | - /* RRSIG, cache if covers DNSKEY RRset */ | |
182 | - if (rdlen < 18) | |
183 | - return STAT_BOGUS; /* bad packet */ | |
184 | - | |
185 | - GETSHORT(type_covered, p); | |
186 | - | |
187 | - if (type_covered == T_DNSKEY) | |
188 | - { | |
189 | - a.addr.dnssec.class = class; | |
190 | - a.addr.dnssec.type = type_covered; | |
191 | - | |
192 | - algo = *p++; | |
193 | - p += 13; /* labels, orig_ttl, expiration, inception */ | |
194 | - GETSHORT(keytag, p); | |
195 | - if ((key = blockdata_alloc((char*)psave, rdlen))) | |
196 | - { | |
197 | - if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DS))) | |
198 | - blockdata_free(key); | |
199 | - else | |
200 | - { | |
201 | - crecp->addr.sig.keydata = key; | |
202 | - crecp->addr.sig.keylen = rdlen; | |
203 | - crecp->addr.sig.keytag = keytag; | |
204 | - crecp->addr.sig.type_covered = type_covered; | |
205 | - crecp->addr.sig.algo = algo; | |
206 | - } | |
207 | - } | |
208 | - } | |
209 | - } | |
210 | - | |
211 | + | |
212 | p = psave; | |
213 | } | |
214 | ||
215 | @@ -1326,7 +1298,8 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char | |
216 | cache_start_insert(); | |
217 | ||
218 | a.addr.dnssec.class = class; | |
219 | - cache_insert(name, &a, now, ttl, flags); | |
220 | + if (!cache_insert(name, &a, now, ttl, flags)) | |
221 | + return STAT_BOGUS; | |
222 | ||
223 | cache_end_insert(); | |
224 | ||
225 | @@ -2028,14 +2001,13 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch | |
226 | /* Not done, validate now */ | |
227 | if (j == i) | |
228 | { | |
229 | - int ttl, keytag, algo, digest, type_covered, sigcnt, rrcnt; | |
230 | + int ttl, keytag, algo, digest, sigcnt, rrcnt; | |
231 | unsigned char *psave; | |
232 | struct all_addr a; | |
233 | struct blockdata *key; | |
234 | struct crec *crecp; | |
235 | char *wildname; | |
236 | - int have_wildcard = 0; | |
237 | - | |
238 | + | |
239 | if (!explore_rrset(header, plen, class1, type1, name, keyname, &sigcnt, &rrcnt)) | |
240 | return STAT_BOGUS; | |
241 | ||
242 | @@ -2096,8 +2068,6 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch | |
243 | ||
244 | if (rc == STAT_SECURE_WILDCARD) | |
245 | { | |
246 | - have_wildcard = 1; | |
247 | - | |
248 | /* An attacker replay a wildcard answer with a different | |
249 | answer and overlay a genuine RR. To prove this | |
250 | hasn't happened, the answer must prove that | |
251 | @@ -2119,7 +2089,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch | |
252 | return rc; | |
253 | } | |
254 | ||
255 | - /* Cache RRsigs in answer section, and if we just validated a DS RRset, cache it */ | |
256 | + /* If we just validated a DS RRset, cache it */ | |
257 | /* Also note if the RRset is the answer to the question, or the target of a CNAME */ | |
258 | cache_start_insert(); | |
259 | ||
260 | @@ -2168,45 +2138,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch | |
261 | } | |
262 | } | |
263 | } | |
264 | - else if (type2 == T_RRSIG) | |
265 | - { | |
266 | - if (rdlen2 < 18) | |
267 | - return STAT_BOGUS; /* bad packet */ | |
268 | - | |
269 | - GETSHORT(type_covered, p2); | |
270 | - | |
271 | - if (type_covered == type1 && | |
272 | - (type_covered == T_A || type_covered == T_AAAA || | |
273 | - type_covered == T_CNAME || type_covered == T_DS || | |
274 | - type_covered == T_DNSKEY || type_covered == T_PTR)) | |
275 | - { | |
276 | - a.addr.dnssec.type = type_covered; | |
277 | - a.addr.dnssec.class = class1; | |
278 | - | |
279 | - algo = *p2++; | |
280 | - p2 += 13; /* labels, orig_ttl, expiration, inception */ | |
281 | - GETSHORT(keytag, p2); | |
282 | - | |
283 | - /* We don't cache sigs for wildcard answers, because to reproduce the | |
284 | - answer from the cache will require one or more NSEC/NSEC3 records | |
285 | - which we don't cache. The lack of the RRSIG ensures that a query for | |
286 | - this RRset asking for a secure answer will always be forwarded. */ | |
287 | - if (!have_wildcard && (key = blockdata_alloc((char*)psave, rdlen2))) | |
288 | - { | |
289 | - if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DS))) | |
290 | - blockdata_free(key); | |
291 | - else | |
292 | - { | |
293 | - crecp->addr.sig.keydata = key; | |
294 | - crecp->addr.sig.keylen = rdlen2; | |
295 | - crecp->addr.sig.keytag = keytag; | |
296 | - crecp->addr.sig.type_covered = type_covered; | |
297 | - crecp->addr.sig.algo = algo; | |
298 | - } | |
299 | - } | |
300 | - } | |
301 | - } | |
302 | - | |
303 | + | |
304 | p2 = psave; | |
305 | } | |
306 | ||
307 | diff --git a/src/rfc1035.c b/src/rfc1035.c | |
308 | index 4eb1772..def8fa0 100644 | |
309 | --- a/src/rfc1035.c | |
310 | +++ b/src/rfc1035.c | |
311 | @@ -1275,11 +1275,9 @@ int check_for_local_domain(char *name, time_t now) | |
312 | struct naptr *naptr; | |
313 | ||
314 | /* Note: the call to cache_find_by_name is intended to find any record which matches | |
315 | - ie A, AAAA, CNAME, DS. Because RRSIG records are marked by setting both F_DS and F_DNSKEY, | |
316 | - cache_find_by name ordinarily only returns records with an exact match on those bits (ie | |
317 | - for the call below, only DS records). The F_NSIGMATCH bit changes this behaviour */ | |
318 | + ie A, AAAA, CNAME. */ | |
319 | ||
320 | - if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME | F_DS | F_NO_RR | F_NSIGMATCH)) && | |
321 | + if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6 | F_CNAME |F_NO_RR)) && | |
322 | (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))) | |
323 | return 1; | |
324 | ||
325 | @@ -1566,9 +1564,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
326 | GETSHORT(flags, pheader); | |
327 | ||
328 | if ((sec_reqd = flags & 0x8000)) | |
329 | - *do_bit = 1;/* do bit */ | |
330 | + { | |
331 | + *do_bit = 1;/* do bit */ | |
332 | + *ad_reqd = 1; | |
333 | + } | |
334 | ||
335 | - *ad_reqd = 1; | |
336 | dryrun = 1; | |
337 | } | |
338 | ||
339 | @@ -1636,98 +1636,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
340 | } | |
341 | } | |
342 | ||
343 | -#ifdef HAVE_DNSSEC | |
344 | - if (option_bool(OPT_DNSSEC_VALID) && (qtype == T_DNSKEY || qtype == T_DS)) | |
345 | - { | |
346 | - int gotone = 0; | |
347 | - struct blockdata *keydata; | |
348 | - | |
349 | - /* Do we have RRSIG? Can't do DS or DNSKEY otherwise. */ | |
350 | - if (sec_reqd) | |
351 | - { | |
352 | - crecp = NULL; | |
353 | - while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY | F_DS))) | |
354 | - if (crecp->uid == qclass && crecp->addr.sig.type_covered == qtype) | |
355 | - break; | |
356 | - } | |
357 | - | |
358 | - if (!sec_reqd || crecp) | |
359 | - { | |
360 | - if (qtype == T_DS) | |
361 | - { | |
362 | - crecp = NULL; | |
363 | - while ((crecp = cache_find_by_name(crecp, name, now, F_DS))) | |
364 | - if (crecp->uid == qclass) | |
365 | - { | |
366 | - gotone = 1; | |
367 | - if (!dryrun) | |
368 | - { | |
369 | - if (crecp->flags & F_NEG) | |
370 | - { | |
371 | - if (crecp->flags & F_NXDOMAIN) | |
372 | - nxdomain = 1; | |
373 | - log_query(F_UPSTREAM, name, NULL, "no DS"); | |
374 | - } | |
375 | - else if ((keydata = blockdata_retrieve(crecp->addr.ds.keydata, crecp->addr.ds.keylen, NULL))) | |
376 | - { | |
377 | - struct all_addr a; | |
378 | - a.addr.keytag = crecp->addr.ds.keytag; | |
379 | - log_query(F_KEYTAG | (crecp->flags & F_CONFIG), name, &a, "DS keytag %u"); | |
380 | - if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, | |
381 | - crec_ttl(crecp, now), &nameoffset, | |
382 | - T_DS, qclass, "sbbt", | |
383 | - crecp->addr.ds.keytag, crecp->addr.ds.algo, | |
384 | - crecp->addr.ds.digest, crecp->addr.ds.keylen, keydata)) | |
385 | - anscount++; | |
386 | - | |
387 | - } | |
388 | - } | |
389 | - } | |
390 | - } | |
391 | - else /* DNSKEY */ | |
392 | - { | |
393 | - crecp = NULL; | |
394 | - while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY))) | |
395 | - if (crecp->uid == qclass) | |
396 | - { | |
397 | - gotone = 1; | |
398 | - if (!dryrun && (keydata = blockdata_retrieve(crecp->addr.key.keydata, crecp->addr.key.keylen, NULL))) | |
399 | - { | |
400 | - struct all_addr a; | |
401 | - a.addr.keytag = crecp->addr.key.keytag; | |
402 | - log_query(F_KEYTAG | (crecp->flags & F_CONFIG), name, &a, "DNSKEY keytag %u"); | |
403 | - if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, | |
404 | - crec_ttl(crecp, now), &nameoffset, | |
405 | - T_DNSKEY, qclass, "sbbt", | |
406 | - crecp->addr.key.flags, 3, crecp->addr.key.algo, crecp->addr.key.keylen, keydata)) | |
407 | - anscount++; | |
408 | - } | |
409 | - } | |
410 | - } | |
411 | - } | |
412 | - | |
413 | - /* Now do RRSIGs */ | |
414 | - if (gotone) | |
415 | - { | |
416 | - ans = 1; | |
417 | - auth = 0; | |
418 | - if (!dryrun && sec_reqd) | |
419 | - { | |
420 | - crecp = NULL; | |
421 | - while ((crecp = cache_find_by_name(crecp, name, now, F_DNSKEY | F_DS))) | |
422 | - if (crecp->uid == qclass && crecp->addr.sig.type_covered == qtype && | |
423 | - (keydata = blockdata_retrieve(crecp->addr.sig.keydata, crecp->addr.sig.keylen, NULL))) | |
424 | - { | |
425 | - add_resource_record(header, limit, &trunc, nameoffset, &ansp, | |
426 | - crec_ttl(crecp, now), &nameoffset, | |
427 | - T_RRSIG, qclass, "t", crecp->addr.sig.keylen, keydata); | |
428 | - anscount++; | |
429 | - } | |
430 | - } | |
431 | - } | |
432 | - } | |
433 | -#endif | |
434 | - | |
435 | if (qclass == C_IN) | |
436 | { | |
437 | struct txt_record *t; | |
438 | @@ -1736,6 +1644,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
439 | if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name)) | |
440 | { | |
441 | ans = 1; | |
442 | + sec_data = 0; | |
443 | if (!dryrun) | |
444 | { | |
445 | log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>"); | |
446 | @@ -1792,6 +1701,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
447 | ||
448 | if (intr) | |
449 | { | |
450 | + sec_data = 0; | |
451 | ans = 1; | |
452 | if (!dryrun) | |
453 | { | |
454 | @@ -1805,6 +1715,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
455 | else if (ptr) | |
456 | { | |
457 | ans = 1; | |
458 | + sec_data = 0; | |
459 | if (!dryrun) | |
460 | { | |
461 | log_query(F_CONFIG | F_RRNAME, name, NULL, "<PTR>"); | |
462 | @@ -1819,38 +1730,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
463 | } | |
464 | else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa))) | |
465 | { | |
466 | - if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd) | |
467 | - { | |
468 | - if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK))) | |
469 | - crecp = NULL; | |
470 | -#ifdef HAVE_DNSSEC | |
471 | - else if (crecp->flags & F_DNSSECOK) | |
472 | - { | |
473 | - int gotsig = 0; | |
474 | - struct crec *rr_crec = NULL; | |
475 | - | |
476 | - while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY))) | |
477 | - { | |
478 | - if (rr_crec->addr.sig.type_covered == T_PTR && rr_crec->uid == C_IN) | |
479 | - { | |
480 | - char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL); | |
481 | - gotsig = 1; | |
482 | - | |
483 | - if (!dryrun && | |
484 | - add_resource_record(header, limit, &trunc, nameoffset, &ansp, | |
485 | - rr_crec->ttd - now, &nameoffset, | |
486 | - T_RRSIG, C_IN, "t", crecp->addr.sig.keylen, sigdata)) | |
487 | - anscount++; | |
488 | - } | |
489 | - } | |
490 | - | |
491 | - if (!gotsig) | |
492 | - crecp = NULL; | |
493 | - } | |
494 | -#endif | |
495 | - } | |
496 | - | |
497 | - if (crecp) | |
498 | + /* Don't use cache when DNSSEC data required. */ | |
499 | + if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !sec_reqd || !(crecp->flags & F_DNSSECOK)) | |
500 | { | |
501 | do | |
502 | { | |
503 | @@ -1860,19 +1741,19 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
504 | ||
505 | if (!(crecp->flags & F_DNSSECOK)) | |
506 | sec_data = 0; | |
507 | - | |
508 | + | |
509 | + ans = 1; | |
510 | + | |
511 | if (crecp->flags & F_NEG) | |
512 | { | |
513 | - ans = 1; | |
514 | auth = 0; | |
515 | if (crecp->flags & F_NXDOMAIN) | |
516 | nxdomain = 1; | |
517 | if (!dryrun) | |
518 | log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL); | |
519 | } | |
520 | - else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd || option_bool(OPT_DNSSEC_VALID)) | |
521 | + else | |
522 | { | |
523 | - ans = 1; | |
524 | if (!(crecp->flags & (F_HOSTS | F_DHCP))) | |
525 | auth = 0; | |
526 | if (!dryrun) | |
527 | @@ -1892,6 +1773,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
528 | else if (is_rev_synth(is_arpa, &addr, name)) | |
529 | { | |
530 | ans = 1; | |
531 | + sec_data = 0; | |
532 | if (!dryrun) | |
533 | { | |
534 | log_query(F_CONFIG | F_REVERSE | is_arpa, name, &addr, NULL); | |
535 | @@ -1908,6 +1790,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
536 | { | |
537 | /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */ | |
538 | ans = 1; | |
539 | + sec_data = 0; | |
540 | nxdomain = 1; | |
541 | if (!dryrun) | |
542 | log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, | |
543 | @@ -1955,6 +1838,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
544 | if (i == 4) | |
545 | { | |
546 | ans = 1; | |
547 | + sec_data = 0; | |
548 | if (!dryrun) | |
549 | { | |
550 | addr.addr.addr4.s_addr = htonl(a); | |
551 | @@ -1993,6 +1877,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
552 | continue; | |
553 | #endif | |
554 | ans = 1; | |
555 | + sec_data = 0; | |
556 | if (!dryrun) | |
557 | { | |
558 | gotit = 1; | |
559 | @@ -2032,48 +1917,8 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen, | |
560 | crecp = save; | |
561 | } | |
562 | ||
563 | - /* If the client asked for DNSSEC and we can't provide RRSIGs, either | |
564 | - because we've not doing DNSSEC or the cached answer is signed by negative, | |
565 | - don't answer from the cache, forward instead. */ | |
566 | - if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && sec_reqd) | |
567 | - { | |
568 | - if (!option_bool(OPT_DNSSEC_VALID) || ((crecp->flags & F_NEG) && (crecp->flags & F_DNSSECOK))) | |
569 | - crecp = NULL; | |
570 | -#ifdef HAVE_DNSSEC | |
571 | - else if (crecp->flags & F_DNSSECOK) | |
572 | - { | |
573 | - /* We're returning validated data, need to return the RRSIG too. */ | |
574 | - struct crec *rr_crec = NULL; | |
575 | - int sigtype = type; | |
576 | - /* The signature may have expired even though the data is still in cache, | |
577 | - forward instead of answering from cache if so. */ | |
578 | - int gotsig = 0; | |
579 | - | |
580 | - if (crecp->flags & F_CNAME) | |
581 | - sigtype = T_CNAME; | |
582 | - | |
583 | - while ((rr_crec = cache_find_by_name(rr_crec, name, now, F_DS | F_DNSKEY))) | |
584 | - { | |
585 | - if (rr_crec->addr.sig.type_covered == sigtype && rr_crec->uid == C_IN) | |
586 | - { | |
587 | - char *sigdata = blockdata_retrieve(rr_crec->addr.sig.keydata, rr_crec->addr.sig.keylen, NULL); | |
588 | - gotsig = 1; | |
589 | - | |
590 | - if (!dryrun && | |
591 | - add_resource_record(header, limit, &trunc, nameoffset, &ansp, | |
592 | - rr_crec->ttd - now, &nameoffset, | |
593 | - T_RRSIG, C_IN, "t", rr_crec->addr.sig.keylen, sigdata)) | |
594 | - anscount++; | |
595 | - } | |
596 | - } | |
597 | - | |
598 | - if (!gotsig) | |
599 | - crecp = NULL; | |
600 | - } | |
601 | -#endif | |
602 | - } | |
603 | - | |
604 | - if (crecp) | |
605 | + /* If the client asked for DNSSEC don't use cached data. */ | |
606 | + if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !sec_reqd || !(crecp->flags & F_DNSSECOK)) | |
607 | do | |
608 | { | |
609 | /* don't answer wildcard queries with data not from /etc/hosts | |
610 | -- | |
611 | 1.7.10.4 | |
612 |