subscription: move most of the implmentation into impl feature

so we can use the types without having openssl, proxmox-sys, etc. as
dependencies.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
Dominik Csapak 2024-11-05 15:05:14 +01:00 committed by Dietmar Maurer
parent f96c0e6036
commit ae55575f2a
3 changed files with 207 additions and 181 deletions

View File

@ -13,20 +13,21 @@ rust-version.workspace = true
[dependencies]
anyhow.workspace = true
base64.workspace = true
hex.workspace = true
openssl.workspace = true
base64 = { workspace = true, optional = true }
hex = { workspace = true, optional = true }
openssl = { workspace = true, optional = true }
regex.workspace = true
serde.workspace = true
serde_json.workspace = true
proxmox-http = { workspace = true, features = ["client-trait", "http-helpers"] }
proxmox-http = { workspace = true, optional = true, features = ["client-trait", "http-helpers"] }
proxmox-serde.workspace = true
proxmox-sys.workspace = true
proxmox-time.workspace = true
proxmox-sys = { workspace = true, optional = true }
proxmox-time = { workspace = true, optional = true }
proxmox-schema = { workspace = true, features = ["api-macro"], optional = true }
[features]
default = []
default = ["impl"]
impl = [ "dep:base64", "dep:hex", "dep:openssl", "dep:proxmox-http", "dep:proxmox-sys", "dep:proxmox-time"]
api-types = ["dep:proxmox-schema"]

View File

@ -1,10 +1,17 @@
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
mod subscription_info;
#[cfg(feature = "impl")]
pub use subscription_info::{
get_hardware_address, ProductType, SubscriptionInfo, SubscriptionStatus,
};
#[cfg(not(feature = "impl"))]
pub use subscription_info::{ProductType, SubscriptionInfo, SubscriptionStatus};
#[cfg(feature = "impl")]
pub mod check;
#[cfg(feature = "impl")]
pub mod files;
#[cfg(feature = "impl")]
pub mod sign;

View File

@ -1,23 +1,11 @@
use std::{fmt::Display, path::Path, str::FromStr};
use std::{fmt::Display, str::FromStr};
use anyhow::{bail, format_err, Error};
use openssl::hash::{hash, DigestBytes, MessageDigest};
use proxmox_sys::fs::file_get_contents;
use proxmox_time::TmEditor;
use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
#[cfg(feature = "api-types")]
use proxmox_schema::{api, Updater};
use crate::sign::Verifier;
pub(crate) const SHARED_KEY_DATA: &str = "kjfdlskfhiuewhfk947368";
/// How long the local key is valid for in between remote checks
pub(crate) const SUBSCRIPTION_MAX_LOCAL_KEY_AGE: i64 = 15 * 24 * 3600;
pub(crate) const SUBSCRIPTION_MAX_LOCAL_SIGNED_KEY_AGE: i64 = 365 * 24 * 3600;
pub(crate) const SUBSCRIPTION_MAX_KEY_CHECK_FAILURE_AGE: i64 = 5 * 24 * 3600;
// Aliases are needed for PVE compat!
#[cfg_attr(feature = "api-types", api())]
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
@ -144,7 +132,35 @@ pub struct SubscriptionInfo {
pub signature: Option<String>,
}
impl SubscriptionInfo {
#[cfg(feature = "impl")]
pub use _impl::get_hardware_address;
#[cfg(feature = "impl")]
pub(crate) use _impl::{md5sum, SHARED_KEY_DATA};
#[cfg(feature = "impl")]
mod _impl {
use std::path::Path;
use anyhow::format_err;
use anyhow::{bail, Error};
use openssl::hash::{hash, DigestBytes, MessageDigest};
use proxmox_sys::fs::file_get_contents;
use proxmox_time::TmEditor;
use crate::sign::Verifier;
pub(crate) const SHARED_KEY_DATA: &str = "kjfdlskfhiuewhfk947368";
/// How long the local key is valid for in between remote checks
pub(crate) const SUBSCRIPTION_MAX_LOCAL_KEY_AGE: i64 = 15 * 24 * 3600;
pub(crate) const SUBSCRIPTION_MAX_LOCAL_SIGNED_KEY_AGE: i64 = 365 * 24 * 3600;
pub(crate) const SUBSCRIPTION_MAX_KEY_CHECK_FAILURE_AGE: i64 = 5 * 24 * 3600;
use super::{ProductType, SubscriptionInfo, SubscriptionStatus};
impl SubscriptionInfo {
/// Returns the canonicalized signed data and, if available, signature contained in `self`.
pub fn signed_data(&self) -> Result<(Vec<u8>, Option<String>), Error> {
let mut data = serde_json::to_value(self)?;
@ -293,25 +309,26 @@ impl SubscriptionInfo {
.ok_or_else(|| format_err!("no next due date set"))
.map(|e| parse_next_due(e))?
}
}
}
/// Shortcut for md5 sums.
pub(crate) fn md5sum(data: &[u8]) -> Result<DigestBytes, Error> {
/// Shortcut for md5 sums.
pub(crate) fn md5sum(data: &[u8]) -> Result<DigestBytes, Error> {
hash(MessageDigest::md5(), data).map_err(Error::from)
}
}
/// Generate the current system's "server ID".
pub fn get_hardware_address() -> Result<String, Error> {
/// Generate the current system's "server ID".
pub fn get_hardware_address() -> Result<String, Error> {
static FILENAME: &str = "/etc/ssh/ssh_host_rsa_key.pub";
let contents = proxmox_sys::fs::file_get_contents(FILENAME)
.map_err(|e| format_err!("Error getting host key - {}", e))?;
let digest = md5sum(&contents).map_err(|e| format_err!("Error digesting host key - {}", e))?;
let digest =
md5sum(&contents).map_err(|e| format_err!("Error digesting host key - {}", e))?;
Ok(hex::encode(digest).to_uppercase())
}
}
fn parse_next_due(value: &str) -> Result<i64, Error> {
fn parse_next_due(value: &str) -> Result<i64, Error> {
let mut components = value.split('-');
let year = components
.next()
@ -336,4 +353,5 @@ fn parse_next_due(value: &str) -> Result<i64, Error> {
tm.set_mday(day)?;
tm.into_epoch()
}
}