From f74a68bb8039d1d6203fa2f332b344865ebcfd40 Mon Sep 17 00:00:00 2001 From: jotape24 Date: Fri, 31 Jan 2025 17:21:41 -0300 Subject: [PATCH] add: flag --tsig was added to client in main.rs and README --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + README.md | 17 ++++++++-------- src/main.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/message.rs | 2 +- 5 files changed, 71 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80131dca..b2aa209e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -382,6 +382,7 @@ dependencies = [ "chrono", "clap", "data-encoding", + "hex", "ipconfig", "lru", "rand 0.8.5", @@ -496,6 +497,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "home" version = "0.5.11" diff --git a/Cargo.toml b/Cargo.toml index a6476b45..99432e27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,5 +21,6 @@ tokio-rustls = "0.26.0" rustls-native-certs = "0.8.0" ipconfig = "0.3.2" data-encoding = "2.7.0" +hex = "0.4.3" [lib] doctest = false diff --git a/README.md b/README.md index cc6d52e9..c4f613fc 100644 --- a/README.md +++ b/README.md @@ -82,14 +82,15 @@ Here it can be specified whether to run a *client* or a *resolver* : - Six options: - | Option | Description | - |-------------------------|-----------------------------------------------------------------| - | `--qtype ` | Query type [default: A] | - | `--qclass ` | Query class [default: IN] | - | `--norecursive` | Disables the use of recursion when specified | - | `--payload ` | Maximum payload for EDNS [default: 512] | - | `--noedns` | Disables the use of EDNS when specified | - | `--protocol ` | Transport protocol, options: "UDP", "TCP", "TLS" [default: UDP] | + | Option | Description | + |-------------------------|--------------------------------------------------------------------------| + | `--qtype ` | Query type [default: A] | + | `--qclass ` | Query class [default: IN] | + | `--norecursive` | Disables the use of recursion when specified | + | `--payload ` | Maximum payload for EDNS [default: 512] | + | `--noedns` | Disables the use of EDNS when specified | + | `--protocol ` | Transport protocol, options: "UDP", "TCP", "TLS" [default: UDP] | + | `--tsig ` | TSIG arguments key, algorithm, fudge, time_signed, key_name, mac_request | - And four EDNS0 options diff --git a/src/main.rs b/src/main.rs index 13af2b15..996f1182 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ use dns_rust::message::DnsMessage; use dns_rust::message::rclass::Rclass; use dns_rust::message::rcode::Rcode; use dns_rust::message::rrtype::Rrtype; +use dns_rust::tsig::tsig_algorithm::TsigAlgorithm; #[derive(Parser, Debug)] struct Cli { @@ -76,6 +77,47 @@ struct ClientArgs { /// Transport protocol, options: "UDP", "TCP", "TLS". #[arg(long, default_value_t = String::from("UDP"))] protocol: String, + + /// TSIG arguments key, algorithm, fudge, time_signed, key_name, mac_request + #[arg(long, value_parser = TsigArgs::from_str)] + tsig: Option, +} + +/// Represents the arguments required for TSIG. +#[derive(Debug, Clone)] +pub struct TsigArgs { + pub key: Vec, + pub alg_name: TsigAlgorithm, + pub fudge: u16, + pub time_signed: u64, + pub key_name: String, + pub mac_request: Vec, +} + +impl TsigArgs { + /// Parses a string into a `TsigArgs` instance. + pub fn from_str(value: &str) -> Result { + let parts: Vec<&str> = value.split(',').collect(); + if parts.len() != 6 { + return Err("Expected 6 values for TSIG args".to_string()); + } + + let key = hex::decode(parts[0].trim()).map_err(|e| e.to_string())?; + let alg_name = TsigAlgorithm::from(parts[1].trim().to_string()); + let fudge = parts[2].trim().parse::().map_err(|e| e.to_string())?; + let time_signed = parts[3].trim().parse::().map_err(|e| e.to_string())?; + let key_name = parts[4].trim().to_string(); + let mac_request = hex::decode(parts[5].trim()).map_err(|e| e.to_string())?; + + Ok(Self { + key, + alg_name, + fudge, + time_signed, + key_name, + mac_request, + }) + } } @@ -162,6 +204,17 @@ pub async fn main() { dns_query_message.add_edns0(max_payload, Rcode::NOERROR, 0, false, some_options); } + if !client_args.tsig.is_none() { + if let Some(tsig_args) = &client_args.tsig { + dns_query_message.sign_message(&*tsig_args.key, + tsig_args.alg_name.clone(), + tsig_args.fudge, + tsig_args.time_signed, + tsig_args.key_name.clone(), + tsig_args.mac_request.clone()); + } + } + // match tcp to set a client let response = match client_args.protocol.as_str() { "UDP" => { diff --git a/src/message.rs b/src/message.rs index 40a7e3f3..4b01aad4 100644 --- a/src/message.rs +++ b/src/message.rs @@ -800,7 +800,7 @@ impl DnsMessage { /// /// dns_message.sign_message(key, algorithm, fudge, time_signed, key_name, mac_request); /// ``` - fn sign_message(&mut self, key: &[u8], alg_name: TsigAlgorithm, + pub fn sign_message(&mut self, key: &[u8], alg_name: TsigAlgorithm, fudge: u16, time_signed: u64, key_name: String, mac_request: Vec) { tsig::sign_tsig(self, key, alg_name, fudge, time_signed, key_name, mac_request); }