config-digest: split out config digest api type into separate crate
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
This commit is contained in:
parent
3497e9edc7
commit
34b21106dd
@ -9,6 +9,7 @@ members = [
|
||||
"proxmox-borrow",
|
||||
"proxmox-client",
|
||||
"proxmox-compression",
|
||||
"proxmox-config-digest",
|
||||
"proxmox-http",
|
||||
"proxmox-http-error",
|
||||
"proxmox-human-byte",
|
||||
@ -113,6 +114,7 @@ proxmox-io = { version = "1.0.0", path = "proxmox-io" }
|
||||
proxmox-lang = { version = "1.1", path = "proxmox-lang" }
|
||||
proxmox-login = { version = "0.1.0", path = "proxmox-login" }
|
||||
proxmox-product-config = { version = "0.1.0", path = "proxmox-product-config" }
|
||||
proxmox-config-digest = { version = "0.1.0", path = "proxmox-config-digest" }
|
||||
proxmox-rest-server = { version = "0.5.2", path = "proxmox-rest-server" }
|
||||
proxmox-router = { version = "2.1.3", path = "proxmox-router" }
|
||||
proxmox-schema = { version = "3.1.1", path = "proxmox-schema" }
|
||||
|
20
proxmox-config-digest/Cargo.toml
Normal file
20
proxmox-config-digest/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
||||
[package]
|
||||
name = "proxmox-config-digest"
|
||||
version = "0.1.0"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
description = "Configuration file digest API type."
|
||||
|
||||
exclude.workspace = true
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
hex.workspace = true
|
||||
serde.workspace = true
|
||||
serde_plain.workspace = true
|
||||
proxmox-schema = { workspace = true, features = ["api-types"] }
|
||||
|
||||
# feature "openssl", allows to compute the SHA256 digest
|
||||
openssl = { workspace = true, optional = true }
|
5
proxmox-config-digest/debian/changelog
Normal file
5
proxmox-config-digest/debian/changelog
Normal file
@ -0,0 +1,5 @@
|
||||
rust-proxmox-config-digest (0.1.0-1) bookworm; urgency=medium
|
||||
|
||||
* initial packaging (split out from proxmox-product-config)
|
||||
|
||||
-- Proxmox Support Team <support@proxmox.com> Wed, 29 May 2024 17:49:33 +0200
|
59
proxmox-config-digest/debian/control
Normal file
59
proxmox-config-digest/debian/control
Normal file
@ -0,0 +1,59 @@
|
||||
Source: rust-proxmox-config-digest
|
||||
Section: rust
|
||||
Priority: optional
|
||||
Build-Depends: debhelper (>= 12),
|
||||
dh-cargo (>= 25),
|
||||
cargo:native <!nocheck>,
|
||||
rustc:native <!nocheck>,
|
||||
libstd-rust-dev <!nocheck>,
|
||||
librust-anyhow-1+default-dev <!nocheck>,
|
||||
librust-hex-0.4+default-dev <!nocheck>,
|
||||
librust-proxmox-schema-3+api-types-dev (>= 3.1.1-~~) <!nocheck>,
|
||||
librust-proxmox-schema-3+default-dev (>= 3.1.1-~~) <!nocheck>,
|
||||
librust-serde-1+default-dev <!nocheck>,
|
||||
librust-serde-plain-1+default-dev <!nocheck>
|
||||
Maintainer: Proxmox Support Team <support@proxmox.com>
|
||||
Standards-Version: 4.6.2
|
||||
Vcs-Git: git://git.proxmox.com/git/proxmox.git
|
||||
Vcs-Browser: https://git.proxmox.com/?p=proxmox.git
|
||||
X-Cargo-Crate: proxmox-config-digest
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: librust-proxmox-config-digest-dev
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends:
|
||||
${misc:Depends},
|
||||
librust-anyhow-1+default-dev,
|
||||
librust-hex-0.4+default-dev,
|
||||
librust-proxmox-schema-3+api-types-dev (>= 3.1.1-~~),
|
||||
librust-proxmox-schema-3+default-dev (>= 3.1.1-~~),
|
||||
librust-serde-1+default-dev,
|
||||
librust-serde-plain-1+default-dev
|
||||
Suggests:
|
||||
librust-proxmox-config-digest+openssl-dev (= ${binary:Version})
|
||||
Provides:
|
||||
librust-proxmox-config-digest+default-dev (= ${binary:Version}),
|
||||
librust-proxmox-config-digest-0-dev (= ${binary:Version}),
|
||||
librust-proxmox-config-digest-0+default-dev (= ${binary:Version}),
|
||||
librust-proxmox-config-digest-0.1-dev (= ${binary:Version}),
|
||||
librust-proxmox-config-digest-0.1+default-dev (= ${binary:Version}),
|
||||
librust-proxmox-config-digest-0.1.0-dev (= ${binary:Version}),
|
||||
librust-proxmox-config-digest-0.1.0+default-dev (= ${binary:Version})
|
||||
Description: Configuration file digest API type - Rust source code
|
||||
Source code for Debianized Rust crate "proxmox-config-digest"
|
||||
|
||||
Package: librust-proxmox-config-digest+openssl-dev
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends:
|
||||
${misc:Depends},
|
||||
librust-proxmox-config-digest-dev (= ${binary:Version}),
|
||||
librust-openssl-0.10+default-dev
|
||||
Provides:
|
||||
librust-proxmox-config-digest-0+openssl-dev (= ${binary:Version}),
|
||||
librust-proxmox-config-digest-0.1+openssl-dev (= ${binary:Version}),
|
||||
librust-proxmox-config-digest-0.1.0+openssl-dev (= ${binary:Version})
|
||||
Description: Configuration file digest API type - feature "openssl"
|
||||
This metapackage enables feature "openssl" for the Rust proxmox-config-digest
|
||||
crate, by pulling in any additional dependencies needed by that feature.
|
18
proxmox-config-digest/debian/copyright
Normal file
18
proxmox-config-digest/debian/copyright
Normal file
@ -0,0 +1,18 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
|
||||
Files:
|
||||
*
|
||||
Copyright: 2019 - 2023 Proxmox Server Solutions GmbH <support@proxmox.com>
|
||||
License: AGPL-3.0-or-later
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU Affero General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option) any
|
||||
later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
details.
|
||||
.
|
||||
You should have received a copy of the GNU Affero General Public License along
|
||||
with this program. If not, see <https://www.gnu.org/licenses/>.
|
7
proxmox-config-digest/debian/debcargo.toml
Normal file
7
proxmox-config-digest/debian/debcargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
overlay = "."
|
||||
crate_src_path = ".."
|
||||
maintainer = "Proxmox Support Team <support@proxmox.com>"
|
||||
|
||||
[source]
|
||||
vcs_git = "git://git.proxmox.com/git/proxmox.git"
|
||||
vcs_browser = "https://git.proxmox.com/?p=proxmox.git"
|
112
proxmox-config-digest/src/lib.rs
Normal file
112
proxmox-config-digest/src/lib.rs
Normal file
@ -0,0 +1,112 @@
|
||||
use anyhow::{bail, Error};
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
use openssl::sha;
|
||||
|
||||
use proxmox_schema::api_types::SHA256_HEX_REGEX;
|
||||
use proxmox_schema::ApiStringFormat;
|
||||
use proxmox_schema::ApiType;
|
||||
use proxmox_schema::Schema;
|
||||
use proxmox_schema::StringSchema;
|
||||
|
||||
pub const PROXMOX_CONFIG_DIGEST_FORMAT: ApiStringFormat =
|
||||
ApiStringFormat::Pattern(&SHA256_HEX_REGEX);
|
||||
|
||||
pub const PROXMOX_CONFIG_DIGEST_SCHEMA: Schema = StringSchema::new(
|
||||
"Prevent changes if current configuration file has different \
|
||||
SHA256 digest. This can be used to prevent concurrent \
|
||||
modifications.",
|
||||
)
|
||||
.format(&PROXMOX_CONFIG_DIGEST_FORMAT)
|
||||
.schema();
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
/// A configuration digest - a SHA256 hash.
|
||||
pub struct ConfigDigest([u8; 32]);
|
||||
|
||||
impl ConfigDigest {
|
||||
pub fn to_hex(&self) -> String {
|
||||
hex::encode(&self.0[..])
|
||||
}
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
pub fn from_slice<T: AsRef<[u8]>>(data: T) -> ConfigDigest {
|
||||
let digest = sha::sha256(data.as_ref());
|
||||
ConfigDigest(digest)
|
||||
}
|
||||
|
||||
/// Detect modified configuration files
|
||||
///
|
||||
/// This function fails with a reasonable error message if checksums do not match.
|
||||
pub fn detect_modification(&self, user_digest: Option<&Self>) -> Result<(), Error> {
|
||||
if let Some(user_digest) = user_digest {
|
||||
if user_digest != self {
|
||||
bail!("detected modified configuration - file changed by other user? Try again.");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiType for ConfigDigest {
|
||||
const API_SCHEMA: Schema = PROXMOX_CONFIG_DIGEST_SCHEMA;
|
||||
}
|
||||
|
||||
impl From<[u8; 32]> for ConfigDigest {
|
||||
#[inline]
|
||||
fn from(digest: [u8; 32]) -> Self {
|
||||
Self(digest)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ConfigDigest> for [u8; 32] {
|
||||
#[inline]
|
||||
fn from(digest: ConfigDigest) -> Self {
|
||||
digest.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for ConfigDigest {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8; 32]> for ConfigDigest {
|
||||
fn as_ref(&self) -> &[u8; 32] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for ConfigDigest {
|
||||
type Target = [u8; 32];
|
||||
|
||||
fn deref(&self) -> &[u8; 32] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for ConfigDigest {
|
||||
fn deref_mut(&mut self) -> &mut [u8; 32] {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ConfigDigest {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.to_hex())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::str::FromStr for ConfigDigest {
|
||||
type Err = hex::FromHexError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, hex::FromHexError> {
|
||||
let mut digest = [0u8; 32];
|
||||
hex::decode_to_slice(s, &mut digest)?;
|
||||
Ok(ConfigDigest(digest))
|
||||
}
|
||||
}
|
||||
|
||||
serde_plain::derive_deserialize_from_fromstr!(ConfigDigest, "valid configuration digest");
|
||||
serde_plain::derive_serialize_from_display!(ConfigDigest);
|
Loading…
Reference in New Issue
Block a user