From 20c5df3d9697e7a8322b4ca4ad687cb882728065 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:42:43 +0200 Subject: [PATCH 01/47] Use domain WIP NSEC3 support. --- Cargo.lock | 472 ++++++++++++++++++++++++++++++++++++++ Cargo.toml | 3 +- src/commands/nsec3hash.rs | 64 +----- 3 files changed, 485 insertions(+), 54 deletions(-) create mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..1ff8b346 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,472 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" + +[[package]] +name = "cc" +version = "1.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "dnst" +version = "0.1.0" +dependencies = [ + "clap", + "domain", + "octseq 0.5.2", + "ring", +] + +[[package]] +name = "domain" +version = "0.10.1" +source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#fbfbdeaeb58a459f1fcb7cbd5132b395a5086617" +dependencies = [ + "bytes", + "octseq 0.5.2-dev", + "rand", + "ring", + "time", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "octseq" +version = "0.5.2-dev" +source = "git+https://github.com/NLnetLabs/octseq.git?rev=3f7797f4274af0a52e66105250ee1186ff2ab6ac#3f7797f4274af0a52e66105250ee1186ff2ab6ac" +dependencies = [ + "bytes", +] + +[[package]] +name = "octseq" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126c3ca37c9c44cec575247f43a3e4374d8927684f129d2beeb0d2cef262fe12" +dependencies = [ + "bytes", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys", +] + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index c9d04455..aad4229e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,8 @@ edition = "2021" [dependencies] clap = { version = "4", features = ["derive"] } -domain = "0.10.1" +#domain = "0.10.3" +domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "sign"] } # for implementation of nsec3 hash until domain has it stabilized octseq = { version = "0.5.1", features = ["std"] } diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 1de1e005..149e679a 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -1,13 +1,12 @@ -use crate::error::Error; +use std::str::FromStr; + use clap::builder::ValueParser; use domain::base::iana::nsec3::Nsec3HashAlg; use domain::base::name::Name; -use domain::base::ToName; -use domain::rdata::nsec3::{Nsec3Salt, OwnerHash}; -// use domain::validator::nsec::nsec3_hash; -use octseq::OctetsBuilder; -use ring::digest; -use std::str::FromStr; +use domain::rdata::nsec3::Nsec3Salt; +use domain::sign::ring::nsec3_hash; + +use crate::error::Error; #[derive(Clone, Debug, clap::Args)] pub struct Nsec3Hash { @@ -64,53 +63,12 @@ impl Nsec3Hash { impl Nsec3Hash { pub fn execute(self) -> Result<(), Error> { - let hash = nsec3_hash(&self.name, self.algorithm, self.iterations, &self.salt) - .to_string() - .to_lowercase(); + let hash = + nsec3_hash::<_, _, Vec>(&self.name, self.algorithm, self.iterations, &self.salt) + .expect("Error while generating NSEC3 hash") + .to_string() + .to_lowercase(); println!("{}.", hash); Ok(()) } } - -// XXX: This is a verbatim copy of the nsec3_hash function from domain::validator::nsec. -// TODO: when exposed/available, replace with implementation from domain::validator::nsec -fn nsec3_hash( - owner: N, - algorithm: Nsec3HashAlg, - iterations: u16, - salt: &Nsec3Salt, -) -> OwnerHash> -where - N: ToName, - HashOcts: AsRef<[u8]>, -{ - let mut buf = Vec::new(); - - owner.compose_canonical(&mut buf).expect("infallible"); - buf.append_slice(salt.as_slice()).expect("infallible"); - - let digest_type = if algorithm == Nsec3HashAlg::SHA1 { - &digest::SHA1_FOR_LEGACY_USE_ONLY - } else { - // totest, unsupported NSEC3 hash algorithm - // Unsupported. - panic!("should not be called with an unsupported algorithm"); - }; - - let mut ctx = digest::Context::new(digest_type); - ctx.update(&buf); - let mut h = ctx.finish(); - - for _ in 0..iterations { - buf.truncate(0); - buf.append_slice(h.as_ref()).expect("infallible"); - buf.append_slice(salt.as_slice()).expect("infallible"); - - let mut ctx = digest::Context::new(digest_type); - ctx.update(&buf); - h = ctx.finish(); - } - - // For normal hash algorithms this should not fail. - OwnerHash::from_octets(h.as_ref().to_vec()).expect("should not fail") -} From d0addc7862a17cea2137787f10c4c9e7b6e5b875 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 29 Oct 2024 12:02:11 +0100 Subject: [PATCH 02/47] Update to latest version of domain branch. Note: now breaks if alg arg is not specified which will be fixed by PR #428. --- Cargo.lock | 32 ++++++++++++++++++++------------ Cargo.toml | 3 ++- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ff8b346..51701e7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "anstream" version = "0.6.15" @@ -139,17 +145,18 @@ version = "0.1.0" dependencies = [ "clap", "domain", - "octseq 0.5.2", + "octseq", "ring", ] [[package]] name = "domain" -version = "0.10.1" -source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#fbfbdeaeb58a459f1fcb7cbd5132b395a5086617" +version = "0.10.3" +source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#735712c9af37af152ca40dfa16523d27f3707646" dependencies = [ "bytes", - "octseq 0.5.2-dev", + "hashbrown", + "octseq", "rand", "ring", "time", @@ -166,6 +173,15 @@ dependencies = [ "wasi", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "allocator-api2", +] + [[package]] name = "heck" version = "0.5.0" @@ -190,14 +206,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[package]] -name = "octseq" -version = "0.5.2-dev" -source = "git+https://github.com/NLnetLabs/octseq.git?rev=3f7797f4274af0a52e66105250ee1186ff2ab6ac#3f7797f4274af0a52e66105250ee1186ff2ab6ac" -dependencies = [ - "bytes", -] - [[package]] name = "octseq" version = "0.5.2" diff --git a/Cargo.toml b/Cargo.toml index aad4229e..9ff2793e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,8 @@ edition = "2021" [dependencies] clap = { version = "4", features = ["derive"] } #domain = "0.10.3" -domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "sign"] } +domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-sign"] } +#domain = { path = "../domain2", features = ["ring", "unstable-sign"] } # for implementation of nsec3 hash until domain has it stabilized octseq = { version = "0.5.1", features = ["std"] } From 445d989b8070c426d05e1e60d86c40ad387ab529 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 29 Oct 2024 12:04:59 +0100 Subject: [PATCH 03/47] Remove commented out line left behind accidentally in Cargo.toml. --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9ff2793e..c4ca3496 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" clap = { version = "4", features = ["derive"] } #domain = "0.10.3" domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-sign"] } -#domain = { path = "../domain2", features = ["ring", "unstable-sign"] } # for implementation of nsec3 hash until domain has it stabilized octseq = { version = "0.5.1", features = ["std"] } From 49131eff8c2e44ebcc136ee275edc4835930ed67 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 29 Oct 2024 14:29:10 +0100 Subject: [PATCH 04/47] Update to latest version of domain branch. --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 51701e7f..b81146e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,7 +152,7 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#735712c9af37af152ca40dfa16523d27f3707646" +source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#d84e2c015078f8ee04d0786de9c6dfb1d330584e" dependencies = [ "bytes", "hashbrown", From 7e4dae952df59eabcf01ca20e890520bb52b84aa Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 29 Oct 2024 22:40:38 +0100 Subject: [PATCH 05/47] Work around missing max length enforcement in Nsec3Salt::from_str(). --- src/commands/nsec3hash.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 149e679a..44248687 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -31,7 +31,7 @@ pub struct Nsec3Hash { iterations: u16, /// The salt in hex representation - #[arg(short = 's', long, value_name = "HEX_STRING", default_value_t = Nsec3Salt::empty())] + #[arg(short = 's', long, value_name = "HEX_STRING", default_value_t = Nsec3Salt::empty(), value_parser = ValueParser::new(Nsec3Hash::parse_salt))] salt: Nsec3Salt>, /// The domain name to hash @@ -44,6 +44,14 @@ impl Nsec3Hash { Name::from_str(&arg.to_lowercase()).map_err(|e| Error::from(e.to_string())) } + pub fn parse_salt(arg: &str) -> Result>, Error> { + if arg.len() >= 512 { + Err(Error::from("Salt too long")) + } else { + Nsec3Salt::>::from_str(arg).map_err(|err| Error::from(err.to_string())) + } + } + pub fn parse_nsec_alg(arg: &str) -> Result { if let Ok(num) = arg.parse() { let alg = Nsec3HashAlg::from_int(num); From 4610832986537e8db2ecc183a39d2f393acb77d4 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 30 Oct 2024 00:51:25 +0100 Subject: [PATCH 06/47] Proof-of-concept automated sanity check against ldns-nsec3-hash using an existing 3rd party ldns Docker image. --- Cargo.lock | 9 ++++++++- Cargo.toml | 3 +++ tests/vs-ldns.rs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/vs-ldns.rs diff --git a/Cargo.lock b/Cargo.lock index b81146e1..91f7db1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -147,12 +147,13 @@ dependencies = [ "domain", "octseq", "ring", + "test_bin", ] [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#d84e2c015078f8ee04d0786de9c6dfb1d330584e" +source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#02c625b45fdb84db94c28827ab0db5be76471a6e" dependencies = [ "bytes", "hashbrown", @@ -342,6 +343,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "test_bin" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e7a7de15468c6e65dd7db81cf3822c1ec94c71b2a3c1a976ea8e4696c91115c" + [[package]] name = "time" version = "0.3.36" diff --git a/Cargo.toml b/Cargo.toml index c4ca3496..dfd14da0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,6 @@ domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3 # for implementation of nsec3 hash until domain has it stabilized octseq = { version = "0.5.1", features = ["std"] } ring = { version = "0.17" } + +[dev-dependencies] +test_bin = "0.4.0" \ No newline at end of file diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs new file mode 100644 index 00000000..8b90195a --- /dev/null +++ b/tests/vs-ldns.rs @@ -0,0 +1,50 @@ +use std::process::Command; + +#[test] +fn nsec3_hash() { + assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["example.com"]); + assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-a", "1", "example.com"]); + assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-s", "", "example.com"]); + assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-s", "DEADBEEF", "example.com"]); + + for iterations in 0..10 { + assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-t", &iterations.to_string(), "example.com"]); + } +} + +fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) { + // milekz/ldns just happens to be an existing image on hub.docker.com that + // contains the ldns binaries which allows us to easily invoke them without + // having to require ldns be installed on the host system. + let Ok(ldns_output) = Command::new("docker") + .arg("run") + .arg("--rm") + .arg("milekz/ldns") + .arg(ldns_command) + .args(args) + .output() + else { + // No Docker on this host, skip this test. + // An alternative would be to mark these tests as #[ignore]'d and require + // users to explicitly run the tests. + return; + }; + + let dnst_output = test_bin::get_test_bin("dnst") + .arg(dnst_subcommand) + .args(args) + .output() + .unwrap(); + + assert_eq!(std::str::from_utf8(&ldns_output.stderr), Ok("")); + assert_eq!(std::str::from_utf8(&dnst_output.stderr), Ok("")); + assert!(!ldns_output.stdout.is_empty()); + assert!(!dnst_output.stdout.is_empty()); + + // This will only work for LDNS commands whose output we are able to + // replicate exactly. + assert_eq!( + std::str::from_utf8(&ldns_output.stdout), + std::str::from_utf8(&dnst_output.stdout) + ); +} From 5980ca743ead5c6d55dead82d670f11cb9260892 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 30 Oct 2024 00:51:44 +0100 Subject: [PATCH 07/47] More closely match ldns-nsec3-hash error output. --- src/commands/nsec3hash.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 44248687..6cdeef76 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -73,7 +73,7 @@ impl Nsec3Hash { pub fn execute(self) -> Result<(), Error> { let hash = nsec3_hash::<_, _, Vec>(&self.name, self.algorithm, self.iterations, &self.salt) - .expect("Error while generating NSEC3 hash") + .expect("Error creating NSEC3 hash") .to_string() .to_lowercase(); println!("{}.", hash); From 7fb5b7a2bb639993068e1888e416b0aa2e4c5f66 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 30 Oct 2024 00:52:00 +0100 Subject: [PATCH 08/47] Match ldns-nsec3-hash exit code behaviour. --- src/main.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 264443be..478eec8b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,24 @@ use clap::Parser; fn main() { - if let Err(err) = dnst::Args::parse().execute() { - eprintln!("{}", err); + // Ensure that we exit with either 0 or 1, to match ldns-xxx command + // behaviour. We can't just call Args::parse() because Clap will exit with + // code 2 on argument parsing error, so instead call try_parse() and + // handle it ourselves. + match dnst::Args::try_parse() { + Ok(args) => { + if let Err(err) = args.execute() { + eprintln!("{}", err); + } else { + std::process::exit(0); + } + } + + Err(err) => { + // Ensure we benefit from Clap pretty coloured error output. + let _ = err.print(); + } } + + std::process::exit(1); } From 76f31bf4f5d2e91ac33452c41b691e3b67194e1e Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 30 Oct 2024 00:52:10 +0100 Subject: [PATCH 09/47] Cargo fmt. --- tests/vs-ldns.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index 8b90195a..ae3bcda0 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -5,10 +5,18 @@ fn nsec3_hash() { assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["example.com"]); assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-a", "1", "example.com"]); assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-s", "", "example.com"]); - assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-s", "DEADBEEF", "example.com"]); + assert_ldns_eq_dnst( + "ldns-nsec3-hash", + "nsec3-hash", + &["-s", "DEADBEEF", "example.com"], + ); for iterations in 0..10 { - assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-t", &iterations.to_string(), "example.com"]); + assert_ldns_eq_dnst( + "ldns-nsec3-hash", + "nsec3-hash", + &["-t", &iterations.to_string(), "example.com"], + ); } } From 1b70e5bd83dad72ea5e682c8b12fb61bb3b784da Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 30 Oct 2024 13:21:45 +0100 Subject: [PATCH 10/47] Minor cleanup. --- src/commands/nsec3hash.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 6cdeef76..49d75938 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -16,7 +16,7 @@ pub struct Nsec3Hash { short = 'a', value_name = "NUMBER_OR_MNEMONIC", default_value_t = Nsec3HashAlg::SHA1, - value_parser = ValueParser::new(Nsec3Hash::parse_nsec_alg) + value_parser = ValueParser::new(Nsec3Hash::parse_alg) )] algorithm: Nsec3HashAlg, @@ -31,7 +31,13 @@ pub struct Nsec3Hash { iterations: u16, /// The salt in hex representation - #[arg(short = 's', long, value_name = "HEX_STRING", default_value_t = Nsec3Salt::empty(), value_parser = ValueParser::new(Nsec3Hash::parse_salt))] + #[arg( + long, + short = 's', + value_name = "HEX_STRING", + default_value_t = Nsec3Salt::empty(), + value_parser = ValueParser::new(Nsec3Hash::parse_salt) + )] salt: Nsec3Salt>, /// The domain name to hash @@ -52,11 +58,9 @@ impl Nsec3Hash { } } - pub fn parse_nsec_alg(arg: &str) -> Result { + pub fn parse_alg(arg: &str) -> Result { if let Ok(num) = arg.parse() { let alg = Nsec3HashAlg::from_int(num); - // check for valid algorithm here, to be consistent with error messages - // if domain::validator::nsec::supported_nsec3_hash(alg) { if alg.to_mnemonic().is_some() { Ok(alg) } else { From 6a38c367c779ff2c1bc890753f2f21346a384d0b Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 30 Oct 2024 14:40:42 +0100 Subject: [PATCH 11/47] Use host based ldns tools for testing and only if ignored tests are run. --- tests/vs-ldns.rs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index ae3bcda0..fe854ac2 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -1,5 +1,6 @@ use std::process::Command; +#[ignore = "should only be run if ldns command line tools are installed"] #[test] fn nsec3_hash() { assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["example.com"]); @@ -21,22 +22,10 @@ fn nsec3_hash() { } fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) { - // milekz/ldns just happens to be an existing image on hub.docker.com that - // contains the ldns binaries which allows us to easily invoke them without - // having to require ldns be installed on the host system. - let Ok(ldns_output) = Command::new("docker") - .arg("run") - .arg("--rm") - .arg("milekz/ldns") - .arg(ldns_command) + let ldns_output = Command::new(ldns_command) .args(args) .output() - else { - // No Docker on this host, skip this test. - // An alternative would be to mark these tests as #[ignore]'d and require - // users to explicitly run the tests. - return; - }; + .unwrap(); let dnst_output = test_bin::get_test_bin("dnst") .arg(dnst_subcommand) From f5e644a3cd46eff5e6e6bd3bef58e07759588ac4 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 30 Oct 2024 23:52:05 +0100 Subject: [PATCH 12/47] Revert exit code change as this has been moved into PR #13. --- src/main.rs | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/main.rs b/src/main.rs index 478eec8b..264443be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,24 +1,7 @@ use clap::Parser; fn main() { - // Ensure that we exit with either 0 or 1, to match ldns-xxx command - // behaviour. We can't just call Args::parse() because Clap will exit with - // code 2 on argument parsing error, so instead call try_parse() and - // handle it ourselves. - match dnst::Args::try_parse() { - Ok(args) => { - if let Err(err) = args.execute() { - eprintln!("{}", err); - } else { - std::process::exit(0); - } - } - - Err(err) => { - // Ensure we benefit from Clap pretty coloured error output. - let _ = err.print(); - } + if let Err(err) = dnst::Args::parse().execute() { + eprintln!("{}", err); } - - std::process::exit(1); } From 0f9aa5b742197dcbd941b469479e1ec9bc5dd782 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Thu, 31 Oct 2024 00:14:30 +0100 Subject: [PATCH 13/47] Update to use nsec3_hash() at its new module location in doman. --- Cargo.lock | 584 +++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 +- src/commands/nsec3hash.rs | 2 +- tests/vs-ldns.rs | 5 +- 4 files changed, 586 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91f7db1f..210d82e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "allocator-api2" version = "0.2.18" @@ -57,6 +72,61 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "byteorder" version = "1.5.0" @@ -130,6 +200,39 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "deranged" version = "0.3.11" @@ -153,14 +256,77 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#02c625b45fdb84db94c28827ab0db5be76471a6e" +source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#beb8e529da0997df98c9e0b9a1298469c05fabab" dependencies = [ "bytes", + "futures-util", "hashbrown", + "moka", "octseq", "rand", "ring", + "serde", "time", + "tokio", + "tracing", +] + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] @@ -174,6 +340,12 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + [[package]] name = "hashbrown" version = "0.14.5" @@ -189,24 +361,115 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "libc" version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "moka" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" +dependencies = [ + "async-lock", + "async-trait", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener", + "futures-util", + "once_cell", + "parking_lot", + "quanta", + "rustc_version", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + [[package]] name = "octseq" version = "0.5.2" @@ -214,8 +477,56 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "126c3ca37c9c44cec575247f43a3e4374d8927684f129d2beeb0d2cef262fe12" dependencies = [ "bytes", + "serde", ] +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "powerfmt" version = "0.2.0" @@ -240,6 +551,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + [[package]] name = "quote" version = "1.0.37" @@ -279,6 +605,24 @@ dependencies = [ "getrandom", ] +[[package]] +name = "raw-cpuid" +version = "11.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + [[package]] name = "ring" version = "0.17.8" @@ -294,6 +638,33 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + [[package]] name = "serde" version = "1.0.210" @@ -320,6 +691,31 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "spin" version = "0.9.8" @@ -343,12 +739,38 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "test_bin" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e7a7de15468c6e65dd7db81cf3822c1ec94c71b2a3c1a976ea8e4696c91115c" +[[package]] +name = "thiserror" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.3.36" @@ -368,6 +790,70 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +[[package]] +name = "tokio" +version = "1.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + [[package]] name = "unicode-ident" version = "1.0.13" @@ -386,12 +872,108 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +dependencies = [ + "getrandom", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index dfd14da0..d7d4beaf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] clap = { version = "4", features = ["derive"] } #domain = "0.10.3" -domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-sign"] } +domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-validator"] } # for implementation of nsec3 hash until domain has it stabilized octseq = { version = "0.5.1", features = ["std"] } diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 49d75938..6989fd4a 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -4,7 +4,7 @@ use clap::builder::ValueParser; use domain::base::iana::nsec3::Nsec3HashAlg; use domain::base::name::Name; use domain::rdata::nsec3::Nsec3Salt; -use domain::sign::ring::nsec3_hash; +use domain::validate::nsec3_hash; use crate::error::Error; diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index fe854ac2..8cdb7d41 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -22,10 +22,7 @@ fn nsec3_hash() { } fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) { - let ldns_output = Command::new(ldns_command) - .args(args) - .output() - .unwrap(); + let ldns_output = Command::new(ldns_command).args(args).output().unwrap(); let dnst_output = test_bin::get_test_bin("dnst") .arg(dnst_subcommand) From 6a57f4b11bc67a84f69fec1e641e1229d6204961 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 5 Nov 2024 09:40:08 +0100 Subject: [PATCH 14/47] Better help message for default value of -a. --- src/commands/nsec3hash.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 6989fd4a..3b5c40f4 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -15,7 +15,7 @@ pub struct Nsec3Hash { long, short = 'a', value_name = "NUMBER_OR_MNEMONIC", - default_value_t = Nsec3HashAlg::SHA1, + default_value = "SHA-1", value_parser = ValueParser::new(Nsec3Hash::parse_alg) )] algorithm: Nsec3HashAlg, From 7a6a9832e381ea9ecd0391231414b318c841fd96 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 5 Nov 2024 09:41:23 +0100 Subject: [PATCH 15/47] Change short arg for iterations to match ldns-signzone. --- src/commands/nsec3hash.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 3b5c40f4..ff44f170 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -23,8 +23,7 @@ pub struct Nsec3Hash { /// The number of hash iterations #[arg( long, - short = 'i', - visible_short_alias = 't', + short = 't', value_name = "NUMBER", default_value_t = 1 )] From 837a2ff5b26954f13cfb19dbfc9441a4622eed64 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 09:26:47 +0100 Subject: [PATCH 16/47] Cargo fmt. --- src/commands/nsec3hash.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index ff44f170..32a6bf70 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -21,12 +21,7 @@ pub struct Nsec3Hash { algorithm: Nsec3HashAlg, /// The number of hash iterations - #[arg( - long, - short = 't', - value_name = "NUMBER", - default_value_t = 1 - )] + #[arg(long, short = 't', value_name = "NUMBER", default_value_t = 1)] iterations: u16, /// The salt in hex representation From 67bb9e7f8551bd1471baf92d2ff7d812d7b58e70 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 09:32:56 +0100 Subject: [PATCH 17/47] Closer alignment to ldns-nsec3-hash. --- src/commands/mod.rs | 2 +- src/commands/nsec3hash.rs | 13 +++++++------ src/main.rs | 2 ++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 2445c862..00c8f6eb 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -7,7 +7,7 @@ use super::error::Error; #[derive(Clone, Debug, clap::Subcommand)] pub enum Command { - /// Print the NSEC3 hash of a given domain name + /// Prints the NSEC3 hash of a given domain name #[command(name = "nsec3-hash")] Nsec3Hash(self::nsec3hash::Nsec3Hash), diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 32a6bf70..9a0a5a37 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -14,28 +14,29 @@ pub struct Nsec3Hash { #[arg( long, short = 'a', - value_name = "NUMBER_OR_MNEMONIC", + value_name = "algorithm", default_value = "SHA-1", - value_parser = ValueParser::new(Nsec3Hash::parse_alg) + value_parser = ValueParser::new(Nsec3Hash::parse_nsec3_alg) )] algorithm: Nsec3HashAlg, /// The number of hash iterations - #[arg(long, short = 't', value_name = "NUMBER", default_value_t = 1)] + // TODO: Default to 0 when run as dnst instead of as ldns-nsec3-hash + #[arg(long, short = 't', value_name = "number", default_value_t = 1)] iterations: u16, /// The salt in hex representation #[arg( long, short = 's', - value_name = "HEX_STRING", + value_name = "string", default_value_t = Nsec3Salt::empty(), value_parser = ValueParser::new(Nsec3Hash::parse_salt) )] salt: Nsec3Salt>, /// The domain name to hash - #[arg(value_name = "DOMAIN_NAME", value_parser = ValueParser::new(Nsec3Hash::parse_name))] + #[arg(value_name = "domain name", value_parser = ValueParser::new(Nsec3Hash::parse_name))] name: Name>, } @@ -52,7 +53,7 @@ impl Nsec3Hash { } } - pub fn parse_alg(arg: &str) -> Result { + pub fn parse_nsec3_alg(arg: &str) -> Result { if let Ok(num) = arg.parse() { let alg = Nsec3HashAlg::from_int(num); if alg.to_mnemonic().is_some() { diff --git a/src/main.rs b/src/main.rs index 264443be..46f745be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@ use clap::Parser; fn main() { + // TODO: Exit with code 1 on CLI args error when run as ldns-nsec3-hash, + // not code 2 as Clap does by default. if let Err(err) = dnst::Args::parse().execute() { eprintln!("{}", err); } From fcbfb2e800aa711873467dcaa94080fb6a984f85 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 09:43:19 +0100 Subject: [PATCH 18/47] Cleanup dependencies. --- Cargo.toml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d7d4beaf..67f7cfd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,13 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] -clap = { version = "4", features = ["derive"] } -#domain = "0.10.3" -domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-validator"] } - -# for implementation of nsec3 hash until domain has it stabilized -octseq = { version = "0.5.1", features = ["std"] } -ring = { version = "0.17" } +clap = { version = "4", features = ["derive"] } +#domain = "0.10.3" +domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-validator"] } [dev-dependencies] test_bin = "0.4.0" \ No newline at end of file From caf8adf8892ee80cf677d3780909ea62fd65ea86 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 09:43:53 +0100 Subject: [PATCH 19/47] Cleanup dependencies (Cargo.lock too). --- Cargo.lock | 2 -- 1 file changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 210d82e0..120ef6dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,8 +248,6 @@ version = "0.1.0" dependencies = [ "clap", "domain", - "octseq", - "ring", "test_bin", ] From 00f30e919b73d318a56511b1d63fdab68ec6c76b Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:39:17 +0100 Subject: [PATCH 20/47] Add initial fuzz testing of the nsec3-hash subcommand. --- Cargo.lock | 24 +- Cargo.toml | 6 +- fuzz/.gitignore | 4 + fuzz/Cargo.lock | 1122 +++++++++++++++++++++++++++++++ fuzz/Cargo.toml | 20 + fuzz/fuzz_targets/nsec3-hash.rs | 9 + src/commands/nsec3hash.rs | 1 + 7 files changed, 1184 insertions(+), 2 deletions(-) create mode 100644 fuzz/.gitignore create mode 100644 fuzz/Cargo.lock create mode 100644 fuzz/Cargo.toml create mode 100644 fuzz/fuzz_targets/nsec3-hash.rs diff --git a/Cargo.lock b/Cargo.lock index 120ef6dd..5068ca06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,6 +72,15 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] + [[package]] name = "async-lock" version = "3.4.0" @@ -242,10 +251,22 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "dnst" version = "0.1.0" dependencies = [ + "arbitrary", "clap", "domain", "test_bin", @@ -254,8 +275,9 @@ dependencies = [ [[package]] name = "domain" version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#beb8e529da0997df98c9e0b9a1298469c05fabab" +source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#f2cabc37eff3d85a42058180319926376604b7f6" dependencies = [ + "arbitrary", "bytes", "futures-util", "hashbrown", diff --git a/Cargo.toml b/Cargo.toml index 67f7cfd5..c7e4be4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,13 @@ version = "0.1.0" edition = "2021" [dependencies] +arbitrary = { version = "1", optional = true, features = ["derive"] } clap = { version = "4", features = ["derive"] } #domain = "0.10.3" domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-validator"] } [dev-dependencies] -test_bin = "0.4.0" \ No newline at end of file +test_bin = "0.4.0" + +[features] +arbitrary = [ "dep:arbitrary", "domain/arbitrary" ] \ No newline at end of file diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 00000000..1a45eee7 --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1,4 @@ +target +corpus +artifacts +coverage diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock new file mode 100644 index 00000000..3a51f621 --- /dev/null +++ b/fuzz/Cargo.lock @@ -0,0 +1,1122 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "cc" +version = "1.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dnst" +version = "0.1.0" +dependencies = [ + "arbitrary", + "clap", + "domain", +] + +[[package]] +name = "dnst-fuzz" +version = "0.0.0" +dependencies = [ + "arbitrary", + "dnst", + "libfuzzer-sys", +] + +[[package]] +name = "domain" +version = "0.10.3" +source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#f2cabc37eff3d85a42058180319926376604b7f6" +dependencies = [ + "arbitrary", + "bytes", + "futures-util", + "hashbrown", + "moka", + "octseq", + "rand", + "ring", + "serde", + "time", + "tokio", + "tracing", +] + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "allocator-api2", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "moka" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" +dependencies = [ + "async-lock", + "async-trait", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener", + "futures-util", + "once_cell", + "parking_lot", + "quanta", + "rustc_version", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "octseq" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126c3ca37c9c44cec575247f43a3e4374d8927684f129d2beeb0d2cef262fe12" +dependencies = [ + "bytes", + "serde", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "raw-cpuid" +version = "11.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.214" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.214" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "thiserror" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "tokio" +version = "1.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +dependencies = [ + "getrandom", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 00000000..7bb1bcf6 --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "dnst-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +arbitrary = "1.4.1" +libfuzzer-sys = "0.4" +dnst = { path = "..", features = ["arbitrary"] } + +[[bin]] +name = "nsec3-hash" +path = "fuzz_targets/nsec3-hash.rs" +test = false +doc = false +bench = false diff --git a/fuzz/fuzz_targets/nsec3-hash.rs b/fuzz/fuzz_targets/nsec3-hash.rs new file mode 100644 index 00000000..81bfb4b4 --- /dev/null +++ b/fuzz/fuzz_targets/nsec3-hash.rs @@ -0,0 +1,9 @@ +#![no_main] + +use libfuzzer_sys::fuzz_target; + +use dnst::commands::nsec3hash::Nsec3Hash; + +fuzz_target!(|cmd: Nsec3Hash| { + let _ = cmd.execute(); +}); diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 9a0a5a37..efa48ff2 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -9,6 +9,7 @@ use domain::validate::nsec3_hash; use crate::error::Error; #[derive(Clone, Debug, clap::Args)] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct Nsec3Hash { /// The hashing algorithm to use #[arg( From 592410b3da0bb7a356202214078fae37d9820419 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 10:40:23 +0100 Subject: [PATCH 21/47] Replace expect() with map_err()?. --- src/commands/nsec3hash.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index efa48ff2..b63da834 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -73,7 +73,7 @@ impl Nsec3Hash { pub fn execute(self) -> Result<(), Error> { let hash = nsec3_hash::<_, _, Vec>(&self.name, self.algorithm, self.iterations, &self.salt) - .expect("Error creating NSEC3 hash") + .map_err(|err| format!("Error creating NSEC3 hash: {err}"))? .to_string() .to_lowercase(); println!("{}.", hash); From e125524afd14c921b543f2396a834a930a6010b7 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:31:21 +0100 Subject: [PATCH 22/47] Add a fuzz testing readme. --- fuzz/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 fuzz/README.md diff --git a/fuzz/README.md b/fuzz/README.md new file mode 100644 index 00000000..98abeffd --- /dev/null +++ b/fuzz/README.md @@ -0,0 +1,13 @@ +`dnst` fuzz testing with cargo-fuzz and libfuzzer + +# tl;dr + +For example, fuzz test the nsec3-hash subcommand for 10 minutes using 8 concurrent jobs: + +``` +cargo +nightly fuzz run nsec3-hash -- -jobs=8 -max_total_time=600 -print_final_stats +``` + +# Further reading + +https://rust-fuzz.github.io/book/introduction.html \ No newline at end of file From c35f9cf705d0a834ea2c39334a9fce1d3027667b Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:49:56 +0100 Subject: [PATCH 23/47] Fix fuzz command. --- fuzz/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzz/README.md b/fuzz/README.md index 98abeffd..4c27916b 100644 --- a/fuzz/README.md +++ b/fuzz/README.md @@ -5,7 +5,7 @@ For example, fuzz test the nsec3-hash subcommand for 10 minutes using 8 concurrent jobs: ``` -cargo +nightly fuzz run nsec3-hash -- -jobs=8 -max_total_time=600 -print_final_stats +cargo +nightly fuzz run nsec3-hash -- -jobs=8 -max_total_time=600 -print_final_stats=1 ``` # Further reading From a3bdf63f7801cb79c92bb63efbef6a6377496923 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:00:43 +0100 Subject: [PATCH 24/47] Added some unit tests. Made the output written to configurable so that tests don't write to stdout. --- src/args.rs | 6 +- src/commands/mod.rs | 7 ++- src/commands/nsec3hash.rs | 122 +++++++++++++++++++++++++++++++++++++- src/main.rs | 2 +- 4 files changed, 128 insertions(+), 9 deletions(-) diff --git a/src/args.rs b/src/args.rs index 02a8725c..513eb699 100644 --- a/src/args.rs +++ b/src/args.rs @@ -1,3 +1,5 @@ +use std::io::Write; + use super::commands::Command; use super::error::Error; @@ -9,7 +11,7 @@ pub struct Args { } impl Args { - pub fn execute(self) -> Result<(), Error> { - self.command.execute() + pub fn execute(self, writer: &mut W) -> Result<(), Error> { + self.command.execute(writer) } } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 00c8f6eb..92f5a933 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,8 +1,9 @@ //! The command of _dnst_. - pub mod help; pub mod nsec3hash; +use std::io::Write; + use super::error::Error; #[derive(Clone, Debug, clap::Subcommand)] @@ -16,9 +17,9 @@ pub enum Command { } impl Command { - pub fn execute(self) -> Result<(), Error> { + pub fn execute(self, writer: &mut W) -> Result<(), Error> { match self { - Self::Nsec3Hash(nsec3hash) => nsec3hash.execute(), + Self::Nsec3Hash(nsec3hash) => nsec3hash.execute(writer), Self::Help(help) => help.execute(), } } diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index b63da834..5ed8d64c 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -1,3 +1,4 @@ +use std::io::Write; use std::str::FromStr; use clap::builder::ValueParser; @@ -70,13 +71,128 @@ impl Nsec3Hash { } impl Nsec3Hash { - pub fn execute(self) -> Result<(), Error> { + pub fn execute(self, writer: &mut W) -> Result<(), Error> { let hash = nsec3_hash::<_, _, Vec>(&self.name, self.algorithm, self.iterations, &self.salt) .map_err(|err| format!("Error creating NSEC3 hash: {err}"))? .to_string() .to_lowercase(); - println!("{}.", hash); - Ok(()) + writeln!(writer, "{}.", hash) + .map_err(|err| Error::from(format!("Error writing to output: {err}"))) + } +} + +// These are just basic tests as there is very little code in this module, the +// actual NSEC3 generation should be tested as part of the domain crate. See +// also: fuzz/fuzz_targets/nsec3-hash.rs. +#[cfg(test)] +mod tests { + use clap::Parser; + + use crate::Args; + + use super::*; + use core::str; + + // The types we use are provided by the domain crate and construction of + // them from bad inputs should be tested there. + #[test] + fn accept_good_inputs() { + // We don't test all permutations as that would take too long (~20 seconds) + for algorithm in ["SHA-1"] { + let algorithm = Nsec3HashAlg::from_mnemonic(algorithm.as_bytes()) + .expect(&format!("Algorithm '{algorithm}' was expected to be okay")); + let nsec3_hash = Nsec3Hash { + algorithm, + iterations: 0, + salt: Nsec3Salt::empty(), + name: Name::root(), + }; + nsec3_hash.execute(&mut std::io::sink()).unwrap(); + } + + for iterations in [0, 1, u16::MAX - 1, u16::MAX] { + let nsec3_hash = Nsec3Hash { + algorithm: Nsec3HashAlg::SHA1, + iterations, + salt: Nsec3Salt::empty(), + name: Name::root(), + }; + nsec3_hash.execute(&mut std::io::sink()).unwrap(); + } + + for salt in ["", "-", "aa", "aabb", "aa".repeat(255).as_str()] { + let salt = + Nsec3Salt::from_str(salt).expect(&format!("Salt '{salt}' was expected to be okay")); + let nsec3_hash = Nsec3Hash { + algorithm: Nsec3HashAlg::SHA1, + iterations: 0, + salt, + name: Name::root(), + }; + nsec3_hash.execute(&mut std::io::sink()).unwrap(); + } + + for name in [ + ".", "a", "a.", "ab", "ab.", "a.ab", "a.ab.", "ab.ab", "ab.ab.", "a.ab.ab", "a.ab.ab.", + ] { + let name = + Name::from_str(name).expect(&format!("Name '{name}' was expected to be okay")); + let nsec3_hash = Nsec3Hash { + algorithm: Nsec3HashAlg::SHA1, + iterations: 0, + salt: Nsec3Salt::empty(), + name, + }; + nsec3_hash.execute(&mut std::io::sink()).unwrap(); + } + } + + #[test] + fn reject_bad_inputs() { + assert_arg_parse_failure(&[]); + assert_arg_parse_failure(&[""]); + + assert_arg_parse_failure(&["-a"]); + assert_arg_parse_failure(&["-a", "nlnetlabs.nl"]); + assert_arg_parse_failure(&["-a", "", "nlnetlabs.nl"]); + assert_arg_parse_failure(&["-a", "2", "nlnetlabs.nl"]); + assert_arg_parse_failure(&["-a", "SHA-256", "nlnetlabs.nl"]); + + assert_arg_parse_failure(&["-t", "nlnetlabs.nl"]); + assert_arg_parse_failure(&["-t", "", "nlnetlabs.nl"]); + assert_arg_parse_failure(&["-t", "-1", "nlnetlabs.nl"]); + assert_arg_parse_failure(&["-t", "abc", "nlnetlabs.nl"]); + assert_arg_parse_failure(&["-t", &((u16::MAX as u32) + 1).to_string(), "nlnetlabs.nl"]); + + assert_arg_parse_failure(&["-s"]); + assert_arg_parse_failure(&["-s", "nlnetlabs.nl"]); + assert_arg_parse_failure(&["-s", "NOTHEX", "nlnetlabs.nl"]); + assert_arg_parse_failure(&["-s", &"aa".repeat(256), "nlnetlabs.nl"]); + } + + #[test] + fn check_defaults() { + // Equivalent to ldns-nsec-hash -t 1 nlnetlabs.nl + let args = parse_cmd_line(&["nlnetlabs.nl"]).unwrap(); + + let mut captured_stdout = vec![]; + assert!(args.execute(&mut captured_stdout).is_ok()); + assert_eq!( + str::from_utf8(&captured_stdout), + Ok("e3dbcbo05tvq0u7po4emvbu79c8vpcgk.\n") + ); + } + + //------------ Helper functions ------------------------------------------ + + fn parse_cmd_line(args: &[&str]) -> Result { + Args::try_parse_from(["dnst", "nsec3-hash"].iter().chain(args)) + } + + fn assert_arg_parse_failure(args: &[&str]) { + if parse_cmd_line(args).is_ok() { + panic!("Expected error with arguments: {args:?}"); + } } } diff --git a/src/main.rs b/src/main.rs index 46f745be..c8a8be22 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use clap::Parser; fn main() { // TODO: Exit with code 1 on CLI args error when run as ldns-nsec3-hash, // not code 2 as Clap does by default. - if let Err(err) = dnst::Args::parse().execute() { + if let Err(err) = dnst::Args::parse().execute(&mut std::io::stdout()) { eprintln!("{}", err); } } From e62938853ec3b9d2d1eab37f3b6e215d0408fa52 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:22:53 +0100 Subject: [PATCH 25/47] Extend the integration test to compare exit codes, and also to give a more human readable error message on test failure. --- tests/vs-ldns.rs | 57 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index 8cdb7d41..97973036 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -19,6 +19,8 @@ fn nsec3_hash() { &["-t", &iterations.to_string(), "example.com"], ); } + + assert_exit_code_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &[]); } fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) { @@ -30,15 +32,60 @@ fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) .output() .unwrap(); - assert_eq!(std::str::from_utf8(&ldns_output.stderr), Ok("")); - assert_eq!(std::str::from_utf8(&dnst_output.stderr), Ok("")); - assert!(!ldns_output.stdout.is_empty()); - assert!(!dnst_output.stdout.is_empty()); + assert_eq!( + std::str::from_utf8(&ldns_output.stderr), + Ok(""), + "Unexpected stderr content for command: {ldns_command} {}", + args.join(" ") + ); + assert_eq!( + std::str::from_utf8(&dnst_output.stderr), + Ok(""), + "Unexpected stderr content for command: {dnst_subcommand} {}", + args.join(" ") + ); + assert!( + !ldns_output.stdout.is_empty(), + "Unexpected stdout content for command: {ldns_command} {}: {:?}", + args.join(" "), + std::str::from_utf8(&ldns_output.stdout) + ); + assert!( + !dnst_output.stdout.is_empty(), + "Unexpected stdout content for command: {dnst_subcommand} {}: {:?}", + args.join(" "), + std::str::from_utf8(&dnst_output.stdout) + ); + assert_eq!( + ldns_output.status.code(), + dnst_output.status.code(), + "Exit code mismatch for command: {ldns_command}/{dnst_subcommand} {}", + args.join(" ") + ); // This will only work for LDNS commands whose output we are able to // replicate exactly. assert_eq!( std::str::from_utf8(&ldns_output.stdout), - std::str::from_utf8(&dnst_output.stdout) + std::str::from_utf8(&dnst_output.stdout), + "Stdout content mismatch for command: {ldns_command}/{dnst_subcommand} {}", + args.join(" ") + ); +} + +fn assert_exit_code_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) { + let ldns_output = Command::new(ldns_command).args(args).output().unwrap(); + + let dnst_output = test_bin::get_test_bin("dnst") + .arg(dnst_subcommand) + .args(args) + .output() + .unwrap(); + + assert_eq!( + ldns_output.status.code(), + dnst_output.status.code(), + "Exit code mismatch for command: {ldns_command}/{dnst_subcommand} {}", + args.join(" ") ); } From 39fb4cfb32d9f68c32bc0dd02c645b00b8880b55 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:29:44 +0100 Subject: [PATCH 26/47] Clippy. --- src/commands/nsec3hash.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 5ed8d64c..2daddfd9 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -99,9 +99,10 @@ mod tests { #[test] fn accept_good_inputs() { // We don't test all permutations as that would take too long (~20 seconds) + #[allow(clippy::single_element_loop)] for algorithm in ["SHA-1"] { let algorithm = Nsec3HashAlg::from_mnemonic(algorithm.as_bytes()) - .expect(&format!("Algorithm '{algorithm}' was expected to be okay")); + .unwrap_or_else(|| panic!("Algorithm '{algorithm}' was expected to be okay")); let nsec3_hash = Nsec3Hash { algorithm, iterations: 0, @@ -122,8 +123,8 @@ mod tests { } for salt in ["", "-", "aa", "aabb", "aa".repeat(255).as_str()] { - let salt = - Nsec3Salt::from_str(salt).expect(&format!("Salt '{salt}' was expected to be okay")); + let salt = Nsec3Salt::from_str(salt) + .unwrap_or_else(|err| panic!("Salt '{salt}' was expected to be okay: {err}")); let nsec3_hash = Nsec3Hash { algorithm: Nsec3HashAlg::SHA1, iterations: 0, @@ -136,8 +137,8 @@ mod tests { for name in [ ".", "a", "a.", "ab", "ab.", "a.ab", "a.ab.", "ab.ab", "ab.ab.", "a.ab.ab", "a.ab.ab.", ] { - let name = - Name::from_str(name).expect(&format!("Name '{name}' was expected to be okay")); + let name = Name::from_str(name) + .unwrap_or_else(|err| panic!("Name '{name}' was expected to be okay: {err}")); let nsec3_hash = Nsec3Hash { algorithm: Nsec3HashAlg::SHA1, iterations: 0, From 4e73709d7049122a2b853fbc15c1264ec57e0025 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:31:09 +0100 Subject: [PATCH 27/47] Inlcude the dnst binary name in the error mesage. --- tests/vs-ldns.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index 97973036..c150c793 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -41,7 +41,7 @@ fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) assert_eq!( std::str::from_utf8(&dnst_output.stderr), Ok(""), - "Unexpected stderr content for command: {dnst_subcommand} {}", + "Unexpected stderr content for command: dnst {dnst_subcommand} {}", args.join(" ") ); assert!( @@ -52,14 +52,14 @@ fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) ); assert!( !dnst_output.stdout.is_empty(), - "Unexpected stdout content for command: {dnst_subcommand} {}: {:?}", + "Unexpected stdout content for command: dnst {dnst_subcommand} {}: {:?}", args.join(" "), std::str::from_utf8(&dnst_output.stdout) ); assert_eq!( ldns_output.status.code(), dnst_output.status.code(), - "Exit code mismatch for command: {ldns_command}/{dnst_subcommand} {}", + "Exit code mismatch for command: {ldns_command}/dnst {dnst_subcommand} {}", args.join(" ") ); @@ -68,7 +68,7 @@ fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) assert_eq!( std::str::from_utf8(&ldns_output.stdout), std::str::from_utf8(&dnst_output.stdout), - "Stdout content mismatch for command: {ldns_command}/{dnst_subcommand} {}", + "Stdout content mismatch for command: {ldns_command}/dnst {dnst_subcommand} {}", args.join(" ") ); } @@ -85,7 +85,7 @@ fn assert_exit_code_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args assert_eq!( ldns_output.status.code(), dnst_output.status.code(), - "Exit code mismatch for command: {ldns_command}/{dnst_subcommand} {}", + "Exit code mismatch for command: {ldns_command}/dnst {dnst_subcommand} {}", args.join(" ") ); } From 44952795556aacfd9c4095a81018d5ed31d16027 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Mon, 11 Nov 2024 22:58:11 +0100 Subject: [PATCH 28/47] Minor fixes and tweaks. Use 0 extra iterations by default in dnst, but 1 for backward compatibility when invoked as ldns-nsec3-hash. --- src/commands/nsec3hash.rs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 51862326..131a6358 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -17,31 +17,36 @@ use super::{parse_os, parse_os_with, LdnsCommand}; pub struct Nsec3Hash { /// The hashing algorithm to use #[arg( - long, + long = "algorithm", short = 'a', - value_name = "algorithm", + value_name = "NUMBER OR MNEMONIC", default_value = "SHA-1", value_parser = ValueParser::new(Nsec3Hash::parse_nsec3_alg) )] algorithm: Nsec3HashAlg, /// The number of hash iterations - // TODO: Default to 0 when run as dnst instead of as ldns-nsec3-hash - #[arg(long, short = 't', value_name = "number", default_value_t = 1)] + #[arg( + long = "iterations", + short = 'i', + visible_short_alias = 't', + value_name = "NUMBER", + default_value_t = 0 + )] iterations: u16, /// The salt in hex representation #[arg( - long, + long = "salt", short = 's', - value_name = "string", + value_name = "HEX STRING", default_value_t = Nsec3Salt::empty(), value_parser = ValueParser::new(Nsec3Hash::parse_salt) )] salt: Nsec3Salt>, /// The domain name to hash - #[arg(value_name = "domain name", value_parser = ValueParser::new(Nsec3Hash::parse_name))] + #[arg(value_name = "DOMAIN NAME", value_parser = ValueParser::new(Nsec3Hash::parse_name))] name: Name>, } @@ -51,7 +56,7 @@ ldns-nsec3-hash [OPTIONS] -a hashing algorithm number -t iterations - -s salt in hex\ + -s salt in hex "; impl LdnsCommand for Nsec3Hash { @@ -112,6 +117,8 @@ impl Nsec3Hash { Name::from_str(&arg.to_lowercase()) } + // Note: This function is only necessary until + // https://github.com/NLnetLabs/domain/pull/431 is merged. pub fn parse_salt(arg: &str) -> Result>, Error> { if arg.len() >= 512 { Err(Error::from("Salt too long")) @@ -238,14 +245,14 @@ mod tests { #[test] fn check_defaults() { - // Equivalent to ldns-nsec-hash -t 1 nlnetlabs.nl + // Equivalent to ldns-nsec3-hash -t 0 nlnetlabs.nl let args = parse_cmd_line(&["nlnetlabs.nl"]).unwrap(); let mut captured_stdout = vec![]; assert!(args.execute(&mut captured_stdout).is_ok()); assert_eq!( str::from_utf8(&captured_stdout), - Ok("e3dbcbo05tvq0u7po4emvbu79c8vpcgk.\n") + Ok("asqe4ap6479d7085ljcs10a2fpb2do94.\n") ); } From 0d5434d315eabda9e77ed2347491c11660badf97 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Mon, 11 Nov 2024 23:11:29 +0100 Subject: [PATCH 29/47] Cargo fmt. --- src/commands/nsec3hash.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 131a6358..be13d688 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -117,8 +117,8 @@ impl Nsec3Hash { Name::from_str(&arg.to_lowercase()) } - // Note: This function is only necessary until - // https://github.com/NLnetLabs/domain/pull/431 is merged. + // Note: This function is only necessary until + // https://github.com/NLnetLabs/domain/pull/431 is merged. pub fn parse_salt(arg: &str) -> Result>, Error> { if arg.len() >= 512 { Err(Error::from("Salt too long")) From 0d3ef7e17a347e4e890fe9e7c025dc6017648a22 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Mon, 11 Nov 2024 23:51:41 +0100 Subject: [PATCH 30/47] Compare dnst as ldns to ldns using symbolic linking. --- Cargo.lock | 49 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + tests/vs-ldns.rs | 65 +++++++++++++++++++++++++++--------------------- 3 files changed, 86 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e18065a..43e60193 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,6 +270,7 @@ dependencies = [ "clap", "domain", "lexopt", + "tempfile", "test_bin", ] @@ -292,6 +293,16 @@ dependencies = [ "tracing", ] +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "event-listener" version = "5.3.1" @@ -313,6 +324,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "fastrand" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" + [[package]] name = "futures-core" version = "0.3.31" @@ -415,6 +432,12 @@ version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "lock_api" version = "0.4.12" @@ -680,6 +703,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -772,6 +808,19 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" +[[package]] +name = "tempfile" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +dependencies = [ + "cfg-if", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "test_bin" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index fc4c94fc..ddc05c3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ lexopt = "0.3.0" [dev-dependencies] test_bin = "0.4.0" +tempfile = "3.14.0" [features] arbitrary = [ "dep:arbitrary", "domain/arbitrary" ] \ No newline at end of file diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index c150c793..6f6126f2 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -1,65 +1,74 @@ use std::process::Command; +use tempfile::TempDir; #[ignore = "should only be run if ldns command line tools are installed"] #[test] fn nsec3_hash() { - assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["example.com"]); - assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-a", "1", "example.com"]); - assert_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &["-s", "", "example.com"]); - assert_ldns_eq_dnst( - "ldns-nsec3-hash", - "nsec3-hash", - &["-s", "DEADBEEF", "example.com"], - ); + assert_ldns_eq_dnst("ldns-nsec3-hash", &["example.com"]); + assert_ldns_eq_dnst("ldns-nsec3-hash", &["-a", "1", "example.com"]); + assert_ldns_eq_dnst("ldns-nsec3-hash", &["-s", "", "example.com"]); + assert_ldns_eq_dnst("ldns-nsec3-hash", &["-s", "DEADBEEF", "example.com"]); for iterations in 0..10 { assert_ldns_eq_dnst( "ldns-nsec3-hash", - "nsec3-hash", &["-t", &iterations.to_string(), "example.com"], ); } - assert_exit_code_ldns_eq_dnst("ldns-nsec3-hash", "nsec3-hash", &[]); + assert_exit_code_ldns_eq_dnst("ldns-nsec3-hash", &[]); +} + +fn create_temp_symlink(ldns_command: &str) -> std::path::PathBuf { + let bin_cmd = test_bin::get_test_bin("dnst"); + let bin_path = bin_cmd.get_program(); + let link_path = TempDir::new() + .expect("Failed to create temporary directory") + .into_path() + .join(ldns_command); + std::os::unix::fs::symlink(bin_path, link_path.clone()).expect(&format!( + "Failed to create symbolic link {} -> {}", + link_path.display(), + bin_path.to_str().unwrap(), + )); + link_path } -fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) { +fn assert_ldns_eq_dnst(ldns_command: &str, args: &[&str]) { let ldns_output = Command::new(ldns_command).args(args).output().unwrap(); - let dnst_output = test_bin::get_test_bin("dnst") - .arg(dnst_subcommand) - .args(args) - .output() - .unwrap(); + let dnst_as_ldns_bin = create_temp_symlink(ldns_command); + + let dnst_output = Command::new(dnst_as_ldns_bin).args(args).output().unwrap(); assert_eq!( std::str::from_utf8(&ldns_output.stderr), Ok(""), - "Unexpected stderr content for command: {ldns_command} {}", + "Unexpected stderr content for ldns command: {ldns_command} {}", args.join(" ") ); assert_eq!( std::str::from_utf8(&dnst_output.stderr), Ok(""), - "Unexpected stderr content for command: dnst {dnst_subcommand} {}", + "Unexpected stderr content for dnst command: {ldns_command} {}", args.join(" ") ); assert!( !ldns_output.stdout.is_empty(), - "Unexpected stdout content for command: {ldns_command} {}: {:?}", + "Unexpected stdout content for ldns command: {ldns_command} {}: {:?}", args.join(" "), std::str::from_utf8(&ldns_output.stdout) ); assert!( !dnst_output.stdout.is_empty(), - "Unexpected stdout content for command: dnst {dnst_subcommand} {}: {:?}", + "Unexpected stdout content for dnst command: {ldns_command} {}: {:?}", args.join(" "), std::str::from_utf8(&dnst_output.stdout) ); assert_eq!( ldns_output.status.code(), dnst_output.status.code(), - "Exit code mismatch for command: {ldns_command}/dnst {dnst_subcommand} {}", + "Exit code mismatch for command: {ldns_command} {}", args.join(" ") ); @@ -68,24 +77,22 @@ fn assert_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) assert_eq!( std::str::from_utf8(&ldns_output.stdout), std::str::from_utf8(&dnst_output.stdout), - "Stdout content mismatch for command: {ldns_command}/dnst {dnst_subcommand} {}", + "Stdout content mismatch for command: {ldns_command} {}", args.join(" ") ); } -fn assert_exit_code_ldns_eq_dnst(ldns_command: &str, dnst_subcommand: &str, args: &[&str]) { +fn assert_exit_code_ldns_eq_dnst(ldns_command: &str, args: &[&str]) { let ldns_output = Command::new(ldns_command).args(args).output().unwrap(); - let dnst_output = test_bin::get_test_bin("dnst") - .arg(dnst_subcommand) - .args(args) - .output() - .unwrap(); + let dnst_as_ldns_bin = create_temp_symlink(ldns_command); + + let dnst_output = Command::new(dnst_as_ldns_bin).args(args).output().unwrap(); assert_eq!( ldns_output.status.code(), dnst_output.status.code(), - "Exit code mismatch for command: {ldns_command}/dnst {dnst_subcommand} {}", + "Exit code mismatch for command: {ldns_command} {}", args.join(" ") ); } From 3932d4dd6fd38ea6c0883f373ab59775209c3a8c Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Mon, 11 Nov 2024 23:52:36 +0100 Subject: [PATCH 31/47] Clippy. --- tests/vs-ldns.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index 6f6126f2..60271348 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -26,11 +26,13 @@ fn create_temp_symlink(ldns_command: &str) -> std::path::PathBuf { .expect("Failed to create temporary directory") .into_path() .join(ldns_command); - std::os::unix::fs::symlink(bin_path, link_path.clone()).expect(&format!( - "Failed to create symbolic link {} -> {}", - link_path.display(), - bin_path.to_str().unwrap(), - )); + std::os::unix::fs::symlink(bin_path, link_path.clone()).unwrap_or_else(|_| { + panic!( + "Failed to create symbolic link {} -> {}", + link_path.display(), + bin_path.to_str().unwrap(), + ) + }); link_path } From b5908231ce95f51c2ae03e313e07fe071afd6040 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Mon, 11 Nov 2024 23:56:11 +0100 Subject: [PATCH 32/47] Integration test is unix only. --- tests/vs-ldns.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index 60271348..14570f9e 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -1,3 +1,4 @@ +#![cfg(unix)] use std::process::Command; use tempfile::TempDir; From b60280dd1009d8c9e07830c9576c28234be01f41 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:24:44 +0100 Subject: [PATCH 33/47] Make help text more closely match the actual ldns-nsec3-hash output. --- src/commands/nsec3hash.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index be13d688..ff12d2a3 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -53,10 +53,9 @@ pub struct Nsec3Hash { const LDNS_HELP: &str = "\ ldns-nsec3-hash [OPTIONS] prints the NSEC3 hash of the given domain name - - -a hashing algorithm number - -t iterations - -s salt in hex +-a [algorithm] hashing algorithm +-t [number] number of hash iterations +-s [string] salt "; impl LdnsCommand for Nsec3Hash { From 20b4e29fba6dcc7ba99252123a38ba2e47232884 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 12 Nov 2024 12:50:16 +0100 Subject: [PATCH 34/47] Add ldns-nsec3-hash man page based on the original, and adjust the dnst-nsec3-hash page to match the current help output of the command. --- doc/manual/source/conf.py | 4 ++-- doc/manual/source/man/dnst-nsec3-hash.rst | 18 +++++++------- doc/manual/source/man/ldns-nsec3-hash.rst | 29 +++++++++++++++++++++++ ldns-nsec3-hash | 1 + 4 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 doc/manual/source/man/ldns-nsec3-hash.rst create mode 120000 ldns-nsec3-hash diff --git a/doc/manual/source/conf.py b/doc/manual/source/conf.py index ffa9b5d4..56e04bdf 100644 --- a/doc/manual/source/conf.py +++ b/doc/manual/source/conf.py @@ -189,8 +189,8 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('man/dnst', 'dnst', 'DNS Management Tools', author, 1), - ('man/dnst-nsec3-hash', 'dnst-nsec3-hash', 'DNS Management Tools', author, - 1), + ('man/dnst-nsec3-hash', 'dnst-nsec3-hash', 'print out the NSEC3 hash for a domain name', author, 1), + ('man/ldns-nsec3-hash', 'ldns-nsec3-hash', 'print out the NSEC3 hash for a domain name', author, 1), ] diff --git a/doc/manual/source/man/dnst-nsec3-hash.rst b/doc/manual/source/man/dnst-nsec3-hash.rst index 20014476..9f675c76 100644 --- a/doc/manual/source/man/dnst-nsec3-hash.rst +++ b/doc/manual/source/man/dnst-nsec3-hash.rst @@ -4,27 +4,27 @@ dnst-nsec3-hash Synopsis -------- -:program:`dnst nsec3-hash` [``options``] :samp:`domain-name` +:program:`dnst nsec3-hash` [``OPTIONS``] :samp:`` Description ----------- -**dnst nsec3-hash** prints the NSEC3 hash for the given domain name. +**dnst nsec3-hash** prints the NSEC3 hash of a given domain name. Options ------- -.. option:: -a number-or-mnemonic, --algorithm=number-or-mnemonic +.. option:: -a , --algorithm Use the given algorithm number for the hash calculation. Defaults to - ``sha1``. + 1 (SHA-1). -.. option:: -s salt, --salt=count +.. option:: -i , -t , --iterations - Use the given salt for the hash calculation. The salt value should be - in hexadecimal format. + Use the given number of additional iterations for the hash calculation. -.. option:: -i count, -t count, --iterations=count +.. option:: -s >, --salt > - Use *count* iterations for the hash calculation. + Use the given salt for the hash calculation. The salt value should be + in hexadecimal format. diff --git a/doc/manual/source/man/ldns-nsec3-hash.rst b/doc/manual/source/man/ldns-nsec3-hash.rst new file mode 100644 index 00000000..20c16e66 --- /dev/null +++ b/doc/manual/source/man/ldns-nsec3-hash.rst @@ -0,0 +1,29 @@ +ldns-nsec3-hash +=============== + +Synopsis +-------- + +:program:`ldns-nsec3-hash` :samp:`<{domain-name}>` + +Description +----------- + +**ldns-nsec3-hash** is used to print out the NSEC3 hash for the given domain name. + +Options +------- + +.. option:: -a number + + Use the given algorithm number for the hash calculation. Defaults to + 1 (SHA-1). + +.. option:: -s salt + + Use the given salt for the hash calculation. The salt value should be + in hexadecimal format. + +.. option:: -t count + + Use count iterations for the hash calculation. diff --git a/ldns-nsec3-hash b/ldns-nsec3-hash new file mode 120000 index 00000000..a780d580 --- /dev/null +++ b/ldns-nsec3-hash @@ -0,0 +1 @@ +target/release/dnst \ No newline at end of file From 19e95a52db4d711b72f3de01b6e1ad0baafe4c13 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:22:41 +0100 Subject: [PATCH 35/47] Don't test with sym link in integration test, do that later in Ploutos packaging. --- Cargo.lock | 49 --------------- Cargo.toml | 1 - tests/vs-ldns.rs | 155 ++++++++++++++++++++++++++--------------------- 3 files changed, 85 insertions(+), 120 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 43e60193..6e18065a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,7 +270,6 @@ dependencies = [ "clap", "domain", "lexopt", - "tempfile", "test_bin", ] @@ -293,16 +292,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "event-listener" version = "5.3.1" @@ -324,12 +313,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fastrand" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" - [[package]] name = "futures-core" version = "0.3.31" @@ -432,12 +415,6 @@ version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - [[package]] name = "lock_api" version = "0.4.12" @@ -703,19 +680,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.38.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -808,19 +772,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" -[[package]] -name = "tempfile" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" -dependencies = [ - "cfg-if", - "fastrand", - "once_cell", - "rustix", - "windows-sys 0.59.0", -] - [[package]] name = "test_bin" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index ddc05c3c..fc4c94fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ lexopt = "0.3.0" [dev-dependencies] test_bin = "0.4.0" -tempfile = "3.14.0" [features] arbitrary = [ "dep:arbitrary", "domain/arbitrary" ] \ No newline at end of file diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index 14570f9e..6a8d82de 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -1,101 +1,116 @@ -#![cfg(unix)] use std::process::Command; -use tempfile::TempDir; + +const TEST_ZONE_NAME: &str = "nlnetlabs.nl"; +const LDNS_NSEC3_CMD: &str = "ldns-nsec3-hash"; +const DNST_NSEC3_SUBCMD: &str = "nsec3-hash"; #[ignore = "should only be run if ldns command line tools are installed"] #[test] fn nsec3_hash() { - assert_ldns_eq_dnst("ldns-nsec3-hash", &["example.com"]); - assert_ldns_eq_dnst("ldns-nsec3-hash", &["-a", "1", "example.com"]); - assert_ldns_eq_dnst("ldns-nsec3-hash", &["-s", "", "example.com"]); - assert_ldns_eq_dnst("ldns-nsec3-hash", &["-s", "DEADBEEF", "example.com"]); + // Note: ldns-nsec3-hash defaults NSEC3 iterations to 1, while dnst + // nsec-hash defaults NSEC3 iterations to 0. + assert_cmds_eq( + &[LDNS_NSEC3_CMD, TEST_ZONE_NAME], + &[DNST_NSEC3_SUBCMD, "--iterations", "1", TEST_ZONE_NAME], + ); + assert_cmds_eq( + &[LDNS_NSEC3_CMD, TEST_ZONE_NAME, "-t", "0"], + &[DNST_NSEC3_SUBCMD, TEST_ZONE_NAME], + ); + assert_cmds_eq( + &[LDNS_NSEC3_CMD, "-a", "1", TEST_ZONE_NAME], + &[ + DNST_NSEC3_SUBCMD, + "--iterations", + "1", + "--algorithm", + "1", + TEST_ZONE_NAME, + ], + ); + assert_cmds_eq( + &[LDNS_NSEC3_CMD, "-s", "", TEST_ZONE_NAME], + &[ + DNST_NSEC3_SUBCMD, + "--iterations", + "1", + "--salt", + "", + TEST_ZONE_NAME, + ], + ); + assert_cmds_eq( + &[LDNS_NSEC3_CMD, "-s", "DEADBEEF", TEST_ZONE_NAME], + &[ + DNST_NSEC3_SUBCMD, + "--iterations", + "1", + "--salt", + "DEADBEEF", + TEST_ZONE_NAME, + ], + ); for iterations in 0..10 { - assert_ldns_eq_dnst( - "ldns-nsec3-hash", - &["-t", &iterations.to_string(), "example.com"], + assert_cmds_eq( + &[ + LDNS_NSEC3_CMD, + "-t", + &iterations.to_string(), + TEST_ZONE_NAME, + ], + &[ + DNST_NSEC3_SUBCMD, + "-i", + &iterations.to_string(), + TEST_ZONE_NAME, + ], ); } - - assert_exit_code_ldns_eq_dnst("ldns-nsec3-hash", &[]); -} - -fn create_temp_symlink(ldns_command: &str) -> std::path::PathBuf { - let bin_cmd = test_bin::get_test_bin("dnst"); - let bin_path = bin_cmd.get_program(); - let link_path = TempDir::new() - .expect("Failed to create temporary directory") - .into_path() - .join(ldns_command); - std::os::unix::fs::symlink(bin_path, link_path.clone()).unwrap_or_else(|_| { - panic!( - "Failed to create symbolic link {} -> {}", - link_path.display(), - bin_path.to_str().unwrap(), - ) - }); - link_path } -fn assert_ldns_eq_dnst(ldns_command: &str, args: &[&str]) { - let ldns_output = Command::new(ldns_command).args(args).output().unwrap(); +fn assert_cmds_eq(cmd1: &[&str], cmd2: &[&str]) { + let cmd1_output = Command::new(&cmd1[0]).args(&cmd1[1..]).output().unwrap(); - let dnst_as_ldns_bin = create_temp_symlink(ldns_command); - - let dnst_output = Command::new(dnst_as_ldns_bin).args(args).output().unwrap(); + let cmd2_output = test_bin::get_test_bin("dnst").args(cmd2).output().unwrap(); assert_eq!( - std::str::from_utf8(&ldns_output.stderr), + std::str::from_utf8(&cmd1_output.stderr), Ok(""), - "Unexpected stderr content for ldns command: {ldns_command} {}", - args.join(" ") + "Unexpected stderr content for command: {}", + cmd1.join(" ") ); assert_eq!( - std::str::from_utf8(&dnst_output.stderr), + std::str::from_utf8(&cmd2_output.stderr), Ok(""), - "Unexpected stderr content for dnst command: {ldns_command} {}", - args.join(" ") + "Unexpected stderr content for command: {}", + cmd2.join(" ") ); assert!( - !ldns_output.stdout.is_empty(), - "Unexpected stdout content for ldns command: {ldns_command} {}: {:?}", - args.join(" "), - std::str::from_utf8(&ldns_output.stdout) + !cmd1_output.stdout.is_empty(), + "Unexpected stdout content for ldns command: {}: {:?}", + cmd1.join(" "), + std::str::from_utf8(&cmd1_output.stdout) ); assert!( - !dnst_output.stdout.is_empty(), - "Unexpected stdout content for dnst command: {ldns_command} {}: {:?}", - args.join(" "), - std::str::from_utf8(&dnst_output.stdout) + !cmd2_output.stdout.is_empty(), + "Unexpected stdout content for dnst command: {}: {:?}", + cmd2.join(" "), + std::str::from_utf8(&cmd2_output.stdout) ); assert_eq!( - ldns_output.status.code(), - dnst_output.status.code(), - "Exit code mismatch for command: {ldns_command} {}", - args.join(" ") + cmd1_output.status.code(), + cmd2_output.status.code(), + "Exit code mismatch for command: {}", + cmd1.join(" ") ); // This will only work for LDNS commands whose output we are able to // replicate exactly. assert_eq!( - std::str::from_utf8(&ldns_output.stdout), - std::str::from_utf8(&dnst_output.stdout), - "Stdout content mismatch for command: {ldns_command} {}", - args.join(" ") - ); -} - -fn assert_exit_code_ldns_eq_dnst(ldns_command: &str, args: &[&str]) { - let ldns_output = Command::new(ldns_command).args(args).output().unwrap(); - - let dnst_as_ldns_bin = create_temp_symlink(ldns_command); - - let dnst_output = Command::new(dnst_as_ldns_bin).args(args).output().unwrap(); - - assert_eq!( - ldns_output.status.code(), - dnst_output.status.code(), - "Exit code mismatch for command: {ldns_command} {}", - args.join(" ") + std::str::from_utf8(&cmd1_output.stdout), + std::str::from_utf8(&cmd2_output.stdout), + "Stdout content mismatch for command: {}", + cmd1.join(" ") ); } From 88809ae620da9e2adc237fb9e3b9c136fad484a8 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:23:57 +0100 Subject: [PATCH 36/47] Remove wrongly committed sym link. --- ldns-nsec3-hash | 1 - 1 file changed, 1 deletion(-) delete mode 120000 ldns-nsec3-hash diff --git a/ldns-nsec3-hash b/ldns-nsec3-hash deleted file mode 120000 index a780d580..00000000 --- a/ldns-nsec3-hash +++ /dev/null @@ -1 +0,0 @@ -target/release/dnst \ No newline at end of file From 456db2421e77a36aa37c49d49b4ddff5275f1695 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:26:30 +0100 Subject: [PATCH 37/47] Clippy. --- tests/vs-ldns.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index 6a8d82de..18c956a3 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -70,7 +70,7 @@ fn nsec3_hash() { } fn assert_cmds_eq(cmd1: &[&str], cmd2: &[&str]) { - let cmd1_output = Command::new(&cmd1[0]).args(&cmd1[1..]).output().unwrap(); + let cmd1_output = Command::new(cmd1[0]).args(&cmd1[1..]).output().unwrap(); let cmd2_output = test_bin::get_test_bin("dnst").args(cmd2).output().unwrap(); From 3c91c505bb5da91c65cc489adb3cddc11f38f1bd Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Tue, 12 Nov 2024 20:28:54 +0100 Subject: [PATCH 38/47] Update dnst-nsec3-hash.rst Co-authored-by: Jannik --- doc/manual/source/man/dnst-nsec3-hash.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/source/man/dnst-nsec3-hash.rst b/doc/manual/source/man/dnst-nsec3-hash.rst index 9f675c76..56e093ba 100644 --- a/doc/manual/source/man/dnst-nsec3-hash.rst +++ b/doc/manual/source/man/dnst-nsec3-hash.rst @@ -23,7 +23,7 @@ Options Use the given number of additional iterations for the hash calculation. -.. option:: -s >, --salt > +.. option:: -s , --salt Use the given salt for the hash calculation. The salt value should be in hexadecimal format. From f9d7da46aa0538de0793382b5aaadbe2309e81f7 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:26:20 +0100 Subject: [PATCH 39/47] More tests and fix a couple of argument parsing bugs. Changes the call tree slightly to allow args to be parsed from within a module without knowing how arg parsing works for dnst vs ldns. --- src/bin/ldns.rs | 13 +- src/commands/nsec3hash.rs | 326 ++++++++++++++++++++++++++------------ src/lib.rs | 44 ++--- src/main.rs | 16 +- 4 files changed, 267 insertions(+), 132 deletions(-) diff --git a/src/bin/ldns.rs b/src/bin/ldns.rs index 543310c7..aa1c63ff 100644 --- a/src/bin/ldns.rs +++ b/src/bin/ldns.rs @@ -6,14 +6,11 @@ use std::process::ExitCode; +use dnst::error::Error; use dnst::try_ldns_compatibility; fn main() -> ExitCode { - let mut args = std::env::args_os(); - args.next().unwrap(); - let args = try_ldns_compatibility(args).expect("ldns commmand is not recognized"); - - match args.execute(&mut std::io::stdout()) { + match run() { Ok(()) => ExitCode::SUCCESS, Err(err) => { err.pretty_print(); @@ -21,3 +18,9 @@ fn main() -> ExitCode { } } } + +fn run() -> Result<(), Error> { + let mut args = std::env::args_os(); + args.next().unwrap(); + try_ldns_compatibility(args)?.execute(&mut std::io::stdout()) +} diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 88840485..11051648 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -74,11 +74,12 @@ impl LdnsCommand for Nsec3Hash { match arg { Arg::Short('a') => { let val = parser.value()?; - algorithm = parse_os_with("algorithm (-a)", &val, Nsec3Hash::parse_nsec3_alg)?; + algorithm = + parse_os_with("algorithm (-a)", &val, Nsec3Hash::parse_nsec3_alg_as_num)?; } Arg::Short('s') => { let val = parser.value()?; - salt = parse_os("salt (-s)", &val)?; + salt = parse_os_with("salt (-s)", &val, Nsec3Hash::parse_salt)?; } Arg::Short('t') => { let val = parser.value()?; @@ -129,16 +130,26 @@ impl Nsec3Hash { pub fn parse_nsec3_alg(arg: &str) -> Result { if let Ok(num) = arg.parse() { - let alg = Nsec3HashAlg::from_int(num); - if alg.to_mnemonic().is_some() { - Ok(alg) - } else { - Err("unknown algorithm number") - } + Self::num_to_nsec3_alg(num) } else { Nsec3HashAlg::from_mnemonic(arg.as_bytes()).ok_or("unknown algorithm mnemonic") } } + + pub fn parse_nsec3_alg_as_num(arg: &str) -> Result { + match arg.parse() { + Ok(num) => Self::num_to_nsec3_alg(num), + Err(_) => Err("malformed algorith number"), + } + } + + pub fn num_to_nsec3_alg(num: u8) -> Result { + let alg = Nsec3HashAlg::from_int(num); + match alg.to_mnemonic() { + Some(_) => Ok(alg), + None => Err("unknown algorithm number"), + } + } } impl Nsec3Hash { @@ -158,113 +169,224 @@ impl Nsec3Hash { // also: fuzz/fuzz_targets/nsec3-hash.rs. #[cfg(test)] mod tests { - use clap::Parser; - - use crate::Args; - - use super::*; - use core::str; - - // The types we use are provided by the domain crate and construction of - // them from bad inputs should be tested there. - #[test] - fn accept_good_inputs() { - // We don't test all permutations as that would take too long (~20 seconds) - #[allow(clippy::single_element_loop)] - for algorithm in ["SHA-1"] { - let algorithm = Nsec3HashAlg::from_mnemonic(algorithm.as_bytes()) - .unwrap_or_else(|| panic!("Algorithm '{algorithm}' was expected to be okay")); - let nsec3_hash = Nsec3Hash { - algorithm, - iterations: 0, - salt: Nsec3Salt::empty(), - name: Name::root(), - }; - nsec3_hash.execute(&mut std::io::sink()).unwrap(); + mod without_cli { + use core::str::FromStr; + + use domain::base::iana::Nsec3HashAlg; + use domain::base::Name; + use domain::rdata::nsec3::Nsec3Salt; + + use crate::commands::nsec3hash::Nsec3Hash; + + // Note: For the types we use that are provided by the domain crate, + // construction of them from bad inputs should be tested in that + // crate, not here. This test exercises the just the actual + // functionalty of this module without the outer layer of CLI argument + // parsing which is independent of whether we are invoked as `dnst + // nsec3-hash`` or as `ldns-nsec3-hash`. + #[test] + fn execute() { + // We don't test all permutations as that would take too long (~20 seconds) + #[allow(clippy::single_element_loop)] + for algorithm in ["SHA-1"] { + let algorithm = Nsec3HashAlg::from_mnemonic(algorithm.as_bytes()) + .unwrap_or_else(|| panic!("Algorithm '{algorithm}' was expected to be okay")); + let nsec3_hash = Nsec3Hash { + algorithm, + iterations: 0, + salt: Nsec3Salt::empty(), + name: Name::root(), + }; + nsec3_hash.execute(&mut std::io::sink()).unwrap(); + } + + for iterations in [0, 1, u16::MAX - 1, u16::MAX] { + let nsec3_hash = Nsec3Hash { + algorithm: Nsec3HashAlg::SHA1, + iterations, + salt: Nsec3Salt::empty(), + name: Name::root(), + }; + nsec3_hash.execute(&mut std::io::sink()).unwrap(); + } + + for salt in ["", "-", "aa", "aabb", "aa".repeat(255).as_str()] { + let salt = Nsec3Salt::from_str(salt) + .unwrap_or_else(|err| panic!("Salt '{salt}' was expected to be okay: {err}")); + let nsec3_hash = Nsec3Hash { + algorithm: Nsec3HashAlg::SHA1, + iterations: 0, + salt, + name: Name::root(), + }; + nsec3_hash.execute(&mut std::io::sink()).unwrap(); + } + + for name in [ + ".", "a", "a.", "ab", "ab.", "a.ab", "a.ab.", "ab.ab", "ab.ab.", "a.ab.ab", + "a.ab.ab.", + ] { + let name = Name::from_str(name) + .unwrap_or_else(|err| panic!("Name '{name}' was expected to be okay: {err}")); + let nsec3_hash = Nsec3Hash { + algorithm: Nsec3HashAlg::SHA1, + iterations: 0, + salt: Nsec3Salt::empty(), + name, + }; + nsec3_hash.execute(&mut std::io::sink()).unwrap(); + } } + } - for iterations in [0, 1, u16::MAX - 1, u16::MAX] { - let nsec3_hash = Nsec3Hash { - algorithm: Nsec3HashAlg::SHA1, - iterations, - salt: Nsec3Salt::empty(), - name: Name::root(), - }; - nsec3_hash.execute(&mut std::io::sink()).unwrap(); + mod with_dnst_cli { + use core::str; + + use crate::error::Error; + use crate::{parse_args, Args}; + + #[test] + fn accept_good_cli_args() { + assert_cmd_eq(&["nlnetlabs.nl"], "asqe4ap6479d7085ljcs10a2fpb2do94.\n"); + assert_cmd_eq( + &["-a", "1", "nlnetlabs.nl"], + "asqe4ap6479d7085ljcs10a2fpb2do94.\n", + ); + assert_cmd_eq( + &["-a", "SHA-1", "nlnetlabs.nl"], + "asqe4ap6479d7085ljcs10a2fpb2do94.\n", + ); + assert_cmd_eq( + &["-i", "0", "nlnetlabs.nl"], + "asqe4ap6479d7085ljcs10a2fpb2do94.\n", + ); + assert_cmd_eq( + &["-i", "1", "nlnetlabs.nl"], + "e3dbcbo05tvq0u7po4emvbu79c8vpcgk.\n", + ); + assert_cmd_eq( + &["-s", "", "nlnetlabs.nl"], + "asqe4ap6479d7085ljcs10a2fpb2do94.\n", + ); + assert_cmd_eq( + &["-s", "DEADBEEF", "nlnetlabs.nl"], + "dfucs7bmmtsil9gij77k1kmocclg5d8a.\n", + ); } - for salt in ["", "-", "aa", "aabb", "aa".repeat(255).as_str()] { - let salt = Nsec3Salt::from_str(salt) - .unwrap_or_else(|err| panic!("Salt '{salt}' was expected to be okay: {err}")); - let nsec3_hash = Nsec3Hash { - algorithm: Nsec3HashAlg::SHA1, - iterations: 0, - salt, - name: Name::root(), - }; - nsec3_hash.execute(&mut std::io::sink()).unwrap(); + #[test] + fn reject_bad_cli_args() { + assert!(parse_cmd_line(&[]).is_err()); + assert!(parse_cmd_line(&[""]).is_err()); + + assert!(parse_cmd_line(&["-a"]).is_err()); + assert!(parse_cmd_line(&["-a", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-a", "", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-a", "2", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-a", "SHA1", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-a", "SHA-256", "nlnetlabs.nl"]).is_err()); + + assert!(parse_cmd_line(&["-i"]).is_err()); + assert!(parse_cmd_line(&["-i", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-i", "", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-i", "-1", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-i", "abc", "nlnetlabs.nl"]).is_err()); + assert!( + parse_cmd_line(&["-i", &((u16::MAX as u32) + 1).to_string(), "nlnetlabs.nl"]) + .is_err() + ); + + assert!(parse_cmd_line(&["-s"]).is_err()); + assert!(parse_cmd_line(&["-s", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-s", "NOTHEX", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-s", &"aa".repeat(256), "nlnetlabs.nl"]).is_err()); } - for name in [ - ".", "a", "a.", "ab", "ab.", "a.ab", "a.ab.", "ab.ab", "ab.ab.", "a.ab.ab", "a.ab.ab.", - ] { - let name = Name::from_str(name) - .unwrap_or_else(|err| panic!("Name '{name}' was expected to be okay: {err}")); - let nsec3_hash = Nsec3Hash { - algorithm: Nsec3HashAlg::SHA1, - iterations: 0, - salt: Nsec3Salt::empty(), - name, - }; - nsec3_hash.execute(&mut std::io::sink()).unwrap(); + //------------ Helper functions ------------------------------------------ + + fn parse_cmd_line(args: &[&str]) -> Result { + parse_args(|| ["dnst", "nsec3-hash"].iter().chain(args).map(Into::into)) } - } - #[test] - fn reject_bad_inputs() { - assert_arg_parse_failure(&[]); - assert_arg_parse_failure(&[""]); - - assert_arg_parse_failure(&["-a"]); - assert_arg_parse_failure(&["-a", "nlnetlabs.nl"]); - assert_arg_parse_failure(&["-a", "", "nlnetlabs.nl"]); - assert_arg_parse_failure(&["-a", "2", "nlnetlabs.nl"]); - assert_arg_parse_failure(&["-a", "SHA-256", "nlnetlabs.nl"]); - - assert_arg_parse_failure(&["-t", "nlnetlabs.nl"]); - assert_arg_parse_failure(&["-t", "", "nlnetlabs.nl"]); - assert_arg_parse_failure(&["-t", "-1", "nlnetlabs.nl"]); - assert_arg_parse_failure(&["-t", "abc", "nlnetlabs.nl"]); - assert_arg_parse_failure(&["-t", &((u16::MAX as u32) + 1).to_string(), "nlnetlabs.nl"]); - - assert_arg_parse_failure(&["-s"]); - assert_arg_parse_failure(&["-s", "nlnetlabs.nl"]); - assert_arg_parse_failure(&["-s", "NOTHEX", "nlnetlabs.nl"]); - assert_arg_parse_failure(&["-s", &"aa".repeat(256), "nlnetlabs.nl"]); + fn assert_cmd_eq(args: &[&str], expected_output: &str) { + let parsed_args = parse_cmd_line(args).unwrap(); + let mut captured_stdout = vec![]; + parsed_args.execute(&mut captured_stdout).unwrap(); + assert_eq!(str::from_utf8(&captured_stdout), Ok(expected_output)); + } } - #[test] - fn check_defaults() { - // Equivalent to ldns-nsec3-hash -t 0 nlnetlabs.nl - let args = parse_cmd_line(&["nlnetlabs.nl"]).unwrap(); - - let mut captured_stdout = vec![]; - assert!(args.execute(&mut captured_stdout).is_ok()); - assert_eq!( - str::from_utf8(&captured_stdout), - Ok("asqe4ap6479d7085ljcs10a2fpb2do94.\n") - ); - } + mod with_ldns_cli { + use core::str; + + use crate::error::Error; + use crate::{parse_args, Args}; + + #[test] + fn accept_good_cli_args() { + assert_cmd_eq(&["nlnetlabs.nl"], "e3dbcbo05tvq0u7po4emvbu79c8vpcgk.\n"); + assert_cmd_eq( + &["-a", "1", "nlnetlabs.nl"], + "e3dbcbo05tvq0u7po4emvbu79c8vpcgk.\n", + ); + assert_cmd_eq( + &["-t", "0", "nlnetlabs.nl"], + "asqe4ap6479d7085ljcs10a2fpb2do94.\n", + ); + assert_cmd_eq( + &["-t", "1", "nlnetlabs.nl"], + "e3dbcbo05tvq0u7po4emvbu79c8vpcgk.\n", + ); + assert_cmd_eq( + &["-s", "", "nlnetlabs.nl"], + "e3dbcbo05tvq0u7po4emvbu79c8vpcgk.\n", + ); + assert_cmd_eq( + &["-s", "DEADBEEF", "nlnetlabs.nl"], + "2h8rboqdrq0ard25vrmc4hjg7m56hnhd.\n", + ); + } + + #[test] + fn reject_bad_cli_args() { + assert!(parse_cmd_line(&[]).is_err()); + assert!(parse_cmd_line(&[""]).is_err()); + + assert!(parse_cmd_line(&["-a"]).is_err()); + assert!(parse_cmd_line(&["-a", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-a", "", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-a", "2", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-a", "SHA1", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-a", "SHA-1", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-a", "SHA-256", "nlnetlabs.nl"]).is_err()); + + assert!(parse_cmd_line(&["-t"]).is_err()); + assert!(parse_cmd_line(&["-t", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-t", "", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-t", "-1", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-t", "abc", "nlnetlabs.nl"]).is_err()); + assert!( + parse_cmd_line(&["-t", &((u16::MAX as u32) + 1).to_string(), "nlnetlabs.nl"]) + .is_err() + ); + + assert!(parse_cmd_line(&["-s"]).is_err()); + assert!(parse_cmd_line(&["-s", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-s", "NOTHEX", "nlnetlabs.nl"]).is_err()); + assert!(parse_cmd_line(&["-s", &"aa".repeat(256), "nlnetlabs.nl"]).is_err()); + } - //------------ Helper functions ------------------------------------------ + //------------ Helper functions ------------------------------------------ - fn parse_cmd_line(args: &[&str]) -> Result { - Args::try_parse_from(["dnst", "nsec3-hash"].iter().chain(args)) - } + fn parse_cmd_line(args: &[&str]) -> Result { + parse_args(|| ["ldns-nsec3-hash"].iter().chain(args).map(Into::into)) + } - fn assert_arg_parse_failure(args: &[&str]) { - if parse_cmd_line(args).is_ok() { - panic!("Expected error with arguments: {args:?}"); + fn assert_cmd_eq(args: &[&str], expected_output: &str) { + let parsed_args = parse_cmd_line(args).unwrap(); + let mut captured_stdout = vec![]; + parsed_args.execute(&mut captured_stdout).unwrap(); + assert_eq!(str::from_utf8(&captured_stdout), Ok(expected_output)); } } } diff --git a/src/lib.rs b/src/lib.rs index a329971d..fc0298e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,29 +1,37 @@ +pub mod args; +pub mod commands; +pub mod error; + use std::{ffi::OsString, path::Path}; -use commands::{nsec3hash::Nsec3Hash, LdnsCommand}; +use clap::Parser; -pub use self::args::Args; +use args::Args; +use commands::{nsec3hash::Nsec3Hash, LdnsCommand}; +use error::Error; -pub mod args; -pub mod commands; -pub mod error; +pub fn parse_args, T: Fn() -> I>( + args_provider: T, +) -> Result { + try_ldns_compatibility(args_provider()).or_else(|_| { + Args::try_parse_from(args_provider()).map_err(|err| Error::new(err.to_string().as_str())) + }) +} -pub fn try_ldns_compatibility>(args: I) -> Option { +pub fn try_ldns_compatibility>(args: I) -> Result { let mut args_iter = args.into_iter(); - let binary_path = args_iter.next()?; + let binary_path = args_iter + .next() + .ok_or::("Missing binary name".into())?; - let binary_name = Path::new(&binary_path).file_name()?.to_str()?; + let binary_name = Path::new(&binary_path) + .file_name() + .ok_or::("Missing binary file name".into())? + .to_str() + .ok_or("Binary file name is not valid Unicode")?; - let res = match binary_name { + match binary_name { "ldns-nsec3-hash" => Nsec3Hash::parse_ldns_args(args_iter), - _ => return None, - }; - - match res { - Ok(args) => Some(args), - Err(err) => { - err.pretty_print(); - std::process::exit(1) - } + _ => Err("Unrecognised LDNS command".into()), } } diff --git a/src/main.rs b/src/main.rs index 69eb0f5f..e2ad42e9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,10 @@ use std::process::ExitCode; -use clap::Parser; +use dnst::error::Error; +use dnst::parse_args; fn main() -> ExitCode { - // If none of the ldns-* tools matched, then we continue with clap - // argument parsing. - let env_args = std::env::args_os(); - let args = dnst::try_ldns_compatibility(env_args).unwrap_or_else(dnst::Args::parse); - - match args.execute(&mut std::io::stdout()) { + match run() { Ok(()) => ExitCode::SUCCESS, Err(err) => { err.pretty_print(); @@ -16,3 +12,9 @@ fn main() -> ExitCode { } } } + +fn run() -> Result<(), Error> { + // If none of the ldns-* tools matched, then we continue with clap + // argument parsing. + parse_args(std::env::args_os)?.execute(&mut std::io::stdout()) +} From e7f21581d7406bae6655325e5b2673cbfcea2daf Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:18:31 +0100 Subject: [PATCH 40/47] Review feedback: inverted assert comments. --- tests/vs-ldns.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/vs-ldns.rs b/tests/vs-ldns.rs index 18c956a3..f34b41ed 100644 --- a/tests/vs-ldns.rs +++ b/tests/vs-ldns.rs @@ -88,13 +88,13 @@ fn assert_cmds_eq(cmd1: &[&str], cmd2: &[&str]) { ); assert!( !cmd1_output.stdout.is_empty(), - "Unexpected stdout content for ldns command: {}: {:?}", + "Expected stdout content for command: {}: {:?}", cmd1.join(" "), std::str::from_utf8(&cmd1_output.stdout) ); assert!( !cmd2_output.stdout.is_empty(), - "Unexpected stdout content for dnst command: {}: {:?}", + "Expected stdout content for command: {}: {:?}", cmd2.join(" "), std::str::from_utf8(&cmd2_output.stdout) ); From f71c9e32e94336070d1df74b851424a8954c9f95 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Thu, 14 Nov 2024 11:03:10 +0100 Subject: [PATCH 41/47] Review feedback: Typo correction. Co-authored-by: Terts Diepraam --- src/commands/nsec3hash.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 11051648..21478751 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -139,7 +139,7 @@ impl Nsec3Hash { pub fn parse_nsec3_alg_as_num(arg: &str) -> Result { match arg.parse() { Ok(num) => Self::num_to_nsec3_alg(num), - Err(_) => Err("malformed algorith number"), + Err(_) => Err("malformed algorithm number"), } } From 52a7bcbac58cd552971064e1db528eae3a9993d4 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Thu, 14 Nov 2024 11:38:32 +0100 Subject: [PATCH 42/47] Fix fuzz test. --- fuzz/fuzz_targets/nsec3-hash.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzz/fuzz_targets/nsec3-hash.rs b/fuzz/fuzz_targets/nsec3-hash.rs index 81bfb4b4..1312c17b 100644 --- a/fuzz/fuzz_targets/nsec3-hash.rs +++ b/fuzz/fuzz_targets/nsec3-hash.rs @@ -5,5 +5,5 @@ use libfuzzer_sys::fuzz_target; use dnst::commands::nsec3hash::Nsec3Hash; fuzz_target!(|cmd: Nsec3Hash| { - let _ = cmd.execute(); + let _ = cmd.execute(&mut std::io::sink()); }); From e54838a84982e69ee5ab123b341665d376b13a66 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Thu, 14 Nov 2024 11:46:46 +0100 Subject: [PATCH 43/47] Remove fuzzing support, it now has its own PR. --- Cargo.lock | 22 - Cargo.toml | 4 - fuzz/.gitignore | 4 - fuzz/Cargo.lock | 1122 ------------------------------- fuzz/Cargo.toml | 20 - fuzz/README.md | 13 - fuzz/fuzz_targets/nsec3-hash.rs | 9 - src/commands/nsec3hash.rs | 4 +- 8 files changed, 1 insertion(+), 1197 deletions(-) delete mode 100644 fuzz/.gitignore delete mode 100644 fuzz/Cargo.lock delete mode 100644 fuzz/Cargo.toml delete mode 100644 fuzz/README.md delete mode 100644 fuzz/fuzz_targets/nsec3-hash.rs diff --git a/Cargo.lock b/Cargo.lock index 6e18065a..56ec1194 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,15 +72,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "arbitrary" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" -dependencies = [ - "derive_arbitrary", -] - [[package]] name = "async-lock" version = "3.4.0" @@ -251,22 +242,10 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derive_arbitrary" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "dnst" version = "0.1.0" dependencies = [ - "arbitrary", "clap", "domain", "lexopt", @@ -278,7 +257,6 @@ name = "domain" version = "0.10.3" source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#e1c1db8e4103eed5f69d77d7b88581298cc00818" dependencies = [ - "arbitrary", "bytes", "futures-util", "hashbrown", diff --git a/Cargo.toml b/Cargo.toml index 3d157243..0b540524 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ name = "ldns" path = "src/bin/ldns.rs" [dependencies] -arbitrary = { version = "1", optional = true, features = ["derive"] } clap = { version = "4", features = ["derive"] } #domain = "0.10.3" domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-validator"] } @@ -17,6 +16,3 @@ lexopt = "0.3.0" [dev-dependencies] test_bin = "0.4.0" - -[features] -arbitrary = [ "dep:arbitrary", "domain/arbitrary" ] \ No newline at end of file diff --git a/fuzz/.gitignore b/fuzz/.gitignore deleted file mode 100644 index 1a45eee7..00000000 --- a/fuzz/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -target -corpus -artifacts -coverage diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock deleted file mode 100644 index 3a51f621..00000000 --- a/fuzz/Cargo.lock +++ /dev/null @@ -1,1122 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - -[[package]] -name = "anstream" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" - -[[package]] -name = "anstyle-parse" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" -dependencies = [ - "anstyle", - "windows-sys 0.59.0", -] - -[[package]] -name = "arbitrary" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-trait" -version = "0.1.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" - -[[package]] -name = "cc" -version = "1.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70" -dependencies = [ - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "4.5.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" - -[[package]] -name = "colorchoice" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derive_arbitrary" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dnst" -version = "0.1.0" -dependencies = [ - "arbitrary", - "clap", - "domain", -] - -[[package]] -name = "dnst-fuzz" -version = "0.0.0" -dependencies = [ - "arbitrary", - "dnst", - "libfuzzer-sys", -] - -[[package]] -name = "domain" -version = "0.10.3" -source = "git+https://github.com/NLnetLabs/domain/?branch=initial-nsec3-generation#f2cabc37eff3d85a42058180319926376604b7f6" -dependencies = [ - "arbitrary", - "bytes", - "futures-util", - "hashbrown", - "moka", - "octseq", - "rand", - "ring", - "serde", - "time", - "tokio", - "tracing", -] - -[[package]] -name = "event-listener" -version = "5.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-macro", - "futures-task", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "allocator-api2", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "jobserver" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "libc" -version = "0.2.161" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" - -[[package]] -name = "libfuzzer-sys" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" -dependencies = [ - "arbitrary", - "cc", - "once_cell", -] - -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi", - "libc", - "wasi", - "windows-sys 0.52.0", -] - -[[package]] -name = "moka" -version = "0.12.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cf62eb4dd975d2dde76432fb1075c49e3ee2331cf36f1f8fd4b66550d32b6f" -dependencies = [ - "async-lock", - "async-trait", - "crossbeam-channel", - "crossbeam-epoch", - "crossbeam-utils", - "event-listener", - "futures-util", - "once_cell", - "parking_lot", - "quanta", - "rustc_version", - "smallvec", - "tagptr", - "thiserror", - "triomphe", - "uuid", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "object" -version = "0.36.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" -dependencies = [ - "memchr", -] - -[[package]] -name = "octseq" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126c3ca37c9c44cec575247f43a3e4374d8927684f129d2beeb0d2cef262fe12" -dependencies = [ - "bytes", - "serde", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro2" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quanta" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" -dependencies = [ - "crossbeam-utils", - "libc", - "once_cell", - "raw-cpuid", - "wasi", - "web-sys", - "winapi", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "raw-cpuid" -version = "11.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_syscall" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "serde" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.214" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "syn" -version = "2.0.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tagptr" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" - -[[package]] -name = "thiserror" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "time" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde", - "time-core", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "tokio" -version = "1.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "triomphe" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "uuid" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" -dependencies = [ - "getrandom", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" -dependencies = [ - "cfg-if", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" - -[[package]] -name = "web-sys" -version = "0.3.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml deleted file mode 100644 index 7bb1bcf6..00000000 --- a/fuzz/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "dnst-fuzz" -version = "0.0.0" -publish = false -edition = "2021" - -[package.metadata] -cargo-fuzz = true - -[dependencies] -arbitrary = "1.4.1" -libfuzzer-sys = "0.4" -dnst = { path = "..", features = ["arbitrary"] } - -[[bin]] -name = "nsec3-hash" -path = "fuzz_targets/nsec3-hash.rs" -test = false -doc = false -bench = false diff --git a/fuzz/README.md b/fuzz/README.md deleted file mode 100644 index 4c27916b..00000000 --- a/fuzz/README.md +++ /dev/null @@ -1,13 +0,0 @@ -`dnst` fuzz testing with cargo-fuzz and libfuzzer - -# tl;dr - -For example, fuzz test the nsec3-hash subcommand for 10 minutes using 8 concurrent jobs: - -``` -cargo +nightly fuzz run nsec3-hash -- -jobs=8 -max_total_time=600 -print_final_stats=1 -``` - -# Further reading - -https://rust-fuzz.github.io/book/introduction.html \ No newline at end of file diff --git a/fuzz/fuzz_targets/nsec3-hash.rs b/fuzz/fuzz_targets/nsec3-hash.rs deleted file mode 100644 index 1312c17b..00000000 --- a/fuzz/fuzz_targets/nsec3-hash.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![no_main] - -use libfuzzer_sys::fuzz_target; - -use dnst::commands::nsec3hash::Nsec3Hash; - -fuzz_target!(|cmd: Nsec3Hash| { - let _ = cmd.execute(&mut std::io::sink()); -}); diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 21478751..e91cf44b 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -14,7 +14,6 @@ use crate::error::Error; use super::{parse_os, parse_os_with, LdnsCommand}; #[derive(Clone, Debug, clap::Args)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] pub struct Nsec3Hash { /// The hashing algorithm to use #[arg( @@ -165,8 +164,7 @@ impl Nsec3Hash { } // These are just basic tests as there is very little code in this module, the -// actual NSEC3 generation should be tested as part of the domain crate. See -// also: fuzz/fuzz_targets/nsec3-hash.rs. +// actual NSEC3 generation should be tested as part of the domain crate. #[cfg(test)] mod tests { mod without_cli { From aa0bdb142d7c50d4aef07148aea223b1477fb4e4 Mon Sep 17 00:00:00 2001 From: Ximon Eighteen <3304436+ximon18@users.noreply.github.com> Date: Thu, 14 Nov 2024 11:53:26 +0100 Subject: [PATCH 44/47] Remove man page changes, they now have their own PR. --- doc/manual/source/conf.py | 4 ++-- doc/manual/source/man/dnst-nsec3-hash.rst | 18 +++++++------- doc/manual/source/man/ldns-nsec3-hash.rst | 29 ----------------------- 3 files changed, 11 insertions(+), 40 deletions(-) delete mode 100644 doc/manual/source/man/ldns-nsec3-hash.rst diff --git a/doc/manual/source/conf.py b/doc/manual/source/conf.py index 56e04bdf..ffa9b5d4 100644 --- a/doc/manual/source/conf.py +++ b/doc/manual/source/conf.py @@ -189,8 +189,8 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('man/dnst', 'dnst', 'DNS Management Tools', author, 1), - ('man/dnst-nsec3-hash', 'dnst-nsec3-hash', 'print out the NSEC3 hash for a domain name', author, 1), - ('man/ldns-nsec3-hash', 'ldns-nsec3-hash', 'print out the NSEC3 hash for a domain name', author, 1), + ('man/dnst-nsec3-hash', 'dnst-nsec3-hash', 'DNS Management Tools', author, + 1), ] diff --git a/doc/manual/source/man/dnst-nsec3-hash.rst b/doc/manual/source/man/dnst-nsec3-hash.rst index 56e093ba..20014476 100644 --- a/doc/manual/source/man/dnst-nsec3-hash.rst +++ b/doc/manual/source/man/dnst-nsec3-hash.rst @@ -4,27 +4,27 @@ dnst-nsec3-hash Synopsis -------- -:program:`dnst nsec3-hash` [``OPTIONS``] :samp:`` +:program:`dnst nsec3-hash` [``options``] :samp:`domain-name` Description ----------- -**dnst nsec3-hash** prints the NSEC3 hash of a given domain name. +**dnst nsec3-hash** prints the NSEC3 hash for the given domain name. Options ------- -.. option:: -a , --algorithm +.. option:: -a number-or-mnemonic, --algorithm=number-or-mnemonic Use the given algorithm number for the hash calculation. Defaults to - 1 (SHA-1). + ``sha1``. -.. option:: -i , -t , --iterations - - Use the given number of additional iterations for the hash calculation. - -.. option:: -s , --salt +.. option:: -s salt, --salt=count Use the given salt for the hash calculation. The salt value should be in hexadecimal format. +.. option:: -i count, -t count, --iterations=count + + Use *count* iterations for the hash calculation. + diff --git a/doc/manual/source/man/ldns-nsec3-hash.rst b/doc/manual/source/man/ldns-nsec3-hash.rst deleted file mode 100644 index 20c16e66..00000000 --- a/doc/manual/source/man/ldns-nsec3-hash.rst +++ /dev/null @@ -1,29 +0,0 @@ -ldns-nsec3-hash -=============== - -Synopsis --------- - -:program:`ldns-nsec3-hash` :samp:`<{domain-name}>` - -Description ------------ - -**ldns-nsec3-hash** is used to print out the NSEC3 hash for the given domain name. - -Options -------- - -.. option:: -a number - - Use the given algorithm number for the hash calculation. Defaults to - 1 (SHA-1). - -.. option:: -s salt - - Use the given salt for the hash calculation. The salt value should be - in hexadecimal format. - -.. option:: -t count - - Use count iterations for the hash calculation. From 1ba4053b01de0ff4b5e728d2c242ac09eab3d8cc Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Tue, 19 Nov 2024 12:25:19 +0100 Subject: [PATCH 45/47] make nsec3-hash compile and work correctly again after merge --- Cargo.lock | 4 +-- Cargo.toml | 2 +- src/bin/ldns.rs | 7 ------ src/commands/mod.rs | 1 - src/commands/nsec3hash.rs | 52 +++++++++++++++++++++++---------------- src/lib.rs | 2 +- src/main.rs | 6 ----- 7 files changed, 35 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56ec1194..0c2aca14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,9 +141,9 @@ checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cc" -version = "1.1.37" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "shlex", ] diff --git a/Cargo.toml b/Cargo.toml index 728c7499..5f44d44f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ path = "src/bin/ldns.rs" [dependencies] clap = { version = "4.3.4", features = ["derive"] } -domain = "0.10.1" +domain = { git = "https://github.com/NLnetLabs/domain/", branch = "initial-nsec3-generation", features = ["ring", "unstable-validator"] } lexopt = "0.3.0" [dev-dependencies] diff --git a/src/bin/ldns.rs b/src/bin/ldns.rs index dc30d453..beda509f 100644 --- a/src/bin/ldns.rs +++ b/src/bin/ldns.rs @@ -6,7 +6,6 @@ use std::process::ExitCode; -use dnst::error::Error; use dnst::try_ldns_compatibility; fn main() -> ExitCode { @@ -25,9 +24,3 @@ fn main() -> ExitCode { } } } - -fn run() -> Result<(), Error> { - let mut args = std::env::args_os(); - args.next().unwrap(); - try_ldns_compatibility(args)?.execute(&mut std::io::stdout()) -} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index b6c4efd1..3251c7c6 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -3,7 +3,6 @@ pub mod help; pub mod nsec3hash; use std::ffi::{OsStr, OsString}; -use std::io::Write; use std::str::FromStr; use nsec3hash::Nsec3Hash; diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index c3c286a7..7afdfe35 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -153,10 +153,11 @@ impl Nsec3Hash { impl Nsec3Hash { pub fn execute(self, env: impl Env) -> Result<(), Error> { - let hash = nsec3_hash(&self.name, self.algorithm, self.iterations, &self.salt) - .map_err(|err| format!("Error creating NSEC3 hash: {err}"))? - .to_string() - .to_lowercase(); + let hash = + nsec3_hash::<_, _, Vec>(&self.name, self.algorithm, self.iterations, &self.salt) + .map_err(|err| format!("Error creating NSEC3 hash: {err}"))? + .to_string() + .to_lowercase(); let mut out = env.stdout(); writeln!(out, "{}.", hash); @@ -176,6 +177,7 @@ mod tests { use domain::rdata::nsec3::Nsec3Salt; use crate::commands::nsec3hash::Nsec3Hash; + use crate::env::fake::{FakeCmd, FakeEnv, FakeStream}; // Note: For the types we use that are provided by the domain crate, // construction of them from bad inputs should be tested in that @@ -185,6 +187,12 @@ mod tests { // nsec3-hash`` or as `ldns-nsec3-hash`. #[test] fn execute() { + let env = FakeEnv { + cmd: FakeCmd::new(["doesn't matter"]), + stdout: FakeStream::default(), + stderr: FakeStream::default(), + }; + // We don't test all permutations as that would take too long (~20 seconds) #[allow(clippy::single_element_loop)] for algorithm in ["SHA-1"] { @@ -196,7 +204,7 @@ mod tests { salt: Nsec3Salt::empty(), name: Name::root(), }; - nsec3_hash.execute(&mut std::io::sink()).unwrap(); + nsec3_hash.execute(&env).unwrap(); } for iterations in [0, 1, u16::MAX - 1, u16::MAX] { @@ -206,7 +214,7 @@ mod tests { salt: Nsec3Salt::empty(), name: Name::root(), }; - nsec3_hash.execute(&mut std::io::sink()).unwrap(); + nsec3_hash.execute(&env).unwrap(); } for salt in ["", "-", "aa", "aabb", "aa".repeat(255).as_str()] { @@ -218,7 +226,7 @@ mod tests { salt, name: Name::root(), }; - nsec3_hash.execute(&mut std::io::sink()).unwrap(); + nsec3_hash.execute(&env).unwrap(); } for name in [ @@ -233,7 +241,7 @@ mod tests { salt: Nsec3Salt::empty(), name, }; - nsec3_hash.execute(&mut std::io::sink()).unwrap(); + nsec3_hash.execute(&env).unwrap(); } } } @@ -241,8 +249,9 @@ mod tests { mod with_dnst_cli { use core::str; + use crate::env::fake::FakeCmd; use crate::error::Error; - use crate::{parse_args, Args}; + use crate::Args; #[test] fn accept_good_cli_args() { @@ -304,22 +313,23 @@ mod tests { //------------ Helper functions ------------------------------------------ fn parse_cmd_line(args: &[&str]) -> Result { - parse_args(|| ["dnst", "nsec3-hash"].iter().chain(args).map(Into::into)) + FakeCmd::new(["dnst", "nsec3-hash"]).args(args).parse() } fn assert_cmd_eq(args: &[&str], expected_output: &str) { - let parsed_args = parse_cmd_line(args).unwrap(); - let mut captured_stdout = vec![]; - parsed_args.execute(&mut captured_stdout).unwrap(); - assert_eq!(str::from_utf8(&captured_stdout), Ok(expected_output)); + let result = FakeCmd::new(["dnst", "nsec3-hash"]).args(args).run(); + assert_eq!(result.exit_code, 0); + assert_eq!(result.stdout, expected_output); + assert_eq!(result.stderr, ""); } } mod with_ldns_cli { use core::str; + use crate::env::fake::FakeCmd; use crate::error::Error; - use crate::{parse_args, Args}; + use crate::Args; #[test] fn accept_good_cli_args() { @@ -378,14 +388,14 @@ mod tests { //------------ Helper functions ------------------------------------------ fn parse_cmd_line(args: &[&str]) -> Result { - parse_args(|| ["ldns-nsec3-hash"].iter().chain(args).map(Into::into)) + FakeCmd::new(["ldns-nsec3-hash"]).args(args).parse() } fn assert_cmd_eq(args: &[&str], expected_output: &str) { - let parsed_args = parse_cmd_line(args).unwrap(); - let mut captured_stdout = vec![]; - parsed_args.execute(&mut captured_stdout).unwrap(); - assert_eq!(str::from_utf8(&captured_stdout), Ok(expected_output)); + let result = FakeCmd::new(["ldns-nsec3-hash"]).args(args).run(); + assert_eq!(result.exit_code, 0); + assert_eq!(result.stdout, expected_output); + assert_eq!(result.stderr, ""); } } } @@ -411,7 +421,7 @@ mod test { let res = cmd.args(["example.test"]).run(); assert_eq!(res.exit_code, 0); - assert_eq!(res.stdout, "o09614ibh1cq1rcc86289olr22ea0fso.\n") + assert_eq!(res.stdout, "jbas736chung3bb701jkjdhqkqlhvug7.\n") } #[test] diff --git a/src/lib.rs b/src/lib.rs index 11502155..8a149998 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ pub fn try_ldns_compatibility>( .to_str() .ok_or("Binary file name is not valid unicode")?; - match binary_name { + let res = match binary_name { "ldns-nsec3-hash" => Nsec3Hash::parse_ldns_args(args_iter), _ => return Ok(None), }; diff --git a/src/main.rs b/src/main.rs index 56ad3d37..b368f32d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,9 +4,3 @@ fn main() -> ExitCode { let env = dnst::env::RealEnv; dnst::run(env).into() } - -fn run() -> Result<(), Error> { - // If none of the ldns-* tools matched, then we continue with clap - // argument parsing. - parse_args(std::env::args_os)?.execute(&mut std::io::stdout()) -} From beaeb9a67f22cc769ea45a09c8a6040804232b7e Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Tue, 19 Nov 2024 14:50:45 +0100 Subject: [PATCH 46/47] nsec3-hash: update default in docs --- doc/manual/source/man/dnst-nsec3-hash.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/source/man/dnst-nsec3-hash.rst b/doc/manual/source/man/dnst-nsec3-hash.rst index 78d35dac..a72450f5 100644 --- a/doc/manual/source/man/dnst-nsec3-hash.rst +++ b/doc/manual/source/man/dnst-nsec3-hash.rst @@ -22,7 +22,7 @@ Options .. option:: -i , -t , --iterations Use the given number of additional iterations for the hash - calculation. Defaults to 1. + calculation. Defaults to 0. .. option:: -s , --salt From 4042d5b61f61c441c8404c500a5dc3ba2b33f066 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Fri, 22 Nov 2024 11:31:05 +0100 Subject: [PATCH 47/47] suggestions from ximon --- src/commands/nsec3hash.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/commands/nsec3hash.rs b/src/commands/nsec3hash.rs index 7afdfe35..852b49b6 100644 --- a/src/commands/nsec3hash.rs +++ b/src/commands/nsec3hash.rs @@ -159,8 +159,7 @@ impl Nsec3Hash { .to_string() .to_lowercase(); - let mut out = env.stdout(); - writeln!(out, "{}.", hash); + writeln!(env.stdout(), "{}.", hash); Ok(()) } } @@ -188,7 +187,7 @@ mod tests { #[test] fn execute() { let env = FakeEnv { - cmd: FakeCmd::new(["doesn't matter"]), + cmd: FakeCmd::new(["unused"]), stdout: FakeStream::default(), stderr: FakeStream::default(), };