]> git.proxmox.com Git - proxmox-backup.git/commitdiff
src/api2/config: check digest
authorDietmar Maurer <dietmar@proxmox.com>
Wed, 15 Jan 2020 11:27:05 +0000 (12:27 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 15 Jan 2020 11:27:05 +0000 (12:27 +0100)
src/api2/config/datastore.rs
src/api2/config/remotes.rs
src/api2/node/dns.rs
src/api2/types.rs
src/section_config.rs
src/tools.rs

index daee1c0a4ef96c8b6fe1acf5860ea930de506286..23eca29fbc787c2fc65ccf79020b225d3a1e7dd8 100644 (file)
@@ -112,6 +112,10 @@ pub fn read_datastore(name: String) -> Result<Value, Error> {
                 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<String>,
     path: Option<String>,
+    digest: Option<String>,
 ) -> 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)?;
 
index 4d0739810656f265d6387e0ce12aed6a0a377f18..b9ece5c42f4b7171b272c7f733641eff7519538c 100644 (file)
@@ -118,6 +118,10 @@ pub fn read_remote(name: String) -> Result<Value, Error> {
                 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<String>,
     userid: Option<String>,
     password: Option<String>,
+    digest: Option<String>,
 ) -> 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)?;
 
index 923e24ad69c0e0611e974e5f6373c2c87e3c08c8..46fd01f758166edb35cb7a58f9d3c5f907236837 100644 (file)
@@ -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)
index 3fc637e122d4cb6349c2ac892ecbef9b168fc4a9..86decc7befc51390570178b42bf3ec7156659d0f 100644 (file)
@@ -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.
 "#
index 12564580b85ba95d48b9258a3e756c8deaeac279..7e553a62aba9947eb750009457917de264ae1f62 100644 (file)
@@ -336,7 +336,6 @@ impl SectionConfig {
     }
 }
 
-
 // cargo test test_section_config1 -- --nocapture
 #[test]
 fn test_section_config1() {
index 5861f0e0280d932ef179ce247c357133c1b1693e..ca7964b47360f61c137646cee1367d7e71bcbf17 100644 (file)
@@ -428,6 +428,16 @@ pub fn join(data: &Vec<String>, 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"