* fix(channels): execute tool calls in channel runtime (#302) * chore(fmt): align repo formatting with rustfmt 1.92
81 lines
2 KiB
Rust
81 lines
2 KiB
Rust
//! Sandbox trait for pluggable OS-level isolation
|
|
|
|
use async_trait::async_trait;
|
|
use std::process::Command;
|
|
|
|
/// Sandbox backend for OS-level isolation
|
|
#[async_trait]
|
|
pub trait Sandbox: Send + Sync {
|
|
/// Wrap a command with sandbox protection
|
|
fn wrap_command(&self, cmd: &mut Command) -> std::io::Result<()>;
|
|
|
|
/// Check if this sandbox backend is available on the current platform
|
|
fn is_available(&self) -> bool;
|
|
|
|
/// Human-readable name of this sandbox backend
|
|
fn name(&self) -> &str;
|
|
|
|
/// Description of what this sandbox provides
|
|
fn description(&self) -> &str;
|
|
}
|
|
|
|
/// No-op sandbox (always available, provides no additional isolation)
|
|
#[derive(Debug, Clone, Default)]
|
|
pub struct NoopSandbox;
|
|
|
|
impl Sandbox for NoopSandbox {
|
|
fn wrap_command(&self, _cmd: &mut Command) -> std::io::Result<()> {
|
|
// Pass through unchanged
|
|
Ok(())
|
|
}
|
|
|
|
fn is_available(&self) -> bool {
|
|
true
|
|
}
|
|
|
|
fn name(&self) -> &str {
|
|
"none"
|
|
}
|
|
|
|
fn description(&self) -> &str {
|
|
"No sandboxing (application-layer security only)"
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn noop_sandbox_name() {
|
|
assert_eq!(NoopSandbox.name(), "none");
|
|
}
|
|
|
|
#[test]
|
|
fn noop_sandbox_is_always_available() {
|
|
assert!(NoopSandbox.is_available());
|
|
}
|
|
|
|
#[test]
|
|
fn noop_sandbox_wrap_command_is_noop() {
|
|
let mut cmd = Command::new("echo");
|
|
cmd.arg("test");
|
|
let original_program = cmd.get_program().to_string_lossy().to_string();
|
|
let original_args: Vec<String> = cmd
|
|
.get_args()
|
|
.map(|s| s.to_string_lossy().to_string())
|
|
.collect();
|
|
|
|
let sandbox = NoopSandbox;
|
|
assert!(sandbox.wrap_command(&mut cmd).is_ok());
|
|
|
|
// Command should be unchanged
|
|
assert_eq!(cmd.get_program().to_string_lossy(), original_program);
|
|
assert_eq!(
|
|
cmd.get_args()
|
|
.map(|s| s.to_string_lossy().to_string())
|
|
.collect::<Vec<_>>(),
|
|
original_args
|
|
);
|
|
}
|
|
}
|