diff options
| author | Bob Halley <halley@dnspython.org> | 2020-08-07 19:20:30 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-07 19:20:30 -0700 |
| commit | 330ddd8fecbe583d71fb9c1033eb12c60f5f6bec (patch) | |
| tree | 2d8e802a01b2851e8fcf2d27cecf361e896c6248 /tests | |
| parent | 157e4e907333fae7fb4c5888949258aa7927f6e9 (diff) | |
| parent | 5891ac286ee4ba934738c94c7189ee2d868fcd3b (diff) | |
| download | dnspython-330ddd8fecbe583d71fb9c1033eb12c60f5f6bec.tar.gz | |
Merge pull request #568 from rthalley/svcb
SVCB and HTTPS support
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/example | 6 | ||||
| -rw-r--r-- | tests/example1.good | 3 | ||||
| -rw-r--r-- | tests/example2.good | 3 | ||||
| -rw-r--r-- | tests/example3.good | 3 | ||||
| -rw-r--r-- | tests/test_svcb.py | 274 |
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)) |
