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
4 Subject: [PATCH 64/98] DNSSEC fix for non-ascii characters in labels.
7 src/dnssec.c | 34 +++++++++++++++++-----------------
8 src/rfc1035.c | 5 +++--
9 2 files changed, 20 insertions(+), 19 deletions(-)
11 diff --git a/src/dnssec.c b/src/dnssec.c
12 index 14bae7e9bf75..8bd5294ce773 100644
15 @@ -552,7 +552,7 @@ static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end,
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 */
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);
28 - if (!extract_name(header, plen, &p, keyname, 1, 0))
29 + if (!extract_name(header, plen, &p, keyname, 2, 0))
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
37 - if (!extract_name(header, plen, &p, name, 1, 10))
38 + if (!extract_name(header, plen, &p, name, 2, 10))
42 @@ -923,7 +923,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
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);
51 @@ -963,7 +963,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
54 if (ntohs(header->qdcount) != 1 ||
55 - !extract_name(header, plen, &p, name, 1, 4))
56 + !extract_name(header, plen, &p, name, 2, 4))
60 @@ -1202,7 +1202,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
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 */
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++)
73 - if (!extract_name(header, plen, &p, workspace1, 1, 10))
74 + if (!extract_name(header, plen, &p, workspace1, 2, 10))
76 p += 8; /* class, type, TTL */
79 - if (!extract_name(header, plen, &p, workspace2, 1, 10))
80 + if (!extract_name(header, plen, &p, workspace2, 2, 10))
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++)
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)))
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++)
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)))
102 @@ -1796,7 +1796,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
104 qname = p1 = (unsigned char *)(header+1);
106 - if (!extract_name(header, plen, &p1, name, 1, 4))
107 + if (!extract_name(header, plen, &p1, name, 2, 4))
111 @@ -1836,7 +1836,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
115 - if (!cname_count-- || !extract_name(header, plen, &p1, name, 1, 0))
116 + if (!cname_count-- || !extract_name(header, plen, &p1, name, 2, 0))
120 @@ -1857,7 +1857,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
122 for (p1 = ans_start, i = 0; i < ntohs(header->ancount) + ntohs(header->nscount); i++)
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 */
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. */
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))
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;
142 - if (!extract_name(header, plen, &p, name, 1, 4))
143 + if (!extract_name(header, plen, &p, name, 2, 4))
147 @@ -2102,7 +2102,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char
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)))
156 @@ -2419,7 +2419,7 @@ unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name
158 for (q = ntohs(header->qdcount); q != 0; q--)
160 - if (!extract_name(header, plen, &p, name, 1, 4))
161 + if (!extract_name(header, plen, &p, name, 2, 4))
162 break; /* bad packet */
165 diff --git a/src/rfc1035.c b/src/rfc1035.c
166 index 5ef5ddb7485e..10832a3d5d2e 100644
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)
177 @@ -86,7 +87,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
179 return 0; /* we only understand bitstrings */
182 + if (isExtract != 1)
183 return 0; /* Cannot compare bitsrings */
186 @@ -128,7 +129,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
189 unsigned char c = *p;
190 - if (isascii(c) && !iscntrl(c) && c != '.')
191 + if ((isExtract == 2 || (isascii(c) && !iscntrl(c))) && c != '.')