add Proof to resource::Record
This commit is contained in:
@@ -5,8 +5,13 @@
|
||||
// https://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
|
||||
//! DNSSEC related Proof of record authenticity
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(feature = "serde-config")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Represents the status of a DNSSEC verified record.
|
||||
///
|
||||
/// see [RFC 4035, DNSSEC Protocol Modifications, March 2005](https://datatracker.ietf.org/doc/html/rfc4035#section-4.3)
|
||||
@@ -18,6 +23,7 @@ use std::fmt;
|
||||
/// security-aware resolver must be able to distinguish between four
|
||||
/// cases:
|
||||
/// ```
|
||||
#[cfg_attr(feature = "serde-config", derive(Deserialize, Serialize))]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Proof {
|
||||
/// An RRset for which the resolver is able to build a chain of
|
||||
@@ -52,11 +58,20 @@ pub enum Proof {
|
||||
}
|
||||
|
||||
impl Proof {
|
||||
/// Returns true if this Proof represents a validated DNSSEC record
|
||||
pub fn is_secure(&self) -> bool {
|
||||
*self == Self::Secure
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Proof {
|
||||
/// Returns `Indeterminate` as the default state for Proof as this is the closest to meaning
|
||||
/// that no DNSSEC verification has happened.
|
||||
fn default() -> Self {
|
||||
Self::Indeterminate
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Proof {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let s = match self {
|
||||
|
@@ -14,7 +14,7 @@ use crate::{
|
||||
rdata::{DNSKEY, KEY, RRSIG, SIG},
|
||||
tbs, Algorithm, PublicKey, PublicKeyEnum,
|
||||
},
|
||||
DNSClass, Name, RData, Record,
|
||||
DNSClass, Name, Record,
|
||||
},
|
||||
serialize::binary::BinEncodable,
|
||||
};
|
||||
|
@@ -18,6 +18,9 @@ use crate::{
|
||||
serialize::binary::{BinDecodable, BinDecoder, BinEncodable, BinEncoder, Restrict},
|
||||
};
|
||||
|
||||
#[cfg(feature = "dnssec")]
|
||||
use crate::rr::dnssec::Proof;
|
||||
|
||||
#[allow(deprecated)]
|
||||
use crate::rr::IntoRecordSet;
|
||||
|
||||
@@ -78,12 +81,14 @@ pub struct Record<R: RecordData = RData> {
|
||||
rdata: Option<R>,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush: bool,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof: Proof,
|
||||
}
|
||||
|
||||
impl Default for Record<RData> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
// TODO: these really should all be Optionals, I was lazy.
|
||||
// TODO: make these part of a Builder instead to cleanup Records at runtime?
|
||||
name_labels: Name::new(),
|
||||
rr_type: RecordType::NULL,
|
||||
dns_class: DNSClass::IN,
|
||||
@@ -91,6 +96,8 @@ impl Default for Record<RData> {
|
||||
rdata: None,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush: false,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof: Proof::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,6 +129,8 @@ impl Record<RData> {
|
||||
rdata: None,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush: false,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof: Proof::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +177,8 @@ impl<R: RecordData> Record<R> {
|
||||
rdata: Some(rdata),
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush: false,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof: Proof::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +193,8 @@ impl<R: RecordData> Record<R> {
|
||||
rdata,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof,
|
||||
} = record;
|
||||
|
||||
match rdata.map(R::try_from_rdata) {
|
||||
@@ -193,6 +206,8 @@ impl<R: RecordData> Record<R> {
|
||||
rdata: None,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof,
|
||||
}),
|
||||
Some(Ok(rdata)) => Ok(Self {
|
||||
name_labels,
|
||||
@@ -202,6 +217,8 @@ impl<R: RecordData> Record<R> {
|
||||
rdata: Some(rdata),
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof,
|
||||
}),
|
||||
Some(Err(rdata)) => Err(Record {
|
||||
name_labels,
|
||||
@@ -211,6 +228,8 @@ impl<R: RecordData> Record<R> {
|
||||
rdata: Some(rdata),
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof,
|
||||
}),
|
||||
}
|
||||
}
|
||||
@@ -225,6 +244,8 @@ impl<R: RecordData> Record<R> {
|
||||
rdata,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof,
|
||||
} = self;
|
||||
|
||||
let rdata: Option<RData> = rdata.map(RecordData::into_rdata);
|
||||
@@ -237,6 +258,8 @@ impl<R: RecordData> Record<R> {
|
||||
rdata,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,6 +325,14 @@ impl<R: RecordData> Record<R> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the DNSSEC Proof for this record, after it's been verified
|
||||
#[cfg(feature = "dnssec")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
|
||||
pub fn set_proof(&mut self, proof: Proof) -> &mut Self {
|
||||
self.proof = proof;
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns the name of the record
|
||||
#[inline]
|
||||
pub fn name(&self) -> &Name {
|
||||
@@ -359,6 +390,14 @@ impl<R: RecordData> Record<R> {
|
||||
pub fn mdns_cache_flush(&self) -> bool {
|
||||
self.mdns_cache_flush
|
||||
}
|
||||
|
||||
/// The Proof of DNSSEC validation for this record, this is only valid if some form of validation has occurred
|
||||
#[cfg(feature = "dnssec")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
|
||||
#[inline]
|
||||
pub fn proof(&self) -> Proof {
|
||||
self.proof
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes `Record` giving public access to fields of `Record` so they can
|
||||
@@ -378,30 +417,25 @@ pub struct RecordParts<R: RecordData = RData> {
|
||||
#[cfg(feature = "mdns")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))]
|
||||
pub mdns_cache_flush: bool,
|
||||
/// mDNS cache flush
|
||||
#[cfg(feature = "dnssec")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
|
||||
pub proof: Proof,
|
||||
}
|
||||
|
||||
impl<R: RecordData> From<Record<R>> for RecordParts<R> {
|
||||
fn from(record: Record<R>) -> Self {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "mdns")] {
|
||||
let Record {
|
||||
name_labels,
|
||||
rr_type,
|
||||
dns_class,
|
||||
ttl,
|
||||
rdata,
|
||||
mdns_cache_flush,
|
||||
} = record;
|
||||
} else {
|
||||
let Record {
|
||||
name_labels,
|
||||
rr_type,
|
||||
dns_class,
|
||||
ttl,
|
||||
rdata,
|
||||
} = record;
|
||||
}
|
||||
}
|
||||
let Record {
|
||||
name_labels,
|
||||
rr_type,
|
||||
dns_class,
|
||||
ttl,
|
||||
rdata,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof,
|
||||
} = record;
|
||||
|
||||
Self {
|
||||
name_labels,
|
||||
@@ -411,6 +445,8 @@ impl<R: RecordData> From<Record<R>> for RecordParts<R> {
|
||||
rdata,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -561,6 +597,8 @@ impl<'r> BinDecodable<'r> for Record<RData> {
|
||||
rdata,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof: Proof::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -746,6 +784,8 @@ pub struct RecordRef<'a, R: RecordData> {
|
||||
rdata: Option<&'a R>,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush: bool,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof: Proof,
|
||||
}
|
||||
|
||||
impl<'a, R: RecordData> RecordRef<'a, R> {
|
||||
@@ -759,6 +799,8 @@ impl<'a, R: RecordData> RecordRef<'a, R> {
|
||||
rdata: self.rdata.cloned(),
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush: self.mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof: self.proof,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -800,6 +842,14 @@ impl<'a, R: RecordData> RecordRef<'a, R> {
|
||||
pub fn mdns_cache_flush(&self) -> bool {
|
||||
self.mdns_cache_flush
|
||||
}
|
||||
|
||||
/// The Proof of DNSSEC validation for this record, this is only valid if some form of validation has occurred
|
||||
#[cfg(feature = "dnssec")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
|
||||
#[inline]
|
||||
pub fn proof(&self) -> Proof {
|
||||
self.proof
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, R: RecordData> TryFrom<&'a Record> for RecordRef<'a, R> {
|
||||
@@ -814,6 +864,8 @@ impl<'a, R: RecordData> TryFrom<&'a Record> for RecordRef<'a, R> {
|
||||
rdata,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof,
|
||||
} = record;
|
||||
|
||||
match rdata.as_ref().and_then(R::try_borrow) {
|
||||
@@ -825,6 +877,8 @@ impl<'a, R: RecordData> TryFrom<&'a Record> for RecordRef<'a, R> {
|
||||
rdata: None,
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush: *mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof: *proof,
|
||||
}),
|
||||
Some(rdata) => Ok(Self {
|
||||
name_labels,
|
||||
@@ -834,6 +888,8 @@ impl<'a, R: RecordData> TryFrom<&'a Record> for RecordRef<'a, R> {
|
||||
rdata: Some(rdata),
|
||||
#[cfg(feature = "mdns")]
|
||||
mdns_cache_flush: *mdns_cache_flush,
|
||||
#[cfg(feature = "dnssec")]
|
||||
proof: *proof,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user