pub struct FileAccess<'a> {
pub(crate) inner: Inner<'a>,
create_with_mode: Option<u32>,
follow_final_links: bool,
}
Expand description
Helper object for accessing a file on disk while checking the necessary permissions.
You can use a FileAccess
when you want to read or write a file,
while making sure that the file obeys the permissions rules of
an associated CheckedDir
or Verifier
.
FileAccess
is a separate type from CheckedDir
and Verifier
so that you can set options to control the behavior of how files are opened.
Note: When we refer to a path “obeying the constraints” of this FileAccess
,
we mean:
- If the
FileAccess
wraps aCheckedDir
, the requirement that it is a relative path containing no “..” elements, or other elements that would take it outside theCheckedDir
. - If the
FileAccess
wraps aVerifier
, there are no requirements.
Fields§
§inner: Inner<'a>
Validator object that we use for checking file permissions.
create_with_mode: Option<u32>
If set, we create files with this mode.
follow_final_links: bool
If set, we follow final-position symlinks in provided paths.
Implementations§
Source§impl<'a> FileAccess<'a>
impl<'a> FileAccess<'a>
Sourcepub(crate) fn from_checked_dir(checked_dir: &'a CheckedDir) -> Self
pub(crate) fn from_checked_dir(checked_dir: &'a CheckedDir) -> Self
Create a new FileAccess
to access files within CheckedDir,
using default options.
Sourcepub(crate) fn from_verifier(verifier: Verifier<'a>) -> Self
pub(crate) fn from_verifier(verifier: Verifier<'a>) -> Self
Create a new FileAccess
to access files anywhere on the filesystem,
using default options.
Sourcefn from_inner(inner: Inner<'a>) -> Self
fn from_inner(inner: Inner<'a>) -> Self
Create a new FileAccess
from inner
,
using default options.
Sourcefn verified_full_path(
&self,
path: &Path,
check_type: FullPathCheck,
) -> Result<PathBuf>
fn verified_full_path( &self, path: &Path, check_type: FullPathCheck, ) -> Result<PathBuf>
Check path constraints on path
and verify its permissions
(or the permissions of its parent) according to check_type
Sourcefn location_unverified<'b>(&self, path: &'b Path) -> Result<Cow<'b, Path>>
fn location_unverified<'b>(&self, path: &'b Path) -> Result<Cow<'b, Path>>
Return the location of path
relative to this verifier.
Fails if path
does not obey the constraints of this FileAccess
,
but does not do any permissions checking.
Sourcepub fn create_with_mode(self, mode: u32) -> Self
pub fn create_with_mode(self, mode: u32) -> Self
Configure this FileAccess: when used to create a file, that file will be created with the provided unix permissions.
If this option is not set, newly created files have mode 0600.
Sourcepub fn follow_final_links(self, follow: bool) -> Self
pub fn follow_final_links(self, follow: bool) -> Self
Configure this FileAccess: if the file to be accessed is a symlink, and this is set to true, we will follow that symlink when creating or reading the file.
By default, this option is false.
Note that if you use this option with a CheckedDir
,
it can read or write a file outside of the CheckedDir
,
which might not be what you wanted.
This option does not affect the handling of links that are not in the final position of the path.
This option does not disable the regular fs-mistrust
checks:
we still ensure that the link’s target, and its location, are not
modifiable by an untrusted user.
Sourcepub fn open<P: AsRef<Path>>(
self,
path: P,
options: &OpenOptions,
) -> Result<File>
pub fn open<P: AsRef<Path>>( self, path: P, options: &OpenOptions, ) -> Result<File>
Open a file relative to this FileAccess
, using a set of OpenOptions
.
path
must be a path to the new file, obeying the constraints of this FileAccess
.
We check, but do not create, the file’s parent directories.
We check the file’s permissions after opening it.
If the file is created (and this is a unix-like operating system), we
always create it with a mode based on create_with_mode()
,
regardless of any mode set in options
.
If create_with_mode()
wasn’t called, we create the file with mode 600.
Sourcefn open_internal(&self, path: &Path, options: &OpenOptions) -> Result<File>
fn open_internal(&self, path: &Path, options: &OpenOptions) -> Result<File>
As open
, but take self
by reference. For internal use.
Sourcepub fn read_to_string<P: AsRef<Path>>(self, path: P) -> Result<String>
pub fn read_to_string<P: AsRef<Path>>(self, path: P) -> Result<String>
Read the contents of the file at path
relative to this FileAccess
, as a
String, if possible.
Return an error if path
is absent, if its permissions are incorrect,
if it does not obey the constraints of this FileAccess
,
or if its contents are not UTF-8.
Sourcepub fn read<P: AsRef<Path>>(self, path: P) -> Result<Vec<u8>>
pub fn read<P: AsRef<Path>>(self, path: P) -> Result<Vec<u8>>
Read the contents of the file at path
relative to this FileAccess
, as a
vector of bytes, if possible.
Return an error if path
is absent, if its permissions are incorrect,
or if it does not obey the constraints of this FileAccess
.
Sourcepub fn write_and_replace<P: AsRef<Path>, C: AsRef<[u8]>>(
self,
path: P,
contents: C,
) -> Result<()>
pub fn write_and_replace<P: AsRef<Path>, C: AsRef<[u8]>>( self, path: P, contents: C, ) -> Result<()>
Store contents
into the file located at path
relative to this FileAccess
.
We won’t write to path
directly: instead, we’ll write to a temporary
file in the same directory as path
, and then replace path
with that
temporary file if we were successful. (This isn’t truly atomic on all
file systems, but it’s closer than many alternatives.)
§Limitations
This function will clobber any existing files with the same name as
path
but with the extension tmp
. (That is, if you are writing to
“foo.txt”, it will replace “foo.tmp” in the same directory.)
This function may give incorrect behavior if multiple threads or processes are writing to the same file at the same time: it is the programmer’s responsibility to use appropriate locking to avoid this.