step (SIG)
This commit is contained in:
parent
0261d27764
commit
adb00b77b6
@ -6,6 +6,7 @@ pub mod types;
|
|||||||
mod eui;
|
mod eui;
|
||||||
mod nsec;
|
mod nsec;
|
||||||
mod nxt;
|
mod nxt;
|
||||||
|
mod sig;
|
||||||
mod time;
|
mod time;
|
||||||
mod uri;
|
mod uri;
|
||||||
|
|
||||||
@ -15,7 +16,8 @@ pub use self::eui::{EUI48Addr, EUI64Addr};
|
|||||||
pub use self::name::{DnsName, DnsCanonicalName, DnsCompressedName};
|
pub use self::name::{DnsName, DnsCanonicalName, DnsCompressedName};
|
||||||
pub use self::nsec::{NsecTypeBitmap, NextHashedOwnerName};
|
pub use self::nsec::{NsecTypeBitmap, NextHashedOwnerName};
|
||||||
pub use self::nxt::NxtTypeBitmap;
|
pub use self::nxt::NxtTypeBitmap;
|
||||||
|
pub use self::sig::OptionalTTL;
|
||||||
pub use self::text::{ShortText, LongText, UnquotedShortText, RemainingText};
|
pub use self::text::{ShortText, LongText, UnquotedShortText, RemainingText};
|
||||||
pub use self::time::{Time, Time48};
|
pub use self::time::{Time, TimeStrict, Time48};
|
||||||
pub use self::types::Type;
|
pub use self::types::Type;
|
||||||
pub use self::uri::UriText;
|
pub use self::uri::UriText;
|
||||||
|
@ -78,7 +78,7 @@ pub fn deserialize_name(data: &mut Cursor<Bytes>, accept_compressed: bool) -> Re
|
|||||||
total_len += 1 + label_len;
|
total_len += 1 + label_len;
|
||||||
// max len 255, but there also needs to be an empty label at the end
|
// max len 255, but there also needs to be an empty label at the end
|
||||||
if total_len > 254 { bail!{"DNS name too long"} }
|
if total_len > 254 { bail!{"DNS name too long"} }
|
||||||
check_enough_data!(data, (label_len), "DnsName label");
|
check_enough_data!(data, label_len, "DnsName label");
|
||||||
data.advance(label_len);
|
data.advance(label_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
52
lib/dnsbox-base/src/common_types/sig.rs
Normal file
52
lib/dnsbox-base/src/common_types/sig.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
use bytes::Bytes;
|
||||||
|
use errors::*;
|
||||||
|
use failure::Fail;
|
||||||
|
use ser::packet::{DnsPacketData, DnsPacketWriteContext};
|
||||||
|
use ser::text::{DnsTextData, DnsTextFormatter, DnsTextContext, next_field};
|
||||||
|
use std::fmt;
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
/// Optional TTL
|
||||||
|
///
|
||||||
|
/// Always present in wire format, but optional in zone; defaults to TTL
|
||||||
|
/// of the RR.
|
||||||
|
///
|
||||||
|
/// Must be followed by a field that doesn't accept any unsigned 32-bit
|
||||||
|
/// integer as text representation (like `TimeStrict` for `SIG`).
|
||||||
|
///
|
||||||
|
/// If field is missing in zone representation the context must provide
|
||||||
|
/// a TTL.
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub struct OptionalTTL(pub u32);
|
||||||
|
|
||||||
|
impl DnsPacketData for OptionalTTL {
|
||||||
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
||||||
|
Ok(OptionalTTL(DnsPacketData::deserialize(data)?))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize(&self, context: &mut DnsPacketWriteContext, packet: &mut Vec<u8>) -> Result<()> {
|
||||||
|
self.0.serialize(context, packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DnsTextData for OptionalTTL {
|
||||||
|
fn dns_parse(context: &DnsTextContext, data: &mut &str) -> ::errors::Result<Self> {
|
||||||
|
let mut data_found = *data;
|
||||||
|
let field = next_field(&mut data_found)?;
|
||||||
|
match field.parse::<u32>() {
|
||||||
|
Ok(ttl) => {
|
||||||
|
*data = data_found;
|
||||||
|
Ok(OptionalTTL(ttl))
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
Ok(OptionalTTL(context.last_ttl()
|
||||||
|
.ok_or_else(|| e.context("TTL not available in context, failed parsing optional TTL"))?
|
||||||
|
))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dns_format(&self, f: &mut DnsTextFormatter) -> fmt::Result {
|
||||||
|
self.0.dns_format(f)
|
||||||
|
}
|
||||||
|
}
|
@ -7,9 +7,12 @@ use std::io::Cursor;
|
|||||||
|
|
||||||
mod epoch;
|
mod epoch;
|
||||||
|
|
||||||
/// timestamp in seconds since epoch (ignoring leap seconds)
|
/// Timestamp in seconds since epoch (ignoring leap seconds)
|
||||||
///
|
///
|
||||||
/// Is expected to wrap around.
|
/// Is expected to wrap around.
|
||||||
|
///
|
||||||
|
/// Accepts both YYYYMMDDHHmmSS or an unsigned 32-bit integer in text
|
||||||
|
/// form; formatted as YYYYMMDDHHmmSS for now.
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct Time(pub u32);
|
pub struct Time(pub u32);
|
||||||
|
|
||||||
@ -37,7 +40,36 @@ impl DnsTextData for Time {
|
|||||||
|
|
||||||
fn dns_format(&self, f: &mut DnsTextFormatter) -> fmt::Result {
|
fn dns_format(&self, f: &mut DnsTextFormatter) -> fmt::Result {
|
||||||
epoch::Tm::from_epoch(self.0 as i64).unwrap().format_YYYYMMDDHHmmSS(&mut*f.format_field()?)
|
epoch::Tm::from_epoch(self.0 as i64).unwrap().format_YYYYMMDDHHmmSS(&mut*f.format_field()?)
|
||||||
// write!(f, "{}", self.0)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Timestamp in seconds since epoch (ignoring leap seconds)
|
||||||
|
///
|
||||||
|
/// Is expected to wrap around.
|
||||||
|
///
|
||||||
|
/// Accepts only YYYYMMDDHHmmSS.
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
pub struct TimeStrict(pub u32);
|
||||||
|
|
||||||
|
impl DnsPacketData for TimeStrict {
|
||||||
|
fn deserialize(data: &mut Cursor<Bytes>) -> Result<Self> {
|
||||||
|
Ok(TimeStrict(DnsPacketData::deserialize(data)?))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize(&self, context: &mut DnsPacketWriteContext, packet: &mut Vec<u8>) -> Result<()> {
|
||||||
|
self.0.serialize(context, packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DnsTextData for TimeStrict {
|
||||||
|
fn dns_parse(_context: &DnsTextContext, data: &mut &str) -> ::errors::Result<Self> {
|
||||||
|
let field = next_field(data)?;
|
||||||
|
let tm = epoch::Tm::parse_YYYYMMDDHHmmSS(field)?;
|
||||||
|
Ok(TimeStrict(tm.epoch() as u32))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dns_format(&self, f: &mut DnsTextFormatter) -> fmt::Result {
|
||||||
|
epoch::Tm::from_epoch(self.0 as i64).unwrap().format_YYYYMMDDHHmmSS(&mut*f.format_field()?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,11 @@ fn serialized_answer(rrdata: Box<RRData>) -> Result<Bytes> {
|
|||||||
|
|
||||||
|
|
||||||
fn check(q: Type, text_input: &'static str, canonic: Option<&'static str>, raw: &'static [u8]) {
|
fn check(q: Type, text_input: &'static str, canonic: Option<&'static str>, raw: &'static [u8]) {
|
||||||
|
// Make sure the canonic representation is sound itself
|
||||||
|
if let Some(canonic) = canonic {
|
||||||
|
check(q, canonic, None, raw);
|
||||||
|
}
|
||||||
|
|
||||||
let canonic = canonic.unwrap_or(text_input);
|
let canonic = canonic.unwrap_or(text_input);
|
||||||
|
|
||||||
let mut context = text::DnsTextContext::new();
|
let mut context = text::DnsTextContext::new();
|
||||||
@ -144,6 +149,9 @@ fn test_NS() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// missing test_MD
|
||||||
|
// missing test_MF
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_CNAME() {
|
fn test_CNAME() {
|
||||||
// local alias
|
// local alias
|
||||||
@ -200,6 +208,9 @@ fn test_SOA() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// missing test_MB
|
||||||
|
// missing test_MG
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_MR() {
|
fn test_MR() {
|
||||||
// BROKEN TESTS (2) (deprecated)
|
// BROKEN TESTS (2) (deprecated)
|
||||||
@ -257,6 +268,8 @@ fn test_HINFO() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// missing test_MINFO
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_MX() {
|
fn test_MX() {
|
||||||
// local name
|
// local name
|
||||||
@ -348,6 +361,20 @@ fn test_AFSDB() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// missing test_RT
|
||||||
|
// missing test_NSAP_PTR
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_SIG() {
|
||||||
|
// not supported by powerdns
|
||||||
|
// last ttl is 3600 in this test environment
|
||||||
|
check(types::SIG,
|
||||||
|
"NXT 1 2 19970102030405 19961211100908 2143 foo.nil. AIYADP8d3zYNyQwW2EM4wXVFdslEJcUx/fxkfBeH1El4ixPFhpfHFElxbvKoWmvjDTCm fiYy2X+8XpFjwICHc398kzWsTMKlxovpz2FnCTM=",
|
||||||
|
Some("NXT 1 2 3600 19970102030405 19961211100908 2143 foo.nil. AIYADP8d3zYNyQwW2EM4wXVFdslEJcUx/fxkfBeH1El4ixPFhpfHFElxbvKoWmvjDTCmfiYy2X+8XpFjwICHc398kzWsTMKlxovpz2FnCTM="),
|
||||||
|
b"\x00\x1e\x01\x02\x00\x00\x0e\x10\x32\xcb\x25\xa5\x32\xae\x88\x44\x08\x5f\x03foo\x03nil\x00\x00\x86\x00\x0c\xff\x1d\xdf\x36\x0d\xc9\x0c\x16\xd8\x43\x38\xc1\x75\x45\x76\xc9\x44\x25\xc5\x31\xfd\xfc\x64\x7c\x17\x87\xd4\x49\x78\x8b\x13\xc5\x86\x97\xc7\x14\x49\x71\x6e\xf2\xa8\x5a\x6b\xe3\x0d\x30\xa6\x7e\x26\x32\xd9\x7f\xbc\x5e\x91\x63\xc0\x80\x87\x73\x7f\x7c\x93\x35\xac\x4c\xc2\xa5\xc6\x8b\xe9\xcf\x61\x67\x09\x33"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_KEY() {
|
fn test_KEY() {
|
||||||
// deprecated (and i don't know what i am doing wrong)
|
// deprecated (and i don't know what i am doing wrong)
|
||||||
@ -358,6 +385,9 @@ fn test_KEY() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// missing test_PX
|
||||||
|
// missing test_GPOS
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_AAAA() {
|
fn test_AAAA() {
|
||||||
check(types::AAAA,
|
check(types::AAAA,
|
||||||
@ -401,6 +431,8 @@ fn test_LOC() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// missing test_NXT
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_SRV() {
|
fn test_SRV() {
|
||||||
// local name
|
// local name
|
||||||
@ -456,6 +488,9 @@ fn test_CERT() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// missing test_A6
|
||||||
|
// missing test_DNAME
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_DS() {
|
fn test_DS() {
|
||||||
check(types::DS,
|
check(types::DS,
|
||||||
@ -700,6 +735,11 @@ fn test_SMIMEA() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// missing test_NINFO
|
||||||
|
// missing test_RKEY
|
||||||
|
// missing test_CDS
|
||||||
|
// missing test_CDNSKEY
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_OPENPGPKEY() {
|
fn test_OPENPGPKEY() {
|
||||||
check(types::OPENPGPKEY,
|
check(types::OPENPGPKEY,
|
||||||
|
@ -182,9 +182,9 @@ pub struct SIG {
|
|||||||
// RFC says this can be omitted in text form if it is the same as
|
// RFC says this can be omitted in text form if it is the same as
|
||||||
// the TTL on the SIG record. not supported to be omitted here
|
// the TTL on the SIG record. not supported to be omitted here
|
||||||
// (TODO?).
|
// (TODO?).
|
||||||
original_ttl: u32,
|
original_ttl: OptionalTTL,
|
||||||
signature_expiration: u32,
|
signature_expiration: TimeStrict,
|
||||||
signature_inception: u32,
|
signature_inception: TimeStrict,
|
||||||
key_tag: u16,
|
key_tag: u16,
|
||||||
signers_name: DnsCanonicalName,
|
signers_name: DnsCanonicalName,
|
||||||
signature: Base64RemainingBlob,
|
signature: Base64RemainingBlob,
|
||||||
|
Loading…
Reference in New Issue
Block a user