refactor(client): make authentication explicit and redact HMAC keys
This commit is contained in:
16 files changed
+184
-119
No files matched your search
@@ -1,10 +1,10 @@
|
||||
use std::time::Duration;
|
||||
use std::{fmt, time::Duration};
|
||||
|
||||
use clap::ValueEnum;
|
||||
use irtt_client::{MAX_DSCP_CODEPOINT, MAX_SERVER_FILL_BYTES, MAX_TTL, MAX_UDP_PAYLOAD_LENGTH};
|
||||
use irtt_proto::{Clock, ReceivedStats, StampAt};
|
||||
|
||||
#[derive(Debug, Clone, clap::Args)]
|
||||
#[derive(Clone, clap::Args)]
|
||||
pub struct CommonClientArgs {
|
||||
/// Probe interval.
|
||||
#[arg(long, default_value = "1s", value_parser = parse_duration)]
|
||||
@@ -63,6 +63,23 @@ pub struct CommonClientArgs {
|
||||
pub loose: bool,
|
||||
}
|
||||
|
||||
impl fmt::Debug for CommonClientArgs {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("CommonClientArgs")
|
||||
.field("interval", &self.interval)
|
||||
.field("length", &self.length)
|
||||
.field("hmac", &self.hmac.as_ref().map(|_| "[REDACTED]"))
|
||||
.field("clock", &self.clock)
|
||||
.field("tstamp", &self.tstamp)
|
||||
.field("stats", &self.stats)
|
||||
.field("server_fill", &self.server_fill)
|
||||
.field("dscp", &self.dscp)
|
||||
.field("ttl", &self.ttl)
|
||||
.field("loose", &self.loose)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
|
||||
pub enum ClockArg {
|
||||
Wall,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use irtt_client::{ClientConfig, NegotiationPolicy, SocketConfig};
|
||||
use irtt_client::{Authentication, ClientConfig, HmacKey, NegotiationPolicy, SocketConfig};
|
||||
|
||||
use super::args::CommonClientArgs;
|
||||
|
||||
@@ -21,7 +21,12 @@ impl CommonClientArgs {
|
||||
stamp_at: self.tstamp.into(),
|
||||
clock: self.clock.into(),
|
||||
dscp: self.dscp,
|
||||
hmac_key: self.hmac.as_ref().map(|key| key.as_bytes().to_vec()),
|
||||
auth: self
|
||||
.hmac
|
||||
.as_ref()
|
||||
.map_or(Authentication::Unauthenticated, |key| {
|
||||
Authentication::Hmac(HmacKey::new(key.as_bytes()))
|
||||
}),
|
||||
server_fill: self.server_fill.clone(),
|
||||
negotiation_policy: if self.loose {
|
||||
NegotiationPolicy::Loose
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::{collections::HashSet, fmt};
|
||||
|
||||
use clap::ValueEnum;
|
||||
use irtt_client::{
|
||||
managed::{ManagedPacing, ManagedTargetConfig, TargetId},
|
||||
ClientAuthConfig,
|
||||
managed::{ManagedPacing, ManagedTargetConfig, TargetAuth, TargetId},
|
||||
Authentication, HmacKey,
|
||||
};
|
||||
|
||||
/// One raw positional target captured by Clap.
|
||||
@@ -35,23 +35,6 @@ pub fn parse_target(input: &str) -> Result<TargetArg, String> {
|
||||
Ok(TargetArg::new(input))
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum TargetAuth {
|
||||
Inherit,
|
||||
Override(Vec<u8>),
|
||||
Disable,
|
||||
}
|
||||
|
||||
impl fmt::Debug for TargetAuth {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Inherit => f.write_str("Inherit"),
|
||||
Self::Override(_) => f.write_str("Override(<redacted>)"),
|
||||
Self::Disable => f.write_str("Disable"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct TargetSpec {
|
||||
pub label: String,
|
||||
@@ -80,16 +63,7 @@ impl fmt::Debug for PreparedTarget {
|
||||
f.debug_struct("PreparedTarget")
|
||||
.field("label", &self.label)
|
||||
.field("server_addr", &self.managed.server_addr)
|
||||
.field(
|
||||
"auth",
|
||||
&match &self.managed.auth {
|
||||
None => TargetAuth::Inherit,
|
||||
Some(ClientAuthConfig { hmac_key: Some(_) }) => {
|
||||
TargetAuth::Override(Vec::new())
|
||||
}
|
||||
Some(ClientAuthConfig { hmac_key: None }) => TargetAuth::Disable,
|
||||
},
|
||||
)
|
||||
.field("auth", &self.managed.auth)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -216,9 +190,9 @@ fn parse_target_syntax(
|
||||
Some(index) => {
|
||||
let value = unescape(&input[index + "@hmac=".len()..])?;
|
||||
let auth = if value.is_empty() {
|
||||
TargetAuth::Disable
|
||||
TargetAuth::Override(Authentication::Unauthenticated)
|
||||
} else {
|
||||
TargetAuth::Override(value.into_bytes())
|
||||
TargetAuth::Override(Authentication::Hmac(HmacKey::new(value.into_bytes())))
|
||||
};
|
||||
(&input[..index], auth)
|
||||
}
|
||||
@@ -287,13 +261,7 @@ pub fn prepare_managed_targets(specs: Vec<TargetSpec>) -> Result<Vec<PreparedTar
|
||||
let mut targets = Vec::with_capacity(specs.len());
|
||||
for spec in specs {
|
||||
let mut managed = ManagedTargetConfig::new(TargetId::from(spec.label.clone()), spec.addr);
|
||||
managed.auth = match spec.auth {
|
||||
TargetAuth::Inherit => None,
|
||||
TargetAuth::Override(hmac_key) => Some(ClientAuthConfig {
|
||||
hmac_key: Some(hmac_key),
|
||||
}),
|
||||
TargetAuth::Disable => Some(ClientAuthConfig { hmac_key: None }),
|
||||
};
|
||||
managed.auth = spec.auth;
|
||||
targets.push(PreparedTarget {
|
||||
label: spec.label,
|
||||
managed,
|
||||
|
||||
Reference in new issue
Block a user