diff --git a/Cargo.lock b/Cargo.lock index 16a307ac6..4b48b4e7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,6 +81,7 @@ dependencies = [ "clap", "config", "derive_builder", + "fs-mistrust", "futures", "libc", "notify", diff --git a/crates/arti-client/src/builder.rs b/crates/arti-client/src/builder.rs index 8140a8e24..3b7c741da 100644 --- a/crates/arti-client/src/builder.rs +++ b/crates/arti-client/src/builder.rs @@ -181,7 +181,8 @@ impl TorClientBuilder { self.runtime, self.config, self.bootstrap_behavior, - self.fs_mistrust.unwrap_or_else(default_fs_mistrust), + self.fs_mistrust + .unwrap_or_else(crate::config::default_fs_mistrust), self.dirmgr_builder.as_ref(), dirmgr_extensions, ) @@ -195,14 +196,3 @@ impl TorClientBuilder { Ok(r) } } - -/// Return a default value for our fs_mistrust configuration. -/// -/// This is based on the environment rather on the configuration file since, -fn default_fs_mistrust() -> fs_mistrust::Mistrust { - let mut mistrust = fs_mistrust::Mistrust::new(); - if std::env::var_os("ARTI_FS_DISABLE_PERMISSION_CHECKS").is_some() { - mistrust.dangerously_trust_everyone(); - } - mistrust -} diff --git a/crates/arti-client/src/config.rs b/crates/arti-client/src/config.rs index 6790fe587..8cb5c29b6 100644 --- a/crates/arti-client/src/config.rs +++ b/crates/arti-client/src/config.rs @@ -358,6 +358,18 @@ impl TorClientConfigBuilder { } } +/// Return a default value for our fs_mistrust configuration. +/// +/// This is based on the environment rather on the configuration, since we may +/// want to use it to determine whether configuration files are safe to read. +pub fn default_fs_mistrust() -> fs_mistrust::Mistrust { + let mut mistrust = fs_mistrust::Mistrust::new(); + if std::env::var_os("ARTI_FS_DISABLE_PERMISSION_CHECKS").is_some() { + mistrust.dangerously_trust_everyone(); + } + mistrust +} + #[cfg(test)] mod test { #![allow(clippy::unwrap_used)] diff --git a/crates/arti/Cargo.toml b/crates/arti/Cargo.toml index bcf15f6e9..11170b76c 100644 --- a/crates/arti/Cargo.toml +++ b/crates/arti/Cargo.toml @@ -24,6 +24,7 @@ journald = ["tracing-journald"] [dependencies] arti-client = { package = "arti-client", path = "../arti-client", version = "0.2.0", default-features = false } +fs-mistrust = { path = "../fs-mistrust", version = "0.1.0" } tor-config = { path = "../tor-config", version = "0.2.0" } tor-error = { path = "../tor-error", version = "0.2.0", default-features = false } tor-rtcompat = { path = "../tor-rtcompat", version = "0.2.0", default-features = false } diff --git a/crates/arti/src/lib.rs b/crates/arti/src/lib.rs index 27b9641ba..9ee12a9bd 100644 --- a/crates/arti/src/lib.rs +++ b/crates/arti/src/lib.rs @@ -151,6 +151,7 @@ pub async fn run( config_sources: arti_config::ConfigurationSources, arti_config: ArtiConfig, client_config: TorClientConfig, + fs_permissions: fs_mistrust::Mistrust, ) -> Result<()> { // Using OnDemand arranges that, while we are bootstrapping, incoming connections wait // for bootstrap to complete, rather than getting errors. @@ -159,6 +160,7 @@ pub async fn run( let client = TorClient::with_runtime(runtime.clone()) .config(client_config) .bootstrap_behavior(OnDemand) + .override_fs_permission_checks(fs_permissions) .create_unbootstrapped()?; if arti_config.application().watch_configuration { watch_cfg::watch_for_config_changes(config_sources, arti_config, client.clone())?; @@ -281,16 +283,26 @@ pub fn main_main() -> Result<()> { .setting(AppSettings::SubcommandRequiredElseHelp) .get_matches(); + let mistrust = arti_client::config::default_fs_mistrust(); + let cfg_sources = { let mut cfg_sources = arti_config::ConfigurationSources::new(); let config_files = matches.values_of_os("config-files").unwrap_or_default(); if config_files.len() == 0 { if let Some(default) = default_config_file() { + match mistrust.verifier().require_file().check(&default) { + Ok(()) => {} + Err(fs_mistrust::Error::NotFound(_)) => {} + Err(e) => return Err(e.into()), + } cfg_sources.push_optional_file(default); } } else { - config_files.for_each(|f| cfg_sources.push_file(f)); + for f in config_files { + mistrust.verifier().require_file().check(f)?; + cfg_sources.push_file(f); + } } matches @@ -355,6 +367,7 @@ pub fn main_main() -> Result<()> { cfg_sources, config, client_config, + mistrust, ))?; Ok(()) } else { diff --git a/doc/semver_status.md b/doc/semver_status.md index fcd13c1c6..226205e97 100644 --- a/doc/semver_status.md +++ b/doc/semver_status.md @@ -38,6 +38,7 @@ MODIFIED: Configuration builder structs are now all Serialize+Deseralize+Debug. BREAKING: Replaced LoggingConfigBuilder::file (taking Vec) with LoggingConfigBuilder::files BREAKING: LoggingConfigBuilder::build() throws ConfigBuildError, not a bespoke error MODIFIED: LoggingConfigBuilder is now Deserialize +BREAKING: Replaced API for `run` to require a fs_mistrust. ### arti-client