]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/test/test-dns-domain.c
build-sys: use #if Y instead of #ifdef Y everywhere
[thirdparty/systemd.git] / src / test / test-dns-domain.c
index 1b0cb153f7fa788d54ab2b3875a69ad942171e8a..75bc5e4a73fde15724ba731dd9dc3b1998c8d956 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
@@ -50,6 +48,7 @@ static void test_dns_label_unescape(void) {
         test_dns_label_unescape_one("..", "", 20, -EINVAL);
         test_dns_label_unescape_one(".foobar", "", 20, -EINVAL);
         test_dns_label_unescape_one("foobar.", "foobar", 20, 6);
+        test_dns_label_unescape_one("foobar..", "foobar", 20, -EINVAL);
 }
 
 static void test_dns_name_to_wire_format_one(const char *what, const char *expect, size_t buffer_sz, int ret) {
@@ -168,7 +167,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);
 }
 
@@ -186,15 +185,15 @@ static void test_dns_name_normalize_one(const char *what, const char *expect, in
 }
 
 static void test_dns_name_normalize(void) {
-        test_dns_name_normalize_one("", "", 0);
+        test_dns_name_normalize_one("", ".", 0);
         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);
-        test_dns_name_normalize_one(".", "", 0);
+        test_dns_name_normalize_one(".", ".", 0);
 }
 
 static void test_dns_name_equal_one(const char *a, const char *b, int ret) {
@@ -216,7 +215,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);
@@ -276,6 +275,25 @@ static void test_dns_name_endswith(void) {
         test_dns_name_endswith_one("x.y\001.z", "waldo", -EINVAL);
 }
 
+static void test_dns_name_startswith_one(const char *a, const char *b, int ret) {
+        assert_se(dns_name_startswith(a, b) == ret);
+}
+
+static void test_dns_name_startswith(void) {
+        test_dns_name_startswith_one("", "", true);
+        test_dns_name_startswith_one("", "xxx", false);
+        test_dns_name_startswith_one("xxx", "", true);
+        test_dns_name_startswith_one("x", "x", true);
+        test_dns_name_startswith_one("x", "y", false);
+        test_dns_name_startswith_one("x.y", "x.y", true);
+        test_dns_name_startswith_one("x.y", "y.x", false);
+        test_dns_name_startswith_one("x.y", "x", true);
+        test_dns_name_startswith_one("x.y", "X", true);
+        test_dns_name_startswith_one("x.y", "y", false);
+        test_dns_name_startswith_one("x.y", "", true);
+        test_dns_name_startswith_one("x.y", "X", true);
+}
+
 static void test_dns_name_is_root(void) {
         assert_se(dns_name_is_root(""));
         assert_se(dns_name_is_root("."));
@@ -321,10 +339,18 @@ static void test_dns_name_concat_one(const char *a, const char *b, int r, const
 }
 
 static void test_dns_name_concat(void) {
+        test_dns_name_concat_one("", "", 0, ".");
+        test_dns_name_concat_one(".", "", 0, ".");
+        test_dns_name_concat_one("", ".", 0, ".");
+        test_dns_name_concat_one(".", ".", 0, ".");
         test_dns_name_concat_one("foo", "bar", 0, "foo.bar");
         test_dns_name_concat_one("foo.foo", "bar.bar", 0, "foo.foo.bar.bar");
         test_dns_name_concat_one("foo", NULL, 0, "foo");
+        test_dns_name_concat_one("foo", ".", 0, "foo");
         test_dns_name_concat_one("foo.", "bar.", 0, "foo.bar");
+        test_dns_name_concat_one(NULL, NULL, 0, ".");
+        test_dns_name_concat_one(NULL, ".", 0, ".");
+        test_dns_name_concat_one(NULL, "foo", 0, "foo");
 }
 
 static void test_dns_name_is_valid_one(const char *s, int ret) {
@@ -334,6 +360,7 @@ static void test_dns_name_is_valid_one(const char *s, int ret) {
 static void test_dns_name_is_valid(void) {
         test_dns_name_is_valid_one("foo", 1);
         test_dns_name_is_valid_one("foo.", 1);
+        test_dns_name_is_valid_one("foo..", 0);
         test_dns_name_is_valid_one("Foo", 1);
         test_dns_name_is_valid_one("foo.bar", 1);
         test_dns_name_is_valid_one("foo.bar.baz", 1);
@@ -341,20 +368,21 @@ static void test_dns_name_is_valid(void) {
         test_dns_name_is_valid_one("foo..bar", 0);
         test_dns_name_is_valid_one(".foo.bar", 0);
         test_dns_name_is_valid_one("foo.bar.", 1);
+        test_dns_name_is_valid_one("foo.bar..", 0);
         test_dns_name_is_valid_one("\\zbar", 0);
         test_dns_name_is_valid_one("ä", 1);
         test_dns_name_is_valid_one("\n", 0);
 
-        /* 256 characters*/
+        /* 256 characters */
         test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345", 0);
 
-        /* 255 characters*/
+        /* 255 characters */
         test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a1234", 0);
 
-        /* 254 characters*/
+        /* 254 characters */
         test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a123", 0);
 
-        /* 253 characters*/
+        /* 253 characters */
         test_dns_name_is_valid_one("a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12345678.a12", 1);
 
         /* label of 64 chars length */
@@ -410,7 +438,7 @@ static void test_dns_service_join_one(const char *a, const char *b, const char *
         assert_se(dns_service_split(t, &x, &y, &z) >= 0);
         assert_se(streq_ptr(a, x));
         assert_se(streq_ptr(b, y));
-        assert_se(streq_ptr(c, z));
+        assert_se(dns_name_equal(c, z) > 0);
 }
 
 static void test_dns_service_join(void) {
@@ -441,18 +469,18 @@ static void test_dns_service_split_one(const char *joined, const char *a, const
 
         if (y) {
                 assert_se(dns_service_join(x, y, z, &t) == 0);
-                assert_se(streq_ptr(joined, t));
+                assert_se(dns_name_equal(joined, t) > 0);
         } else
-                assert_se(!x && streq_ptr(z, joined));
+                assert_se(!x && dns_name_equal(z, joined) > 0);
 }
 
 static void test_dns_service_split(void) {
-        test_dns_service_split_one("", NULL, NULL, "", 0);
+        test_dns_service_split_one("", NULL, NULL, ".", 0);
         test_dns_service_split_one("foo", NULL, NULL, "foo", 0);
         test_dns_service_split_one("foo.bar", NULL, NULL, "foo.bar", 0);
         test_dns_service_split_one("_foo.bar", NULL, NULL, "_foo.bar", 0);
-        test_dns_service_split_one("_foo._bar", NULL, "_foo._bar", "", 0);
-        test_dns_service_split_one("_meh._foo._bar", "_meh", "_foo._bar", "", 0);
+        test_dns_service_split_one("_foo._bar", NULL, "_foo._bar", ".", 0);
+        test_dns_service_split_one("_meh._foo._bar", "_meh", "_foo._bar", ".", 0);
         test_dns_service_split_one("Wuff\\032Wuff._foo._bar.waldo.com", "Wuff Wuff", "_foo._bar", "waldo.com", 0);
 }
 
@@ -471,7 +499,7 @@ static void test_dns_name_change_suffix(void) {
         test_dns_name_change_suffix_one("foo.bar.waldi.quux", "quux", "piff.paff", 1, "foo.bar.waldi.piff.paff");
         test_dns_name_change_suffix_one("foo.bar.waldi.quux", "", "piff.paff", 1, "foo.bar.waldi.quux.piff.paff");
         test_dns_name_change_suffix_one("", "", "piff.paff", 1, "piff.paff");
-        test_dns_name_change_suffix_one("", "", "", 1, "");
+        test_dns_name_change_suffix_one("", "", "", 1, ".");
         test_dns_name_change_suffix_one("a", "b", "c", 0, NULL);
 }
 
@@ -559,7 +587,100 @@ static void test_dns_name_compare_func(void) {
         assert_se(dns_name_compare_func("de.", "heise.de") != 0);
 }
 
+static void test_dns_name_common_suffix_one(const char *a, const char *b, const char *result) {
+        const char *c;
+
+        assert_se(dns_name_common_suffix(a, b, &c) >= 0);
+        assert_se(streq(c, result));
+}
+
+static void test_dns_name_common_suffix(void) {
+        test_dns_name_common_suffix_one("", "", "");
+        test_dns_name_common_suffix_one("foo", "", "");
+        test_dns_name_common_suffix_one("", "foo", "");
+        test_dns_name_common_suffix_one("foo", "bar", "");
+        test_dns_name_common_suffix_one("bar", "foo", "");
+        test_dns_name_common_suffix_one("foo", "foo", "foo");
+        test_dns_name_common_suffix_one("quux.foo", "foo", "foo");
+        test_dns_name_common_suffix_one("foo", "quux.foo", "foo");
+        test_dns_name_common_suffix_one("this.is.a.short.sentence", "this.is.another.short.sentence", "short.sentence");
+        test_dns_name_common_suffix_one("FOO.BAR", "tEST.bAR", "BAR");
+}
+
+static void test_dns_name_apply_idna_one(const char *s, int expected, const char *result) {
+        _cleanup_free_ char *buf = NULL;
+        int r;
+
+        r = dns_name_apply_idna(s, &buf);
+        log_debug("dns_name_apply_idna: \"%s\" → %d/\"%s\" (expected %d/\"%s\")",
+                  s, r, strnull(buf), expected, strnull(result));
+
+        /* Different libidn2 versions are more and less accepting
+         * of underscore-prefixed names. So let's list the lowest
+         * expected return value. */
+        assert_se(r >= expected);
+        if (expected == 1)
+                assert_se(dns_name_equal(buf, result) == 1);
+}
+
+static void test_dns_name_apply_idna(void) {
+#if HAVE_LIBIDN2 || HAVE_LIBIDN
+        const int ret = 1;
+#else
+        const int ret = 0;
+#endif
+
+        /* IDNA2008 forbids names with hyphens in third and fourth positions
+         * (https://tools.ietf.org/html/rfc5891#section-4.2.3.1).
+         * IDNA2003 does not have this restriction
+         * (https://tools.ietf.org/html/rfc3490#section-5).
+         * This means that when using libidn we will transform and test more
+         * labels. If registrars follow IDNA2008 we'll just be performing a
+         * useless lookup.
+         */
+#if HAVE_LIBIDN
+        const int ret2 = 1;
+#else
+        const int ret2 = 0;
+#endif
+
+        test_dns_name_apply_idna_one("", ret, "");
+        test_dns_name_apply_idna_one("foo", ret, "foo");
+        test_dns_name_apply_idna_one("foo.", ret, "foo");
+        test_dns_name_apply_idna_one("foo.bar", ret, "foo.bar");
+        test_dns_name_apply_idna_one("foo.bar.", ret, "foo.bar");
+        test_dns_name_apply_idna_one("föö", ret, "xn--f-1gaa");
+        test_dns_name_apply_idna_one("föö.", ret, "xn--f-1gaa");
+        test_dns_name_apply_idna_one("föö.bär", ret, "xn--f-1gaa.xn--br-via");
+        test_dns_name_apply_idna_one("föö.bär.", ret, "xn--f-1gaa.xn--br-via");
+        test_dns_name_apply_idna_one("xn--f-1gaa.xn--br-via", ret, "xn--f-1gaa.xn--br-via");
+
+        test_dns_name_apply_idna_one("_443._tcp.fedoraproject.org", ret2,
+                                     "_443._tcp.fedoraproject.org");
+        test_dns_name_apply_idna_one("_443", ret2, "_443");
+        test_dns_name_apply_idna_one("gateway", ret, "gateway");
+        test_dns_name_apply_idna_one("_gateway", ret2, "_gateway");
+
+        test_dns_name_apply_idna_one("r3---sn-ab5l6ne7.googlevideo.com", ret2,
+                                     ret2 ? "r3---sn-ab5l6ne7.googlevideo.com" : "");
+}
+
+static void test_dns_name_is_valid_or_address(void) {
+        assert_se(dns_name_is_valid_or_address(NULL) == 0);
+        assert_se(dns_name_is_valid_or_address("") == 0);
+        assert_se(dns_name_is_valid_or_address("foobar") > 0);
+        assert_se(dns_name_is_valid_or_address("foobar.com") > 0);
+        assert_se(dns_name_is_valid_or_address("foobar..com") == 0);
+        assert_se(dns_name_is_valid_or_address("foobar.com.") > 0);
+        assert_se(dns_name_is_valid_or_address("127.0.0.1") > 0);
+        assert_se(dns_name_is_valid_or_address("::") > 0);
+        assert_se(dns_name_is_valid_or_address("::1") > 0);
+}
+
 int main(int argc, char *argv[]) {
+        log_set_max_level(LOG_DEBUG);
+        log_parse_environment();
+        log_open();
 
         test_dns_label_unescape();
         test_dns_label_unescape_suffix();
@@ -567,6 +688,7 @@ int main(int argc, char *argv[]) {
         test_dns_name_normalize();
         test_dns_name_equal();
         test_dns_name_endswith();
+        test_dns_name_startswith();
         test_dns_name_between();
         test_dns_name_is_root();
         test_dns_name_is_single_label();
@@ -583,6 +705,9 @@ int main(int argc, char *argv[]) {
         test_dns_name_count_labels();
         test_dns_name_equal_skip();
         test_dns_name_compare_func();
+        test_dns_name_common_suffix();
+        test_dns_name_apply_idna();
+        test_dns_name_is_valid_or_address();
 
         return 0;
 }