use std::path::{Path, PathBuf};
use crate::error::SandboxError;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum ProtectSystem {
#[default]
No,
Yes,
Full,
Strict,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum ProtectHome {
#[default]
No,
Yes,
ReadOnly,
}
#[derive(Debug, Clone, Default)]
pub struct Sandbox {
pub(crate) protect_system: ProtectSystem,
pub(crate) protect_home: ProtectHome,
pub(crate) read_only_paths: Vec<PathBuf>,
pub(crate) read_write_paths: Vec<PathBuf>,
pub(crate) inaccessible_paths: Vec<PathBuf>,
pub(crate) exec_paths: Vec<PathBuf>,
pub(crate) no_exec_paths: Vec<PathBuf>,
pub(crate) private_network: bool,
pub(crate) no_new_privileges: bool,
pub(crate) limit_nofile: Option<u64>,
pub(crate) limit_nproc: Option<u64>,
pub(crate) limit_core: Option<u64>,
pub(crate) limit_fsize: Option<u64>,
pub(crate) limit_data: Option<u64>,
pub(crate) limit_stack: Option<u64>,
pub(crate) limit_cpu: Option<u64>,
pub(crate) limit_memlock: Option<u64>,
}
impl Sandbox {
pub fn new() -> Self {
Self::default()
}
pub fn protect_system(mut self, level: ProtectSystem) -> Self {
self.protect_system = level;
self
}
pub fn protect_home(mut self, level: ProtectHome) -> Self {
self.protect_home = level;
self
}
pub fn read_only_paths<I, P>(mut self, paths: I) -> Self
where
I: IntoIterator<Item = P>,
P: AsRef<Path>,
{
self.read_only_paths
.extend(paths.into_iter().map(|p| p.as_ref().to_path_buf()));
self
}
pub fn read_write_paths<I, P>(mut self, paths: I) -> Self
where
I: IntoIterator<Item = P>,
P: AsRef<Path>,
{
self.read_write_paths
.extend(paths.into_iter().map(|p| p.as_ref().to_path_buf()));
self
}
pub fn inaccessible_paths<I, P>(mut self, paths: I) -> Self
where
I: IntoIterator<Item = P>,
P: AsRef<Path>,
{
self.inaccessible_paths
.extend(paths.into_iter().map(|p| p.as_ref().to_path_buf()));
self
}
pub fn exec_paths<I, P>(mut self, paths: I) -> Self
where
I: IntoIterator<Item = P>,
P: AsRef<Path>,
{
self.exec_paths
.extend(paths.into_iter().map(|p| p.as_ref().to_path_buf()));
self
}
pub fn no_exec_paths<I, P>(mut self, paths: I) -> Self
where
I: IntoIterator<Item = P>,
P: AsRef<Path>,
{
self.no_exec_paths
.extend(paths.into_iter().map(|p| p.as_ref().to_path_buf()));
self
}
pub fn private_network(mut self, enable: bool) -> Self {
self.private_network = enable;
self
}
pub fn no_new_privileges(mut self, enable: bool) -> Self {
self.no_new_privileges = enable;
self
}
pub fn limit_nofile(mut self, limit: u64) -> Self {
self.limit_nofile = Some(limit);
self
}
pub fn limit_nproc(mut self, limit: u64) -> Self {
self.limit_nproc = Some(limit);
self
}
pub fn limit_core(mut self, limit: u64) -> Self {
self.limit_core = Some(limit);
self
}
pub fn limit_fsize(mut self, limit: u64) -> Self {
self.limit_fsize = Some(limit);
self
}
pub fn limit_data(mut self, limit: u64) -> Self {
self.limit_data = Some(limit);
self
}
pub fn limit_stack(mut self, limit: u64) -> Self {
self.limit_stack = Some(limit);
self
}
pub fn limit_cpu(mut self, limit: u64) -> Self {
self.limit_cpu = Some(limit);
self
}
pub fn limit_memlock(mut self, limit: u64) -> Self {
self.limit_memlock = Some(limit);
self
}
pub fn build(self) -> Result<SandboxPolicy, SandboxError> {
Ok(SandboxPolicy { config: self })
}
}
#[derive(Debug, Clone)]
pub struct SandboxPolicy {
pub(crate) config: Sandbox,
}