Преглед на файлове

fix(api): allow underscores in CNAME targets

The previous check was based on the wrong pdns code location.
Consultation on pdns IRC revealed the right one.

Fixes regression from 0605f3879012ce6dc4c06f5d7711875348c9e468
Peter Thomassen преди 2 години
родител
ревизия
bbcbc55a72
променени са 3 файла, в които са добавени 19 реда и са изтрити 10 реда
  1. 17 8
      api/desecapi/dns.py
  2. 1 1
      api/desecapi/tests/test_rrsets.py
  3. 1 1
      test/e2e2/spec/test_api_rr.py

+ 17 - 8
api/desecapi/dns.py

@@ -98,16 +98,23 @@ class LongQuotedTXT(dns.rdtypes.txtbase.TXTBase):
                 file.write(s)
 
 
-def _HostnameMixin(name_field, *, allow_root):
-    # Taken from https://github.com/PowerDNS/pdns/blob/4646277d05f293777a3d2423a3b188ccdf42c6bc/pdns/dnsname.cc#L419
-    hostname_re = re.compile(r"^(([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)\.)+$")
+def _NameMixin(name_field, *, allow_root, hostname=True):
+    pattern = (
+        # https://github.com/PowerDNS/pdns/blob/4646277d05f293777a3d2423a3b188ccdf42c6bc/pdns/dnsname.cc#L419
+        re.compile(r"^(([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)\.)+$")
+        if hostname
+        else
+        # https://github.com/PowerDNS/pdns/blob/4646277d05f293777a3d2423a3b188ccdf42c6bc/pdns/dnsname.cc#L473
+        # with the exception of [/@ :\\]
+        re.compile(r"^(([A-Za-z0-9_*-]+)\.)+$")
+    )
 
     class Mixin:
         def to_text(self, origin=None, relativize=True, **kw):
             name = getattr(self, name_field)
             if (
                 not (allow_root and name == dns.name.root)
-                and hostname_re.match(str(name)) is None
+                and pattern.match(str(name)) is None
             ):
                 raise ValueError(f"invalid {name_field}: {name}")
             return super().to_text(origin, relativize, **kw)
@@ -116,20 +123,22 @@ def _HostnameMixin(name_field, *, allow_root):
 
 
 @dns.immutable.immutable
-class CNAME(_HostnameMixin("target", allow_root=True), dns.rdtypes.ANY.CNAME.CNAME):
+class CNAME(
+    _NameMixin("target", allow_root=True, hostname=False), dns.rdtypes.ANY.CNAME.CNAME
+):
     pass
 
 
 @dns.immutable.immutable
-class MX(_HostnameMixin("exchange", allow_root=True), dns.rdtypes.ANY.MX.MX):
+class MX(_NameMixin("exchange", allow_root=True), dns.rdtypes.ANY.MX.MX):
     pass
 
 
 @dns.immutable.immutable
-class NS(_HostnameMixin("target", allow_root=False), dns.rdtypes.ANY.NS.NS):
+class NS(_NameMixin("target", allow_root=False), dns.rdtypes.ANY.NS.NS):
     pass
 
 
 @dns.immutable.immutable
-class SRV(_HostnameMixin("target", allow_root=True), dns.rdtypes.IN.SRV.SRV):
+class SRV(_NameMixin("target", allow_root=True), dns.rdtypes.IN.SRV.SRV):
     pass

+ 1 - 1
api/desecapi/tests/test_rrsets.py

@@ -840,7 +840,7 @@ class AuthenticatedRRSetTestCase(AuthenticatedRRSetBaseTestCase):
                 "61655 13 4 C838A5C66FCBF83B8B6B50C3CEEC3524777FE4AF8A9FE0172ECAD242 48B0CA1A216DD0D538F20C130DD3059538204B04",
                 "6454 8 5 24396E17E36D031F71C354B06A979A67A01F503E",
             ],
-            "CNAME": ["example.com."],
+            "CNAME": ["example.com.", "*._under-score.-foo_bar.example.net.", "."],
             "CSYNC": ["0 0", "66 1 A", "66 2 AAAA", "66 3 A NS AAAA", "66 15 NSEC"],
             "DHCID": ["aaaaaaaaaaaa", "aa aaa  aaaa a a a"],
             "DLV": [

+ 1 - 1
test/e2e2/spec/test_api_rr.py

@@ -169,7 +169,7 @@ VALID_RECORDS_NON_CANONICAL = {
         '6454 8 2 5C BA665A006F6487625C6218522F09BD3673C25FA10F25CB18459AA1 0DF1F520',
     ],
     'CERT': ['6 0 0 sadfdQ==', '06 00 00 sadfee==', 'IPGP 00 00 sadfee=='],
-    'CNAME': ['EXAMPLE.TEST.'],
+    'CNAME': ['EXAMPLE.TEST.', '*._under-score.-foo_bar.example.net.'],
     'CSYNC': ['066 03  NS  AAAA A'],
     'DHCID': ['aa aaa  aaaa a a a', 'xxxx'],
     'DLV': [