summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBob Halley <halley@dnspython.org>2020-08-07 19:20:30 -0700
committerGitHub <noreply@github.com>2020-08-07 19:20:30 -0700
commit330ddd8fecbe583d71fb9c1033eb12c60f5f6bec (patch)
tree2d8e802a01b2851e8fcf2d27cecf361e896c6248 /tests
parent157e4e907333fae7fb4c5888949258aa7927f6e9 (diff)
parent5891ac286ee4ba934738c94c7189ee2d868fcd3b (diff)
downloaddnspython-330ddd8fecbe583d71fb9c1033eb12c60f5f6bec.tar.gz
Merge pull request #568 from rthalley/svcb
SVCB and HTTPS support
Diffstat (limited to 'tests')
-rw-r--r--tests/example6
-rw-r--r--tests/example1.good3
-rw-r--r--tests/example2.good3
-rw-r--r--tests/example3.good3
-rw-r--r--tests/test_svcb.py274
5 files changed, 289 insertions, 0 deletions
diff --git a/tests/example b/tests/example
index 29dcb26..b077248 100644
--- a/tests/example
+++ b/tests/example
@@ -232,3 +232,9 @@ amtrelay04 AMTRELAY 10 0 2 2001:db8::15
amtrelay05 AMTRELAY 128 1 3 amtrelays.example.com.
csync0 CSYNC 12345 0 A MX RRSIG NSEC TYPE1234
avc01 AVC "app-name:WOLFGANG|app-class:OAM|business=yes"
+svcb01 SVCB (
+100 foo.com. mandatory="alpn,port" alpn="h2,h3" no-default-alpn port="12345"
+echconfig="abcd" ipv4hint=1.2.3.4,4.3.2.1 ipv6hint=1::2,3::4 key12345="foo"
+)
+https01 HTTPS 0 svc
+https02 HTTPS 1 . port=8002 echconfig="abcd"
diff --git a/tests/example1.good b/tests/example1.good
index beb57af..8cef642 100644
--- a/tests/example1.good
+++ b/tests/example1.good
@@ -60,6 +60,8 @@ hinfo02 3600 IN HINFO "PC" "NetBSD"
hip01 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip02 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
hip03 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2.example.com.
+https01 3600 IN HTTPS 0 svc
+https02 3600 IN HTTPS 1 . port="8002" echconfig="abcd"
ipseckey01 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
ipseckey02 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
ipseckey03 3600 IN IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
@@ -110,6 +112,7 @@ spf 3600 IN SPF "v=spf1 mx -all"
srv01 3600 IN SRV 0 0 0 .
srv02 3600 IN SRV 65535 65535 65535 old-slow-box.example.com.
sshfp1 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab
+svcb01 3600 IN SVCB 100 foo.com. mandatory="alpn,port" alpn="h2,h3" no-default-alpn port="12345" ipv4hint="1.2.3.4,4.3.2.1" echconfig="abcd" ipv6hint="1::2,3::4" key12345="foo"
t 301 IN A 73.80.65.49
tlsa1 3600 IN TLSA 3 1 1 a9cdf989b504fe5dca90c0d2167b6550570734f7c763e09fdf88904e06157065
tlsa2 3600 IN TLSA 1 0 1 efddf0d915c7bdc5782c0881e1b2a95ad099fbdd06d7b1f77982d9364338d955
diff --git a/tests/example2.good b/tests/example2.good
index 75c787c..a6d374e 100644
--- a/tests/example2.good
+++ b/tests/example2.good
@@ -60,6 +60,8 @@ hinfo02.example. 3600 IN HINFO "PC" "NetBSD"
hip01.example. 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip02.example. 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
hip03.example. 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2.example.com.
+https01.example. 3600 IN HTTPS 0 svc.example.
+https02.example. 3600 IN HTTPS 1 . port="8002" echconfig="abcd"
ipseckey01.example. 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
ipseckey02.example. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
ipseckey03.example. 3600 IN IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
@@ -110,6 +112,7 @@ spf.example. 3600 IN SPF "v=spf1 mx -all"
srv01.example. 3600 IN SRV 0 0 0 .
srv02.example. 3600 IN SRV 65535 65535 65535 old-slow-box.example.com.
sshfp1.example. 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab
+svcb01.example. 3600 IN SVCB 100 foo.com. mandatory="alpn,port" alpn="h2,h3" no-default-alpn port="12345" ipv4hint="1.2.3.4,4.3.2.1" echconfig="abcd" ipv6hint="1::2,3::4" key12345="foo"
t.example. 301 IN A 73.80.65.49
tlsa1.example. 3600 IN TLSA 3 1 1 a9cdf989b504fe5dca90c0d2167b6550570734f7c763e09fdf88904e06157065
tlsa2.example. 3600 IN TLSA 1 0 1 efddf0d915c7bdc5782c0881e1b2a95ad099fbdd06d7b1f77982d9364338d955
diff --git a/tests/example3.good b/tests/example3.good
index beb57af..8cef642 100644
--- a/tests/example3.good
+++ b/tests/example3.good
@@ -60,6 +60,8 @@ hinfo02 3600 IN HINFO "PC" "NetBSD"
hip01 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip02 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
hip03 3600 IN HIP 2 200100107b1a74df365639cc39f1d578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2.example.com.
+https01 3600 IN HTTPS 0 svc
+https02 3600 IN HTTPS 1 . port="8002" echconfig="abcd"
ipseckey01 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
ipseckey02 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
ipseckey03 3600 IN IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtu gbo6BSGvgqt4AQ==
@@ -110,6 +112,7 @@ spf 3600 IN SPF "v=spf1 mx -all"
srv01 3600 IN SRV 0 0 0 .
srv02 3600 IN SRV 65535 65535 65535 old-slow-box.example.com.
sshfp1 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab
+svcb01 3600 IN SVCB 100 foo.com. mandatory="alpn,port" alpn="h2,h3" no-default-alpn port="12345" ipv4hint="1.2.3.4,4.3.2.1" echconfig="abcd" ipv6hint="1::2,3::4" key12345="foo"
t 301 IN A 73.80.65.49
tlsa1 3600 IN TLSA 3 1 1 a9cdf989b504fe5dca90c0d2167b6550570734f7c763e09fdf88904e06157065
tlsa2 3600 IN TLSA 1 0 1 efddf0d915c7bdc5782c0881e1b2a95ad099fbdd06d7b1f77982d9364338d955
diff --git a/tests/test_svcb.py b/tests/test_svcb.py
new file mode 100644
index 0000000..a11a13b
--- /dev/null
+++ b/tests/test_svcb.py
@@ -0,0 +1,274 @@
+import unittest
+
+import dns.rdata
+import dns.rdtypes.svcbbase
+
+class SVCBTestCase(unittest.TestCase):
+ def check_valid_inputs(self, inputs):
+ expected = inputs[0]
+ for text in inputs:
+ rr = dns.rdata.from_text('IN', 'SVCB', text)
+ new_text = rr.to_text()
+ self.assertEqual(expected, new_text)
+
+ def check_invalid_inputs(self, inputs):
+ for text in inputs:
+ with self.assertRaises(dns.exception.SyntaxError):
+ dns.rdata.from_text('IN', 'SVCB', text)
+
+ def test_svcb_general_invalid(self):
+ invalid_inputs = (
+ # Duplicate keys
+ "1 . alpn=h2 alpn=h3",
+ "1 . alpn=h2 key1=h3",
+ # Quoted keys
+ "1 . \"alpn=h2\"",
+ # Invalid space
+ "1 . alpn= h2",
+ "1 . alpn =h2",
+ "1 . alpn = h2",
+ "1 . alpn= \"h2\"",
+ "1 . =alpn",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_svcb_mandatory(self):
+ valid_inputs = (
+ "1 . mandatory=\"alpn,no-default-alpn\" alpn=\"h2\" no-default-alpn",
+ "1 . mandatory=alpn,no-default-alpn alpn=h2 no-default-alpn",
+ "1 . mandatory=key1,key2 alpn=h2 no-default-alpn",
+ "1 . mandatory=alpn,no-default-alpn key1=\\002h2 key2=\"\"",
+ "1 . mandatory=alpn,no-default-alpn key1=\\002h2 key2",
+ "1 . key0=\\000\\001\\000\\002 alpn=h2 no-default-alpn",
+ "1 . alpn=h2 no-default-alpn mandatory=alpn,no-default-alpn",
+ )
+ self.check_valid_inputs(valid_inputs)
+
+ invalid_inputs = (
+ # unknown key
+ "1 . mandatory=foo",
+ # key 0
+ "1 . mandatory=key0",
+ "1 . mandatory=key0,alpn",
+ # missing key
+ "1 . mandatory=alpn",
+ # duplicate
+ "1 . mandatory=alpn,alpn alpn=h2",
+ # invalid escaping
+ "1 . mandatory=\\alpn alpn=h2",
+ # 0 in wire format
+ "1 . key0=\\000\\000",
+ # invalid length in wire format
+ "1 . key0=\\000",
+ # out of order in wire format
+ "1 . key0=\\000\\002\\000\\001 alpn=h2 no-default-alpn",
+ # leading zeros
+ "1 . mandatory=key1,key002 alpn=h2 no-default-alpn",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_svcb_alpn(self):
+ valid_inputs_two_items = (
+ "1 . alpn=\"h2,h3\"",
+ "1 . alpn=h2,h3",
+ "1 . alpn=h\\050,h3",
+ "1 . alpn=\"h\\050,h3\"",
+ "1 . alpn=\\h2,h3",
+ "1 . key1=\\002h2\\002h3",
+ )
+ self.check_valid_inputs(valid_inputs_two_items)
+
+ valid_inputs_one_item = (
+ "1 . alpn=\"h2\\,h3\"",
+ "1 . alpn=h2\\,h3",
+ "1 . alpn=h2\\044h3",
+ )
+ self.check_valid_inputs(valid_inputs_one_item)
+
+ invalid_inputs = (
+ "1 . alpn=h2,,h3",
+ "1 . alpn=01234567890abcdef01234567890abcdef01234567890abcdef"
+ "01234567890abcdef01234567890abcdef01234567890abcdef"
+ "01234567890abcdef01234567890abcdef01234567890abcdef"
+ "01234567890abcdef01234567890abcdef01234567890abcdef"
+ "01234567890abcdef01234567890abcdef01234567890abcdef"
+ "01234567890abcdef",
+ "1 . key1=\\000",
+ "1 . key1=\\002x",
+ "1 . alpn=\",h2,h3\"",
+ "1 . alpn=\"h2,h3,\"",
+ "1 . alpn",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_svcb_no_default_alpn(self):
+ valid_inputs = (
+ "1 . no-default-alpn",
+ "1 . no-default-alpn=\"\"",
+ "1 . key2",
+ "1 . key2=\"\"",
+ )
+ self.check_valid_inputs(valid_inputs)
+
+ invalid_inputs = (
+ "1 . no-default-alpn=foo",
+ "1 . no-default-alpn=",
+ "1 . key2=foo",
+ "1 . key2=",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_svcb_port(self):
+ valid_inputs = (
+ "1 . port=\"53\"",
+ "1 . port=53",
+ "1 . key3=\\000\\053",
+ )
+ self.check_valid_inputs(valid_inputs)
+
+ invalid_inputs = (
+ "1 . port=",
+ "1 . port=53x",
+ "1 . port=x53",
+ "1 . port=53,54",
+ "1 . port=53\\,54",
+ "1 . key3=\\000",
+ "1 . port=65536",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_svcb_echconfig(self):
+ valid_inputs = (
+ "1 . echconfig=\"Zm9vMA==\"",
+ "1 . echconfig=Zm9vMA==",
+ "1 . key5=foo0",
+ "1 . key5=\\102\\111\\111\\048",
+ )
+ self.check_valid_inputs(valid_inputs)
+
+ invalid_inputs = (
+ "1 . echconfig=",
+ "1 . echconfig=Zm9vMA",
+ "1 . echconfig=\\090m9vMA==",
+ "1 . key5=",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_svcb_ipv4hint(self):
+ valid_inputs = (
+ "1 . ipv4hint=\"0.0.0.0,1.1.1.1\"",
+ "1 . ipv4hint=0.0.0.0,1.1.1.1",
+ "1 . key4=\\000\\000\\000\\000\\001\\001\\001\\001",
+ )
+ self.check_valid_inputs(valid_inputs)
+
+ invalid_inputs = (
+ "1 . ipv4hint=",
+ "1 . ipv4hint=1234",
+ "1 . ipv4hint=1\\.2.3.4",
+ "1 . ipv4hint=1.2.3.4\\,2.3.4.5",
+ "1 . ipv4hint",
+ "1 . key4=",
+ "1 . key4=123",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_svcb_ipv6hint(self):
+ valid_inputs = (
+ "1 . ipv6hint=\"::4,1::\"",
+ "1 . ipv6hint=::4,1::",
+ "1 . key6=\\000\\000\\000\\000\\000\\000\\000\\000"
+ "\\000\\000\\000\\000\\000\\000\\000\\004"
+ "\\000\\001\\000\\000\\000\\000\\000\\000"
+ "\\000\\000\\000\\000\\000\\000\\000\\000",
+ )
+ self.check_valid_inputs(valid_inputs)
+
+ invalid_inputs = (
+ "1 . ipv6hint=",
+ "1 . ipv6hint=1234",
+ "1 . ipv6hint=1\\::2",
+ "1 . ipv6hint=::1\\,::2",
+ "1 . ipv6hint",
+ "1 . key6=",
+ "1 . key6=123",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_svcb_unknown(self):
+ valid_inputs_one_key = (
+ "1 . key23=\"key45\"",
+ "1 . key23=key45",
+ "1 . key23=key\\052\\053",
+ "1 . key23=\"key\\052\\053\"",
+ "1 . key23=\\107\\101\\121\\052\\053",
+ )
+ self.check_valid_inputs(valid_inputs_one_key)
+
+ valid_inputs_two_keys = (
+ "1 . key24 key48",
+ "1 . key24=\"\" key48",
+ )
+ self.check_valid_inputs(valid_inputs_two_keys)
+
+ invalid_inputs = (
+ "1 . key65536=foo",
+ "1 . key24= key48",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_svcb_wire(self):
+ valid_inputs = (
+ "1 . mandatory=\"alpn,port\" alpn=\"h2\" port=\"257\"",
+ "\\# 24 0001 00 0000000400010003 00010003026832 000300020101",
+ )
+ self.check_valid_inputs(valid_inputs)
+
+ everything = \
+ "100 foo.com. mandatory=\"alpn,port\" alpn=\"h2,h3\" " \
+ " no-default-alpn port=\"12345\" echconfig=\"abcd\" " \
+ " ipv4hint=1.2.3.4,4.3.2.1 ipv6hint=1::2,3::4" \
+ " key12345=\"foo\""
+ rr = dns.rdata.from_text('IN', 'SVCB', everything)
+ rr2 = dns.rdata.from_text('IN', 'SVCB', rr.to_generic().to_text())
+ self.assertEqual(rr, rr2)
+
+ invalid_inputs = (
+ # As above, but the keys are out of order.
+ "\\# 24 0001 00 0000000400010003 000300020101 00010003026832",
+ # As above, but the mandatory keys don't match
+ "\\# 24 0001 00 0000000400010002 000300020101 00010003026832",
+ "\\# 24 0001 00 0000000400010004 000300020101 00010003026832",
+ )
+ self.check_invalid_inputs(invalid_inputs)
+
+ def test_misc_escape(self):
+ rdata = dns.rdata.from_text('in', 'svcb', '1 . alpn=\\010\\010')
+ expected = '1 . alpn="\\010\\010"'
+ self.assertEqual(rdata.to_text(), expected)
+ with self.assertRaises(dns.exception.SyntaxError):
+ dns.rdata.from_text('in', 'svcb', '1 . alpn=\\0')
+ with self.assertRaises(dns.exception.SyntaxError):
+ dns.rdata.from_text('in', 'svcb', '1 . alpn=\\00')
+ with self.assertRaises(dns.exception.SyntaxError):
+ dns.rdata.from_text('in', 'svcb', '1 . alpn=\\00q')
+ # This doesn't usually get exercised, so we do it directly.
+ gp = dns.rdtypes.svcbbase.GenericParam.from_value('\\001\\002')
+ expected = '"\\001\\002"'
+ self.assertEqual(gp.to_text(), expected)
+
+ def test_alias_mode(self):
+ rd = dns.rdata.from_text('in', 'svcb', '0 .')
+ self.assertEqual(len(rd.params), 0)
+ self.assertEqual(rd.target, dns.name.root)
+ self.assertEqual(rd.to_text(), '0 .')
+ rd = dns.rdata.from_text('in', 'svcb', '0 elsewhere.')
+ self.assertEqual(rd.target, dns.name.from_text('elsewhere.'))
+ self.assertEqual(len(rd.params), 0)
+ # provoke 'parameters in AliasMode' from text.
+ with self.assertRaises(dns.exception.SyntaxError):
+ dns.rdata.from_text('in', 'svcb', '0 elsewhere. alpn=h2')
+ # provoke 'parameters in AliasMode' from wire too.
+ wire = bytes.fromhex('0000000000000400010003')
+ with self.assertRaises(dns.exception.FormError):
+ dns.rdata.from_wire('in', 'svcb', wire, 0, len(wire))