]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/dnsmasq/021-Tweaks_to_EDNS0_handling_in_DNS_replies.patch
kernel: update to 3.14.62
[ipfire-2.x.git] / src / patches / dnsmasq / 021-Tweaks_to_EDNS0_handling_in_DNS_replies.patch
CommitLineData
1e1b03d5
MF
1From dd4ad9ac7ea6d51dcc34a1f2cd2da14efbb87714 Mon Sep 17 00:00:00 2001
2From: Simon Kelley <simon@thekelleys.org.uk>
3Date: Thu, 17 Dec 2015 10:44:58 +0000
4Subject: [PATCH] Tweaks to EDNS0 handling in DNS replies.
5
6---
7 src/dnssec.c | 20 +++++++++-----------
8 src/rfc1035.c | 57 +++++++++++++++++++++++++++++++++------------------------
9 2 files changed, 42 insertions(+), 35 deletions(-)
10
11diff --git a/src/dnssec.c b/src/dnssec.c
12index dc563e0..012b2a6 100644
13--- a/src/dnssec.c
14+++ b/src/dnssec.c
15@@ -2129,18 +2129,16 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
16 /* Empty DS without NSECS */
17 if (qtype == T_DS)
18 return STAT_BOGUS;
19- else
20+
21+ rc = zone_status(name, qclass, keyname, now);
22+ if (rc != STAT_SECURE)
23 {
24- rc = zone_status(name, qclass, keyname, now);
25- if (rc != STAT_SECURE)
26- {
27- if (class)
28- *class = qclass; /* Class for NEED_DS or NEED_DNSKEY */
29- return rc;
30- }
31-
32- return STAT_BOGUS; /* signed zone, no NSECs */
33- }
34+ if (class)
35+ *class = qclass; /* Class for NEED_DS or NEED_DNSKEY */
36+ return rc;
37+ }
38+
39+ return STAT_BOGUS; /* signed zone, no NSECs */
40 }
41
42 if (nsec_type == T_NSEC)
43diff --git a/src/rfc1035.c b/src/rfc1035.c
44index def8fa0..188d05f 100644
45--- a/src/rfc1035.c
46+++ b/src/rfc1035.c
47@@ -1539,7 +1539,13 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
48 int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
49 struct mx_srv_record *rec;
50 size_t len;
51-
52+
53+ if (ntohs(header->ancount) != 0 ||
54+ ntohs(header->nscount) != 0 ||
55+ ntohs(header->qdcount) == 0 ||
56+ OPCODE(header) != QUERY )
57+ return 0;
58+
59 /* Don't return AD set if checking disabled. */
60 if (header->hb4 & HB4_CD)
61 sec_data = 0;
62@@ -1548,33 +1554,32 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
63 *ad_reqd = header->hb4 & HB4_AD;
64 *do_bit = 0;
65
66- /* If there is an RFC2671 pseudoheader then it will be overwritten by
67+ /* If there is an additional data section then it will be overwritten by
68 partial replies, so we have to do a dry run to see if we can answer
69- the query. We check to see if the do bit is set, if so we always
70- forward rather than answering from the cache, which doesn't include
71- security information, unless we're in DNSSEC validation mode. */
72+ the query. */
73
74- if (find_pseudoheader(header, qlen, NULL, &pheader, NULL))
75- {
76- unsigned short flags;
77-
78- have_pseudoheader = 1;
79+ if (ntohs(header->arcount) != 0)
80+ {
81+ dryrun = 1;
82
83- pheader += 4; /* udp size, ext_rcode */
84- GETSHORT(flags, pheader);
85-
86- if ((sec_reqd = flags & 0x8000))
87- {
88- *do_bit = 1;/* do bit */
89- *ad_reqd = 1;
90+ /* If there's an additional section, there might be an EDNS(0) pseudoheader */
91+ if (find_pseudoheader(header, qlen, NULL, &pheader, NULL))
92+ {
93+ unsigned short flags;
94+
95+ have_pseudoheader = 1;
96+
97+ pheader += 4; /* udp size, ext_rcode */
98+ GETSHORT(flags, pheader);
99+
100+ if ((sec_reqd = flags & 0x8000))
101+ {
102+ *do_bit = 1;/* do bit */
103+ *ad_reqd = 1;
104+ }
105 }
106-
107- dryrun = 1;
108 }
109
110- if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
111- return 0;
112-
113 for (rec = daemon->mxnames; rec; rec = rec->next)
114 rec->offset = 0;
115
116@@ -1730,8 +1735,12 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
117 }
118 else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
119 {
120- /* Don't use cache when DNSSEC data required. */
121- if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) || !sec_reqd || !(crecp->flags & F_DNSSECOK))
122+ /* Don't use cache when DNSSEC data required, unless we know that
123+ the zone is unsigned, which implies that we're doing
124+ validation. */
125+ if ((crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) ||
126+ !sec_reqd ||
127+ (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))
128 {
129 do
130 {
131--
1321.7.10.4
133