sandbox_runtime/sandbox/
mod.rs

1//! Platform-specific sandbox implementations.
2
3#[cfg(target_os = "macos")]
4pub mod macos;
5
6#[cfg(target_os = "linux")]
7pub mod linux;
8
9use crate::config::SandboxRuntimeConfig;
10use crate::error::SandboxError;
11use crate::utils::Platform;
12
13/// Check if sandboxing dependencies are available for the current platform.
14pub fn check_dependencies(platform: Platform) -> Result<(), SandboxError> {
15    match platform {
16        Platform::MacOS => {
17            // sandbox-exec is built into macOS
18            Ok(())
19        }
20        Platform::Linux => {
21            #[cfg(target_os = "linux")]
22            {
23                if !linux::check_bwrap() {
24                    return Err(SandboxError::MissingDependency(
25                        "bubblewrap (bwrap) is required for Linux sandboxing".to_string(),
26                    ));
27                }
28                if !linux::check_socat() {
29                    return Err(SandboxError::MissingDependency(
30                        "socat is required for Linux network sandboxing".to_string(),
31                    ));
32                }
33                Ok(())
34            }
35            #[cfg(not(target_os = "linux"))]
36            {
37                Err(SandboxError::UnsupportedPlatform(
38                    "Linux sandbox code not compiled on this platform".to_string(),
39                ))
40            }
41        }
42    }
43}
44
45/// Wrap a command with platform-specific sandboxing.
46pub async fn wrap_command(
47    command: &str,
48    config: &SandboxRuntimeConfig,
49    platform: Platform,
50    http_proxy_port: Option<u16>,
51    socks_proxy_port: Option<u16>,
52    #[cfg(target_os = "linux")] http_socket_path: Option<&str>,
53    #[cfg(target_os = "linux")] socks_socket_path: Option<&str>,
54    shell: Option<&str>,
55    enable_log_monitor: bool,
56) -> Result<WrapResult, SandboxError> {
57    match platform {
58        Platform::MacOS => {
59            #[cfg(target_os = "macos")]
60            {
61                let (wrapped, log_tag) = macos::wrap_command(
62                    command,
63                    config,
64                    http_proxy_port,
65                    socks_proxy_port,
66                    shell,
67                    enable_log_monitor,
68                )?;
69                Ok(WrapResult {
70                    command: wrapped,
71                    log_tag,
72                    warnings: vec![],
73                })
74            }
75            #[cfg(not(target_os = "macos"))]
76            {
77                Err(SandboxError::UnsupportedPlatform(
78                    "macOS sandbox code not compiled on this platform".to_string(),
79                ))
80            }
81        }
82        Platform::Linux => {
83            #[cfg(target_os = "linux")]
84            {
85                let cwd = std::env::current_dir()?;
86                let (wrapped, warnings) = linux::generate_bwrap_command(
87                    command,
88                    config,
89                    &cwd,
90                    http_socket_path,
91                    socks_socket_path,
92                    http_proxy_port.unwrap_or(3128),
93                    socks_proxy_port.unwrap_or(1080),
94                    shell,
95                )?;
96                Ok(WrapResult {
97                    command: wrapped,
98                    log_tag: None,
99                    warnings,
100                })
101            }
102            #[cfg(not(target_os = "linux"))]
103            {
104                Err(SandboxError::UnsupportedPlatform(
105                    "Linux sandbox code not compiled on this platform".to_string(),
106                ))
107            }
108        }
109    }
110}
111
112/// Result of wrapping a command with sandbox.
113#[derive(Debug)]
114pub struct WrapResult {
115    /// The wrapped command string.
116    pub command: String,
117    /// Log tag for violation monitoring (macOS only).
118    pub log_tag: Option<String>,
119    /// Warnings generated during wrapping.
120    pub warnings: Vec<String>,
121}