80 lines
1.9 KiB
Rust
80 lines
1.9 KiB
Rust
mod agents;
|
|
mod blacklist;
|
|
pub mod cli;
|
|
pub mod config;
|
|
mod errors;
|
|
mod preflight;
|
|
mod sandbox;
|
|
|
|
pub use errors::SandboxError;
|
|
|
|
use std::env;
|
|
use std::ffi::OsString;
|
|
use std::fs;
|
|
use std::os::unix::process::CommandExt;
|
|
use std::path::PathBuf;
|
|
|
|
pub enum SandboxMode {
|
|
Blacklist,
|
|
Whitelist,
|
|
}
|
|
|
|
pub struct SandboxConfig {
|
|
pub mode: SandboxMode,
|
|
pub hardened: bool,
|
|
pub no_net: bool,
|
|
pub extra_rw: Vec<PathBuf>,
|
|
pub extra_ro: Vec<PathBuf>,
|
|
pub mask: Vec<PathBuf>,
|
|
pub bwrap_args: Vec<String>,
|
|
pub command: PathBuf,
|
|
pub command_args: Vec<OsString>,
|
|
pub chdir: PathBuf,
|
|
pub dry_run: bool,
|
|
}
|
|
|
|
pub fn require_home() -> Result<String, SandboxError> {
|
|
env::var("HOME")
|
|
.ok()
|
|
.filter(|h| !h.is_empty())
|
|
.ok_or(SandboxError::HomeNotSet)
|
|
}
|
|
|
|
pub fn require_run_user() -> Result<String, SandboxError> {
|
|
env::var("XDG_RUNTIME_DIR")
|
|
.ok()
|
|
.or_else(resolve_run_user_from_proc)
|
|
.ok_or(SandboxError::RunUserNotFound)
|
|
}
|
|
|
|
fn resolve_run_user_from_proc() -> Option<String> {
|
|
let status = fs::read_to_string("/proc/self/status").ok()?;
|
|
for line in status.lines() {
|
|
if let Some(rest) = line.strip_prefix("Uid:") {
|
|
let uid = rest.split_whitespace().next()?;
|
|
return Some(format!("/run/user/{uid}"));
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
pub fn run(config: SandboxConfig) -> Result<(), SandboxError> {
|
|
preflight::check(&config)?;
|
|
|
|
let mut cmd = sandbox::build_command(&config)?;
|
|
|
|
if config.dry_run {
|
|
println!("{}", shell_quote_command(&cmd));
|
|
return Ok(());
|
|
}
|
|
|
|
Err(SandboxError::Io(cmd.exec()))
|
|
}
|
|
|
|
fn shell_quote_command(cmd: &std::process::Command) -> String {
|
|
let prog = cmd.get_program().to_string_lossy();
|
|
let args = cmd.get_args().map(|a| a.to_string_lossy());
|
|
let all: Vec<_> = std::iter::once(prog).chain(args).collect();
|
|
shlex::try_join(all.iter().map(|s| s.as_ref())).unwrap()
|
|
}
|