Test invalid replicated signatures are rejected
This commit is contained in:
parent
0ffc950dc6
commit
2a8a348b97
2 changed files with 212 additions and 4 deletions
|
|
@ -789,6 +789,210 @@ fn unsigned_keychain_and_auth_ops_are_rejected_during_peer_sync() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalidly_signed_keychain_and_auth_ops_are_rejected_during_peer_sync() {
|
||||
let left_home = tempfile::tempdir().expect("left tempdir");
|
||||
let right_home = tempfile::tempdir().expect("right tempdir");
|
||||
if !unix_sockets_available(left_home.path()) || !unix_sockets_available(right_home.path()) {
|
||||
return;
|
||||
}
|
||||
assert!(run_geth(left_home.path(), &["init"]).status.success());
|
||||
assert!(run_geth(right_home.path(), &["init"]).status.success());
|
||||
for home in [left_home.path(), right_home.path()] {
|
||||
std::fs::write(
|
||||
home.join("config.toml"),
|
||||
"[iroh]\nrelay_mode = \"disabled\"\nlocal_discovery = false\n",
|
||||
)
|
||||
.expect("write config");
|
||||
}
|
||||
let fake_admin_public_key =
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFakeAdminKeyMaterialForNegativeTests test@geth\n";
|
||||
let fake_admin_public_key_path = left_home.path().join("fake-admin.pub");
|
||||
std::fs::write(&fake_admin_public_key_path, fake_admin_public_key)
|
||||
.expect("write fake admin public key");
|
||||
|
||||
let mut left_daemon = spawn_daemon(left_home.path());
|
||||
let mut right_daemon = spawn_daemon(right_home.path());
|
||||
wait_for_socket(&left_home.path().join("run/geth.sock"));
|
||||
wait_for_socket(&right_home.path().join("run/geth.sock"));
|
||||
|
||||
let trust_admin = run_geth(
|
||||
left_home.path(),
|
||||
&[
|
||||
"keychain",
|
||||
"init",
|
||||
"--admin-key",
|
||||
fake_admin_public_key_path
|
||||
.to_str()
|
||||
.expect("fake admin public key path"),
|
||||
],
|
||||
);
|
||||
assert!(
|
||||
trust_admin.status.success(),
|
||||
"trust admin stderr: {}",
|
||||
String::from_utf8_lossy(&trust_admin.stderr)
|
||||
);
|
||||
|
||||
let left_card_path = left_home.path().join("left-peer-card.json");
|
||||
let right_card_path = right_home.path().join("right-peer-card.json");
|
||||
assert!(
|
||||
run_geth(
|
||||
left_home.path(),
|
||||
&[
|
||||
"peer",
|
||||
"export",
|
||||
"--out",
|
||||
left_card_path.to_str().expect("left card path"),
|
||||
],
|
||||
)
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
assert!(
|
||||
run_geth(
|
||||
right_home.path(),
|
||||
&[
|
||||
"peer",
|
||||
"export",
|
||||
"--out",
|
||||
right_card_path.to_str().expect("right card path"),
|
||||
],
|
||||
)
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
let right_card_json = std::fs::read_to_string(&right_card_path).expect("read right card");
|
||||
let right_card: geth_discovery::PeerCard =
|
||||
serde_json::from_str(&right_card_json).expect("decode right card");
|
||||
assert!(
|
||||
run_geth(
|
||||
left_home.path(),
|
||||
&[
|
||||
"peer",
|
||||
"import",
|
||||
right_card_path.to_str().expect("right card path"),
|
||||
],
|
||||
)
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
assert!(
|
||||
run_geth(
|
||||
right_home.path(),
|
||||
&[
|
||||
"peer",
|
||||
"import",
|
||||
left_card_path.to_str().expect("left card path"),
|
||||
],
|
||||
)
|
||||
.status
|
||||
.success()
|
||||
);
|
||||
|
||||
let signer = geth_types::KeyId::new(geth_ssh_identity::ssh_public_key_fingerprint(
|
||||
fake_admin_public_key,
|
||||
));
|
||||
let keychain_op = geth_keychain::KeychainOp {
|
||||
id: geth_types::AuthOpId::new("keychain-op:invalid-signature-user-add"),
|
||||
created_at: geth_types::UnixMillis(20),
|
||||
kind: geth_keychain::KeychainOpKind::UserAdd {
|
||||
user: geth_types::UserId::new("user:invalid-signature"),
|
||||
name: "Invalid Signature".to_owned(),
|
||||
},
|
||||
};
|
||||
let auth_op = geth_auth::AuthOp {
|
||||
id: geth_types::AuthOpId::new("auth-op:invalid-signature-grant"),
|
||||
resource: geth_types::ResourceId::new("resource:ssh-proxy:local"),
|
||||
created_at: geth_types::UnixMillis(21),
|
||||
kind: geth_auth::AuthOpKind::GrantCreate {
|
||||
grant_id: "grant:invalid-signature".to_owned(),
|
||||
principal: geth_types::PrincipalId::new("node:invalid-signature"),
|
||||
capabilities: vec![geth_types::Capability::new("ssh_proxy.connect")],
|
||||
},
|
||||
};
|
||||
let right_paths = geth_config::GethPaths::from_home(right_home.path());
|
||||
let right_store =
|
||||
geth_store::Store::open(&right_paths.metadata_db()).expect("open right store");
|
||||
right_store
|
||||
.insert_keychain_op(&geth_store::StoredKeychainOp {
|
||||
op_id: keychain_op.id.to_string(),
|
||||
op_json: serde_json::to_string(&keychain_op).expect("encode keychain op"),
|
||||
created_at_ms: keychain_op.created_at.0,
|
||||
})
|
||||
.expect("insert invalidly signed keychain op");
|
||||
right_store
|
||||
.insert_keychain_signature(&geth_store::StoredKeychainSignature {
|
||||
op_id: keychain_op.id.to_string(),
|
||||
signer: signer.to_string(),
|
||||
signer_public_key: fake_admin_public_key.to_owned(),
|
||||
namespace: geth_keychain::KEYCHAIN_SIGNATURE_NAMESPACE.to_owned(),
|
||||
signature: b"not a valid openssh signature".to_vec(),
|
||||
created_at_ms: 22,
|
||||
})
|
||||
.expect("insert invalid keychain signature");
|
||||
right_store
|
||||
.insert_auth_op(&geth_store::StoredAuthOp {
|
||||
op_id: auth_op.id.to_string(),
|
||||
resource_id: auth_op.resource.to_string(),
|
||||
op_json: serde_json::to_string(&auth_op).expect("encode auth op"),
|
||||
created_at_ms: auth_op.created_at.0,
|
||||
})
|
||||
.expect("insert invalidly signed auth op");
|
||||
right_store
|
||||
.insert_auth_signature(&geth_store::StoredAuthSignature {
|
||||
op_id: auth_op.id.to_string(),
|
||||
signer: signer.to_string(),
|
||||
signer_public_key: fake_admin_public_key.to_owned(),
|
||||
namespace: geth_auth::AUTH_SIGNATURE_NAMESPACE.to_owned(),
|
||||
signature: b"not a valid openssh signature".to_vec(),
|
||||
created_at_ms: 23,
|
||||
})
|
||||
.expect("insert invalid auth signature");
|
||||
|
||||
let keychain_sync = run_geth(
|
||||
left_home.path(),
|
||||
&["keychain", "sync", right_card.node_id.as_str()],
|
||||
);
|
||||
let auth_sync = run_geth(
|
||||
left_home.path(),
|
||||
&["auth", "sync", right_card.node_id.as_str()],
|
||||
);
|
||||
let _ = left_daemon.kill();
|
||||
let _ = right_daemon.kill();
|
||||
let _ = left_daemon.wait();
|
||||
let _ = right_daemon.wait();
|
||||
|
||||
assert!(
|
||||
keychain_sync.status.success(),
|
||||
"keychain sync stderr: {}",
|
||||
String::from_utf8_lossy(&keychain_sync.stderr)
|
||||
);
|
||||
assert!(
|
||||
auth_sync.status.success(),
|
||||
"auth sync stderr: {}",
|
||||
String::from_utf8_lossy(&auth_sync.stderr)
|
||||
);
|
||||
assert!(String::from_utf8_lossy(&keychain_sync.stdout).contains("invalid_ops_rejected: 1"));
|
||||
assert!(String::from_utf8_lossy(&auth_sync.stdout).contains("invalid_ops_rejected: 1"));
|
||||
|
||||
let left_paths = geth_config::GethPaths::from_home(left_home.path());
|
||||
let left_store = geth_store::Store::open(&left_paths.metadata_db()).expect("open left store");
|
||||
assert!(
|
||||
!left_store
|
||||
.list_keychain_ops()
|
||||
.expect("list left keychain ops")
|
||||
.iter()
|
||||
.any(|op| op.op_id == keychain_op.id.as_str())
|
||||
);
|
||||
assert!(
|
||||
!left_store
|
||||
.list_auth_ops()
|
||||
.expect("list left auth ops")
|
||||
.iter()
|
||||
.any(|op| op.op_id == auth_op.id.as_str())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn peer_card_export_import_and_list_are_candidate_only() {
|
||||
let source_home = tempfile::tempdir().expect("source tempdir");
|
||||
|
|
|
|||
Loading…
Reference in a new issue