Add authorized pipe messages over Iroh

This commit is contained in:
Eric Wendland 2026-05-20 13:57:14 +02:00
commit 78dbbf240b
11 changed files with 712 additions and 31 deletions

View file

@ -1,4 +1,5 @@
use anyhow::{Context, Result, bail};
use base64::Engine;
use clap::{Args, Parser, Subcommand};
use geth_config::GethPaths;
use geth_control::{ControlRequest, ControlResponse};
@ -395,6 +396,19 @@ pub enum PipeCommand {
#[arg(long)]
bearer_secret: Option<String>,
},
Send {
target: String,
message: String,
#[arg(long)]
node: Option<String>,
#[arg(long)]
bearer_secret: Option<String>,
},
Recv {
name: String,
#[arg(long)]
peek: bool,
},
}
#[derive(Debug, Subcommand)]
@ -863,6 +877,18 @@ fn request_for_command(command: Command) -> Result<ControlRequest> {
node,
bearer_secret,
},
PipeCommand::Send {
target,
message,
node,
bearer_secret,
} => ControlRequest::PipeSend {
target,
data_base64: base64::engine::general_purpose::STANDARD.encode(message.as_bytes()),
node,
bearer_secret,
},
PipeCommand::Recv { name, peek } => ControlRequest::PipeRecv { name, peek },
},
Command::Db { command } => match command {
DbCommand::Add { name, path } => ControlRequest::DbAdd { name, path },
@ -1951,6 +1977,55 @@ fn print_response(response: ControlResponse, json: bool) -> Result<()> {
println!("reason: {reason}");
println!("note: {note}");
}
ControlResponse::PipeSent {
message,
listener_found,
note,
} => {
println!("listener_found: {listener_found}");
if let Some(message) = message {
println!("pipe: {}", message.pipe);
println!("received_at_ms: {}", message.received_at.0);
print_pipe_message_data(&message)?;
}
println!("note: {note}");
}
ControlResponse::PipeRemoteSent {
peer_node_id,
peer_agent_id,
endpoint_id,
message,
listener_found,
allowed,
reason,
note,
} => {
println!("peer: {peer_node_id}");
println!("agent: {peer_agent_id}");
println!("endpoint: {endpoint_id}");
println!("allowed: {allowed}");
println!("listener_found: {listener_found}");
if let Some(message) = message {
println!("pipe: {}", message.pipe);
println!("received_at_ms: {}", message.received_at.0);
}
println!("reason: {reason}");
println!("note: {note}");
}
ControlResponse::PipeMessages {
name,
messages,
drained,
note,
} => {
println!("pipe: {name}");
println!("messages: {}", messages.len());
println!("drained: {drained}");
for message in messages {
print_pipe_message_data(&message)?;
}
println!("note: {note}");
}
ControlResponse::SshProxyConnected {
peer_node_id,
peer_agent_id,
@ -2051,6 +2126,20 @@ fn print_file_conflict(conflict: &geth_cas::FileConflict) {
}
}
fn print_pipe_message_data(message: &geth_pipe::PipeMessage) -> Result<()> {
let bytes = base64::engine::general_purpose::STANDARD
.decode(&message.data_base64)
.context("decode pipe message")?;
match String::from_utf8(bytes) {
Ok(text) => println!("{text}"),
Err(error) => println!(
"base64:{}",
base64::engine::general_purpose::STANDARD.encode(error.into_bytes())
),
}
Ok(())
}
fn shell_quote_command(command: &[String]) -> String {
command
.iter()