Prevent unsigned Fleet collectors from claiming federation provenance
This commit is contained in:
@@ -4,27 +4,27 @@
|
||||
//! Trust is bilateral — both sides must agree. Federated nodes periodically
|
||||
//! sync container status, health metrics, and availability.
|
||||
|
||||
pub(crate) mod handshake_delivery;
|
||||
mod invites;
|
||||
pub mod pending;
|
||||
pub(crate) mod handshake_delivery;
|
||||
mod storage;
|
||||
mod sync;
|
||||
mod types;
|
||||
|
||||
// Re-export all public items so `crate::federation::*` continues to work.
|
||||
pub use invites::{accept_invite, create_invite, parse_invite};
|
||||
pub(crate) use invites::restrict_discovery_invite;
|
||||
pub use invites::{accept_invite, create_invite, parse_invite};
|
||||
// Crate-internal: used by the periodic federation auto-sync to re-assert
|
||||
// membership to peers that don't list us back (asymmetry self-heal).
|
||||
pub(crate) use invites::notify_join;
|
||||
// Crate-internal: peer-joined resolves the granted trust level by matching
|
||||
// the acceptor's invite_token against our stored outgoing invites.
|
||||
pub(crate) use storage::load_invites;
|
||||
pub(crate) use storage::{load_unique_payment_peer, load_unique_payment_peer_by_did};
|
||||
#[allow(unused_imports)]
|
||||
pub use storage::{
|
||||
add_node, fips_npub_for_onion, load_nodes, load_removed_dids, record_peer_transport,
|
||||
record_sync_result, remove_node, save_nodes, set_trust_level, update_node,
|
||||
};
|
||||
pub(crate) use storage::{load_invites, load_node_identities};
|
||||
pub(crate) use storage::{load_unique_payment_peer, load_unique_payment_peer_by_did};
|
||||
pub use sync::{build_local_state, deploy_to_peer, sync_with_peer, sync_with_peer_by_did};
|
||||
pub use types::{AppStatus, FederatedNode, NodeStateSnapshot, TrustLevel, TrustSource};
|
||||
|
||||
@@ -71,6 +71,23 @@ pub async fn load_nodes(data_dir: &Path) -> Result<Vec<FederatedNode>> {
|
||||
load_nodes_inner(data_dir).await
|
||||
}
|
||||
|
||||
/// Every persisted relationship identity, before display-only onion deduplication.
|
||||
/// Callers excluding unsigned claims must not lose an observer/untrusted DID
|
||||
/// merely because another record currently shares its route.
|
||||
pub(crate) async fn load_node_identities(
|
||||
data_dir: &Path,
|
||||
) -> Result<std::collections::HashSet<String>> {
|
||||
let _guard = FEDERATION_STORE_LOCK.lock().await;
|
||||
let content = match fs::read(data_dir.join(FEDERATION_DIR).join(NODES_FILE)).await {
|
||||
Ok(content) => content,
|
||||
Err(error) if error.kind() == std::io::ErrorKind::NotFound => return Ok(Default::default()),
|
||||
Err(error) => return Err(error).context("Could not read federation identities"),
|
||||
};
|
||||
let file: NodesFile = serde_json::from_slice(&content)
|
||||
.context("Invalid federation identities; unsigned claims cannot replace them")?;
|
||||
Ok(file.nodes.into_iter().map(|node| node.did).collect())
|
||||
}
|
||||
|
||||
/// Resolve payment identity from persisted records before display deduplication
|
||||
/// can merge fields from different identities sharing an address.
|
||||
pub(crate) async fn load_unique_payment_peer(
|
||||
|
||||
Reference in New Issue
Block a user