feat: run zsh fork shell tool via shell-escalation

This commit is contained in:
Michael Bolin
2026-02-24 10:10:16 -08:00
parent f6053fdfb3
commit 3f7fbdd3a3
24 changed files with 706 additions and 723 deletions
+2 -2
View File
@@ -22,6 +22,6 @@ pub use unix::Stopwatch;
#[cfg(unix)]
pub use unix::main_execve_wrapper;
#[cfg(unix)]
pub use unix::run;
#[cfg(unix)]
pub use unix::run_escalate_server;
#[cfg(unix)]
pub use unix::run_shell_escalation_execve_wrapper;
@@ -42,7 +42,6 @@ impl ShellPolicyFactory {
/// Public only because it is the associated `Policy` type in the public
/// `EscalationPolicyFactory` impl for `ShellPolicyFactory`.
#[doc(hidden)]
pub struct ShellEscalationPolicy {
provider: Arc<dyn ShellActionProvider>,
stopwatch: Stopwatch,
@@ -27,7 +27,10 @@ fn get_escalate_client() -> anyhow::Result<AsyncDatagramSocket> {
Ok(unsafe { AsyncDatagramSocket::from_raw_fd(client_fd) }?)
}
pub async fn run(file: String, argv: Vec<String>) -> anyhow::Result<i32> {
pub async fn run_shell_escalation_execve_wrapper(
file: String,
argv: Vec<String>,
) -> anyhow::Result<i32> {
let handshake_client = get_escalate_client()?;
let (server, client) = AsyncSocket::pair()?;
const HANDSHAKE_MESSAGE: [u8; 1] = [0];
@@ -45,7 +45,7 @@ pub trait ShellCommandExecutor: Send + Sync {
#[derive(Debug, serde::Deserialize, serde::Serialize)]
pub struct ExecParams {
/// The bash string to execute.
/// The the string of Zsh/shell to execute.
pub command: String,
/// The working directory to execute the command in. Must be an absolute path.
pub workdir: String,
@@ -58,20 +58,22 @@ pub struct ExecParams {
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ExecResult {
pub exit_code: i32,
pub stdout: String,
pub stderr: String,
/// Aggregated stdout+stderr output for compatibility with existing callers.
pub output: String,
pub duration: Duration,
pub timed_out: bool,
}
#[allow(clippy::module_name_repetitions)]
pub struct EscalateServer {
struct EscalateServer {
bash_path: PathBuf,
execve_wrapper: PathBuf,
policy: Arc<dyn EscalationPolicy>,
}
impl EscalateServer {
pub fn new<P>(bash_path: PathBuf, execve_wrapper: PathBuf, policy: P) -> Self
fn new<P>(bash_path: PathBuf, execve_wrapper: PathBuf, policy: P) -> Self
where
P: EscalationPolicy + Send + Sync + 'static,
{
@@ -82,7 +84,7 @@ impl EscalateServer {
}
}
pub async fn exec(
async fn exec(
&self,
params: ExecParams,
cancel_rx: CancellationToken,
@@ -20,6 +20,6 @@ pub async fn main_execve_wrapper() -> anyhow::Result<()> {
.init();
let ExecveWrapperCli { file, argv } = ExecveWrapperCli::parse();
let exit_code = crate::run(file, argv).await?;
let exit_code = crate::run_shell_escalation_execve_wrapper(file, argv).await?;
std::process::exit(exit_code);
}
+1 -1
View File
@@ -64,7 +64,7 @@ pub mod stopwatch;
pub use self::core_shell_escalation::ShellActionProvider;
pub use self::core_shell_escalation::ShellPolicyFactory;
pub use self::escalate_client::run;
pub use self::escalate_client::run_shell_escalation_execve_wrapper;
pub use self::escalate_protocol::EscalateAction;
pub use self::escalate_server::EscalationPolicyFactory;
pub use self::escalate_server::ExecParams;