130 lines
4.7 KiB
Rust
130 lines
4.7 KiB
Rust
use std::path::PathBuf;
|
|
|
|
#[derive(Debug)]
|
|
pub enum SandboxError {
|
|
HomeNotSet,
|
|
RunUserNotFound,
|
|
BwrapNotFound,
|
|
CommandNotFound(PathBuf),
|
|
CommandNotExecutable(PathBuf),
|
|
PathMissing(PathBuf),
|
|
ChdirMissing(PathBuf),
|
|
CurrentDirUnavailable(std::io::Error),
|
|
GlobPattern(glob::PatternError),
|
|
Io(std::io::Error),
|
|
ConfigRead {
|
|
path: PathBuf,
|
|
source: std::io::Error,
|
|
},
|
|
ConfigParse {
|
|
path: PathBuf,
|
|
source: toml::de::Error,
|
|
},
|
|
ProfileNotFound(String),
|
|
ConflictingMode,
|
|
ConflictingEnvKey(String),
|
|
InvalidEnvEntry(String),
|
|
UnknownConfigKey(String),
|
|
NestedExtraConfig(PathBuf),
|
|
ConfigPathNotAbsolute(PathBuf),
|
|
InvalidBwrapArg(String),
|
|
InvalidBindSpec(String),
|
|
NoCommand,
|
|
Seccomp(String),
|
|
SeccompUnsupportedArch(String),
|
|
}
|
|
|
|
impl std::fmt::Display for SandboxError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::HomeNotSet => write!(
|
|
f,
|
|
"$HOME is not set; cannot determine which paths to protect"
|
|
),
|
|
Self::RunUserNotFound => write!(
|
|
f,
|
|
"cannot determine XDG_RUNTIME_DIR; tried $XDG_RUNTIME_DIR and /proc/self/status"
|
|
),
|
|
Self::BwrapNotFound => write!(
|
|
f,
|
|
"bwrap not found; install bubblewrap (e.g. `apt install bubblewrap` or `pacman -S bubblewrap`)"
|
|
),
|
|
Self::CommandNotFound(p) => write!(f, "command not found: {}", p.display()),
|
|
Self::CommandNotExecutable(p) => {
|
|
write!(f, "command is not executable: {}", p.display())
|
|
}
|
|
Self::PathMissing(p) => write!(f, "path does not exist: {}", p.display()),
|
|
Self::ChdirMissing(p) => write!(f, "--chdir path does not exist: {}", p.display()),
|
|
Self::CurrentDirUnavailable(e) => write!(f, "cannot determine current directory: {e}"),
|
|
Self::GlobPattern(e) => write!(f, "invalid glob pattern: {e}"),
|
|
Self::Io(e) => write!(f, "I/O error: {e}"),
|
|
Self::ConfigRead { path, source } => {
|
|
write!(f, "cannot read config file '{}': {source}", path.display())
|
|
}
|
|
Self::ConfigParse { path, source } => {
|
|
write!(f, "cannot parse config file '{}': {source}", path.display())
|
|
}
|
|
Self::ProfileNotFound(name) => write!(f, "profile not found in config: {name}"),
|
|
Self::ConflictingMode => write!(
|
|
f,
|
|
"config section sets both blacklist and whitelist to true"
|
|
),
|
|
Self::ConflictingEnvKey(key) => {
|
|
write!(f, "conflicting environment variable options for key: {key}")
|
|
}
|
|
Self::InvalidEnvEntry(raw) => {
|
|
write!(f, "invalid env entry (expected KEY or KEY=VALUE): {raw:?}")
|
|
}
|
|
Self::UnknownConfigKey(key) => write!(f, "unknown config key: {key}"),
|
|
Self::NestedExtraConfig(p) => write!(
|
|
f,
|
|
"extra-config file '{}' sets its own extra-config (nesting not supported)",
|
|
p.display()
|
|
),
|
|
Self::ConfigPathNotAbsolute(p) => {
|
|
write!(f, "config path is not absolute: {}", p.display())
|
|
}
|
|
Self::InvalidBwrapArg(s) => {
|
|
write!(f, "invalid quoting in --bwrap-arg: {s}")
|
|
}
|
|
Self::InvalidBindSpec(s) => {
|
|
write!(f, "invalid bind spec (expected SRC or SRC:DST): {s:?}")
|
|
}
|
|
Self::NoCommand => write!(
|
|
f,
|
|
"no command to run; specify a command via config, entrypoint, or pass one after --"
|
|
),
|
|
Self::Seccomp(msg) => write!(f, "failed to build seccomp filter: {msg}"),
|
|
Self::SeccompUnsupportedArch(arch) => write!(
|
|
f,
|
|
"seccomp filtering is not supported on this architecture: {arch} (use --no-seccomp to disable)"
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for SandboxError {
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
match self {
|
|
Self::CurrentDirUnavailable(e) => Some(e),
|
|
Self::GlobPattern(e) => Some(e),
|
|
Self::Io(e) => Some(e),
|
|
Self::ConfigRead { source, .. } => Some(source),
|
|
Self::ConfigParse { source, .. } => Some(source),
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<std::io::Error> for SandboxError {
|
|
fn from(e: std::io::Error) -> Self {
|
|
Self::Io(e)
|
|
}
|
|
}
|
|
|
|
impl From<glob::PatternError> for SandboxError {
|
|
fn from(e: glob::PatternError) -> Self {
|
|
Self::GlobPattern(e)
|
|
}
|
|
}
|