use crate::{Access, AccessFs, AccessNet, BitFlags};
use std::io;
use std::path::PathBuf;
use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum RulesetError {
#[error(transparent)]
HandleAccesses(#[from] HandleAccessesError),
#[error(transparent)]
CreateRuleset(#[from] CreateRulesetError),
#[error(transparent)]
AddRules(#[from] AddRulesError),
#[error(transparent)]
RestrictSelf(#[from] RestrictSelfError),
}
#[test]
fn ruleset_error_breaking_change() {
use crate::*;
let _: RulesetError = RulesetError::HandleAccesses(HandleAccessesError::Fs(
HandleAccessError::Compat(CompatError::Access(AccessError::Empty)),
));
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum HandleAccessError<T>
where
T: Access,
{
#[error(transparent)]
Compat(#[from] CompatError<T>),
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum HandleAccessesError {
#[error(transparent)]
Fs(HandleAccessError<AccessFs>),
#[error(transparent)]
Net(HandleAccessError<AccessNet>),
}
impl<A> From<HandleAccessError<A>> for HandleAccessesError
where
A: Access,
{
fn from(error: HandleAccessError<A>) -> Self {
A::into_handle_accesses_error(error)
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum CreateRulesetError {
#[error("failed to create a ruleset: {source}")]
#[non_exhaustive]
CreateRulesetCall { source: io::Error },
#[error("missing handled access")]
MissingHandledAccess,
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum AddRuleError<T>
where
T: Access,
{
#[error("failed to add a rule: {source}")]
#[non_exhaustive]
AddRuleCall { source: io::Error },
#[error("access-rights not handled by the ruleset: {incompatible:?}")]
UnhandledAccess {
access: BitFlags<T>,
incompatible: BitFlags<T>,
},
#[error(transparent)]
Compat(#[from] CompatError<T>),
}
impl<A> From<AddRuleError<A>> for AddRulesError
where
A: Access,
{
fn from(error: AddRuleError<A>) -> Self {
A::into_add_rules_error(error)
}
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum AddRulesError {
#[error(transparent)]
Fs(AddRuleError<AccessFs>),
#[error(transparent)]
Net(AddRuleError<AccessNet>),
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum CompatError<T>
where
T: Access,
{
#[error(transparent)]
PathBeneath(#[from] PathBeneathError),
#[error(transparent)]
Access(#[from] AccessError<T>),
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum PathBeneathError {
#[error("failed to check file descriptor type: {source}")]
#[non_exhaustive]
StatCall { source: io::Error },
#[error("incompatible directory-only access-rights: {incompatible:?}")]
DirectoryAccess {
access: BitFlags<AccessFs>,
incompatible: BitFlags<AccessFs>,
},
}
#[derive(Debug, Error)]
pub enum AccessError<T>
where
T: Access,
{
#[error("empty access-right")]
Empty,
#[error("unknown access-rights (at build time): {unknown:?}")]
Unknown {
access: BitFlags<T>,
unknown: BitFlags<T>,
},
#[error("fully incompatible access-rights: {access:?}")]
Incompatible { access: BitFlags<T> },
#[error("partially incompatible access-rights: {incompatible:?}")]
PartiallyCompatible {
access: BitFlags<T>,
incompatible: BitFlags<T>,
},
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum RestrictSelfError {
#[error("failed to set no_new_privs: {source}")]
#[non_exhaustive]
SetNoNewPrivsCall { source: io::Error },
#[error("failed to restrict the calling thread: {source}")]
#[non_exhaustive]
RestrictSelfCall { source: io::Error },
}
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum PathFdError {
#[error("failed to open \"{path}\": {source}")]
#[non_exhaustive]
OpenCall { source: io::Error, path: PathBuf },
}
#[cfg(test)]
#[derive(Debug, Error)]
pub(crate) enum TestRulesetError {
#[error(transparent)]
Ruleset(#[from] RulesetError),
#[error(transparent)]
PathFd(#[from] PathFdError),
#[error(transparent)]
File(#[from] std::io::Error),
}