[37aaf89] | 1 | Description: Cache SOA records |
---|
| 2 | For more information, how this patch helps to mitigate poisoning attack, |
---|
| 3 | see http://www.your.org/dnscache. |
---|
| 4 | Author: Jeff King <peff@peff.net> |
---|
| 5 | Date: Tue, 18 Jun 2019 01:11:07 +0000 |
---|
| 6 | Debian-Bug: https://bugs.debian.org/516394 |
---|
| 7 | Last-Update: 2020-07-26 |
---|
| 8 | |
---|
| 9 | diff --git a/query.c b/query.c |
---|
| 10 | index 085cf44..372d0a6 100644 |
---|
| 11 | --- a/query.c |
---|
| 12 | +++ b/query.c |
---|
| 13 | @@ -319,6 +319,29 @@ static int doit(struct query *z,int state) |
---|
| 14 | } |
---|
| 15 | } |
---|
| 16 | |
---|
| 17 | + if (typematch(DNS_T_SOA,dtype)) { |
---|
| 18 | + byte_copy(key,2,DNS_T_SOA); |
---|
| 19 | + cached = cache_get(key,dlen + 2,&cachedlen,&ttl); |
---|
| 20 | + if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) { |
---|
| 21 | + log_cachedanswer(d,DNS_T_SOA); |
---|
| 22 | + if (!rqa(z)) goto DIE; |
---|
| 23 | + pos = 0; |
---|
| 24 | + while (pos = dns_packet_copy(cached,cachedlen,pos,misc,20)) { |
---|
| 25 | + pos = dns_packet_getname(cached,cachedlen,pos,&t2); |
---|
| 26 | + if (!pos) break; |
---|
| 27 | + pos = dns_packet_getname(cached,cachedlen,pos,&t3); |
---|
| 28 | + if (!pos) break; |
---|
| 29 | + if (!response_rstart(d,DNS_T_SOA,ttl)) goto DIE; |
---|
| 30 | + if (!response_addname(t2)) goto DIE; |
---|
| 31 | + if (!response_addname(t3)) goto DIE; |
---|
| 32 | + if (!response_addbytes(misc,20)) goto DIE; |
---|
| 33 | + response_rfinish(RESPONSE_ANSWER); |
---|
| 34 | + } |
---|
| 35 | + cleanup(z); |
---|
| 36 | + return 1; |
---|
| 37 | + } |
---|
| 38 | + } |
---|
| 39 | + |
---|
| 40 | if (typematch(DNS_T_A,dtype)) { |
---|
| 41 | byte_copy(key,2,DNS_T_A); |
---|
| 42 | cached = cache_get(key,dlen + 2,&cachedlen,&ttl); |
---|
| 43 | @@ -351,7 +374,7 @@ static int doit(struct query *z,int state) |
---|
| 44 | } |
---|
| 45 | } |
---|
| 46 | |
---|
| 47 | - if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) { |
---|
| 48 | + if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype) && !typematch(DNS_T_SOA,dtype)) { |
---|
| 49 | byte_copy(key,2,dtype); |
---|
| 50 | cached = cache_get(key,dlen + 2,&cachedlen,&ttl); |
---|
| 51 | if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) { |
---|
| 52 | @@ -591,15 +614,24 @@ static int doit(struct query *z,int state) |
---|
| 53 | else if (byte_equal(type,2,DNS_T_AXFR)) |
---|
| 54 | ; |
---|
| 55 | else if (byte_equal(type,2,DNS_T_SOA)) { |
---|
| 56 | + int non_authority = 0; |
---|
| 57 | + save_start(); |
---|
| 58 | while (i < j) { |
---|
| 59 | pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE; |
---|
| 60 | pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE; |
---|
| 61 | pos = dns_packet_getname(buf,len,pos,&t3); if (!pos) goto DIE; |
---|
| 62 | pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) goto DIE; |
---|
| 63 | - if (records[i] < posauthority) |
---|
| 64 | + if (records[i] < posauthority) { |
---|
| 65 | log_rrsoa(whichserver,t1,t2,t3,misc,ttl); |
---|
| 66 | + save_data(misc,20); |
---|
| 67 | + save_data(t2,dns_domain_length(t2)); |
---|
| 68 | + save_data(t3,dns_domain_length(t3)); |
---|
| 69 | + non_authority++; |
---|
| 70 | + } |
---|
| 71 | ++i; |
---|
| 72 | } |
---|
| 73 | + if (non_authority) |
---|
| 74 | + save_finish(DNS_T_SOA,t1,ttl); |
---|
| 75 | } |
---|
| 76 | else if (byte_equal(type,2,DNS_T_CNAME)) { |
---|
| 77 | pos = dns_packet_skipname(buf,len,records[j - 1]); if (!pos) goto DIE; |
---|