use std::ffi::OsString;
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::syscall_filter::SyscallFilter;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct DirectoryMount {
pub target: PathBuf,
pub source: PathBuf,
pub writable: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SandboxConfiguration {
pub time_limit: Option<u64>,
pub memory_limit: Option<u64>,
pub stack_limit: Option<u64>,
pub executable: PathBuf,
pub args: Vec<OsString>,
pub env: Vec<(OsString, OsString)>,
pub mount_paths: Vec<DirectoryMount>,
pub working_directory: PathBuf,
pub stdin: Option<PathBuf>,
pub stdout: Option<PathBuf>,
pub stderr: Option<PathBuf>,
pub syscall_filter: Option<SyscallFilter>,
pub mount_tmpfs: bool,
pub wall_time_limit: Option<u64>,
pub cpu_core: Option<usize>,
pub uid: usize,
pub gid: usize,
pub mount_proc: bool,
}
impl Default for SandboxConfiguration {
fn default() -> Self {
SandboxConfiguration {
time_limit: None,
memory_limit: None,
stack_limit: None,
executable: PathBuf::from("/bin/sh"),
args: vec![],
env: vec![],
mount_paths: vec![],
working_directory: PathBuf::from("/"),
stdin: None,
stdout: None,
stderr: None,
syscall_filter: None,
mount_tmpfs: false,
wall_time_limit: None,
cpu_core: None,
uid: 0,
gid: 0,
mount_proc: false,
}
}
}
impl SandboxConfiguration {
pub fn build(&self) -> SandboxConfiguration {
self.clone()
}
pub fn time_limit(&mut self, time_limit: u64) -> &mut Self {
self.time_limit = Some(time_limit);
self
}
pub fn memory_limit(&mut self, memory_limit: u64) -> &mut Self {
self.memory_limit = Some(memory_limit);
self
}
pub fn stack_limit(&mut self, stack_limit: u64) -> &mut Self {
self.stack_limit = Some(stack_limit);
self
}
pub fn stdin<P: Into<PathBuf>>(&mut self, stdin: P) -> &mut Self {
self.stdin = Some(stdin.into());
self
}
pub fn stdout<P: Into<PathBuf>>(&mut self, stdout: P) -> &mut Self {
self.stdout = Some(stdout.into());
self
}
pub fn stderr<P: Into<PathBuf>>(&mut self, stderr: P) -> &mut Self {
self.stderr = Some(stderr.into());
self
}
pub fn executable<P: Into<PathBuf>>(&mut self, executable: P) -> &mut Self {
self.executable = executable.into();
self
}
pub fn working_directory<P: Into<PathBuf>>(&mut self, working_directory: P) -> &mut Self {
self.working_directory = working_directory.into();
self
}
pub fn arg<S: Into<OsString>>(&mut self, arg: S) -> &mut Self {
self.args.push(arg.into());
self
}
pub fn env<S: Into<OsString>, T: Into<OsString>>(
&mut self,
variable: S,
value: T,
) -> &mut Self {
self.env.push((variable.into(), value.into()));
self
}
pub fn mount<P, Q>(&mut self, source: P, target: Q, writable: bool) -> &mut Self
where
P: Into<PathBuf>,
Q: Into<PathBuf>,
{
self.mount_paths.push(DirectoryMount {
source: source.into(),
target: target.into(),
writable,
});
self
}
pub fn syscall_filter(&mut self, filter: SyscallFilter) -> &mut Self {
self.syscall_filter = Some(filter);
self
}
pub fn mount_tmpfs(&mut self, value: bool) -> &mut Self {
self.mount_tmpfs = value;
self
}
pub fn wall_time_limit(&mut self, value: u64) -> &mut Self {
self.wall_time_limit = Some(value);
self
}
pub fn run_on_core(&mut self, value: usize) -> &mut Self {
self.cpu_core = Some(value);
self
}
pub fn uid(&mut self, uid: usize) -> &mut Self {
self.uid = uid;
self
}
pub fn gid(&mut self, gid: usize) -> &mut Self {
self.gid = gid;
self
}
pub fn mount_proc(&mut self, mount_proc: bool) -> &mut Self {
self.mount_proc = mount_proc;
self
}
}