By default, forbid special files.
This commit is contained in:
parent
2042d0934b
commit
d574afa230
|
@ -1,6 +1,9 @@
|
|||
//! Implementation logic for `fs-mistrust`.
|
||||
|
||||
use std::{fs::Metadata, path::Path};
|
||||
use std::{
|
||||
fs::{FileType, Metadata},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
use std::os::unix::prelude::MetadataExt;
|
||||
|
@ -88,18 +91,11 @@ impl<'a> super::Verifier<'a> {
|
|||
self.enforce_type
|
||||
} else {
|
||||
// We make sure that everything at a higher level is a directory.
|
||||
Some(Type::Dir)
|
||||
Type::Dir
|
||||
};
|
||||
|
||||
let have_type = meta.file_type();
|
||||
match want_type {
|
||||
Some(Type::Dir) if !have_type.is_dir() => {
|
||||
errors.push(Error::BadType(path.into()));
|
||||
}
|
||||
Some(Type::File) if !have_type.is_file() => {
|
||||
errors.push(Error::BadType(path.into()));
|
||||
}
|
||||
_ => {}
|
||||
if !want_type.matches(meta.file_type()) {
|
||||
errors.push(Error::BadType(path.into()));
|
||||
}
|
||||
|
||||
// If we are on unix, make sure that the owner and permissions are
|
||||
|
@ -152,3 +148,16 @@ impl<'a> super::Verifier<'a> {
|
|||
errors
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Type {
|
||||
/// Return true if this required type is matched by a given `FileType`
|
||||
/// object.
|
||||
fn matches(&self, have_type: FileType) -> bool {
|
||||
match self {
|
||||
Type::Dir => have_type.is_dir(),
|
||||
Type::File => have_type.is_file(),
|
||||
Type::DirOrFile => have_type.is_dir() || have_type.is_file(),
|
||||
Type::Anything => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,6 @@
|
|||
// - Test the absolute heck out of it.
|
||||
|
||||
// POSSIBLY TODO:
|
||||
// - Forbid special files even when not checking file type?
|
||||
// - Cache information across runs.
|
||||
// - Add a way to recursively check the contents of a directory.
|
||||
// - Define a hard-to-misuse API for opening files, making secret directories, etc etc.
|
||||
|
@ -205,7 +204,7 @@ pub struct Verifier<'a> {
|
|||
|
||||
/// If the user called [`Verifier::require_file`] or
|
||||
/// [`Verifier::require_directory`], which did they call?
|
||||
enforce_type: Option<Type>,
|
||||
enforce_type: Type,
|
||||
}
|
||||
|
||||
/// A type of object that we have been told to require.
|
||||
|
@ -215,6 +214,10 @@ enum Type {
|
|||
Dir,
|
||||
/// A regular file.
|
||||
File,
|
||||
/// A directory or a regular file.
|
||||
DirOrFile,
|
||||
/// Absolutely anything at all.
|
||||
Anything,
|
||||
}
|
||||
|
||||
impl Mistrust {
|
||||
|
@ -279,7 +282,7 @@ impl Mistrust {
|
|||
mistrust: self,
|
||||
readable_okay: false,
|
||||
collect_multiple_errors: false,
|
||||
enforce_type: None,
|
||||
enforce_type: Type::DirOrFile,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,14 +313,25 @@ impl<'a> Verifier<'a> {
|
|||
/// Configure this `Verifier` to require that all paths it checks be
|
||||
/// files (not directories).
|
||||
pub fn require_file(mut self) -> Self {
|
||||
self.enforce_type = Some(Type::File);
|
||||
self.enforce_type = Type::File;
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure this `Verifier` to require that all paths it checks be
|
||||
/// directories.
|
||||
pub fn require_directory(mut self) -> Self {
|
||||
self.enforce_type = Some(Type::Dir);
|
||||
self.enforce_type = Type::Dir;
|
||||
self
|
||||
}
|
||||
|
||||
/// Configure this `Verifier` to allow the paths that it checks to be
|
||||
/// filesystem objects of any type.
|
||||
///
|
||||
/// By default, the final path (after resolving all links) must be a
|
||||
/// directory or a regular file, not (for example) a block device or a named
|
||||
/// pipe.
|
||||
pub fn permit_all_object_types(mut self) -> Self {
|
||||
self.enforce_type = Type::Anything;
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -397,7 +411,7 @@ impl<'a> Verifier<'a> {
|
|||
/// * after creating the directory, we found that it had a permissions or
|
||||
/// ownership problem.
|
||||
pub fn make_directory<P: AsRef<Path>>(mut self, path: P) -> Result<()> {
|
||||
self.enforce_type = Some(Type::Dir);
|
||||
self.enforce_type = Type::Dir;
|
||||
|
||||
let path = path.as_ref();
|
||||
match self.clone().check(path) {
|
||||
|
|
Loading…
Reference in New Issue