From d7f84b92abab46df146b98b74055b175d3b72f50 Mon Sep 17 00:00:00 2001 From: Ian Jackson <ijackson@chiark.greenend.org.uk> Date: Thu, 12 May 2022 15:12:33 +0100 Subject: [PATCH] config load: Move mistrust checking to load() As per https://gitlab.torproject.org/tpo/core/arti/-/issues/472 Experimentation convinced me the Mistrust should be within the ConfigurationSources. --- crates/arti-config/src/lib.rs | 49 ++++++++++++++++++++++++----------- crates/arti/src/lib.rs | 15 ++++++----- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/crates/arti-config/src/lib.rs b/crates/arti-config/src/lib.rs index 384e700314..9fb94af821 100644 --- a/crates/arti-config/src/lib.rs +++ b/crates/arti-config/src/lib.rs @@ -49,6 +49,8 @@ use tor_config::CmdLine; +use config::ConfigError; + /// The synchronous configuration builder type we use. /// /// (This is a type alias that config should really provide.) @@ -63,6 +65,8 @@ pub struct ConfigurationSources { files: Vec<(PathBuf, MustRead)>, /// A list of command-line options to apply after parsing the files. options: Vec<String>, + /// We will check all files we read + mistrust: fs_mistrust::Mistrust, } /// Rules for whether we should proceed if a configuration file is unreadable. @@ -100,8 +104,7 @@ impl ConfigurationSources { default_config_file: impl Into<PathBuf>, config_files_options: impl IntoIterator<Item = F>, cmdline_toml_override_options: impl IntoIterator<Item = O>, - mistrust: &fs_mistrust::Mistrust, - ) -> Result<Self, fs_mistrust::Error> + ) -> Self where F: Into<PathBuf>, O: Into<String>, @@ -111,17 +114,11 @@ impl ConfigurationSources { let mut any_files = false; for f in config_files_options { let f = f.into(); - mistrust.verifier().require_file().check(&f)?; cfg_sources.push_file(f); any_files = true; } if !any_files { let default = default_config_file.into(); - match mistrust.verifier().require_file().check(&default) { - Ok(()) => {} - Err(fs_mistrust::Error::NotFound(_)) => {} - Err(e) => return Err(e), - } cfg_sources.push_optional_file(default); } @@ -129,7 +126,7 @@ impl ConfigurationSources { cfg_sources.push_option(s); } - Ok(cfg_sources) + cfg_sources } /// Add `p` to the list of files that we want to read configuration from. @@ -158,15 +155,25 @@ impl ConfigurationSources { self.options.push(option.into()); } + /// Sets the filesystem permission mistrust + pub fn set_mistrust(&mut self, mistrust: fs_mistrust::Mistrust) { + self.mistrust = mistrust; + } + + /// Reads the filesystem permission mistrust + pub fn mistrust(&self) -> &fs_mistrust::Mistrust { + &self.mistrust + } + /// Return an iterator over the files that we care about. pub fn files(&self) -> impl Iterator<Item = &Path> { self.files.iter().map(|(f, _)| f.as_path()) } /// Load the configuration into a new [`config::Config`]. - pub fn load(&self) -> Result<config::Config, config::ConfigError> { + pub fn load(&self) -> Result<config::Config, ConfigError> { let mut builder = config::Config::builder(); - builder = add_sources(builder, &self.files, &self.options); + builder = add_sources(builder, &self.mistrust, &self.files, &self.options)?; builder.build() } } @@ -175,17 +182,25 @@ impl ConfigurationSources { /// builder. fn add_sources<P>( mut builder: ConfigBuilder, + mistrust: &fs_mistrust::Mistrust, files: &[(P, MustRead)], opts: &[String], -) -> ConfigBuilder +) -> Result<ConfigBuilder, ConfigError> where P: AsRef<Path>, { for (path, must_read) in files { // Not going to use File::with_name here, since it doesn't // quite do what we want. - let f: config::File<_, _> = path.as_ref().into(); let required = must_read == &MustRead::MustRead; + + match mistrust.verifier().require_file().check(&path) { + Ok(()) => {} + Err(fs_mistrust::Error::NotFound(_)) if !required => {} + Err(e) => return Err(ConfigError::Foreign(e.into())), + } + + let f: config::File<_, _> = path.as_ref().into(); builder = builder.add_source(f.format(config::FileFormat::Toml).required(required)); } @@ -195,7 +210,7 @@ where } builder = builder.add_source(cmdline); - builder + Ok(builder) } #[cfg(test)] @@ -217,7 +232,11 @@ friends = 4242 files: &[(P, MustRead)], opts: &[String], ) -> Result<config::Config, config::ConfigError> { - add_sources(config::Config::builder(), files, opts).build() + let mut mistrust = fs_mistrust::Mistrust::new(); + mistrust.dangerously_trust_everyone(); + add_sources(config::Config::builder(), &mistrust, files, opts) + .unwrap() + .build() } #[test] diff --git a/crates/arti/src/lib.rs b/crates/arti/src/lib.rs index 16fbf38a10..c293a93949 100644 --- a/crates/arti/src/lib.rs +++ b/crates/arti/src/lib.rs @@ -373,12 +373,15 @@ pub fn main_main() -> Result<()> { mistrust }; - let cfg_sources = arti_config::ConfigurationSources::from_cmdline( - default_config_file()?, - matches.values_of_os("config-files").unwrap_or_default(), - matches.values_of("option").unwrap_or_default(), - &mistrust, - )?; + let cfg_sources = { + let mut cfg_sources = arti_config::ConfigurationSources::from_cmdline( + default_config_file()?, + matches.values_of_os("config-files").unwrap_or_default(), + matches.values_of("option").unwrap_or_default(), + ); + cfg_sources.set_mistrust(mistrust); + cfg_sources + }; let cfg = cfg_sources.load()?; -- GitLab