summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-26 23:02:12 +0100
committertv <tv@krebsco.de>2026-10-26 23:02:12 +0100
commitca93e40b170b49f98a8c379acc3ac4c33361decd (patch)
tree175f9a94ca5db8ea5f55286dcc6c383e09756daa
parentc11324bef3e93aac3748c6bb62c4a60872ea3f62 (diff)
don't leak swarm key in handshake logs
-rw-r--r--src/transport/mod.rs65
1 files changed, 55 insertions, 10 deletions
diff --git a/src/transport/mod.rs b/src/transport/mod.rs
index 3bc88e4..febbdf0 100644
--- a/src/transport/mod.rs
+++ b/src/transport/mod.rs
@@ -156,14 +156,8 @@ impl std::fmt::Display for BlobId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BlobId::Change(hash) => write!(f, "change:{hash}"),
- BlobId::Content(hash) => {
- write!(f, "content:")?;
- hash.iter().try_for_each(|byte| write!(f, "{byte:02x}"))
- }
- BlobId::Delta(id) => {
- write!(f, "delta:")?;
- id.iter().try_for_each(|byte| write!(f, "{byte:02x}"))
- }
+ BlobId::Content(hash) => write!(f, "content:{}", Hex(hash)),
+ BlobId::Delta(id) => write!(f, "delta:{}", Hex(id)),
}
}
}
@@ -280,7 +274,7 @@ impl ParsedMessage {
}
}
-#[derive(Debug, Clone, Serialize, Deserialize)]
+#[derive(Clone, Serialize, Deserialize)]
pub(crate) struct HelloRequest {
/// The sender's swarm, if it knows it (a new node doesn't yet). A receiver in
/// another swarm doesn't answer.
@@ -303,7 +297,7 @@ pub(crate) struct HelloRequest {
pub(crate) handshake: u32,
}
-#[derive(Debug, Clone, Serialize, Deserialize)]
+#[derive(Clone, Serialize, Deserialize)]
pub(crate) struct HelloReply {
pub(crate) swarm_id: String,
pub(crate) peers: Vec<String>,
@@ -328,6 +322,57 @@ pub(crate) struct HelloReply {
pub(crate) sender_run_id: RunId,
}
+/// Bytes shown as lowercase hex, e.g. run IDs in logs.
+pub(crate) struct Hex<'a>(pub(crate) &'a [u8]);
+
+impl std::fmt::Display for Hex<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.0.iter().try_for_each(|byte| write!(f, "{byte:02x}"))
+ }
+}
+
+impl std::fmt::Debug for Hex<'_> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self, f)
+ }
+}
+
+/// Whether a handshake carries a swarm-key proof, not the proof: logged messages don't
+/// hand out tags, and stay short.
+fn auth_shown(auth: &[u8]) -> &'static str {
+ if auth.is_empty() { "none" } else { "present" }
+}
+
+impl std::fmt::Debug for HelloRequest {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("HelloRequest")
+ .field("swarm_id", &self.swarm_id)
+ .field("epoch", &self.epoch)
+ .field("epoch_seq", &self.epoch_seq)
+ .field("auth", &auth_shown(&self.auth))
+ .field("ready", &self.ready)
+ .field("run_id", &Hex(&self.run_id))
+ .field("handshake", &self.handshake)
+ .finish()
+ }
+}
+
+impl std::fmt::Debug for HelloReply {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("HelloReply")
+ .field("swarm_id", &self.swarm_id)
+ .field("peers", &self.peers.len())
+ .field("epoch", &self.epoch)
+ .field("epoch_seq", &self.epoch_seq)
+ .field("auth", &auth_shown(&self.auth))
+ .field("ready", &self.ready)
+ .field("run_id", &Hex(&self.run_id))
+ .field("away_ms", &self.away_ms)
+ .field("sender_run_id", &Hex(&self.sender_run_id))
+ .finish()
+ }
+}
+
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct SyncEnvelope {
pub(crate) swarm_id: String,