summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-12-27 21:14:29 +0100
committerLennart Poettering <lennart@poettering.net>2015-12-28 14:46:39 +0100
commitc7feab764702e483ef84b47429387a9a54d451ff (patch)
tree0318756cf5600d3816a4f9360b34f290ee5fdc70
parentea3a892fe39037d71afa43aca12bf1e408a686b4 (diff)
shared: relax restrictions on valid domain name characters a bit
Previously, we'd not allow control characters to be embedded in domain names, even when escaped. Since cloudflare uses \000 however to implement its synthethic minimally covering NSEC RRs, we should allow them, as long as they are properly escaped.
-rw-r--r--src/shared/dns-domain.c14
-rw-r--r--src/test/test-dns-domain.c6
2 files changed, 12 insertions, 8 deletions
diff --git a/src/shared/dns-domain.c b/src/shared/dns-domain.c
index 0273b9e3c9..68404ca9e5 100644
--- a/src/shared/dns-domain.c
+++ b/src/shared/dns-domain.c
@@ -98,8 +98,13 @@ int dns_label_unescape(const char **name, char *dest, size_t sz) {
((unsigned) (n[1] - '0') * 10) +
((unsigned) (n[2] - '0'));
- /* Don't allow CC characters or anything that doesn't fit in 8bit */
- if (k < ' ' || k > 255 || k == 127)
+ /* Don't allow anything that doesn't
+ * fit in 8bit. Note that we do allow
+ * control characters, as some servers
+ * (e.g. cloudflare) are happy to
+ * generate labels with them
+ * inside. */
+ if (k > 255)
return -EINVAL;
if (d)
@@ -245,7 +250,7 @@ int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) {
*(q++) = *p;
sz -= 1;
- } else if ((uint8_t) *p >= (uint8_t) ' ' && *p != 127) {
+ } else {
/* Everything else */
@@ -259,8 +264,7 @@ int dns_label_escape(const char *p, size_t l, char *dest, size_t sz) {
sz -= 4;
- } else
- return -EINVAL;
+ }
p++;
l--;
diff --git a/src/test/test-dns-domain.c b/src/test/test-dns-domain.c
index 1b0cb153f7..6c3c49908f 100644
--- a/src/test/test-dns-domain.c
+++ b/src/test/test-dns-domain.c
@@ -168,7 +168,7 @@ static void test_dns_label_escape_one(const char *what, size_t l, const char *ex
static void test_dns_label_escape(void) {
test_dns_label_escape_one("", 0, NULL, -EINVAL);
test_dns_label_escape_one("hallo", 5, "hallo", 5);
- test_dns_label_escape_one("hallo", 6, NULL, -EINVAL);
+ test_dns_label_escape_one("hallo", 6, "hallo\\000", 9);
test_dns_label_escape_one("hallo hallo.foobar,waldi", 24, "hallo\\032hallo\\.foobar\\044waldi", 31);
}
@@ -190,7 +190,7 @@ static void test_dns_name_normalize(void) {
test_dns_name_normalize_one("f", "f", 0);
test_dns_name_normalize_one("f.waldi", "f.waldi", 0);
test_dns_name_normalize_one("f \\032.waldi", "f\\032\\032.waldi", 0);
- test_dns_name_normalize_one("\\000", NULL, -EINVAL);
+ test_dns_name_normalize_one("\\000", "\\000", 0);
test_dns_name_normalize_one("..", NULL, -EINVAL);
test_dns_name_normalize_one(".foobar", NULL, -EINVAL);
test_dns_name_normalize_one("foobar.", "foobar", 0);
@@ -216,7 +216,7 @@ static void test_dns_name_equal(void) {
test_dns_name_equal_one("abc.def", "CBA.def", false);
test_dns_name_equal_one("", "xxx", false);
test_dns_name_equal_one("ab", "a", false);
- test_dns_name_equal_one("\\000", "xxxx", -EINVAL);
+ test_dns_name_equal_one("\\000", "\\000", true);
test_dns_name_equal_one(".", "", true);
test_dns_name_equal_one(".", ".", true);
test_dns_name_equal_one("..", "..", -EINVAL);