feat(#1026): validate and forward cert_fingerprint in parse_peer_hives
This commit is contained in:
parent
93ecbcb879
commit
9e2d6aa343
1 changed files with 32 additions and 3 deletions
|
|
@ -257,10 +257,14 @@ struct StateSnapshot {
|
||||||
|
|
||||||
/// One peer hive for the P33RS dashboard tab. Derived from
|
/// One peer hive for the P33RS dashboard tab. Derived from
|
||||||
/// `HYPERHIVE_PEERS` env; `url` is the peer's HTTPS dashboard root.
|
/// `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)]
|
#[derive(Serialize)]
|
||||||
struct PeerHiveView {
|
struct PeerHiveView {
|
||||||
name: String,
|
name: String,
|
||||||
url: String,
|
url: String,
|
||||||
|
cert_fingerprint: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `OpQuestion` + computed `question_refs` / `answer_refs`. Built
|
/// `OpQuestion` + computed `question_refs` / `answer_refs`. Built
|
||||||
|
|
@ -494,13 +498,38 @@ fn parse_peer_hives() -> Vec<PeerHiveView> {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
};
|
};
|
||||||
raw.into_iter()
|
raw.into_iter()
|
||||||
.map(|r| PeerHiveView {
|
.map(|r| {
|
||||||
name: r.domain.clone(),
|
let cert_fingerprint = r.cert_fingerprint.and_then(|fp| {
|
||||||
url: format!("https://{}/", r.domain),
|
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()
|
.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
|
/// Group live containers by their assigned web UI port; clusters with
|
||||||
/// more than one member are port-hash collisions the operator needs
|
/// more than one member are port-hash collisions the operator needs
|
||||||
/// to resolve by renaming. Manager (fixed at 8000) and sub-agents
|
/// to resolve by renaming. Manager (fixed at 8000) and sub-agents
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue