From edd6eebe1a6b9d4c91e4c62e082ca12567e69d78 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 8 Feb 2024 18:28:05 +0100 Subject: [PATCH] mv tests into conformance-tests package --- Cargo.lock | 7 + packages/conformance-tests/Cargo.toml | 11 ++ packages/conformance-tests/src/lib.rs | 3 + packages/conformance-tests/src/resolver.rs | 4 + .../conformance-tests/src/resolver/dns.rs | 3 + .../src/resolver/dns/scenarios.rs | 62 +++++++ .../conformance-tests/src/resolver/dnssec.rs | 3 + .../src/resolver/dnssec/scenarios.rs | 118 ++++++++++++ packages/dns-test/src/recursive_resolver.rs | 174 ------------------ 9 files changed, 211 insertions(+), 174 deletions(-) create mode 100644 packages/conformance-tests/Cargo.toml create mode 100644 packages/conformance-tests/src/lib.rs create mode 100644 packages/conformance-tests/src/resolver.rs create mode 100644 packages/conformance-tests/src/resolver/dns.rs create mode 100644 packages/conformance-tests/src/resolver/dns/scenarios.rs create mode 100644 packages/conformance-tests/src/resolver/dnssec.rs create mode 100644 packages/conformance-tests/src/resolver/dnssec/scenarios.rs diff --git a/Cargo.lock b/Cargo.lock index c3039e0c..46f2b24b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,13 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "conformance-tests" +version = "0.1.0" +dependencies = [ + "dns-test", +] + [[package]] name = "dns-test" version = "0.1.0" diff --git a/packages/conformance-tests/Cargo.toml b/packages/conformance-tests/Cargo.toml new file mode 100644 index 00000000..548b378d --- /dev/null +++ b/packages/conformance-tests/Cargo.toml @@ -0,0 +1,11 @@ +[package] +edition = "2021" +name = "conformance-tests" +publish = false +version = "0.1.0" + +[dependencies] +dns-test.path = "../dns-test" + +[lib] +doctest = false diff --git a/packages/conformance-tests/src/lib.rs b/packages/conformance-tests/src/lib.rs new file mode 100644 index 00000000..dd939657 --- /dev/null +++ b/packages/conformance-tests/src/lib.rs @@ -0,0 +1,3 @@ +#![cfg(test)] + +mod resolver; diff --git a/packages/conformance-tests/src/resolver.rs b/packages/conformance-tests/src/resolver.rs new file mode 100644 index 00000000..85e4d364 --- /dev/null +++ b/packages/conformance-tests/src/resolver.rs @@ -0,0 +1,4 @@ +//! Recursive resolver role + +mod dns; +mod dnssec; diff --git a/packages/conformance-tests/src/resolver/dns.rs b/packages/conformance-tests/src/resolver/dns.rs new file mode 100644 index 00000000..4902447e --- /dev/null +++ b/packages/conformance-tests/src/resolver/dns.rs @@ -0,0 +1,3 @@ +//! plain DNS functionality + +mod scenarios; diff --git a/packages/conformance-tests/src/resolver/dns/scenarios.rs b/packages/conformance-tests/src/resolver/dns/scenarios.rs new file mode 100644 index 00000000..d76e9aee --- /dev/null +++ b/packages/conformance-tests/src/resolver/dns/scenarios.rs @@ -0,0 +1,62 @@ +use std::net::Ipv4Addr; + +use dns_test::client::{Client, Dnssec, Recurse}; +use dns_test::name_server::NameServer; +use dns_test::record::RecordType; +use dns_test::zone_file::Root; +use dns_test::{RecursiveResolver, Result, FQDN}; + +#[test] +fn can_resolve() -> Result<()> { + let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4); + let needle_fqdn = FQDN("example.nameservers.com.")?; + + let mut root_ns = NameServer::new(FQDN::ROOT)?; + let mut com_ns = NameServer::new(FQDN::COM)?; + + let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?)?; + nameservers_ns + .a(root_ns.fqdn().clone(), root_ns.ipv4_addr()) + .a(com_ns.fqdn().clone(), com_ns.ipv4_addr()) + .a(needle_fqdn.clone(), expected_ipv4_addr); + let nameservers_ns = nameservers_ns.start()?; + + eprintln!("nameservers.com.zone:\n{}", nameservers_ns.zone_file()); + + com_ns.referral( + nameservers_ns.zone().clone(), + nameservers_ns.fqdn().clone(), + nameservers_ns.ipv4_addr(), + ); + let com_ns = com_ns.start()?; + + eprintln!("com.zone:\n{}", com_ns.zone_file()); + + root_ns.referral(FQDN::COM, com_ns.fqdn().clone(), com_ns.ipv4_addr()); + let root_ns = root_ns.start()?; + + eprintln!("root.zone:\n{}", root_ns.zone_file()); + + let roots = &[Root::new(root_ns.fqdn().clone(), root_ns.ipv4_addr())]; + let resolver = RecursiveResolver::start(roots, &[])?; + let resolver_ip_addr = resolver.ipv4_addr(); + + let client = Client::new()?; + let output = client.dig( + Recurse::Yes, + Dnssec::No, + resolver_ip_addr, + RecordType::A, + &needle_fqdn, + )?; + + assert!(output.status.is_noerror()); + + let [answer] = output.answer.try_into().unwrap(); + let a = answer.try_into_a().unwrap(); + + assert_eq!(needle_fqdn, a.fqdn); + assert_eq!(expected_ipv4_addr, a.ipv4_addr); + + Ok(()) +} diff --git a/packages/conformance-tests/src/resolver/dnssec.rs b/packages/conformance-tests/src/resolver/dnssec.rs new file mode 100644 index 00000000..63400356 --- /dev/null +++ b/packages/conformance-tests/src/resolver/dnssec.rs @@ -0,0 +1,3 @@ +//! DNSSEC functionality + +mod scenarios; diff --git a/packages/conformance-tests/src/resolver/dnssec/scenarios.rs b/packages/conformance-tests/src/resolver/dnssec/scenarios.rs new file mode 100644 index 00000000..62edb1f7 --- /dev/null +++ b/packages/conformance-tests/src/resolver/dnssec/scenarios.rs @@ -0,0 +1,118 @@ +use std::net::Ipv4Addr; + +use dns_test::client::{Client, Dnssec, Recurse}; +use dns_test::name_server::NameServer; +use dns_test::record::RecordType; +use dns_test::zone_file::Root; +use dns_test::{RecursiveResolver, Result, FQDN}; + +// no DS records are involved; this is a single-link chain of trust +#[test] +fn can_validate_without_delegation() -> Result<()> { + let mut ns = NameServer::new(FQDN::ROOT)?; + ns.a(ns.fqdn().clone(), ns.ipv4_addr()); + let ns = ns.sign()?; + + let root_ksk = ns.key_signing_key().clone(); + let root_zsk = ns.zone_signing_key().clone(); + + eprintln!("root.zone.signed:\n{}", ns.signed_zone_file()); + + let ns = ns.start()?; + + eprintln!("root.zone:\n{}", ns.zone_file()); + + let roots = &[Root::new(ns.fqdn().clone(), ns.ipv4_addr())]; + + let trust_anchor = [root_ksk.clone(), root_zsk.clone()]; + let resolver = RecursiveResolver::start(roots, &trust_anchor)?; + let resolver_addr = resolver.ipv4_addr(); + + let client = Client::new()?; + let output = client.dig( + Recurse::Yes, + Dnssec::Yes, + resolver_addr, + RecordType::SOA, + &FQDN::ROOT, + )?; + + assert!(output.status.is_noerror()); + assert!(output.flags.authenticated_data); + + Ok(()) +} + +#[test] +fn can_validate_with_delegation() -> Result<()> { + let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4); + let needle = FQDN("example.nameservers.com.")?; + + let mut root_ns = NameServer::new(FQDN::ROOT)?; + let mut com_ns = NameServer::new(FQDN::COM)?; + + let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?)?; + nameservers_ns + .a(root_ns.fqdn().clone(), root_ns.ipv4_addr()) + .a(com_ns.fqdn().clone(), com_ns.ipv4_addr()) + .a(needle.clone(), expected_ipv4_addr); + let nameservers_ns = nameservers_ns.sign()?; + let nameservers_ds = nameservers_ns.ds().clone(); + let nameservers_ns = nameservers_ns.start()?; + + eprintln!("nameservers.com.zone:\n{}", nameservers_ns.zone_file()); + + com_ns + .referral( + nameservers_ns.zone().clone(), + nameservers_ns.fqdn().clone(), + nameservers_ns.ipv4_addr(), + ) + .ds(nameservers_ds); + let com_ns = com_ns.sign()?; + let com_ds = com_ns.ds().clone(); + let com_ns = com_ns.start()?; + + eprintln!("com.zone:\n{}", com_ns.zone_file()); + + root_ns + .referral(FQDN::COM, com_ns.fqdn().clone(), com_ns.ipv4_addr()) + .ds(com_ds); + let root_ns = root_ns.sign()?; + let root_ksk = root_ns.key_signing_key().clone(); + let root_zsk = root_ns.zone_signing_key().clone(); + + eprintln!("root.zone.signed:\n{}", root_ns.signed_zone_file()); + + let root_ns = root_ns.start()?; + + eprintln!("root.zone:\n{}", root_ns.zone_file()); + + let roots = &[Root::new(root_ns.fqdn().clone(), root_ns.ipv4_addr())]; + + let resolver = RecursiveResolver::start(roots, &[root_ksk.clone(), root_zsk.clone()])?; + let resolver_ip_addr = resolver.ipv4_addr(); + + let client = Client::new()?; + let output = client.dig( + Recurse::Yes, + Dnssec::Yes, + resolver_ip_addr, + RecordType::A, + &needle, + )?; + + drop(resolver); + + assert!(output.status.is_noerror()); + + assert!(output.flags.authenticated_data); + + let [a, _rrsig] = output.answer.try_into().unwrap(); + let a = a.try_into_a().unwrap(); + + assert_eq!(needle, a.fqdn); + assert_eq!(expected_ipv4_addr, a.ipv4_addr); + + Ok(()) +} diff --git a/packages/dns-test/src/recursive_resolver.rs b/packages/dns-test/src/recursive_resolver.rs index 6713dcb9..8c318cd4 100644 --- a/packages/dns-test/src/recursive_resolver.rs +++ b/packages/dns-test/src/recursive_resolver.rs @@ -72,182 +72,8 @@ fn unbound_conf(use_dnssec: bool) -> String { #[cfg(test)] mod tests { - - use crate::{ - client::{Client, Dnssec, Recurse}, - name_server::NameServer, - record::RecordType, - FQDN, - }; - use super::*; - #[test] - fn can_resolve() -> Result<()> { - let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4); - let needle = FQDN("example.nameservers.com.")?; - - let mut root_ns = NameServer::new(FQDN::ROOT)?; - let mut com_ns = NameServer::new(FQDN::COM)?; - - let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?)?; - nameservers_ns - .a(root_ns.fqdn().clone(), root_ns.ipv4_addr()) - .a(com_ns.fqdn().clone(), com_ns.ipv4_addr()) - .a(needle.clone(), expected_ipv4_addr); - let nameservers_ns = nameservers_ns.start()?; - - eprintln!("nameservers.com.zone:\n{}", nameservers_ns.zone_file()); - - com_ns.referral( - nameservers_ns.zone().clone(), - nameservers_ns.fqdn().clone(), - nameservers_ns.ipv4_addr(), - ); - let com_ns = com_ns.start()?; - - eprintln!("com.zone:\n{}", com_ns.zone_file()); - - root_ns.referral(FQDN::COM, com_ns.fqdn().clone(), com_ns.ipv4_addr()); - let root_ns = root_ns.start()?; - - eprintln!("root.zone:\n{}", root_ns.zone_file()); - - let roots = &[Root::new(root_ns.fqdn().clone(), root_ns.ipv4_addr())]; - let resolver = RecursiveResolver::start(roots, &[])?; - let resolver_ip_addr = resolver.ipv4_addr(); - - let client = Client::new()?; - let output = client.dig( - Recurse::Yes, - Dnssec::No, - resolver_ip_addr, - RecordType::A, - &needle, - )?; - - assert!(output.status.is_noerror()); - - let [answer] = output.answer.try_into().unwrap(); - let a = answer.try_into_a().unwrap(); - - assert_eq!(needle, a.fqdn); - assert_eq!(expected_ipv4_addr, a.ipv4_addr); - - Ok(()) - } - - // no DS records are involved; this is a single-link chain of trust - #[test] - fn can_validate_without_delegation() -> Result<()> { - let mut ns = NameServer::new(FQDN::ROOT)?; - ns.a(ns.fqdn().clone(), ns.ipv4_addr()); - let ns = ns.sign()?; - - let root_ksk = ns.key_signing_key().clone(); - let root_zsk = ns.zone_signing_key().clone(); - - eprintln!("root.zone.signed:\n{}", ns.signed_zone_file()); - - let ns = ns.start()?; - - eprintln!("root.zone:\n{}", ns.zone_file()); - - let roots = &[Root::new(ns.fqdn().clone(), ns.ipv4_addr())]; - - let trust_anchor = [root_ksk.clone(), root_zsk.clone()]; - let resolver = RecursiveResolver::start(roots, &trust_anchor)?; - let resolver_addr = resolver.ipv4_addr(); - - let client = Client::new()?; - let output = client.dig( - Recurse::Yes, - Dnssec::Yes, - resolver_addr, - RecordType::SOA, - &FQDN::ROOT, - )?; - - assert!(output.status.is_noerror()); - assert!(output.flags.authenticated_data); - - Ok(()) - } - - #[test] - fn can_validate_with_delegation() -> Result<()> { - let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4); - let needle = FQDN("example.nameservers.com.")?; - - let mut root_ns = NameServer::new(FQDN::ROOT)?; - let mut com_ns = NameServer::new(FQDN::COM)?; - - let mut nameservers_ns = NameServer::new(FQDN("nameservers.com.")?)?; - nameservers_ns - .a(root_ns.fqdn().clone(), root_ns.ipv4_addr()) - .a(com_ns.fqdn().clone(), com_ns.ipv4_addr()) - .a(needle.clone(), expected_ipv4_addr); - let nameservers_ns = nameservers_ns.sign()?; - let nameservers_ds = nameservers_ns.ds().clone(); - let nameservers_ns = nameservers_ns.start()?; - - eprintln!("nameservers.com.zone:\n{}", nameservers_ns.zone_file()); - - com_ns - .referral( - nameservers_ns.zone().clone(), - nameservers_ns.fqdn().clone(), - nameservers_ns.ipv4_addr(), - ) - .ds(nameservers_ds); - let com_ns = com_ns.sign()?; - let com_ds = com_ns.ds().clone(); - let com_ns = com_ns.start()?; - - eprintln!("com.zone:\n{}", com_ns.zone_file()); - - root_ns - .referral(FQDN::COM, com_ns.fqdn().clone(), com_ns.ipv4_addr()) - .ds(com_ds); - let root_ns = root_ns.sign()?; - let root_ksk = root_ns.key_signing_key().clone(); - let root_zsk = root_ns.zone_signing_key().clone(); - - eprintln!("root.zone.signed:\n{}", root_ns.signed_zone_file()); - - let root_ns = root_ns.start()?; - - eprintln!("root.zone:\n{}", root_ns.zone_file()); - - let roots = &[Root::new(root_ns.fqdn().clone(), root_ns.ipv4_addr())]; - - let resolver = RecursiveResolver::start(roots, &[root_ksk.clone(), root_zsk.clone()])?; - let resolver_ip_addr = resolver.ipv4_addr(); - - let client = Client::new()?; - let output = client.dig( - Recurse::Yes, - Dnssec::Yes, - resolver_ip_addr, - RecordType::A, - &needle, - )?; - - drop(resolver); - - assert!(output.status.is_noerror()); - - assert!(output.flags.authenticated_data); - - let [a, _rrsig] = output.answer.try_into().unwrap(); - let a = a.try_into_a().unwrap(); - - assert_eq!(needle, a.fqdn); - assert_eq!(expected_ipv4_addr, a.ipv4_addr); - - Ok(()) - } - #[test] fn terminate_works() -> Result<()> { let resolver = RecursiveResolver::start(&[], &[])?;