1 From 394ff492da6af5da7e7d356be9586683bc5fc011 Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Sun, 29 Mar 2015 22:17:14 +0100
4 Subject: [PATCH 065/113] Allow control characters in names in the cache,
8 src/cache.c | 19 +++++++++++++++++--
9 src/dnssec.c | 34 +++++++++++++++++-----------------
10 src/rfc1035.c | 7 +++----
11 3 files changed, 37 insertions(+), 23 deletions(-)
13 diff --git a/src/cache.c b/src/cache.c
14 index c95624c42b1c..873c5779044c 100644
17 @@ -1399,6 +1399,19 @@ int cache_make_stat(struct txt_record *t)
21 +/* There can be names in the cache containing control chars, don't
22 + mess up logging or open security holes. */
23 +static char *sanitise(char *name)
26 + for (r = (unsigned char *)name; *r; r++)
27 + if (!isprint((int)*r))
28 + return "<name unprintable>";
34 void dump_cache(time_t now)
36 struct server *serv, *serv1;
37 @@ -1452,9 +1465,9 @@ void dump_cache(time_t now)
39 if (strlen(n) == 0 && !(cache->flags & F_REVERSE))
41 - p += sprintf(p, "%-30.30s ", n);
42 + p += sprintf(p, "%-30.30s ", sanitise(n));
43 if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache))
44 - a = cache_get_cname_target(cache);
45 + a = sanitise(cache_get_cname_target(cache));
47 else if (cache->flags & F_DS)
49 @@ -1587,6 +1600,8 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
50 if (!option_bool(OPT_LOG))
53 + name = sanitise(name);
58 diff --git a/src/dnssec.c b/src/dnssec.c
59 index 8bd5294ce773..14bae7e9bf75 100644
62 @@ -552,7 +552,7 @@ static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end,
66 - if (d == 0 && extract_name(header, plen, p, buff, 2, 0))
67 + if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
68 /* domain-name, canonicalise */
71 @@ -811,7 +811,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
72 GETLONG(sig_inception, p);
75 - if (!extract_name(header, plen, &p, keyname, 2, 0))
76 + if (!extract_name(header, plen, &p, keyname, 1, 0))
79 /* RFC 4035 5.3.1 says that the Signer's Name field MUST equal
80 @@ -866,7 +866,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
84 - if (!extract_name(header, plen, &p, name, 2, 10))
85 + if (!extract_name(header, plen, &p, name, 1, 10))
89 @@ -923,7 +923,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
91 /* namebuff used for workspace above, restore to leave unchanged on exit */
92 p = (unsigned char*)(rrset[0]);
93 - extract_name(header, plen, &p, name, 2, 0);
94 + extract_name(header, plen, &p, name, 1, 0);
98 @@ -963,7 +963,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
101 if (ntohs(header->qdcount) != 1 ||
102 - !extract_name(header, plen, &p, name, 2, 4))
103 + !extract_name(header, plen, &p, name, 1, 4))
107 @@ -1202,7 +1202,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
110 p = (unsigned char *)(header+1);
111 - extract_name(header, plen, &p, name, 2, 4);
112 + extract_name(header, plen, &p, name, 1, 4);
113 p += 4; /* qtype, qclass */
115 if (!(p = skip_section(p, ntohs(header->ancount), header, plen)))
116 @@ -1419,12 +1419,12 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
117 for (i = 0; i < nsec_count; i++)
120 - if (!extract_name(header, plen, &p, workspace1, 2, 10))
121 + if (!extract_name(header, plen, &p, workspace1, 1, 10))
123 p += 8; /* class, type, TTL */
126 - if (!extract_name(header, plen, &p, workspace2, 2, 10))
127 + if (!extract_name(header, plen, &p, workspace2, 1, 10))
130 rc = hostname_cmp(workspace1, name);
131 @@ -1553,7 +1553,7 @@ static int check_nsec3_coverage(struct dns_header *header, size_t plen, int dige
132 for (i = 0; i < nsec_count; i++)
135 - if (!extract_name(header, plen, &p, workspace1, 2, 0) ||
136 + if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
137 !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
140 @@ -1730,7 +1730,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
141 for (i = 0; i < nsec_count; i++)
144 - if (!extract_name(header, plen, &p, workspace1, 2, 0) ||
145 + if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
146 !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
149 @@ -1796,7 +1796,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
151 qname = p1 = (unsigned char *)(header+1);
153 - if (!extract_name(header, plen, &p1, name, 2, 4))
154 + if (!extract_name(header, plen, &p1, name, 1, 4))
158 @@ -1836,7 +1836,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
162 - if (!cname_count-- || !extract_name(header, plen, &p1, name, 2, 0))
163 + if (!cname_count-- || !extract_name(header, plen, &p1, name, 1, 0))
167 @@ -1857,7 +1857,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
169 for (p1 = ans_start, i = 0; i < ntohs(header->ancount) + ntohs(header->nscount); i++)
171 - if (!extract_name(header, plen, &p1, name, 2, 10))
172 + if (!extract_name(header, plen, &p1, name, 1, 10))
173 return STAT_BOGUS; /* bad packet */
176 @@ -2039,7 +2039,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
177 an unsigned zone. Return STAT_NO_SIG to cause this to be proved. */
179 /* Get name of missing answer */
180 - if (!extract_name(header, plen, &qname, name, 2, 0))
181 + if (!extract_name(header, plen, &qname, name, 1, 0))
184 if (nsec_type == T_NSEC)
185 @@ -2061,7 +2061,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char
186 int cname_count = CNAME_CHAIN;
189 - if (!extract_name(header, plen, &p, name, 2, 4))
190 + if (!extract_name(header, plen, &p, name, 1, 4))
194 @@ -2102,7 +2102,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char
196 /* Loop down CNAME chain/ */
197 if (!cname_count-- ||
198 - !extract_name(header, plen, &p, name, 2, 0) ||
199 + !extract_name(header, plen, &p, name, 1, 0) ||
200 !(p = skip_questions(header, plen)))
203 @@ -2419,7 +2419,7 @@ unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name
205 for (q = ntohs(header->qdcount); q != 0; q--)
207 - if (!extract_name(header, plen, &p, name, 2, 4))
208 + if (!extract_name(header, plen, &p, name, 1, 4))
209 break; /* bad packet */
212 diff --git a/src/rfc1035.c b/src/rfc1035.c
213 index 10832a3d5d2e..7a07b0cee906 100644
220 -/* isExtract == 2 -> DNSSEC mode, no bitstrings, no ascii checks. */
221 int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
222 char *name, int isExtract, int extrabytes)
224 @@ -87,7 +86,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
226 return 0; /* we only understand bitstrings */
228 - if (isExtract != 1)
230 return 0; /* Cannot compare bitsrings */
233 @@ -129,8 +128,8 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
236 unsigned char c = *p;
237 - if ((isExtract == 2 || (isascii(c) && !iscntrl(c))) && c != '.')
239 + if (c != 0 && c != '.')