resolver: check that out queries don't have the AD bit
This commit is contained in:
parent
a58fb71eeb
commit
2de7139bc6
@ -2,9 +2,9 @@ use std::net::Ipv4Addr;
|
|||||||
|
|
||||||
use base64::prelude::*;
|
use base64::prelude::*;
|
||||||
use dns_test::{
|
use dns_test::{
|
||||||
name_server::{Graph, NameServer, Sign},
|
name_server::{Graph, NameServer, Running, Sign},
|
||||||
record::Record,
|
record::Record,
|
||||||
Network, Resolver, Result, FQDN,
|
Network, Resolver, Result, TrustAnchor, FQDN,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn bad_signature_in_leaf_nameserver(
|
pub fn bad_signature_in_leaf_nameserver(
|
||||||
@ -48,3 +48,28 @@ pub fn bad_signature_in_leaf_nameserver(
|
|||||||
|
|
||||||
Ok((resolver, graph))
|
Ok((resolver, graph))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn minimally_secure(
|
||||||
|
leaf_fqdn: FQDN,
|
||||||
|
leaf_ipv4_addr: Ipv4Addr,
|
||||||
|
) -> Result<(Resolver, Vec<NameServer<Running>>, TrustAnchor)> {
|
||||||
|
assert_eq!(Some(FQDN::NAMESERVERS), leaf_fqdn.parent());
|
||||||
|
|
||||||
|
let network = Network::new()?;
|
||||||
|
|
||||||
|
let mut leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;
|
||||||
|
leaf_ns.add(Record::a(leaf_fqdn.clone(), leaf_ipv4_addr));
|
||||||
|
|
||||||
|
let Graph {
|
||||||
|
nameservers,
|
||||||
|
root,
|
||||||
|
trust_anchor,
|
||||||
|
} = Graph::build(leaf_ns, Sign::Yes)?;
|
||||||
|
|
||||||
|
let trust_anchor = trust_anchor.unwrap();
|
||||||
|
let resolver = Resolver::new(&network, root)
|
||||||
|
.trust_anchor(&trust_anchor)
|
||||||
|
.start(&dns_test::SUBJECT)?;
|
||||||
|
|
||||||
|
Ok((resolver, nameservers, trust_anchor))
|
||||||
|
}
|
||||||
|
@ -1 +1,2 @@
|
|||||||
mod section_4_1;
|
mod section_4_1;
|
||||||
|
mod section_4_6;
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
|
use dns_test::{
|
||||||
|
client::{Client, DigSettings},
|
||||||
|
record::RecordType,
|
||||||
|
tshark::{Capture, Direction},
|
||||||
|
Result, FQDN,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::resolver::dnssec::fixtures;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn clears_ad_bit_in_outgoing_queries() -> Result<()> {
|
||||||
|
let leaf_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
||||||
|
let leaf_fqdn = FQDN("example.nameservers.com.")?;
|
||||||
|
|
||||||
|
let (resolver, nameservers, _trust_anchor) =
|
||||||
|
fixtures::minimally_secure(leaf_fqdn.clone(), leaf_ipv4_addr)?;
|
||||||
|
|
||||||
|
let mut tshark = resolver.eavesdrop()?;
|
||||||
|
|
||||||
|
let resolver_addr = resolver.ipv4_addr();
|
||||||
|
|
||||||
|
let client = Client::new(resolver.network())?;
|
||||||
|
let settings = *DigSettings::default().recurse().authentic_data();
|
||||||
|
let _output = client.dig(settings, resolver_addr, RecordType::A, &leaf_fqdn)?;
|
||||||
|
|
||||||
|
tshark.wait_for_capture()?;
|
||||||
|
let captures = tshark.terminate()?;
|
||||||
|
|
||||||
|
let client_addr = client.ipv4_addr();
|
||||||
|
let mut ns_checks_count = 0;
|
||||||
|
let mut client_checks_count = 0;
|
||||||
|
let ns_addrs = nameservers
|
||||||
|
.iter()
|
||||||
|
.map(|ns| ns.ipv4_addr())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
for Capture { message, direction } in captures {
|
||||||
|
match direction {
|
||||||
|
Direction::Incoming { source } => {
|
||||||
|
if source == client_addr {
|
||||||
|
// sanity check
|
||||||
|
assert!(message.is_ad_flag_set());
|
||||||
|
|
||||||
|
client_checks_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Direction::Outgoing { destination } => {
|
||||||
|
if destination == client_addr {
|
||||||
|
// skip response to client
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
assert!(ns_addrs.contains(&destination));
|
||||||
|
|
||||||
|
assert!(!message.is_ad_flag_set());
|
||||||
|
|
||||||
|
ns_checks_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity checks
|
||||||
|
assert_eq!(1, client_checks_count);
|
||||||
|
assert_ne!(0, dbg!(ns_checks_count));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,11 +1,13 @@
|
|||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use dns_test::client::{Client, DigSettings};
|
use dns_test::client::{Client, DigSettings};
|
||||||
use dns_test::name_server::{Graph, NameServer, Sign};
|
use dns_test::name_server::NameServer;
|
||||||
use dns_test::record::{Record, RecordType};
|
use dns_test::record::{Record, RecordType};
|
||||||
use dns_test::zone_file::Root;
|
use dns_test::zone_file::Root;
|
||||||
use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN};
|
use dns_test::{Network, Resolver, Result, TrustAnchor, FQDN};
|
||||||
|
|
||||||
|
use crate::resolver::dnssec::fixtures;
|
||||||
|
|
||||||
// no DS records are involved; this is a single-link chain of trust
|
// no DS records are involved; this is a single-link chain of trust
|
||||||
#[ignore]
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
@ -49,24 +51,12 @@ fn can_validate_with_delegation() -> Result<()> {
|
|||||||
let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
let expected_ipv4_addr = Ipv4Addr::new(1, 2, 3, 4);
|
||||||
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
let needle_fqdn = FQDN("example.nameservers.com.")?;
|
||||||
|
|
||||||
let network = Network::new()?;
|
let (resolver, _nameservers, trust_anchor) =
|
||||||
|
fixtures::minimally_secure(needle_fqdn.clone(), expected_ipv4_addr)?;
|
||||||
|
|
||||||
let mut leaf_ns = NameServer::new(&dns_test::PEER, FQDN::NAMESERVERS, &network)?;
|
|
||||||
leaf_ns.add(Record::a(needle_fqdn.clone(), expected_ipv4_addr));
|
|
||||||
|
|
||||||
let Graph {
|
|
||||||
nameservers: _nameservers,
|
|
||||||
root,
|
|
||||||
trust_anchor,
|
|
||||||
} = Graph::build(leaf_ns, Sign::Yes)?;
|
|
||||||
|
|
||||||
let trust_anchor = &trust_anchor.unwrap();
|
|
||||||
let resolver = Resolver::new(&network, root)
|
|
||||||
.trust_anchor(trust_anchor)
|
|
||||||
.start(&dns_test::SUBJECT)?;
|
|
||||||
let resolver_addr = resolver.ipv4_addr();
|
let resolver_addr = resolver.ipv4_addr();
|
||||||
|
|
||||||
let client = Client::new(&network)?;
|
let client = Client::new(resolver.network())?;
|
||||||
let settings = *DigSettings::default().recurse().authentic_data();
|
let settings = *DigSettings::default().recurse().authentic_data();
|
||||||
let output = client.dig(settings, resolver_addr, RecordType::A, &needle_fqdn)?;
|
let output = client.dig(settings, resolver_addr, RecordType::A, &needle_fqdn)?;
|
||||||
|
|
||||||
@ -80,7 +70,7 @@ fn can_validate_with_delegation() -> Result<()> {
|
|||||||
assert_eq!(needle_fqdn, a.fqdn);
|
assert_eq!(needle_fqdn, a.fqdn);
|
||||||
assert_eq!(expected_ipv4_addr, a.ipv4_addr);
|
assert_eq!(expected_ipv4_addr, a.ipv4_addr);
|
||||||
|
|
||||||
let output = client.delv(resolver_addr, RecordType::A, &needle_fqdn, trust_anchor)?;
|
let output = client.delv(resolver_addr, RecordType::A, &needle_fqdn, &trust_anchor)?;
|
||||||
assert!(output.starts_with("; fully validated"));
|
assert!(output.starts_with("; fully validated"));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -183,6 +183,20 @@ impl Message {
|
|||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_ad_flag_set(&self) -> bool {
|
||||||
|
let Some(authenticated) = self.inner["dns.flags_tree"]
|
||||||
|
.as_object()
|
||||||
|
.unwrap()
|
||||||
|
.get("dns.flags.authenticated")
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let authenticated = authenticated.as_str().unwrap();
|
||||||
|
assert_eq!("1", authenticated);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn opt_record(&self) -> Option<&serde_json::Value> {
|
fn opt_record(&self) -> Option<&serde_json::Value> {
|
||||||
for (key, value) in self.inner.get("Additional records")?.as_object()? {
|
for (key, value) in self.inner.get("Additional records")?.as_object()? {
|
||||||
if key.ends_with(": type OPT") {
|
if key.ends_with(": type OPT") {
|
||||||
|
Loading…
Reference in New Issue
Block a user