limit returned records to supported algorithms

This commit is contained in:
Benjamin Fry 2017-01-08 16:42:00 -08:00
parent 4c0318ec95
commit 0660fece60
9 changed files with 127 additions and 86 deletions

View File

@ -6,6 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added
- support for ECDSAP256SHA256, ECDSAP384SHA384 and ED25519 (client and server)
- additional config options for keys to named, see `tests/named_test_configs/example.toml`
- When EDNS option is present, return only the digest understood matching RRSETs
## 0.9.3
### Changed

View File

@ -342,6 +342,8 @@ fn verify_rrset<H>(client: SecureClientHandle<H>,
if let RecordType::DNSKEY = rrset.record_type {
if rrsigs.is_empty() {
debug!("unsigned key: {}, {:?}", rrset.name, rrset.record_type);
// FIXME: validate that this DNSKEY is stronger than the one lower in the chain,
// also, set the min algorithm to this algorithm to prevent downgrade attacks.
return verify_dnskey_rrset(client.clone_with_context(), rrset)
}
}

View File

@ -95,6 +95,12 @@ impl SupportedAlgorithms {
}
}
impl Default for SupportedAlgorithms {
fn default() -> SupportedAlgorithms {
SupportedAlgorithms::from_vec(&[Algorithm::RSASHA256])
}
}
// impl<'a> SupportedAlgorithms {
// pub fn iter(&self) -> SupportedAlgorithmsIter<'a> {
// SupportedAlgorithmsIter::new(self)

View File

@ -22,6 +22,11 @@ use ::serialize::binary::*;
use ::error::*;
use ::rr::dnssec::SupportedAlgorithms;
/// The OPT record type is used for ExtendedDNS records.
///
/// These allow for additional information to be associated with the DNS request that otherwise
/// would require changes to the DNS protocol.
///
/// [RFC 6891, EDNS(0) Extensions, April 2013](https://tools.ietf.org/html/rfc6891#section-6)
///
/// ```text

View File

@ -9,6 +9,7 @@ use std::slice::Iter;
use std::vec;
use ::rr::{DNSClass, Name, Record, RecordType, RData};
use ::rr::dnssec::{Algorithm, SupportedAlgorithms};
/// Set of resource records associated to a name and type
#[derive(Clone, Debug, PartialEq)]
@ -105,9 +106,7 @@ impl RecordSet {
}
}
/// # Return value
///
/// `DNSClass` of the RecordSet
/// Returns the `DNSClass` of the RecordSet
pub fn get_dns_class(&self) -> DNSClass {
self.dns_class
}
@ -122,6 +121,8 @@ impl RecordSet {
}
}
/// Returns the time-to-live for the record.
///
/// # Return value
///
/// TTL, time-to-live, of the Resource Record Set, this is the maximum length of time that an
@ -130,12 +131,31 @@ impl RecordSet {
self.ttl
}
/// # Return value
/// Returns a Vec of all records in the set.
///
/// Slice of all records in the set
pub fn get_records(&self, and_rrsigs: bool) -> Vec<&Record> {
/// # Arguments
///
/// * `and_rrsigs` - if true, RRSIGs will be returned if they exist
/// * `supported_algorithms` - the RRSIGs will be filtered by the set of supported_algorithms,
/// and then only the maximal RRSIG algorithm will be returned.
pub fn get_records(&self, and_rrsigs: bool, supported_algorithms: SupportedAlgorithms) -> Vec<&Record> {
if and_rrsigs {
self.records.iter().chain(self.rrsigs.iter()).collect()
let rrsigs = self.rrsigs.iter()
.filter(|record| {
if let &RData::SIG(ref rrsig) = record.get_rdata() {
supported_algorithms.has(rrsig.get_algorithm())
} else {
false
}
})
.max_by_key(|record| {
if let &RData::SIG(ref rrsig) = record.get_rdata() {
rrsig.get_algorithm()
} else {
Algorithm::RSASHA1
}
});
self.records.iter().chain(rrsigs).collect()
} else {
self.records.iter().collect()
}
@ -146,16 +166,12 @@ impl RecordSet {
self.records.iter()
}
/// # Return value
///
/// True if there are no records in this set
/// Returns true if there are no records in this set
pub fn is_empty(&self) -> bool {
self.records.is_empty()
}
/// # Return value
///
/// The serial number at which the record was updated.
/// Returns the serial number at which the record was updated.
pub fn get_serial(&self) -> u32 {
self.serial
}
@ -383,20 +399,20 @@ mod test {
let insert = Record::new().name(name.clone()).ttl(86400).rr_type(record_type).dns_class(DNSClass::IN).rdata(RData::A(Ipv4Addr::new(93,184,216,24))).clone();
assert!(rr_set.insert(insert.clone(), 0));
assert_eq!(rr_set.get_records(false).len(), 1);
assert!(rr_set.get_records(false).contains(&&insert));
assert_eq!(rr_set.get_records(false, Default::default()).len(), 1);
assert!(rr_set.get_records(false, Default::default()).contains(&&insert));
// dups ignored
assert!(!rr_set.insert(insert.clone(), 0));
assert_eq!(rr_set.get_records(false).len(), 1);
assert!(rr_set.get_records(false).contains(&&insert));
assert_eq!(rr_set.get_records(false, Default::default()).len(), 1);
assert!(rr_set.get_records(false, Default::default()).contains(&&insert));
// add one
let insert1 = Record::new().name(name.clone()).ttl(86400).rr_type(record_type).dns_class(DNSClass::IN).rdata(RData::A(Ipv4Addr::new(93,184,216,25))).clone();
assert!(rr_set.insert(insert1.clone(), 0));
assert_eq!(rr_set.get_records(false).len(), 2);
assert!(rr_set.get_records(false).contains(&&insert));
assert!(rr_set.get_records(false).contains(&&insert1));
assert_eq!(rr_set.get_records(false, Default::default()).len(), 2);
assert!(rr_set.get_records(false, Default::default()).contains(&&insert));
assert!(rr_set.get_records(false, Default::default()).contains(&&insert1));
}
#[test]
@ -410,19 +426,19 @@ mod test {
let new_serial = Record::new().name(name.clone()).ttl(3600).rr_type(RecordType::SOA).dns_class(DNSClass::IN).rdata(RData::SOA(SOA::new(Name::parse("sns.dns.icann.net.", None).unwrap(), Name::parse("noc.dns.icann.net.", None).unwrap(), 2015082404, 7200, 3600, 1209600, 3600 ))).clone();
assert!(rr_set.insert(insert.clone(), 0));
assert!(rr_set.get_records(false).contains(&&insert));
assert!(rr_set.get_records(false, Default::default()).contains(&&insert));
// same serial number
assert!(!rr_set.insert(same_serial.clone(), 0));
assert!(rr_set.get_records(false).contains(&&insert));
assert!(!rr_set.get_records(false).contains(&&same_serial));
assert!(rr_set.get_records(false, Default::default()).contains(&&insert));
assert!(!rr_set.get_records(false, Default::default()).contains(&&same_serial));
assert!(rr_set.insert(new_serial.clone(), 0));
assert!(!rr_set.insert(same_serial.clone(), 0));
assert!(!rr_set.insert(insert.clone(), 0));
assert!(rr_set.get_records(false).contains(&&new_serial));
assert!(!rr_set.get_records(false).contains(&&insert));
assert!(!rr_set.get_records(false).contains(&&same_serial));
assert!(rr_set.get_records(false, Default::default()).contains(&&new_serial));
assert!(!rr_set.get_records(false, Default::default()).contains(&&insert));
assert!(!rr_set.get_records(false, Default::default()).contains(&&same_serial));
}
#[test]
@ -438,12 +454,12 @@ mod test {
let new_record = Record::new().name(name.clone()).ttl(3600).rr_type(RecordType::CNAME).dns_class(DNSClass::IN).rdata(RData::CNAME(new_cname.clone()) ).clone();
assert!(rr_set.insert(insert.clone(), 0));
assert!(rr_set.get_records(false).contains(&&insert));
assert!(rr_set.get_records(false, Default::default()).contains(&&insert));
// update the record
assert!(rr_set.insert(new_record.clone(), 0));
assert!(!rr_set.get_records(false).contains(&&insert));
assert!(rr_set.get_records(false).contains(&&new_record));
assert!(!rr_set.get_records(false, Default::default()).contains(&&insert));
assert!(rr_set.get_records(false, Default::default()).contains(&&new_record));
}
#[test]
@ -474,7 +490,7 @@ mod test {
assert!(rr_set.insert(insert.clone(), 0));
assert!(!rr_set.remove(&insert, 0));
assert!(rr_set.get_records(false).contains(&&insert));
assert!(rr_set.get_records(false, Default::default()).contains(&&insert));
}
#[test]

View File

@ -21,7 +21,7 @@ use trust_dns::error::*;
use trust_dns::op::{Message, UpdateMessage, ResponseCode, Query};
use trust_dns::rr::{DNSClass, Name, RData, Record, RecordType, RrKey, RecordSet};
use trust_dns::rr::rdata::{NSEC, SIG};
use trust_dns::rr::dnssec::{KeyPair, Signer};
use trust_dns::rr::dnssec::{KeyPair, Signer, SupportedAlgorithms};
use ::authority::{Journal, UpdateResult, ZoneType};
use ::error::{PersistenceErrorKind, PersistenceResult};
@ -182,12 +182,12 @@ impl Authority {
/// should be used, see `get_soa_secure()`, which will optionally return RRSIGs.
pub fn get_soa(&self) -> Option<&Record> {
// SOA should be origin|SOA
self.lookup(&self.origin, RecordType::SOA, false).first().map(|v| *v)
self.lookup(&self.origin, RecordType::SOA, false, SupportedAlgorithms::new()).first().map(|v| *v)
}
/// Returns the SOA record for the zone
pub fn get_soa_secure(&self, is_secure: bool) -> Vec<&Record> {
self.lookup(&self.origin, RecordType::SOA, is_secure)
pub fn get_soa_secure(&self, is_secure: bool, supported_algorithms: SupportedAlgorithms) -> Vec<&Record> {
self.lookup(&self.origin, RecordType::SOA, is_secure, supported_algorithms)
}
/// Returns the minimum ttl (as used in the SOA record)
@ -230,8 +230,8 @@ impl Authority {
return serial;
}
pub fn get_ns(&self, is_secure: bool) -> Vec<&Record> {
self.lookup(&self.origin, RecordType::NS, is_secure)
pub fn get_ns(&self, is_secure: bool, supported_algorithms: SupportedAlgorithms) -> Vec<&Record> {
self.lookup(&self.origin, RecordType::NS, is_secure, supported_algorithms)
}
/// [RFC 2136](https://tools.ietf.org/html/rfc2136), DNS Update, April 1997
@ -334,7 +334,7 @@ impl Authority {
match require.get_rr_type() {
// ANY ANY empty Name is in use
RecordType::ANY => {
if self.lookup(require.get_name(), RecordType::ANY, false).is_empty() {
if self.lookup(require.get_name(), RecordType::ANY, false, SupportedAlgorithms::new()).is_empty() {
return Err(ResponseCode::NXDomain);
} else {
continue;
@ -342,7 +342,7 @@ impl Authority {
},
// ANY rrset empty RRset exists (value independent)
rrset @ _ => {
if self.lookup(require.get_name(), rrset, false).is_empty() {
if self.lookup(require.get_name(), rrset, false, SupportedAlgorithms::new()).is_empty() {
return Err(ResponseCode::NXRRSet);
} else {
continue;
@ -358,7 +358,7 @@ impl Authority {
match require.get_rr_type() {
// NONE ANY empty Name is not in use
RecordType::ANY => {
if !self.lookup(require.get_name(), RecordType::ANY, false).is_empty() {
if !self.lookup(require.get_name(), RecordType::ANY, false, SupportedAlgorithms::new()).is_empty() {
return Err(ResponseCode::YXDomain);
} else {
continue;
@ -366,7 +366,7 @@ impl Authority {
},
// NONE rrset empty RRset does not exist
rrset @ _ => {
if !self.lookup(require.get_name(), rrset, false).is_empty() {
if !self.lookup(require.get_name(), rrset, false, SupportedAlgorithms::new()).is_empty() {
return Err(ResponseCode::YXRRSet);
} else {
continue;
@ -379,7 +379,7 @@ impl Authority {
,
class @ _ if class == self.class =>
// zone rrset rr RRset exists (value dependent)
if self.lookup(require.get_name(), require.get_rr_type(), false)
if self.lookup(require.get_name(), require.get_rr_type(), false, SupportedAlgorithms::new())
.iter()
.filter(|rr| *rr == &require)
.next()
@ -442,7 +442,7 @@ impl Authority {
.filter_map(|sig0| if let &RData::SIG(ref sig) = sig0.get_rdata() { Some(sig) } else { None })
.any(|sig| {
let name = sig.get_signer_name();
let keys = self.lookup(name, RecordType::KEY, false);
let keys = self.lookup(name, RecordType::KEY, false, SupportedAlgorithms::new());
debug!("found keys {:?}", keys);
keys.iter()
.filter_map(|rr_set| if let &RData::KEY(ref key) = rr_set.get_rdata() { Some(key) } else { None })
@ -827,7 +827,7 @@ impl Authority {
///
/// Returns a vectory containing the results of the query, it will be empty if not found. If
/// `is_secure` is true, in the case of no records found then NSEC records will be returned.
pub fn search(&self, query: &Query, is_secure: bool) -> Vec<&Record> {
pub fn search(&self, query: &Query, is_secure: bool, supported_algorithms: SupportedAlgorithms) -> Vec<&Record> {
let record_type: RecordType = query.get_query_type();
// if this is an AXFR zone transfer, verify that this is either the slave or master
@ -842,7 +842,7 @@ impl Authority {
// it would be better to stream this back, rather than packaging everything up in an array
// though for UDP it would still need to be bundled
let mut query_result: Vec<_> = self.lookup(query.get_name(), record_type, is_secure);
let mut query_result: Vec<_> = self.lookup(query.get_name(), record_type, is_secure, supported_algorithms);
if RecordType::AXFR == record_type {
if let Some(soa) = self.get_soa() {
@ -874,7 +874,7 @@ impl Authority {
/// # Return value
///
/// None if there are no matching records, otherwise a `Vec` containing the found records.
pub fn lookup(&self, name: &Name, rtype: RecordType, is_secure: bool) -> Vec<&Record> {
pub fn lookup(&self, name: &Name, rtype: RecordType, is_secure: bool, supported_algorithms: SupportedAlgorithms) -> Vec<&Record> {
// on an SOA request always return the SOA, regardless of the name
let name: &Name = if rtype == RecordType::SOA { &self.origin } else { name };
let rr_key = RrKey::new(name, rtype);
@ -885,12 +885,12 @@ impl Authority {
self.records.values().filter(|rr_set| rtype == RecordType::ANY || rr_set.get_record_type() != RecordType::SOA)
.filter(|rr_set| rtype == RecordType::AXFR || rr_set.get_name() == name)
.fold(Vec::<&Record>::new(), |mut vec, rr_set| {
vec.append(&mut rr_set.get_records(is_secure));
vec.append(&mut rr_set.get_records(is_secure, supported_algorithms));
vec
})
},
_ => {
self.records.get(&rr_key).map_or(vec![], |rr_set| rr_set.get_records(is_secure).into_iter().collect())
self.records.get(&rr_key).map_or(vec![], |rr_set| rr_set.get_records(is_secure, supported_algorithms).into_iter().collect())
}
};
@ -904,11 +904,11 @@ impl Authority {
/// * `name` - given this name (i.e. the lookup name), return the NSEC record that is less than
/// this
/// * `is_secure` - if true then it will return RRSIG records as well
pub fn get_nsec_records(&self, name: &Name, is_secure: bool) -> Vec<&Record> {
pub fn get_nsec_records(&self, name: &Name, is_secure: bool, supported_algorithms: SupportedAlgorithms) -> Vec<&Record> {
self.records.values().filter(|rr_set| rr_set.get_record_type() == RecordType::NSEC)
.skip_while(|rr_set| name < rr_set.get_name())
.next()
.map_or(vec![], |rr_set| rr_set.get_records(is_secure).into_iter().collect())
.map_or(vec![], |rr_set| rr_set.get_records(is_secure, supported_algorithms).into_iter().collect())
}
/// (Re)generates the nsec records, increments the serial number nad signs the zone
@ -1017,7 +1017,7 @@ impl Authority {
signer.get_signer_name(),
// TODO: this is a nasty clone... the issue is that the vec
// from get_records is of Vec<&R>, but we really want &[R]
&rr_set.get_records(false).into_iter().cloned().collect::<Vec<Record>>());
&rr_set.get_records(false, SupportedAlgorithms::new()).into_iter().cloned().collect::<Vec<Record>>());
// TODO, maybe chain these with some ETL operations instead?
if hash.is_err() {

View File

@ -22,7 +22,7 @@ use std::sync::RwLock;
use trust_dns::op::{Edns, Message, MessageType, OpCode, Query, UpdateMessage, RequestHandler, ResponseCode};
use trust_dns::rr::{Name, RecordType};
use trust_dns::rr::dnssec::{Algorithm, SupportedAlgorithms};
use trust_dns::rr::rdata::opt::EdnsOption;
use trust_dns::rr::rdata::opt::{EdnsCode, EdnsOption};
use ::authority::{Authority, ZoneType};
@ -248,16 +248,25 @@ impl Catalog {
if let Some(ref_authority) = self.find_auth_recurse(query.get_name()) {
let authority = &ref_authority.read().unwrap(); // poison errors should panic
debug!("found authority: {:?}", authority.get_origin());
let is_dnssec = request.get_edns().map_or(false, |edns|edns.is_dnssec_ok());
let (is_dnssec, supported_algorithms) = request.get_edns()
.map_or((false, SupportedAlgorithms::new()), |edns| {
let supported_algorithms = if let Some(&EdnsOption::DAU(algs)) = edns.get_option(&EdnsCode::DAU) {
algs
} else {
Default::default()
};
let records = authority.search(query, is_dnssec);
(edns.is_dnssec_ok(), supported_algorithms)
});
let records = authority.search(query, is_dnssec, supported_algorithms);
if !records.is_empty() {
response.response_code(ResponseCode::NoError);
response.authoritative(true);
response.add_answers(records.into_iter().cloned());
// get the NS records
let ns = authority.get_ns(is_dnssec);
let ns = authority.get_ns(is_dnssec, supported_algorithms);
if ns.is_empty() { warn!("there are no NS records for: {:?}", authority.get_origin()); }
else {
response.add_name_servers(ns.into_iter().cloned());
@ -265,14 +274,14 @@ impl Catalog {
} else {
if is_dnssec {
// get NSEC records
let nsecs = authority.get_nsec_records(query.get_name(), is_dnssec);
let nsecs = authority.get_nsec_records(query.get_name(), is_dnssec, supported_algorithms);
response.add_name_servers(nsecs.into_iter().cloned());
}
// in the not found case it's standard to return the SOA in the authority section
response.response_code(ResponseCode::NXDomain);
let soa = authority.get_soa_secure(is_dnssec);
let soa = authority.get_soa_secure(is_dnssec, supported_algorithms);
if soa.is_empty() { warn!("there is no SOA record for: {:?}", authority.get_origin()); }
else {
response.add_name_servers(soa.into_iter().cloned());

View File

@ -11,6 +11,7 @@ use std::net::*;
use rusqlite::*;
use trust_dns::rr::*;
use trust_dns::rr::dnssec::*;
use trust_dns::rr::rdata::*;
use trust_dns::op::*;
use trust_dns_server::authority::*;
@ -26,7 +27,7 @@ fn test_search() {
let mut query: Query = Query::new();
query.name(origin.clone());
let result = example.search(&query, false);
let result = example.search(&query, false, SupportedAlgorithms::new());
if !result.is_empty() {
assert_eq!(result.first().unwrap().get_rr_type(), RecordType::A);
assert_eq!(result.first().unwrap().get_dns_class(), DNSClass::IN);
@ -45,7 +46,7 @@ fn test_search_www() {
let mut query: Query = Query::new();
query.name(www_name.clone());
let result = example.search(&query, false);
let result = example.search(&query, false, SupportedAlgorithms::new());
if !result.is_empty() {
assert_eq!(result.first().unwrap().get_rr_type(), RecordType::A);
assert_eq!(result.first().unwrap().get_dns_class(), DNSClass::IN);
@ -62,22 +63,22 @@ fn test_authority() {
assert!(authority.get_soa().is_some());
assert_eq!(authority.get_soa().unwrap().get_dns_class(), DNSClass::IN);
assert!(!authority.lookup(authority.get_origin(), RecordType::NS, false).is_empty());
assert!(!authority.lookup(authority.get_origin(), RecordType::NS, false, SupportedAlgorithms::new()).is_empty());
let mut lookup: Vec<_> = authority.get_ns(false);
let mut lookup: Vec<_> = authority.get_ns(false, SupportedAlgorithms::new());
lookup.sort();
assert_eq!(**lookup.first().unwrap(), Record::new().name(authority.get_origin().clone()).ttl(86400).rr_type(RecordType::NS).dns_class(DNSClass::IN).rdata(RData::NS(Name::parse("a.iana-servers.net.", None).unwrap()) ).clone());
assert_eq!(**lookup.last().unwrap(), Record::new().name(authority.get_origin().clone()).ttl(86400).rr_type(RecordType::NS).dns_class(DNSClass::IN).rdata(RData::NS(Name::parse("b.iana-servers.net.", None).unwrap()) ).clone());
assert!(!authority.lookup(authority.get_origin(), RecordType::TXT, false).is_empty());
assert!(!authority.lookup(authority.get_origin(), RecordType::TXT, false, SupportedAlgorithms::new()).is_empty());
let mut lookup: Vec<_> = authority.lookup(authority.get_origin(), RecordType::TXT, false);
let mut lookup: Vec<_> = authority.lookup(authority.get_origin(), RecordType::TXT, false, SupportedAlgorithms::new());
lookup.sort();
assert_eq!(**lookup.first().unwrap(), Record::new().name(authority.get_origin().clone()).ttl(60).rr_type(RecordType::TXT).dns_class(DNSClass::IN).rdata(RData::TXT(TXT::new(vec!["$Id: example.com 4415 2015-08-24 20:12:23Z davids $".to_string()]))).clone());
assert_eq!(**authority.lookup(authority.get_origin(), RecordType::A, false).first().unwrap(), Record::new().name(authority.get_origin().clone()).ttl(86400).rr_type(RecordType::A).dns_class(DNSClass::IN).rdata(RData::A(Ipv4Addr::new(93,184,216,34))).clone());
assert_eq!(**authority.lookup(authority.get_origin(), RecordType::A, false, SupportedAlgorithms::new()).first().unwrap(), Record::new().name(authority.get_origin().clone()).ttl(86400).rr_type(RecordType::A).dns_class(DNSClass::IN).rdata(RData::A(Ipv4Addr::new(93,184,216,34))).clone());
}
#[test]
@ -183,20 +184,20 @@ fn test_update() {
{
// assert that the correct set of records is there.
let mut www_rrset: Vec<&Record> = authority.lookup(&www_name, RecordType::ANY, false);
let mut www_rrset: Vec<&Record> = authority.lookup(&www_name, RecordType::ANY, false, SupportedAlgorithms::new());
www_rrset.sort();
assert_eq!(www_rrset, original_vec.iter().collect::<Vec<&Record>>());
// assert new record doesn't exist
assert!(authority.lookup(&new_name, RecordType::ANY, false).is_empty());
assert!(authority.lookup(&new_name, RecordType::ANY, false, SupportedAlgorithms::new()).is_empty());
}
//
// zone rrset rr Add to an RRset
let add_record = &[Record::new().name(new_name.clone()).ttl(86400).rr_type(RecordType::A).dns_class(DNSClass::IN).rdata(RData::A(Ipv4Addr::new(93,184,216,24))).clone()];
assert!(authority.update_records(add_record, true).expect("update failed"));
assert_eq!(authority.lookup(&new_name, RecordType::ANY, false), add_record.iter().collect::<Vec<&Record>>());
assert_eq!(authority.lookup(&new_name, RecordType::ANY, false, SupportedAlgorithms::new()), add_record.iter().collect::<Vec<&Record>>());
assert_eq!(serial + 1, authority.get_serial());
let add_www_record = &[Record::new().name(www_name.clone()).ttl(86400).rr_type(RecordType::A).dns_class(DNSClass::IN).rdata(RData::A(Ipv4Addr::new(10,0,0,1))).clone()];
@ -204,7 +205,7 @@ fn test_update() {
assert_eq!(serial + 2, authority.get_serial());
{
let mut www_rrset = authority.lookup(&www_name, RecordType::ANY, false);
let mut www_rrset = authority.lookup(&www_name, RecordType::ANY, false, SupportedAlgorithms::new());
www_rrset.sort();
let mut plus_10 = original_vec.clone();
@ -219,8 +220,8 @@ fn test_update() {
assert!(authority.update_records(del_record, true).expect("update failed"));
assert_eq!(serial + 3, authority.get_serial());
{
println!("after delete of specific record: {:?}", authority.lookup(&new_name, RecordType::ANY, false));
assert!(authority.lookup(&new_name, RecordType::ANY, false).is_empty());
println!("after delete of specific record: {:?}", authority.lookup(&new_name, RecordType::ANY, false, SupportedAlgorithms::new()));
assert!(authority.lookup(&new_name, RecordType::ANY, false, SupportedAlgorithms::new()).is_empty());
}
// remove one from www
@ -228,7 +229,7 @@ fn test_update() {
assert!(authority.update_records(del_record, true).expect("update failed"));
assert_eq!(serial + 4, authority.get_serial());
{
let mut www_rrset = authority.lookup(&www_name, RecordType::ANY, false);
let mut www_rrset = authority.lookup(&www_name, RecordType::ANY, false, SupportedAlgorithms::new());
www_rrset.sort();
assert_eq!(www_rrset, original_vec.iter().collect::<Vec<&Record>>());
@ -246,7 +247,7 @@ fn test_update() {
removed_a_vec.sort();
{
let mut www_rrset = authority.lookup(&www_name, RecordType::ANY, false);
let mut www_rrset = authority.lookup(&www_name, RecordType::ANY, false, SupportedAlgorithms::new());
www_rrset.sort();
assert_eq!(www_rrset, removed_a_vec.iter().collect::<Vec<&Record>>());
@ -257,7 +258,7 @@ fn test_update() {
println!("deleting all records");
let del_record = &[Record::new().name(www_name.clone()).ttl(86400).rr_type(RecordType::ANY).dns_class(DNSClass::ANY).rdata(RData::NULL(NULL::new())).clone()];
assert!(authority.update_records(del_record, true).expect("update failed"));
assert!(authority.lookup(&www_name, RecordType::ANY, false).is_empty());
assert!(authority.lookup(&www_name, RecordType::ANY, false, SupportedAlgorithms::new()).is_empty());
assert_eq!(serial + 6, authority.get_serial());
}
@ -265,7 +266,7 @@ fn test_update() {
fn test_zone_signing() {
let authority: Authority = create_secure_example();
let results = authority.lookup(&authority.get_origin(), RecordType::AXFR, true);
let results = authority.lookup(&authority.get_origin(), RecordType::AXFR, true, SupportedAlgorithms::all());
assert!(results.iter().any(|r| r.get_rr_type() == RecordType::DNSKEY), "must contain a DNSKEY");
@ -289,7 +290,7 @@ fn test_get_nsec() {
let name = Name::new().label("zzz").label("example").label("com");
let authority: Authority = create_secure_example();
let results = authority.get_nsec_records(&name, true);
let results = authority.get_nsec_records(&name, true, SupportedAlgorithms::all());
for record in results.iter() {
assert!(record.get_name() < &name);
@ -314,10 +315,10 @@ fn test_journal() {
authority.update_records(&[new_record.clone(), delete_record], true).unwrap();
// assert that the correct set of records is there.
let new_rrset: Vec<&Record> = authority.lookup(&new_name, RecordType::A, false);
let new_rrset: Vec<&Record> = authority.lookup(&new_name, RecordType::A, false, SupportedAlgorithms::new());
assert!(new_rrset.iter().all(|r| *r == &new_record));
let delete_rrset: Vec<&Record> = authority.lookup(&delete_name, RecordType::A, false);
let delete_rrset: Vec<&Record> = authority.lookup(&delete_name, RecordType::A, false, SupportedAlgorithms::new());
assert!(delete_rrset.is_empty());
// that record should have been recorded... let's reload the journal and see if we get it.
@ -329,10 +330,10 @@ fn test_journal() {
recovered_authority.recover_with_journal(authority.get_journal().expect("journal not Some")).expect("recovery");
// assert that the correct set of records is there.
let new_rrset: Vec<&Record> = recovered_authority.lookup(&new_name, RecordType::A, false);
let new_rrset: Vec<&Record> = recovered_authority.lookup(&new_name, RecordType::A, false, SupportedAlgorithms::new());
assert!(new_rrset.iter().all(|r| *r == &new_record));
let delete_rrset: Vec<&Record> = authority.lookup(&delete_name, RecordType::A, false);
let delete_rrset: Vec<&Record> = authority.lookup(&delete_name, RecordType::A, false, SupportedAlgorithms::new());
assert!(delete_rrset.is_empty());
}

View File

@ -5,6 +5,7 @@ use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
use trust_dns::rr::*;
use trust_dns::rr::dnssec::*;
use trust_dns::serialize::txt::*;
use trust_dns_server::authority::*;
@ -69,7 +70,7 @@ venera A 10.1.0.52
}
// NS
let mut ns_records: Vec<&Record> = authority.lookup(&Name::with_labels(vec!["isi".into(),"edu".into()]), RecordType::NS, false);
let mut ns_records: Vec<&Record> = authority.lookup(&Name::with_labels(vec!["isi".into(),"edu".into()]), RecordType::NS, false, SupportedAlgorithms::new());
let mut compare = vec![ // this is cool, zip up the expected results... works as long as the order is good.
Name::new().label("a").label("isi").label("edu"),
Name::new().label("venera").label("isi").label("edu"),
@ -93,7 +94,7 @@ venera A 10.1.0.52
}
// MX
let mut mx_records: Vec<&Record> = authority.lookup(&Name::new().label("isi").label("edu"), RecordType::MX, false);
let mut mx_records: Vec<&Record> = authority.lookup(&Name::new().label("isi").label("edu"), RecordType::MX, false, SupportedAlgorithms::new());
let mut compare = vec![
(10, Name::new().label("venera").label("isi").label("edu")),
(20, Name::new().label("vaxa").label("isi").label("edu")),
@ -118,7 +119,7 @@ venera A 10.1.0.52
}
// A
let a_record: &Record = authority.lookup(&Name::new().label("a").label("isi").label("edu"), RecordType::A, false).first().cloned().unwrap();
let a_record: &Record = authority.lookup(&Name::new().label("a").label("isi").label("edu"), RecordType::A, false, SupportedAlgorithms::new()).first().cloned().unwrap();
assert_eq!(&Name::new().label("a").label("isi").label("edu"), a_record.get_name());
assert_eq!(60, a_record.get_ttl()); // TODO: should this be minimum or expire?
assert_eq!(DNSClass::IN, a_record.get_dns_class());
@ -130,7 +131,7 @@ venera A 10.1.0.52
}
// AAAA
let aaaa_record: &Record = authority.lookup(&Name::new().label("aaaa").label("isi").label("edu"), RecordType::AAAA, false).first().cloned().unwrap();
let aaaa_record: &Record = authority.lookup(&Name::new().label("aaaa").label("isi").label("edu"), RecordType::AAAA, false, SupportedAlgorithms::new()).first().cloned().unwrap();
assert_eq!(&Name::new().label("aaaa").label("isi").label("edu"), aaaa_record.get_name());
if let RData::AAAA(ref address) = *aaaa_record.get_rdata() {
assert_eq!(&Ipv6Addr::from_str("4321:0:1:2:3:4:567:89ab").unwrap(), address);
@ -139,7 +140,7 @@ venera A 10.1.0.52
}
// SHORT
let short_record: &Record = authority.lookup(&Name::new().label("short").label("isi").label("edu"), RecordType::A, false).first().cloned().unwrap();
let short_record: &Record = authority.lookup(&Name::new().label("short").label("isi").label("edu"), RecordType::A, false, SupportedAlgorithms::new()).first().cloned().unwrap();
assert_eq!(&Name::new().label("short").label("isi").label("edu"), short_record.get_name());
assert_eq!(70, short_record.get_ttl());
if let RData::A(ref address) = *short_record.get_rdata() {
@ -149,7 +150,7 @@ venera A 10.1.0.52
}
// TXT
let mut txt_records: Vec<&Record> = authority.lookup(&Name::new().label("a").label("isi").label("edu"), RecordType::TXT, false);
let mut txt_records: Vec<&Record> = authority.lookup(&Name::new().label("a").label("isi").label("edu"), RecordType::TXT, false, SupportedAlgorithms::new());
let compare = vec![
vec!["I".to_string(), "am".to_string(), "a".to_string(), "txt".to_string(), "record".to_string()],
vec!["I".to_string(), "am".to_string(), "another".to_string(), "txt".to_string(), "record".to_string()],
@ -174,7 +175,7 @@ venera A 10.1.0.52
}
// PTR
let ptr_record: &Record = authority.lookup(&Name::new().label("103").label("0").label("3").label("26").label("in-addr").label("arpa"), RecordType::PTR, false).first().cloned().unwrap();
let ptr_record: &Record = authority.lookup(&Name::new().label("103").label("0").label("3").label("26").label("in-addr").label("arpa"), RecordType::PTR, false, SupportedAlgorithms::new()).first().cloned().unwrap();
if let RData::PTR( ref ptrdname ) = *ptr_record.get_rdata() {
assert_eq!(&Name::new().label("a").label("isi").label("edu"), ptrdname);
} else {
@ -182,7 +183,7 @@ venera A 10.1.0.52
}
// SRV
let srv_record: &Record = authority.lookup(&Name::new().label("_ldap").label("_tcp").label("service").label("isi").label("edu"), RecordType::SRV, false).first().cloned().unwrap();
let srv_record: &Record = authority.lookup(&Name::new().label("_ldap").label("_tcp").label("service").label("isi").label("edu"), RecordType::SRV, false, SupportedAlgorithms::new()).first().cloned().unwrap();
if let RData::SRV(ref rdata) = *srv_record.get_rdata() {
assert_eq!(rdata.get_priority(), 1);
assert_eq!(rdata.get_weight(), 2);