Add restricted SSH admin shell

This commit is contained in:
Eric Wendland 2026-05-21 01:49:48 +02:00
commit 59ccf6c748
9 changed files with 358 additions and 14 deletions

View file

@ -236,6 +236,11 @@ pub enum ControlRequest {
node: String,
bearer_secret: Option<String>,
},
SshAdminShell {
node: String,
command: String,
bearer_secret: Option<String>,
},
DbAdd {
name: String,
path: PathBuf,
@ -724,6 +729,16 @@ pub enum ControlResponse {
reason: String,
note: String,
},
SshAdminShellOutput {
peer_node_id: String,
peer_agent_id: String,
endpoint_id: String,
command: String,
output: String,
allowed: bool,
reason: String,
note: String,
},
NotImplemented {
module: String,
command: String,
@ -857,6 +872,12 @@ pub enum PeerControlRequest {
nonce: String,
bearer_proof: Option<BearerProof>,
},
SshAdminShell {
peer_card: PeerCard,
command: String,
nonce: String,
bearer_proof: Option<BearerProof>,
},
DocumentSync {
peer_card: PeerCard,
name: String,
@ -1038,6 +1059,19 @@ pub enum PeerControlResponse {
nonce: String,
note: String,
},
SshAdminShellOutput {
node_id: String,
agent_id: String,
endpoint_id: String,
remote_endpoint_id: String,
command: String,
output: String,
allowed: bool,
reason: String,
evaluated_ops: usize,
nonce: String,
note: String,
},
DocumentSynced {
node_id: String,
agent_id: String,
@ -1571,6 +1605,16 @@ mod tests {
request
);
let request = ControlRequest::SshAdminShell {
node: "node:peer".to_owned(),
command: "status".to_owned(),
bearer_secret: None,
};
assert_eq!(
decode_request(&encode_request(&request).expect("encode")).expect("decode"),
request
);
let response = ControlResponse::SshProxyConnected {
peer_node_id: "node:peer".to_owned(),
peer_agent_id: "agent:peer".to_owned(),
@ -1591,6 +1635,21 @@ mod tests {
response
);
let response = ControlResponse::SshAdminShellOutput {
peer_node_id: "node:peer".to_owned(),
peer_agent_id: "agent:peer".to_owned(),
endpoint_id: "endpoint:peer".to_owned(),
command: "status".to_owned(),
output: "node_id=node:peer".to_owned(),
allowed: true,
reason: "direct grant".to_owned(),
note: "restricted admin shell".to_owned(),
};
assert_eq!(
decode_response(&encode_response(&response).expect("encode")).expect("decode"),
response
);
let request = ControlRequest::DbChanges {
name: "notes".to_owned(),
after_db_version: Some(7),
@ -2039,6 +2098,34 @@ mod tests {
request
);
let request = PeerControlRequest::SshAdminShell {
peer_card: PeerCard {
node_id: "node:caller".into(),
agent_id: "agent:caller".into(),
endpoints: Vec::new(),
issued_at: geth_types::UnixMillis(1),
signature: geth_discovery::SignatureMetadata {
namespace: "geth.peer-card.v1@geth.local".to_owned(),
signer: "agent:caller".to_owned(),
public_key: "key".to_owned(),
signature: "sig".to_owned(),
},
},
command: "status".to_owned(),
nonce: "nonce".to_owned(),
bearer_proof: Some(BearerProof {
secret: "bearer:test".into(),
resource: "resource:ssh-proxy:local".into(),
capabilities: vec!["ssh_proxy.admin_shell".into()],
nonce: "nonce".to_owned(),
response: "response".to_owned(),
}),
};
assert_eq!(
decode_peer_request(&encode_peer_request(&request).expect("encode")).expect("decode"),
request
);
let request = PeerControlRequest::PipeListen {
peer_card: PeerCard {
node_id: "node:caller".into(),
@ -2209,6 +2296,25 @@ mod tests {
response
);
let response = PeerControlResponse::SshAdminShellOutput {
node_id: "node:peer".to_owned(),
agent_id: "agent:peer".to_owned(),
endpoint_id: "endpoint:peer".to_owned(),
remote_endpoint_id: "endpoint:caller".to_owned(),
command: "status".to_owned(),
output: "node_id=node:peer".to_owned(),
allowed: true,
reason: "direct grant".to_owned(),
evaluated_ops: 1,
nonce: "nonce".to_owned(),
note: "restricted admin shell".to_owned(),
};
assert_eq!(
decode_peer_response(&encode_peer_response(&response).expect("encode"))
.expect("decode"),
response
);
let response = PeerControlResponse::DbSynced {
node_id: "node:peer".to_owned(),
agent_id: "agent:peer".to_owned(),