]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dns-domain: add helper that checks whether domain is dot suffixed
authorLennart Poettering <lennart@poettering.net>
Tue, 29 Sep 2020 09:52:15 +0000 (11:52 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 29 Sep 2020 10:09:16 +0000 (12:09 +0200)
src/shared/dns-domain.c
src/shared/dns-domain.h
src/test/test-dns-domain.c

index b812665315f63dc0dc872dc03660a1508c969743..00e12e681fec36914db4a7a4c71f86b9224b4de0 100644 (file)
@@ -41,8 +41,9 @@ int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags f
                                 /* Trailing dash */
                                 return -EINVAL;
 
                                 /* Trailing dash */
                                 return -EINVAL;
 
-                        if (*n == '.')
+                        if (n[0] == '.' && (n[1] != 0 || !FLAGS_SET(flags, DNS_LABEL_LEAVE_TRAILING_DOT)))
                                 n++;
                                 n++;
+
                         break;
                 }
 
                         break;
                 }
 
@@ -139,7 +140,7 @@ int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags f
                 return -EINVAL;
 
         /* More than one trailing dot? */
                 return -EINVAL;
 
         /* More than one trailing dot? */
-        if (*n == '.')
+        if (n[0] == '.' && !FLAGS_SET(flags, DNS_LABEL_LEAVE_TRAILING_DOT))
                 return -EINVAL;
 
         if (sz >= 1 && d)
                 return -EINVAL;
 
         if (sz >= 1 && d)
@@ -1372,3 +1373,19 @@ int dns_name_is_valid_or_address(const char *name) {
 
         return dns_name_is_valid(name);
 }
 
         return dns_name_is_valid(name);
 }
+
+int dns_name_dot_suffixed(const char *name) {
+        const char *p = name;
+        int r;
+
+        for (;;) {
+                if (streq(p, "."))
+                        return true;
+
+                r = dns_label_unescape(&p, NULL, DNS_LABEL_MAX, DNS_LABEL_LEAVE_TRAILING_DOT);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return false;
+        }
+}
index 6ed512c6b1656515c3a17b99fe994e6baedcf84e..60de7af22721d892cf7cfba5dc76788d9177ce28 100644 (file)
@@ -25,8 +25,9 @@
 #define DNS_N_LABELS_MAX 127
 
 typedef enum DNSLabelFlags {
 #define DNS_N_LABELS_MAX 127
 
 typedef enum DNSLabelFlags {
-        DNS_LABEL_LDH        = 1 << 0, /* Follow the "LDH" rule — only letters, digits, and internal hyphens. */
-        DNS_LABEL_NO_ESCAPES = 1 << 1, /* Do not treat backslashes specially */
+        DNS_LABEL_LDH                = 1 << 0, /* Follow the "LDH" rule — only letters, digits, and internal hyphens. */
+        DNS_LABEL_NO_ESCAPES         = 1 << 1, /* Do not treat backslashes specially */
+        DNS_LABEL_LEAVE_TRAILING_DOT = 1 << 2, /* Leave trailing dot in place */
 } DNSLabelFlags;
 
 int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags);
 } DNSLabelFlags;
 
 int dns_label_unescape(const char **name, char *dest, size_t sz, DNSLabelFlags flags);
@@ -110,3 +111,5 @@ int dns_name_common_suffix(const char *a, const char *b, const char **ret);
 int dns_name_apply_idna(const char *name, char **ret);
 
 int dns_name_is_valid_or_address(const char *name);
 int dns_name_apply_idna(const char *name, char **ret);
 
 int dns_name_is_valid_or_address(const char *name);
+
+int dns_name_dot_suffixed(const char *name);
index ead5311705d63c8ac6e8665ce71297f35de98942..b73dc56465617a3336c2aee7c988958a2a12a0ee 100644 (file)
@@ -780,6 +780,20 @@ static void test_dns_name_is_valid_or_address(void) {
         assert_se(dns_name_is_valid_or_address("::1") > 0);
 }
 
         assert_se(dns_name_is_valid_or_address("::1") > 0);
 }
 
+static void test_dns_name_dot_suffixed(void) {
+        log_info("/* %s */", __func__);
+
+        assert_se(dns_name_dot_suffixed("") == 0);
+        assert_se(dns_name_dot_suffixed(".") > 0);
+        assert_se(dns_name_dot_suffixed("foo") == 0);
+        assert_se(dns_name_dot_suffixed("foo.") > 0);
+        assert_se(dns_name_dot_suffixed("foo\\..") > 0);
+        assert_se(dns_name_dot_suffixed("foo\\.") == 0);
+        assert_se(dns_name_dot_suffixed("foo.bar.") > 0);
+        assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\..") > 0);
+        assert_se(dns_name_dot_suffixed("foo.bar\\.\\.\\.\\.") == 0);
+}
+
 int main(int argc, char *argv[]) {
         test_setup_logging(LOG_DEBUG);
 
 int main(int argc, char *argv[]) {
         test_setup_logging(LOG_DEBUG);
 
@@ -810,6 +824,7 @@ int main(int argc, char *argv[]) {
         test_dns_name_common_suffix();
         test_dns_name_apply_idna();
         test_dns_name_is_valid_or_address();
         test_dns_name_common_suffix();
         test_dns_name_apply_idna();
         test_dns_name_is_valid_or_address();
+        test_dns_name_dot_suffixed();
 
         return 0;
 }
 
         return 0;
 }