From 002a191abf51d8147a044bde57e72b74947b72c8 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Wed, 15 Jan 2020 12:27:05 +0100 Subject: [PATCH] src/api2/config: check digest --- src/api2/config/datastore.rs | 12 +++++++++++- src/api2/config/remotes.rs | 13 +++++++++++-- src/api2/node/dns.rs | 4 ++-- src/api2/types.rs | 2 +- src/section_config.rs | 1 - src/tools.rs | 10 ++++++++++ 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/api2/config/datastore.rs b/src/api2/config/datastore.rs index daee1c0a..23eca29f 100644 --- a/src/api2/config/datastore.rs +++ b/src/api2/config/datastore.rs @@ -112,6 +112,10 @@ pub fn read_datastore(name: String) -> Result { optional: true, schema: datastore::DIR_NAME_SCHEMA, }, + digest: { + optional: true, + schema: PROXMOX_CONFIG_DIGEST_SCHEMA, + }, }, }, )] @@ -120,12 +124,18 @@ pub fn update_datastore( name: String, comment: Option, path: Option, + digest: Option, ) -> Result<(), Error> { let _lock = crate::tools::open_file_locked(datastore::DATASTORE_CFG_LOCKFILE, std::time::Duration::new(10, 0))?; // pass/compare digest - let (mut config, _digest) = datastore::config()?; + let (mut config, expected_digest) = datastore::config()?; + + if let Some(ref digest) = digest { + let digest = proxmox::tools::hex_to_digest(digest)?; + crate::tools::detect_modified_configuration_file(&digest, &expected_digest)?; + } let mut data: datastore::DataStoreConfig = config.lookup("datastore", &name)?; diff --git a/src/api2/config/remotes.rs b/src/api2/config/remotes.rs index 4d073981..b9ece5c4 100644 --- a/src/api2/config/remotes.rs +++ b/src/api2/config/remotes.rs @@ -118,6 +118,10 @@ pub fn read_remote(name: String) -> Result { optional: true, schema: remotes::REMOTE_PASSWORD_SCHEMA, }, + digest: { + optional: true, + schema: PROXMOX_CONFIG_DIGEST_SCHEMA, + }, }, }, )] @@ -128,12 +132,17 @@ pub fn update_remote( host: Option, userid: Option, password: Option, + digest: Option, ) -> Result<(), Error> { let _lock = crate::tools::open_file_locked(remotes::REMOTES_CFG_LOCKFILE, std::time::Duration::new(10, 0))?; - // pass/compare digest - let (mut config, _digest) = remotes::config()?; + let (mut config, expected_digest) = remotes::config()?; + + if let Some(ref digest) = digest { + let digest = proxmox::tools::hex_to_digest(digest)?; + crate::tools::detect_modified_configuration_file(&digest, &expected_digest)?; + } let mut data: remotes::Remote = config.lookup("remote", &name)?; diff --git a/src/api2/node/dns.rs b/src/api2/node/dns.rs index 923e24ad..46fd01f7 100644 --- a/src/api2/node/dns.rs +++ b/src/api2/node/dns.rs @@ -118,7 +118,7 @@ pub const ROUTER: Router = Router::new() &ObjectSchema::new( "Returns DNS server IPs and sreach domain.", &sorted!([ - ("digest", false, &PVE_CONFIG_DIGEST_SCHEMA), + ("digest", false, &PROXMOX_CONFIG_DIGEST_SCHEMA), ("search", true, &SEARCH_DOMAIN_SCHEMA), ("dns1", true, &FIRST_DNS_SERVER_SCHEMA), ("dns2", true, &SECOND_DNS_SERVER_SCHEMA), @@ -138,7 +138,7 @@ pub const ROUTER: Router = Router::new() ("dns1", true, &FIRST_DNS_SERVER_SCHEMA), ("dns2", true, &SECOND_DNS_SERVER_SCHEMA), ("dns3", true, &THIRD_DNS_SERVER_SCHEMA), - ("digest", true, &PVE_CONFIG_DIGEST_SCHEMA), + ("digest", true, &PROXMOX_CONFIG_DIGEST_SCHEMA), ]), ) ).protected(true) diff --git a/src/api2/types.rs b/src/api2/types.rs index 3fc637e1..86decc7b 100644 --- a/src/api2/types.rs +++ b/src/api2/types.rs @@ -85,7 +85,7 @@ pub const PASSWORD_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&PASSWORD_REGEX); -pub const PVE_CONFIG_DIGEST_SCHEMA: Schema = StringSchema::new(r#"\ +pub const PROXMOX_CONFIG_DIGEST_SCHEMA: Schema = StringSchema::new(r#"\ Prevent changes if current configuration file has different SHA256 digest. This can be used to prevent concurrent modifications. "# diff --git a/src/section_config.rs b/src/section_config.rs index 12564580..7e553a62 100644 --- a/src/section_config.rs +++ b/src/section_config.rs @@ -336,7 +336,6 @@ impl SectionConfig { } } - // cargo test test_section_config1 -- --nocapture #[test] fn test_section_config1() { diff --git a/src/tools.rs b/src/tools.rs index 5861f0e0..ca7964b4 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -428,6 +428,16 @@ pub fn join(data: &Vec, sep: char) -> String { list } +/// Detect modified configuration files +/// +/// This function fails with a resonable error message if checksums do not match. +pub fn detect_modified_configuration_file(digest1: &[u8;32], digest2: &[u8;32]) -> Result<(), Error> { + if digest1 != digest2 { + bail!("detected modified configuration - file changed by other user? Try again."); + } + Ok(()) +} + /// normalize uri path /// /// Do not allow ".", "..", or hidden files ".XXXX"