feat(#1026): validate and forward cert_fingerprint in parse_peer_hives

This commit is contained in:
damocles 2026-06-01 21:54:28 +02:00 committed by mara
commit 9e2d6aa343

View file

@ -257,10 +257,14 @@ struct StateSnapshot {
/// One peer hive for the P33RS dashboard tab. Derived from
/// `HYPERHIVE_PEERS` env; `url` is the peer's HTTPS dashboard root.
/// `cert_fingerprint` is `Some("sha256:<hex64>")` when the peer uses a
/// self-signed cert and the operator pinned its fingerprint in
/// `services.hyperhive.swarm.peers`.
#[derive(Serialize)]
struct PeerHiveView {
name: String,
url: String,
cert_fingerprint: Option<String>,
}
/// `OpQuestion` + computed `question_refs` / `answer_refs`. Built
@ -494,13 +498,38 @@ fn parse_peer_hives() -> Vec<PeerHiveView> {
return Vec::new();
};
raw.into_iter()
.map(|r| PeerHiveView {
name: r.domain.clone(),
url: format!("https://{}/", r.domain),
.map(|r| {
let cert_fingerprint = r.cert_fingerprint.and_then(|fp| {
if validate_cert_fingerprint(&fp) {
Some(fp)
} else {
tracing::warn!(
domain = %r.domain,
fingerprint = %fp,
"HYPERHIVE_PEERS: invalid cert_fingerprint format \
(expected `sha256:<64 hex chars>`); ignoring fingerprint"
);
None
}
});
PeerHiveView {
name: r.domain.clone(),
url: format!("https://{}/", r.domain),
cert_fingerprint,
}
})
.collect()
}
/// Validate a TLS certificate fingerprint string from `HYPERHIVE_PEERS`.
/// Accepts `sha256:<64 hex chars>` (upper or lower case).
fn validate_cert_fingerprint(fp: &str) -> bool {
let Some(hex) = fp.strip_prefix("sha256:") else {
return false;
};
hex.len() == 64 && hex.chars().all(|c| c.is_ascii_hexdigit())
}
/// Group live containers by their assigned web UI port; clusters with
/// more than one member are port-hash collisions the operator needs
/// to resolve by renaming. Manager (fixed at 8000) and sub-agents