limit returned records to supported algorithms
This commit is contained in:
parent
4c0318ec95
commit
0660fece60
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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() {
|
||||
|
@ -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());
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user