From ff07b5e3a89b8662584259fd0c94ec6e1eab8fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Fri, 5 Jan 2024 14:17:33 +0100 Subject: [PATCH] Add tests for bad configurations --- pkcs11/src/api/mod.rs | 2 +- pkcs11/src/config/config_file.rs | 49 +++++++++++-------- pkcs11/src/config/initialization.rs | 76 +++++++++++++++++++++++++++-- pkcs11/src/config/logging.rs | 3 +- 4 files changed, 105 insertions(+), 25 deletions(-) diff --git a/pkcs11/src/api/mod.rs b/pkcs11/src/api/mod.rs index 4694aecb..f4332686 100644 --- a/pkcs11/src/api/mod.rs +++ b/pkcs11/src/api/mod.rs @@ -44,7 +44,7 @@ pub extern "C" fn C_Initialize(pInitArgs: CK_VOID_PTR) -> CK_RV { let mut result = Ok(()); DEVICE_INIT.call_once(|| { - let res = crate::config::initialization::initialize_configuration(); + let res = crate::config::initialization::initialize(); match res { Ok(device) => { _ = DEVICE.set(device); diff --git a/pkcs11/src/config/config_file.rs b/pkcs11/src/config/config_file.rs index ae9a9011..6b33589b 100644 --- a/pkcs11/src/config/config_file.rs +++ b/pkcs11/src/config/config_file.rs @@ -1,3 +1,5 @@ +use std::{io::Read, mem}; + use merge::Merge; use serde::{Deserialize, Serialize}; @@ -11,16 +13,10 @@ pub enum ConfigError { const CONFIG_FILE_NAME: &str = "p11nethsm.conf"; const ENV_VAR_CONFIG_FILE: &str = "P11NETHSM_CONFIG_FILE"; -pub fn read_configuration() -> Result { - let mut config = P11Config::default(); - +pub fn config_files() -> Result>, ConfigError> { if let Ok(file_path) = std::env::var(ENV_VAR_CONFIG_FILE) { - let file = std::fs::File::open(file_path).map_err(ConfigError::Io)?; - let config_file = serde_yaml::from_reader(file).map_err(ConfigError::Yaml)?; - - config.merge(config_file); - - return Ok(config); + let file = std::fs::read(file_path).map_err(ConfigError::Io)?; + return Ok(vec![file]); } let mut config_folders = vec![ @@ -32,28 +28,42 @@ pub fn read_configuration() -> Result { config_folders.push(format!("{}/.config/nitrokey", home)); } - let mut file_read = false; - + let mut res: Vec> = Vec::new(); + let mut buffer: Vec = Vec::new(); for folder in config_folders { let file_path = format!("{}/{}", folder, CONFIG_FILE_NAME); - - if let Ok(file) = std::fs::File::open(file_path) { - let config_file = serde_yaml::from_reader(file).map_err(ConfigError::Yaml)?; - - config.merge(config_file); - file_read = true; + if let Ok(mut file) = std::fs::File::open(file_path) { + file.read_to_end(&mut buffer).map_err(ConfigError::Io)?; + res.push(mem::take(&mut buffer)); } } - // if no config file was found, return an error + Ok(res) +} - if !file_read { +pub fn merge_configurations(configs: Vec>) -> Result { + let mut config = P11Config::default(); + + // if no config file was found, return an error + if configs.is_empty() { return Err(ConfigError::NoConfigFile); } + for file in configs { + let parsed = serde_yaml::from_slice(&file).map_err(ConfigError::Yaml)?; + config.merge(parsed); + } + Ok(config) } +#[cfg(test)] +pub fn read_configuration() -> Result { + let configs = config_files()?; + + merge_configurations(configs) +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub enum LogLevel { Trace, @@ -198,6 +208,7 @@ mod tests { use super::*; #[test] + #[ignore] fn test_read_home_config() { let config = r#" enable_set_attribute_value: true diff --git a/pkcs11/src/config/initialization.rs b/pkcs11/src/config/initialization.rs index 84cfbf23..a0553a44 100644 --- a/pkcs11/src/config/initialization.rs +++ b/pkcs11/src/config/initialization.rs @@ -4,7 +4,7 @@ use std::{ }; use super::{ - config_file::SlotConfig, + config_file::{config_files, SlotConfig}, device::{Device, Slot}, }; use log::{debug, error, trace}; @@ -21,9 +21,9 @@ pub enum InitializationError { NoUser(String), } -pub fn initialize_configuration() -> Result { - let config = - crate::config::config_file::read_configuration().map_err(InitializationError::Config)?; +pub fn initialize_with_configs(configs: Vec>) -> Result { + let config = crate::config::config_file::merge_configurations(configs) + .map_err(InitializationError::Config)?; crate::config::logging::configure_logger(&config); // initialize the clients @@ -38,6 +38,10 @@ pub fn initialize_configuration() -> Result { }) } +pub fn initialize() -> Result { + initialize_with_configs(config_files().map_err(InitializationError::Config)?) +} + struct DangerIgnoreVerifier {} impl ServerCertVerifier for DangerIgnoreVerifier { @@ -159,3 +163,67 @@ fn slot_from_config(slot: &SlotConfig) -> Result { db: Arc::new(Mutex::new(crate::backend::db::Db::new())), }) } + +#[cfg(test)] +mod tests { + use super::*; + + /// Test various good and bad configs for panics + #[test] + fn test_config_loading() { + let configs: Vec> = vec![ + r#" +slots: + - label: LocalHSM + description: Local HSM (docker) + operator: + username: "operator" + password: "opPassphrase" + administrator: + username: "admin" + password: "Administrator" + instances: + - url: "https://localhost:8443/api/v1" + danger_insecure_cert: true + sha256_fingerprints: + - "31:92:8E:A4:5E:16:5C:A7:33:44:E8:E9:8E:64:C4:AE:7B:2A:57:E5:77:43:49:F3:69:C9:8F:C4:2F:3A:3B:6E" + retries: + count: 10 + delay_seconds: 1 + timeout_seconds: 10 + "#.into(), + ]; + + assert!(initialize_with_configs(configs).is_ok()); + + let configs_bad_fingerprint: Vec> = vec![ + r#" +slots: + - label: LocalHSM + description: Local HSM (docker) + operator: + username: "operator" + password: "opPassphrase" + administrator: + username: "admin" + password: "Administrator" + instances: + - url: "https://localhost:8443/api/v1" + danger_insecure_cert: true + sha256_fingerprints: + - "31:92:8E:A4:5Eeeeee:16:5C:A7:33:44:E8:E9:8E:64:C4:AE:7B:2A:57:E5:77:43:49:F3:69:C9:8F:C4:2F:3A:3B:6E" + retries: + count: 10 + delay_seconds: 1 + timeout_seconds: 10 + "#.into(), + ]; + assert!(initialize_with_configs(configs_bad_fingerprint).is_err()); + let configs_bad_yml: Vec> = vec![r#" +dict: +bad_yml + "# + .into()]; + assert!(initialize_with_configs(configs_bad_yml).is_err()); + } +} diff --git a/pkcs11/src/config/logging.rs b/pkcs11/src/config/logging.rs index 7ad5d83c..8e4c43f1 100644 --- a/pkcs11/src/config/logging.rs +++ b/pkcs11/src/config/logging.rs @@ -32,5 +32,6 @@ pub fn configure_logger(config: &P11Config) { builder.target(env_logger::Target::Pipe(file)); } - builder.init() + // Don't crash on re-initialization + builder.try_init().ok(); }