test_api_rr.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. from typing import List, Tuple
  2. import pytest
  3. from conftest import DeSECAPIV1Client, query_replication, NSLordClient, assert_eventually
  4. def generate_params(dict_value_lists_by_type: dict) -> List[Tuple[str, str]]:
  5. return [
  6. (rr_type, value)
  7. for rr_type in dict_value_lists_by_type.keys()
  8. for value in dict_value_lists_by_type[rr_type]
  9. ]
  10. VALID_RECORDS_CANONICAL = {
  11. 'A': ['127.0.0.1', '127.0.0.2'],
  12. 'AAAA': ['::1', '::2'],
  13. 'AFSDB': ['2 turquoise.femto.edu.'],
  14. 'APL': [
  15. # from RFC 3123 Sec. 4
  16. '1:192.168.32.0/21 !1:192.168.38.0/28',
  17. '1:192.168.42.0/26 1:192.168.42.64/26 1:192.168.42.128/25',
  18. '1:127.0.0.1/32 1:172.16.64.0/22',
  19. '1:224.0.0.0/4 2:ff00::/8',
  20. ],
  21. 'CAA': [
  22. '128 issue "letsencrypt.org"', '128 iodef "mailto:desec@example.com"',
  23. '1 issue "letsencrypt.org"'
  24. ],
  25. 'CDNSKEY': [
  26. None,
  27. '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5O fv4akjQGN2zY5AgB/2jmdR/+1PvXFqzK CAGJv4wjABEBNWLLFm7ew1hHMDZEKVL1 7aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKax T4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0 P+2F+TLKl3D0L/cD',
  28. '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy 9mvL5qGQTuaG5TSrNqEAR6b/qvxDx6my 4JmEmjUPA1JeEI9YfTUieMr2UZflu7aI bZFLw0vqiYrywCGrCHXLalOrEOmrvAxL vq4vHtuTlH7JIszzYBSes8g1vle6KG7x XiP3U5Ll96Qiu6bZ31rlMQSPB20xbqJJ h6psNSrQs41QvdcXAej+K2Hl1Wd8kPri ec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFa W2m7N/Wy4qcFU13roWKDEAstbxH5CHPo BfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lv u9TAiZPc0oysY6aslO7jXv16Gws=',
  29. '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iD SFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/ NTEoai5bxoipVQQXzHlzyg==',
  30. '0 3 0 AA==',
  31. ],
  32. 'CDS': [
  33. None,
  34. '6454 8 1 24396e17e36d031f71c354b06a979a67a01f503e',
  35. '0 0 0 00',
  36. ],
  37. 'CERT': [], # handled in non-canonical, because apply presentation format conversion on the stack (but not here)
  38. 'CNAME': ['example.com.'],
  39. 'CSYNC': ['0 0', '66 1 A', '66 2 AAAA', '66 3 A NS AAAA', '66 15 NSEC'],
  40. 'DHCID': ['aaaaaaaaaaaa', 'xxxx'],
  41. 'DLV': ['6454 8 1 24396e17e36d031f71c354b06a979a67a01f503e'],
  42. 'DNAME': ['example.com.'],
  43. 'DNSKEY': [
  44. None,
  45. '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5O fv4akjQGN2zY5AgB/2jmdR/+1PvXFqzK CAGJv4wjABEBNWLLFm7ew1hHMDZEKVL1 7aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKax T4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0 P+2F+TLKl3D0L/cD',
  46. '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy 9mvL5qGQTuaG5TSrNqEAR6b/qvxDx6my 4JmEmjUPA1JeEI9YfTUieMr2UZflu7aI bZFLw0vqiYrywCGrCHXLalOrEOmrvAxL vq4vHtuTlH7JIszzYBSes8g1vle6KG7x XiP3U5Ll96Qiu6bZ31rlMQSPB20xbqJJ h6psNSrQs41QvdcXAej+K2Hl1Wd8kPri ec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFa W2m7N/Wy4qcFU13roWKDEAstbxH5CHPo BfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lv u9TAiZPc0oysY6aslO7jXv16Gws=',
  47. '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iD SFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/ NTEoai5bxoipVQQXzHlzyg==',
  48. ],
  49. 'DS': ['6454 8 1 24396e17e36d031f71c354b06a979a67a01f503e'],
  50. 'EUI48': ['aa-bb-cc-dd-ee-ff'],
  51. 'EUI64': ['aa-bb-cc-dd-ee-ff-00-11'],
  52. 'HINFO': ['"ARMv8-A" "Linux"'],
  53. 'HTTPS': [
  54. '1 h3POOL.exaMPLe. alpn=h2,h3',
  55. '1 h3POOL.exaMPLe. alpn=h2,h3 ech="MTIzLi4uCg=="',
  56. ],
  57. # 'IPSECKEY': ['12 0 2 . asdfdQ==', '3 1 1 127.0.0.1 asdfdQ==', '12 3 1 example.com. asdfdQ==',],
  58. 'KX': ['4 example.com.', '28 io.', '0 .'],
  59. 'L32': ['10 10.1.2.0'],
  60. 'L64': ['10 2001:0db8:2140:2000'],
  61. 'LOC': ['23 12 59.000 N 42 22 48.500 W 65.00m 20.00m 10.00m 10.00m'],
  62. 'LP': ['10 l64-subnet1.example.com.'],
  63. 'MX': ['10 example.com.', '20 1.1.1.1.'],
  64. 'NAPTR': ['100 50 "s" "z3950+I2L+I2C" "" _z3950._tcp.gatech.edu.'],
  65. 'NID': ['10 0014:4fff:ff20:ee64'],
  66. 'NS': ['ns1.example.com.'],
  67. 'OPENPGPKEY': [
  68. 'mQINBF3yev8BEADR9GxB6OJ5AJlXBWc3nWyWZ+yNNVBiy73XjgOs0uowbxph'
  69. 'dIw6l75M6xw3i9xAlcjAGG2710FJaye7EZHot3RTIgHpn4FrErQSpNPuJKjD'
  70. 'IedZZ4av5SRtz5FfnXhNkQGs7jAVi6FmjR9/0GWMxj0BdbcOmeePCUfIIH7T'
  71. 'ujQJ2c3XHOu/kZ1h4zsFVSslcLEi4KXy0I52pEz0E2CyJrxCLdBd7uU7wDCg'
  72. 'G8KrIP3UJ5EtukP/LMq4D1eZ4FmtVqzkuDYlJJo70XQytEK9UqDdaDvlUeS5'
  73. 'FrVj4Zf7OaC5YcSvQemVV4VYSBgJIPb+iFY21/1mXAxyYaunqaR0j5qNaMjr'
  74. 'E2g3ADRxJiLExhhzlqwJU8+Lc+0QajF/s3lc+dB5usSPqGk6Eb4hBEMaqQvg'
  75. '5I0W8pFtHINYipNW5xGSrsX0pyWVai6EkoTXfjbBMC7khwmwsycJ8pYj3ipe'
  76. 'aNQuUP+XXqJKepoVOY2475Z7YT1NRRbGGEp743mbqKo4SnEKxS2kApo1UPd1'
  77. 'FbI50TZ62Vsv4tne3bR25eCycjdvIOp6zPm/Pf9LFVm5KF8Wd2U3vRi/uo4v'
  78. 'HPUK1RoIzjmirp3XUBGBgHd/mhlOADPWB9dE96eXK4yEHlbfomfFiKAisHDc'
  79. 'vUa0E/UbklYBhJjdWBaw1fDDyiSxsBCTsq4ObQARAQABtBFzdXBwb3J0QHBv'
  80. 'c3Rlby5kZYkCVAQTAQgAPhYhBJZxyBhcZRmrtOitn6TrgtJXP3x3BQJd8nr/'
  81. 'AhsDBQkDw7iABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEKTrgtJXP3x3'
  82. '+UIP/jpw6Nkp5hLbXxpPRSL2TyyWDfEHPKkBQfU+jnAUIN+WgAV27HpOa+vZ'
  83. '/hmTKOG6SlTOxHWACmDiUVfhLOYMV8QPDD3yPFCZWo4UxBKPZaai6GQwr44u'
  84. 'zCcU+E6AdFnb2nbzYSgACrErU5o5JoU2lPgleMI3FYsG8wb/kQAD7XGDX+Ev'
  85. 'tAbAQGK5EgevycJzot/hsR/S6EM/l0VsW74DIje3fbp3gaJY2fUG9fTdQu7a'
  86. 'gj6f9HuZAvXHIuSFeA/kwhUWuZfTcct8PV78gwQB4d6AOFMzoxLaFQAzxuTR'
  87. '60kZxsyyi4U5km6D/XzI9rTd228PD8xkGr/2Kx1YRU0ixZnohv9xNc4GP/69'
  88. 'GNWbbOZcyJcSL+kvych+ddbP5VjHea+b4vT35KV++PMndj+78BE1u5sdqWir'
  89. 'X9pi09go7SW1BlaJsMHrkR0P8yFCaFWLyCmIC7C/KcSuHVwcjVYWHynLq6CK'
  90. 'kkv4r8BNM/QFzPCeozXjMk7zq9TkJjLVxsUVNcZaNqzlWO0JzCfE6ICpHhyI'
  91. 'g/1bO/VJQyk+6llyX1LwRKCeKQCp6KcLx4qnjgZ8g1ArNvazNot9fAssgAUz'
  92. 'yoyOBF1SYJxWnzu9GE1F47zU1iD6FB8mjspvE00voDs8t2e+xtZoqsM12WtC'
  93. '8R4VbCY0LmTPGiWyxD9y7TnUlDfHuQINBF3yev8BEAC4dyN2BPiHCmwtKV/3'
  94. '9ZUMVCjb39wnsAA8CH7WAAM5j+k8/uXKUmTcFoZ7+9ya6PZCLXbPC64FIAwl'
  95. 'YalzCEP5Jx25Ct/DPhVJPIFWHMOYbyUbLJ8tlC1vnnDhd8czeGmozkuyofMh'
  96. '39QzR3SLzOqucJO3GC6Fx7eFNasajJsaAXaQToKx8YqKCGG4nHxn0Ucb79+G'
  97. '/0wQhtR0Mk3CxcajYJAsTV2ulW05P9xqovblXImXDZpgv0bQ2TX43SdR17yk'
  98. 'QzL33HRNCT7clLblHLMPQVxYy1yGS6hOAQj/Rmp+BO7d3S082+oyAFWeb7a9'
  99. 'fwzedbxPeiE2VOLtZizQUWIHHqwKP0tNEWRvSfCbc6ktvZQnHCIKyhmTC8N7'
  100. 'kvS4T6WjWzpc1M+GOMlOqhtW6t3zV1i2tkcpujduBGRIZ8ZQY+yo/i1HSL5t'
  101. 'N98606YXN1s2JyqwAkBJfPYiMp67J2uaFsML3YQEKAxR64GhkjFR/OqYtlIB'
  102. 'cx1PvcrPbVWQzXZBfFyjbAd55MnWVk6GrbM3y1QATN3NNhXfbMzLLU6cw/8p'
  103. 'sJw0+hxv1W2bJTftrs/5PyLryNOKYHbPEtC6aIyuzbIFFKWxkNshUiasd82Q'
  104. 'Jafgx3pFNnCtB61UV46QeqPI7sVueLslurqVgEGb2dS6unKYWXedoIMELm3C'
  105. 'g0XdJQARAQABiQI8BBgBCAAmFiEElnHIGFxlGau06K2fpOuC0lc/fHcFAl3y'
  106. 'ev8CGwwFCQPDuIAACgkQpOuC0lc/fHc/PxAAj29SBqW6ZRG8zOOw0Dmg1sg4'
  107. 'ONYtJ4hEzqPv2WbtOKxgtdcjQS1gMadtfcrH0omZPn8YmeojdbJCd5b9UBYr'
  108. 'h4Km3usURy79ouqvyQdZOIBOCUuvNcAUX2xvgUEHQW+rDpkd2mxdASsay1I7'
  109. 'yx2S0xE/QP/L2dH0470JWJ+tCIz3WuW2BEi+wijy2tqJfzIkIWA5ND2jwl4n'
  110. 'roY7srmAwZfXlh97/T5oOPIUsupIp+vmtMd4B0qa1wLGFDch+VwVvklLN5/Q'
  111. 'Vfbedy1Y8yHYiRWSrd3pHvkdtE5rI8qCOWaU/271plT9MZiwHe5WzCWESbKi'
  112. 'dwHQanM0Y6+Y8rrvUWGXrlPDvVd3Gd6TjqNhA8+AEiG+BHsw7Azc5in97/yW'
  113. '9cAYEldWv1tUjxgqvWWbGA8E6M/EuE3FuM48HNODfEh/b0ut+b2UAtuz3LzK'
  114. 'NVpqYZ9NIebpIMlUuJoQc9rPCWzMDNX37iGRBA016L7VizeJRpJ8VPRAQWHe'
  115. 'L5eC85dx9wcdK152fqlOUj729J2TZ5JYQdm9vF2cA6bsIB9m48j/UzNEeV3W'
  116. 'NZ3nuZqQ9VjVLYiPURbdkYxWfUvFdVawfqUZ4PGKbVWrFfod8WwHa+gsP4UJ'
  117. 'hLN/nxCalBbc3HnyYo0Inlytu4fumElS7kuUVNielOsJlyUr8kfxU3c6MPk=',
  118. ],
  119. 'PTR': ['example.com.', '*.example.com.'],
  120. 'RP': ['hostmaster.example.com. .'],
  121. 'SMIMEA': ['3 1 0 aabbccddeeff'],
  122. 'SPF': [
  123. '"v=spf1 ip4:10.1" ".1.1 ip4:127" ".0.0.0/16 ip4:192.168.0.0/27 include:example.com -all"',
  124. '"v=spf1 include:example.com ~all"',
  125. '"v=spf1 ip4:10.1.1.1 ip4:127.0.0.0/16 ip4:192.168.0.0/27 include:example.com -all"',
  126. '"spf2.0/pra,mfrom ip6:2001:558:fe14:76:68:87:28:0/120 -all"',
  127. ],
  128. 'SRV': ['0 0 0 .', '100 1 5061 example.com.'],
  129. 'SSHFP': ['2 2 aabbcceeddff'],
  130. 'SVCB': [
  131. '2 sVc2.example.NET. port=1234 ipv6hint=2001:db8::2',
  132. '2 sVc2.example.NET. port=1234 ech="MjIyLi4uCg==" ipv6hint=2001:db8::2',
  133. ],
  134. 'TLSA': ['3 0 2 696b8f6b92a913560b23ef5720c378881faffe74432d04eb35db957c0a93987b47adf26abb5dac10ba482597ae16edb069b511bec3e26010d1927bf6392760dd 696b8f6b92a913560b23ef5720c378881faffe74432d04eb35db957c0a93987b47adf26abb5dac10ba482597ae16edb069b511bec3e26010d1927bf6392760dd',],
  135. 'TXT': [
  136. '"foobar"',
  137. '"foo" "bar"',
  138. '"foo" "" "bar"',
  139. '"" "" "foo" "" "bar"',
  140. r'"new\010line"',
  141. r'"\000" "NUL byte yo"',
  142. r'"\130\164name\164Boss\164type\1611"', # binary stuff with first bit 1
  143. f'"{"a" * 255}" "{"a" * 243}"', # 500 byte total wire length
  144. r'"\000\001\002\003\004\005\006\007\008\009\010\011\012\013\014\015\016\017\018\019\020\021\022\023\024\025\026\027\028\029\030\031 !\"#$%&' + "'" + r'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\127\128\129\130\131\132\133\134\135\136\137\138\139\140\141\142\143\144\145\146\147\148\149\150\151\152\153\154\155\156\157\158\159\160\161\162\163\164\165\166\167\168\169\170\171\172\173\174\175\176\177\178\179\180\181\182\183\184\185\186\187\188\189\190\191\192\193\194\195\196\197\198\199\200\201\202\203\204\205\206\207\208\209\210\211\212\213\214\215\216\217\218\219\220\221\222\223\224\225\226\227\228\229\230\231\232\233\234\235\236\237\238\239\240\241\242\243\244\245\246\247\248\249\250\251\252\253\254" "\255"',
  145. ],
  146. 'URI': ['10 1 "ftp://ftp1.example.com/public"'],
  147. }
  148. VALID_RECORDS_NON_CANONICAL = {
  149. 'A': ['127.0.0.3'],
  150. 'AAAA': ['0000::0000:0003', '2001:db8::128.2.129.4'],
  151. 'AFSDB': ['03 turquoise.FEMTO.edu.'],
  152. 'APL': ['2:FF00:0:0:0:0::/8 !1:192.168.38.0/28'],
  153. 'CAA': ['0128 "issue" "letsencrypt.org"'],
  154. 'CDNSKEY': [
  155. '0256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5Ofv4akjQGN2zY5AgB/2jmdR/+1PvXFqzKCAGJv4wjABEBNWLLFm7ew1hHMDZEKVL17aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKaxT4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0P+2F+TLKl3D0L/cD',
  156. '257 03 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy9mvL5qGQTuaG5TSrNqEAR6b/qvxDx6my4JmEmjUPA1JeEI9YfTUieMr2UZflu7aIbZFLw0vqiYrywCGrCHXLalOrEOmrvAxLvq4vHtuTlH7JIszzYBSes8g1vle6KG7xXiP3U5Ll96Qiu6bZ31rlMQSPB20xbqJJh6psNSrQs41QvdcXAej+K2Hl1Wd8kPriec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFaW2m7N/Wy4qcFU13roWKDEAstbxH5CHPoBfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lvu9TAiZPc0oysY6aslO7jXv16Gws=',
  157. '257 3 013 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iDSFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/NTEoai5bxoipVQQXzHlzyg==',
  158. ],
  159. 'CDS': [
  160. '06454 08 01 24396e17e36d031f71c354b06a979a67a01f503e',
  161. '6454 8 2 5C BA665A006F6487625C6218522F09BD3673C25FA10F25CB18459AA1 0DF1F520',
  162. ],
  163. 'CERT': ['6 0 0 sadfdQ==', '06 00 00 sadfee==', 'IPGP 00 00 sadfee=='],
  164. 'CNAME': ['EXAMPLE.TEST.'],
  165. 'CSYNC': ['066 03 NS AAAA A'],
  166. 'DHCID': ['aa aaa aaaa a a a', 'xxxx'],
  167. 'DLV': [
  168. '06454 08 01 24396e17e36d031f71c354b06a979a67a01f503e',
  169. '6454 8 2 5C BA665A006F6487625C6218522F09BD3673C25FA10F25CB18459AA1 0DF1F520',
  170. ],
  171. 'DNAME': ['EXAMPLE.TEST.'],
  172. 'DNSKEY': [
  173. '0256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5Ofv4akjQGN2zY5AgB/2jmdR/+1PvXFqzKCAGJv4wjABEBNWLLFm7ew1hHMDZEKVL17aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKaxT4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0P+2F+TLKl3D0L/cD',
  174. '257 03 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy9mvL5qGQTuaG5TSrNqEAR6b/qvxDx6my4JmEmjUPA1JeEI9YfTUieMr2UZflu7aIbZFLw0vqiYrywCGrCHXLalOrEOmrvAxLvq4vHtuTlH7JIszzYBSes8g1vle6KG7xXiP3U5Ll96Qiu6bZ31rlMQSPB20xbqJJh6psNSrQs41QvdcXAej+K2Hl1Wd8kPriec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFaW2m7N/Wy4qcFU13roWKDEAstbxH5CHPoBfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lvu9TAiZPc0oysY6aslO7jXv16Gws=',
  175. '257 3 013 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iDSFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/NTEoai5bxoipVQQXzHlzyg==',
  176. ],
  177. 'DS': [
  178. '06454 08 01 24396e17e36d031f71c354b06a979a67a01f503e',
  179. '6454 8 2 5C BA665A006F6487625C6218522F09BD3673C25FA10F25CB18459AA1 0DF1F520',
  180. ],
  181. 'EUI48': ['AA-BB-CC-DD-EE-F1'],
  182. 'EUI64': ['AA-BB-CC-DD-EE-FF-00-12'],
  183. 'HINFO': ['cpu os'],
  184. 'HTTPS': [
  185. # from https://www.ietf.org/archive/id/draft-ietf-dnsop-svcb-https-06.html#name-examples, with ech base64'd
  186. '1 . alpn=h3',
  187. '0 pool.svc.example.',
  188. '1 h3pool.example. alpn=h2,h3 ech="MTIzLi4uCg=="',
  189. '2 . alpn=h2 ech="YWJjLi4uCg=="',
  190. # made-up (not from RFC)
  191. '1 pool.svc.example. no-default-alpn alpn=h2 port=1234 ipv4hint=192.168.123.1',
  192. '2 . ech=... key65333=ex1 key65444=ex2 mandatory=key65444,ech', # see #section-7
  193. ],
  194. # 'IPSECKEY': ['12 0 2 . asdfdf==', '03 1 1 127.0.00.1 asdfdf==', '12 3 1 example.com. asdfdf==',],
  195. 'KX': ['012 example.TEST.'],
  196. 'L32': ['010 10.1.2.0', '65535 1.2.3.4'],
  197. 'L64': ['010 2001:0Db8:2140:2000', '10 2001:0DB8:1140:1000'],
  198. 'LOC': ['023 012 59 N 042 022 48.500 W 65.00m 20.00m 10.00m 10.00m'],
  199. 'LP': ['010 l64-subnet1.example.com.', '65535 .'],
  200. 'MX': ['10 010.1.1.1.'],
  201. 'NAPTR': ['100 50 "s" "z3950+I2L+I2C" "" _z3950._tcp.gatech.edu.'],
  202. 'NID': ['010 0014:4fff:ff20:Ee64', '65535 0014:4fff:ff20:ee64'],
  203. 'NS': ['EXaMPLE.COM.'],
  204. 'OPENPGPKEY': [
  205. 'mG8EXtVIsRMFK4EEAC==',
  206. 'mQINBF3yev8BEADR9GxB6OJ5AJlXBWc3nWyWZ+yNNVBiy73XjgOs0uowbxph '
  207. 'dIw6l75M6xw3i9xAlcjAGG2710FJaye7EZHot3RTIgHpn4FrErQSpNPuJKjD '
  208. 'IedZZ4av5SRtz5FfnXhNkQGs7jAVi6FmjR9/0GWMxj0BdbcOmeePCUfIIH7T '
  209. 'ujQJ2c3XHOu/kZ1h4zsFVSslcLEi4KXy0I52pEz0E2CyJrxCLdBd7uU7wDCg '
  210. 'G8KrIP3UJ5EtukP/LMq4D1eZ4FmtVqzkuDYlJJo70XQytEK9UqDdaDvlUeS5 '
  211. 'FrVj4Zf7OaC5YcSvQemVV4VYSBgJIPb+iFY21/1mXAxyYaunqaR0j5qNaMjr '
  212. 'E2g3ADRxJiLExhhzlqwJU8+Lc+0QajF/s3lc+dB5usSPqGk6Eb4hBEMaqQvg '
  213. '5I0W8pFtHINYipNW5xGSrsX0pyWVai6EkoTXfjbBMC7khwmwsycJ8pYj3ipe '
  214. 'aNQuUP+XXqJKepoVOY2475Z7YT1NRRbGGEp743mbqKo4SnEKxS2kApo1UPd1 '
  215. 'FbI50TZ62Vsv4tne3bR25eCycjdvIOp6zPm/Pf9LFVm5KF8Wd2U3vRi/uo4v '
  216. 'HPUK1RoIzjmirp3XUBGBgHd/mhlOADPWB9dE96eXK4yEHlbfomfFiKAisHDc '
  217. 'vUa0E/UbklYBhJjdWBaw1fDDyiSxsBCTsq4ObQARAQABtBFzdXBwb3J0QHBv '
  218. 'c3Rlby5kZYkCVAQTAQgAPhYhBJZxyBhcZRmrtOitn6TrgtJXP3x3BQJd8nr/ '
  219. 'AhsDBQkDw7iABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEKTrgtJXP3x3 '
  220. '+UIP/jpw6Nkp5hLbXxpPRSL2TyyWDfEHPKkBQfU+jnAUIN+WgAV27HpOa+vZ '
  221. '/hmTKOG6SlTOxHWACmDiUVfhLOYMV8QPDD3yPFCZWo4UxBKPZaai6GQwr44u '
  222. 'zCcU+E6AdFnb2nbzYSgACrErU5o5JoU2lPgleMI3FYsG8wb/kQAD7XGDX+Ev '
  223. 'tAbAQGK5EgevycJzot/hsR/S6EM/l0VsW74DIje3fbp3gaJY2fUG9fTdQu7a '
  224. 'gj6f9HuZAvXHIuSFeA/kwhUWuZfTcct8PV78gwQB4d6AOFMzoxLaFQAzxuTR '
  225. '60kZxsyyi4U5km6D/XzI9rTd228PD8xkGr/2Kx1YRU0ixZnohv9xNc4GP/69 '
  226. 'GNWbbOZcyJcSL+kvych+ddbP5VjHea+b4vT35KV++PMndj+78BE1u5sdqWir '
  227. 'X9pi09go7SW1BlaJsMHrkR0P8yFCaFWLyCmIC7C/KcSuHVwcjVYWHynLq6CK '
  228. 'kkv4r8BNM/QFzPCeozXjMk7zq9TkJjLVxsUVNcZaNqzlWO0JzCfE6ICpHhyI '
  229. 'g/1bO/VJQyk+6llyX1LwRKCeKQCp6KcLx4qnjgZ8g1ArNvazNot9fAssgAUz '
  230. 'yoyOBF1SYJxWnzu9GE1F47zU1iD6FB8mjspvE00voDs8t2e+xtZoqsM12WtC '
  231. '8R4VbCY0LmTPGiWyxD9y7TnUlDfHuQINBF3yev8BEAC4dyN2BPiHCmwtKV/3 '
  232. '9ZUMVCjb39wnsAA8CH7WAAM5j+k8/uXKUmTcFoZ7+9ya6PZCLXbPC64FIAwl '
  233. 'YalzCEP5Jx25Ct/DPhVJPIFWHMOYbyUbLJ8tlC1vnnDhd8czeGmozkuyofMh '
  234. '39QzR3SLzOqucJO3GC6Fx7eFNasajJsaAXaQToKx8YqKCGG4nHxn0Ucb79+G '
  235. '/0wQhtR0Mk3CxcajYJAsTV2ulW05P9xqovblXImXDZpgv0bQ2TX43SdR17yk '
  236. 'QzL33HRNCT7clLblHLMPQVxYy1yGS6hOAQj/Rmp+BO7d3S082+oyAFWeb7a9 '
  237. 'fwzedbxPeiE2VOLtZizQUWIHHqwKP0tNEWRvSfCbc6ktvZQnHCIKyhmTC8N7 '
  238. 'kvS4T6WjWzpc1M+GOMlOqhtW6t3zV1i2tkcpujduBGRIZ8ZQY+yo/i1HSL5t '
  239. 'N98606YXN1s2JyqwAkBJfPYiMp67J2uaFsML3YQEKAxR64GhkjFR/OqYtlIB '
  240. 'cx1PvcrPbVWQzXZBfFyjbAd55MnWVk6GrbM3y1QATN3NNhXfbMzLLU6cw/8p '
  241. 'sJw0+hxv1W2bJTftrs/5PyLryNOKYHbPEtC6aIyuzbIFFKWxkNshUiasd82Q '
  242. 'Jafgx3pFNnCtB61UV46QeqPI7sVueLslurqVgEGb2dS6unKYWXedoIMELm3C '
  243. 'g0XdJQARAQABiQI8BBgBCAAmFiEElnHIGFxlGau06K2fpOuC0lc/fHcFAl3y '
  244. 'ev8CGwwFCQPDuIAACgkQpOuC0lc/fHc/PxAAj29SBqW6ZRG8zOOw0Dmg1sg4 '
  245. 'ONYtJ4hEzqPv2WbtOKxgtdcjQS1gMadtfcrH0omZPn8YmeojdbJCd5b9UBYr '
  246. 'h4Km3usURy79ouqvyQdZOIBOCUuvNcAUX2xvgUEHQW+rDpkd2mxdASsay1I7 '
  247. 'yx2S0xE/QP/L2dH0470JWJ+tCIz3WuW2BEi+wijy2tqJfzIkIWA5ND2jwl4n '
  248. 'roY7srmAwZfXlh97/T5oOPIUsupIp+vmtMd4B0qa1wLGFDch+VwVvklLN5/Q '
  249. 'Vfbedy1Y8yHYiRWSrd3pHvkdtE5rI8qCOWaU/271plT9MZiwHe5WzCWESbKi '
  250. 'dwHQanM0Y6+Y8rrvUWGXrlPDvVd3Gd6TjqNhA8+AEiG+BHsw7Azc5in97/yW '
  251. '9cAYEldWv1tUjxgqvWWbGA8E6M/EuE3FuM48HNODfEh/b0ut+b2UAtuz3LzK '
  252. 'NVpqYZ9NIebpIMlUuJoQc9rPCWzMDNX37iGRBA016L7VizeJRpJ8VPRAQWHe '
  253. 'L5eC85dx9wcdK152fqlOUj729J2TZ5JYQdm9vF2cA6bsIB9m48j/UzNEeV3W '
  254. 'NZ3nuZqQ9VjVLYiPURbdkYxWfUvFdVawfqUZ4PGKbVWrFfod8WwHa+gsP4UJ '
  255. 'hLN/nxCalBbc3HnyYo0Inlytu4fumElS7kuUVNielOsJlyUr8kfxU3c6MPk=',
  256. ],
  257. 'PTR': ['EXAMPLE.TEST.'],
  258. 'RP': ['hostmaster.EXAMPLE.com. .'],
  259. 'SMIMEA': ['3 01 0 aabbccDDeeff'],
  260. 'SPF': [],
  261. 'SRV': ['100 01 5061 example.com.'],
  262. 'SSHFP': ['02 2 aabbcceeddff'],
  263. 'SVCB': [
  264. '0 svc4-baz.example.net.',
  265. '1 . key65333=...',
  266. '2 svc2.example.net. ech="MjIyLi4uCg==" ipv6hint=2001:db8::2 port=1234',
  267. ],
  268. 'TLSA': ['003 00 002 696B8F6B92A913560b23ef5720c378881faffe74432d04eb35db957c0a93987b47adf26abb5dac10ba482597ae16edb069b511bec3e26010d1927bf6392760dd',],
  269. 'TXT': [
  270. f'"{"a" * 498}" ',
  271. '"' + 124 * '🧥' + '==="', # 501 byte total length
  272. '"🧥 👚 👕 👖 👔 👗 👙 👘 👠 👡 👢 👞 👟 🥾 🥿 🧦 🧤 🧣 🎩 🧢 👒 🎓 ⛑ 👑 👝 👛 👜 💼 🎒 "',
  273. '"🧥 👚 👕 👖 👔 👗 👙 👘 👠 👡 👢 👞 👟 🥾 🥿 🧦 🧤 🧣 🎩 🧢 👒 🎓 ⛑ 👑 👝 👛 👜 💼 🎒 👓 🕶 🥽 🥼 🌂 🧵"',
  274. '"' + ''.join(fr'\{n:03}' for n in range(256)) + '"', # all bytes
  275. ],
  276. 'URI': ['10 01 "ftp://ftp1.example.test/public"',],
  277. }
  278. INVALID_RECORDS = {
  279. 'A': ['127.0.0.999', '127.000.0.01', '127.0.0.256', '::1', 'foobar', '10.0.1', '10!'],
  280. 'AAAA': ['::g', '1:1:1:1:1:1:1:1:', '1:1:1:1:1:1:1:1:1'],
  281. 'AFSDB': ['example.com.', '1 1', '1 de'],
  282. 'APL': [
  283. '0:192.168.32.0/21 !1:192.168.38.0/28',
  284. '1:192.168.32.0/21 !!1:192.168.38.0/28',
  285. '1:192.168.32.0/33',
  286. '18:12345/2',
  287. '1:127.0.0.1',
  288. '2:::/129',
  289. ],
  290. 'CAA': ['43235 issue "letsencrypt.org"'],
  291. 'CDNSKEY': [
  292. 'a 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iDSFZNORnQuHKtJ9Wpyz+kNryq uB78Pyk/NTEoai5bxoipVQQXzHlzyg==',
  293. '0 3 0 0',
  294. ],
  295. 'CDS': [
  296. 'a 8 1 24396E17E36D031F71C354B06A979A67A01F503E',
  297. '6454 8 1 aabbccddeeff',
  298. '0 0 0 0',
  299. ],
  300. 'CERT': ['6 0 sadfdd=='],
  301. 'CNAME': ['example.com', '10 example.com.'],
  302. 'CSYNC': ['0 -1 A', '444 65536 A', '0 3 AAA'],
  303. 'DHCID': ['x', 'xx', 'xxx'],
  304. 'DLV': ['-34 13 1 aabbccddeeff'],
  305. 'DNAME': ['example.com', '10 example.com.'],
  306. 'DNSKEY': ['a 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iDSFZNORnQuHKtJ9Wpyz+kNryq uB78Pyk/NTEoai5bxoipVQQXzHlzyg=='],
  307. 'DS': [
  308. '-34 13 1 24396E17E36D031F71C354B06A979A67A01F503E',
  309. '6454 8 1 aabbccddeeff',
  310. ],
  311. 'EUI48': ['aa-bb-ccdd-ee-ff', 'AA-BB-CC-DD-EE-GG'],
  312. 'EUI64': ['aa-bb-cc-dd-ee-ff-gg-11', 'AA-BB-C C-DD-EE-FF-00-11'],
  313. 'HINFO': ['"ARMv8-A"', f'"a" "{"b" * 256}"'],
  314. 'HTTPS': [
  315. # from https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-02#section-10.3, with ech base64'd
  316. '1 h3pool alpn=h2,h3 ech="MTIzLi4uCg=="',
  317. # made-up (not from RFC)
  318. '0 pool.svc.example. no-default-alpn port=1234 ipv4hint=192.168.123.1', # no keys in alias mode
  319. '1 pool.svc.example. no-default-alpn port=1234 ipv4hint=192.168.123.1 ipv4hint=192.168.123.2', # dup
  320. ],
  321. # 'IPSECKEY': [],
  322. 'KX': ['-1 example.com', '10 example.com'],
  323. 'L32': ['65536 10.1.2.0', '5 a.1.2.0', '10 10.1.02.0'],
  324. 'L64': ['65536 2001:0DB8:4140:4000', '5 01:0DB8:4140:4000'],
  325. 'LOC': ['23 12 61.000 N 42 22 48.500 W 65.00m 20.00m 10.00m 10.00m', 'foo', '1.1.1.1'],
  326. 'LP': ['10 l64-subnet1.example.com', '-3 l64-subnet1.example.com.', '65536 l64-subnet1.example.com.'],
  327. 'MX': ['10 example.com', 'example.com.', '-5 asdf.', '65537 asdf.' '10 _foo.example.com.', '10 $url.'],
  328. 'NAPTR': ['100 50 "s" "z3950+I2L+I2C" "" _z3950._tcp.gatech.edu',
  329. '100 50 "s" "" _z3950._tcp.gatech.edu.',
  330. '100 50 3 2 "z3950+I2L+I2C" "" _z3950._tcp.gatech.edu.'],
  331. 'NID': ['010 14:4fff:ff20:Ee64', 'd 0014:4fff:ff20:ee64', '20 ::14::ee64'],
  332. 'NS': ['ns1.example.com', '127.0.0.1'],
  333. 'OPENPGPKEY': ['1 2 3'],
  334. 'PTR': ['"example.com."', '10 *.example.com.'],
  335. 'RP': ['hostmaster.example.com.', '10 foo.'],
  336. 'SMIMEA': ['3 1 0 aGVsbG8gd29ybGQh', 'x 0 0 aabbccddeeff'],
  337. 'SPF': ['"v=spf1', 'v=spf1 include:example.com ~all'],
  338. 'SRV': ['0 0 0 0', '100 5061 example.com.', '0 0 16920 _foo.example.com.', '0 0 16920 $url.'],
  339. 'SSHFP': ['aabbcceeddff'],
  340. 'SVCB': [
  341. '0 svc4-baz.example.net. keys=val',
  342. '1 not.fully.qualified key65333=...',
  343. '2 duplicate.key. ech="MjIyLi4uCg==" ech="MjIyLi4uCg=="',
  344. ],
  345. 'TLSA': ['3 1 1 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'],
  346. 'TXT': [
  347. 'foob"ar',
  348. 'v=spf1 include:example.com ~all',
  349. '"foo\nbar"',
  350. '"\x00" "Django rejects literal NUL byte"',
  351. ],
  352. 'URI': ['"1" "2" "3"'],
  353. }
  354. INVALID_RECORDS_PARAMS = [(rr_type, value) for rr_type in INVALID_RECORDS.keys() for value in INVALID_RECORDS[rr_type]]
  355. def test_soundness():
  356. assert INVALID_RECORDS.keys() == VALID_RECORDS_CANONICAL.keys() == VALID_RECORDS_NON_CANONICAL.keys()
  357. @pytest.mark.parametrize("rr_type,value", generate_params(VALID_RECORDS_CANONICAL))
  358. def test_create_valid_canonical(api_user_domain: DeSECAPIV1Client, rr_type: str, value: str):
  359. domain_name = api_user_domain.domain
  360. expected = set()
  361. subname = 'a'
  362. if rr_type in ('CDNSKEY', 'CDS', 'DNSKEY'):
  363. expected |= api_user_domain.get_key_params(domain_name, rr_type)
  364. subname = ''
  365. if value is not None:
  366. assert api_user_domain.rr_set_create(domain_name, rr_type, [value], subname=subname).status_code == 201
  367. expected.add(value)
  368. _, rrset = NSLordClient.query(f'{subname}.{domain_name}'.strip('.'), rr_type)
  369. assert rrset == expected
  370. assert_eventually(lambda: query_replication(domain_name, subname, rr_type) == expected)
  371. @pytest.mark.parametrize("rr_type,value", generate_params(VALID_RECORDS_NON_CANONICAL))
  372. def test_create_valid_non_canonical(api_user_domain: DeSECAPIV1Client, rr_type: str, value: str):
  373. domain_name = api_user_domain.domain
  374. expected = set()
  375. subname = 'a'
  376. if rr_type in ('CDNSKEY', 'CDS', 'DNSKEY'):
  377. expected |= api_user_domain.get_key_params(domain_name, rr_type)
  378. subname = ''
  379. if value is not None:
  380. assert api_user_domain.rr_set_create(domain_name, rr_type, [value], subname=subname).status_code == 201
  381. expected.add(value)
  382. _, rrset = NSLordClient.query(f'{subname}.{domain_name}'.strip('.'), rr_type)
  383. assert len(rrset) == len(expected)
  384. assert_eventually(lambda: len(query_replication(domain_name, subname, rr_type)) == len(expected))
  385. @pytest.mark.parametrize("rr_type,value", INVALID_RECORDS_PARAMS)
  386. def test_create_invalid(api_user_domain: DeSECAPIV1Client, rr_type: str, value: str):
  387. assert api_user_domain.rr_set_create(api_user_domain.domain, rr_type, [value]).status_code == 400
  388. def test_create_long_subname(api_user_domain: DeSECAPIV1Client):
  389. subname = 'a' * 63
  390. assert api_user_domain.rr_set_create(api_user_domain.domain, "AAAA", ["::1"], subname=subname).status_code == 201
  391. assert NSLordClient.query(f"{subname}.{api_user_domain.domain}", "AAAA")[1] == {"::1"}
  392. assert_eventually(lambda: query_replication(api_user_domain.domain, subname, "AAAA") == {"::1"})
  393. def test_add_remove_DNSKEY(api_user_domain: DeSECAPIV1Client):
  394. domain_name = api_user_domain.domain
  395. auto_dnskeys = api_user_domain.get_key_params(domain_name, 'DNSKEY')
  396. # After adding another DNSKEY, we expect it to be part of the nameserver's response (along with the automatic ones)
  397. value = '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iD SFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/ NTEoai5bxoipVQQXzHlzyg=='
  398. assert api_user_domain.rr_set_create(domain_name, 'DNSKEY', [value], subname='').status_code == 201
  399. assert NSLordClient.query(domain_name, 'DNSKEY')[1] == auto_dnskeys | {value}
  400. assert_eventually(lambda: query_replication(domain_name, '', 'DNSKEY') == auto_dnskeys | {value})
  401. # After deleting it, we expect that the automatically managed ones are still there
  402. assert api_user_domain.rr_set_delete(domain_name, "DNSKEY", subname='').status_code == 204
  403. assert NSLordClient.query(domain_name, 'DNSKEY')[1] == auto_dnskeys
  404. assert_eventually(lambda: query_replication(domain_name, '', 'DNSKEY') == auto_dnskeys)