Skip to content

Commit a18485c

Browse files
committed
dns: send REFUSED is name contains special characters
1 parent 11a9db0 commit a18485c

File tree

7 files changed

+83
-37
lines changed

7 files changed

+83
-37
lines changed

src/cache.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,6 @@ hsk_cache_key_set(hsk_cache_key_t *ck, const char *name, uint16_t type) {
262262
if (!hsk_dns_name_verify(name))
263263
return false;
264264

265-
if (hsk_dns_name_dirty(name))
266-
return false;
267-
268265
int labels = hsk_dns_label_count(name);
269266
bool ref = false;
270267

src/dns.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -725,9 +725,6 @@ hsk_dns_rr_set_name(hsk_dns_rr_t *rr, const char *name) {
725725
if (!hsk_dns_name_verify(name))
726726
return false;
727727

728-
if (hsk_dns_name_dirty(name))
729-
return false;
730-
731728
if (hsk_dns_name_is_fqdn(name))
732729
strcpy(rr->name, name);
733730
else
@@ -2404,26 +2401,31 @@ hsk_dns_name_alloc(
24042401

24052402
bool
24062403
hsk_dns_name_dirty(const char *name) {
2407-
char *s = (char *)name;
2404+
int len = strlen(name);
2405+
if (len > HSK_DNS_MAX_LABEL)
2406+
return true;
24082407

2409-
while (*s) {
2410-
uint8_t c = (uint8_t)*s;
2408+
for (int i = 0; i < len; i++) {
2409+
uint8_t c = name[i];
2410+
2411+
if (c >= 0x41 && c <= 0x5a)
2412+
c ^= 0x20;
24112413

24122414
switch (c) {
2413-
case 0x28 /*(*/:
2414-
case 0x29 /*)*/:
2415-
case 0x3b /*;*/:
2416-
case 0x20 /* */:
2417-
case 0x40 /*@*/:
2418-
case 0x22 /*"*/:
2419-
case 0x5c /*\\*/:
2420-
return true;
2415+
case 0x5f: /* _ */
2416+
case 0x2d: /* - */
2417+
if (i == 0 || i == len - 1) {
2418+
return true;
2419+
} else {
2420+
continue;
2421+
}
24212422
}
24222423

2423-
if (c < 0x20 || c > 0x7e)
2424+
if (c < 0x30 ||
2425+
(c > 0x39 && c < 0x61) ||
2426+
c > 0x7a) {
24242427
return true;
2425-
2426-
s += 1;
2428+
}
24272429
}
24282430

24292431
return false;

src/ns.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ hsk_ns_onrecv(
297297
const struct sockaddr *addr,
298298
uint32_t flags
299299
) {
300+
uint8_t *wire = NULL;
301+
size_t wire_len = 0;
302+
hsk_dns_msg_t *msg = NULL;
303+
300304
hsk_dns_req_t *req = hsk_dns_req_create(data, data_len, addr);
301305

302306
if (!req) {
@@ -306,10 +310,6 @@ hsk_ns_onrecv(
306310

307311
hsk_dns_req_print(req, "ns: ");
308312

309-
uint8_t *wire = NULL;
310-
size_t wire_len = 0;
311-
hsk_dns_msg_t *msg = NULL;
312-
313313
// Hit cache first.
314314
msg = hsk_cache_get(&ns->cache, req);
315315

@@ -434,6 +434,28 @@ hsk_ns_onrecv(
434434
goto done;
435435
}
436436

437+
// Send REFUSED if name is dirty
438+
// (contains escaped byte codes or special characters)
439+
if (hsk_dns_name_dirty(req->tld)) {
440+
msg = hsk_resource_to_refused();
441+
442+
if (!msg) {
443+
hsk_ns_log(ns, "failed creating refused\n");
444+
goto fail;
445+
}
446+
447+
if (!hsk_dns_msg_finalize(&msg, req, ns->ec, ns->key, &wire, &wire_len)) {
448+
hsk_ns_log(ns, "could not reply\n");
449+
goto done;
450+
}
451+
452+
hsk_ns_log(ns, "refusing query for msg (%u): %u\n", req->id, wire_len);
453+
454+
hsk_ns_send(ns, wire, wire_len, addr, true);
455+
456+
goto done;
457+
}
458+
437459
// Requesting a lookup.
438460
if (req->labels > 0) {
439461
// Check blacklist.

src/req.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,9 @@ hsk_dns_req_create(
8383
// Grab the first question.
8484
hsk_dns_qs_t *qs = msg->qd.items[0];
8585

86-
#if 0
87-
if (qs->class != HSK_DNS_IN)
88-
goto fail;
89-
90-
// Don't allow dirty names.
91-
if (hsk_dns_name_dirty(qs->name))
92-
goto fail;
93-
#endif
94-
9586
// Check for a TLD.
9687
hsk_dns_label_get(qs->name, -1, req->tld);
9788

98-
// Don't allow dirty TLDs.
99-
if (hsk_dns_name_dirty(req->tld))
100-
goto fail;
101-
10289
// Lowercase.
10390
hsk_to_lower(req->tld);
10491

src/resource.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,6 +1133,18 @@ hsk_resource_to_servfail(void) {
11331133
return msg;
11341134
}
11351135

1136+
hsk_dns_msg_t *
1137+
hsk_resource_to_refused(void) {
1138+
hsk_dns_msg_t *msg = hsk_dns_msg_alloc();
1139+
1140+
if (!msg)
1141+
return NULL;
1142+
1143+
msg->code = HSK_DNS_REFUSED;
1144+
1145+
return msg;
1146+
}
1147+
11361148
hsk_dns_msg_t *
11371149
hsk_resource_to_notimp(void) {
11381150
hsk_dns_msg_t *msg = hsk_dns_msg_alloc();

src/resource.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ hsk_resource_to_nx(void);
8888
hsk_dns_msg_t *
8989
hsk_resource_to_servfail(void);
9090

91+
hsk_dns_msg_t *
92+
hsk_resource_to_refused(void);
93+
9194
hsk_dns_msg_t *
9295
hsk_resource_to_notimp(void);
9396

test/hnsd-test.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,34 @@ test_pointer_to_ip() {
6060
assert(family6 == HSK_DNS_AAAA);
6161
}
6262

63+
void
64+
test_name_dirty() {
65+
printf("test_name_dirty\n");
66+
67+
assert(!hsk_dns_name_dirty("hello"));
68+
assert(!hsk_dns_name_dirty("HELLO"));
69+
assert(!hsk_dns_name_dirty("heLLo"));
70+
assert(!hsk_dns_name_dirty("HeLl0"));
71+
assert(!hsk_dns_name_dirty("hel-lo"));
72+
assert(!hsk_dns_name_dirty("1"));
73+
assert(!hsk_dns_name_dirty("000_000"));
74+
assert(!hsk_dns_name_dirty("this-domain-name-has-sixty-three-octets-taking-max-label-length"));
75+
assert(hsk_dns_name_dirty("hel!lo"));
76+
assert(hsk_dns_name_dirty("-hello"));
77+
assert(hsk_dns_name_dirty("hello_"));
78+
assert(hsk_dns_name_dirty("1@1"));
79+
assert(hsk_dns_name_dirty("x\\000y"));
80+
assert(hsk_dns_name_dirty("H&ELLO"));
81+
assert(hsk_dns_name_dirty("3 3"));
82+
assert(hsk_dns_name_dirty("this-domain-name-has-sixtyfour-octets-exceeding-max-label-length"));
83+
}
84+
6385
int
6486
main() {
6587
printf("Testing hnsd...\n");
6688
test_base32();
6789
test_pointer_to_ip();
90+
test_name_dirty();
6891

6992
printf("ok\n");
7093

0 commit comments

Comments
 (0)