mirror of
git://git.proxmox.com/git/proxmox-backup-qemu.git
synced 2025-08-26 01:49:21 +03:00
api: add master key support
this is a breaking change/API extension. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
committed by
Thomas Lamprecht
parent
58f4a111bd
commit
d8aa155c6c
@ -176,6 +176,7 @@ ProxmoxBackupHandle *proxmox_backup_new(const char *repo,
|
||||
const char *password,
|
||||
const char *keyfile,
|
||||
const char *key_password,
|
||||
const char *master_keyfile,
|
||||
bool compress,
|
||||
bool encrypt,
|
||||
const char *fingerprint,
|
||||
|
@ -8,9 +8,11 @@ use futures::future::{Future, Either, FutureExt};
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
use proxmox_backup::tools::runtime::get_runtime_with_builder;
|
||||
use proxmox_backup::backup::{CryptConfig, CryptMode, BackupDir, BackupManifest, load_and_decrypt_key};
|
||||
use proxmox_backup::backup::{CryptConfig, CryptMode, BackupDir, BackupManifest, KeyConfig, load_and_decrypt_key, rsa_encrypt_key_config};
|
||||
use proxmox_backup::client::{HttpClient, HttpClientOptions, BackupWriter};
|
||||
|
||||
use proxmox::tools::fs::file_get_contents;
|
||||
|
||||
use super::BackupSetup;
|
||||
use crate::capi_types::*;
|
||||
use crate::registry::Registry;
|
||||
@ -22,6 +24,7 @@ pub(crate) struct BackupTask {
|
||||
compress: bool,
|
||||
crypt_mode: CryptMode,
|
||||
crypt_config: Option<Arc<CryptConfig>>,
|
||||
rsa_encrypted_key: Option<Vec<u8>>,
|
||||
writer: OnceCell<Arc<BackupWriter>>,
|
||||
last_manifest: OnceCell<Arc<BackupManifest>>,
|
||||
manifest: Arc<Mutex<BackupManifest>>,
|
||||
@ -44,16 +47,28 @@ impl BackupTask {
|
||||
runtime: Arc<Runtime>
|
||||
) -> Result<Self, Error> {
|
||||
|
||||
let crypt_config = match setup.keyfile {
|
||||
None => None,
|
||||
let (crypt_config, rsa_encrypted_key) = match setup.keyfile {
|
||||
None => (None, None),
|
||||
Some(ref path) => {
|
||||
let (key, _, _) = load_and_decrypt_key(path, & || {
|
||||
let (key, created, _) = load_and_decrypt_key(path, & || {
|
||||
match setup.key_password {
|
||||
Some(ref key_password) => Ok(key_password.as_bytes().to_vec()),
|
||||
None => bail!("no key_password specified"),
|
||||
}
|
||||
})?;
|
||||
Some(Arc::new(CryptConfig::new(key)?))
|
||||
let rsa_encrypted_key = match setup.master_keyfile {
|
||||
Some(ref master_keyfile) => {
|
||||
let pem = file_get_contents(master_keyfile)?;
|
||||
let rsa = openssl::rsa::Rsa::public_key_from_pem(&pem)?;
|
||||
|
||||
let mut key_config = KeyConfig::without_password(key)?;
|
||||
key_config.created = created; // keep original value
|
||||
|
||||
Some(rsa_encrypt_key_config(rsa, &key_config)?)
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
(Some(Arc::new(CryptConfig::new(key)?)), rsa_encrypted_key)
|
||||
}
|
||||
};
|
||||
|
||||
@ -65,10 +80,21 @@ impl BackupTask {
|
||||
let registry = Arc::new(Mutex::new(Registry::<ImageUploadInfo>::new()));
|
||||
let known_chunks = Arc::new(Mutex::new(HashSet::new()));
|
||||
|
||||
Ok(Self { runtime, setup, compress, crypt_mode, crypt_config, abort,
|
||||
registry, manifest, known_chunks,
|
||||
writer: OnceCell::new(), last_manifest: OnceCell::new(),
|
||||
aborted: OnceCell::new() })
|
||||
Ok(Self {
|
||||
runtime,
|
||||
setup,
|
||||
compress,
|
||||
crypt_mode,
|
||||
crypt_config,
|
||||
rsa_encrypted_key,
|
||||
abort,
|
||||
registry,
|
||||
manifest,
|
||||
known_chunks,
|
||||
writer: OnceCell::new(),
|
||||
last_manifest: OnceCell::new(),
|
||||
aborted: OnceCell::new()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new(setup: BackupSetup, compress: bool, crypt_mode: CryptMode) -> Result<Self, Error> {
|
||||
@ -258,6 +284,7 @@ impl BackupTask {
|
||||
let command_future = finish_backup(
|
||||
self.need_writer()?,
|
||||
self.crypt_config.clone(),
|
||||
self.rsa_encrypted_key.clone(),
|
||||
Arc::clone(&self.manifest),
|
||||
);
|
||||
|
||||
|
@ -438,8 +438,18 @@ pub(crate) async fn write_data(
|
||||
pub(crate) async fn finish_backup(
|
||||
client: Arc<BackupWriter>,
|
||||
crypt_config: Option<Arc<CryptConfig>>,
|
||||
rsa_encrypted_key: Option<Vec<u8>>,
|
||||
manifest: Arc<Mutex<BackupManifest>>,
|
||||
) -> Result<c_int, Error> {
|
||||
if let Some(rsa_encrypted_key) = rsa_encrypted_key {
|
||||
let target = ENCRYPTED_KEY_BLOB_NAME;
|
||||
let options = UploadOptions { compress: false, encrypt: false, ..UploadOptions::default() };
|
||||
let stats = client
|
||||
.upload_blob_from_data(rsa_encrypted_key, target, options)
|
||||
.await?;
|
||||
manifest.lock().unwrap().add_file(target.to_string(), stats.size, stats.csum, CryptMode::Encrypt)?;
|
||||
};
|
||||
|
||||
|
||||
let manifest = {
|
||||
let guard = manifest.lock().unwrap();
|
||||
|
@ -137,6 +137,7 @@ pub(crate) struct BackupSetup {
|
||||
pub password: String,
|
||||
pub keyfile: Option<std::path::PathBuf>,
|
||||
pub key_password: Option<String>,
|
||||
pub master_keyfile: Option<std::path::PathBuf>,
|
||||
pub fingerprint: Option<String>,
|
||||
}
|
||||
|
||||
@ -208,6 +209,7 @@ pub extern "C" fn proxmox_backup_new(
|
||||
password: *const c_char,
|
||||
keyfile: *const c_char,
|
||||
key_password: *const c_char,
|
||||
master_keyfile: *const c_char,
|
||||
compress: bool,
|
||||
encrypt: bool,
|
||||
fingerprint: *const c_char,
|
||||
@ -227,6 +229,11 @@ pub extern "C" fn proxmox_backup_new(
|
||||
let keyfile = tools::utf8_c_string(keyfile)?.map(std::path::PathBuf::from);
|
||||
let key_password = tools::utf8_c_string(key_password)?;
|
||||
let fingerprint = tools::utf8_c_string(fingerprint)?;
|
||||
let master_keyfile = tools::utf8_c_string(master_keyfile)?.map(std::path::PathBuf::from);
|
||||
|
||||
if master_keyfile.is_some() && keyfile.is_none() {
|
||||
return Err(format_err!("can't use master keyfile without keyfile"));
|
||||
}
|
||||
|
||||
let crypt_mode = if keyfile.is_some() {
|
||||
if encrypt { CryptMode::Encrypt } else { CryptMode::SignOnly }
|
||||
@ -246,6 +253,7 @@ pub extern "C" fn proxmox_backup_new(
|
||||
backup_time: backup_time as i64,
|
||||
keyfile,
|
||||
key_password,
|
||||
master_keyfile,
|
||||
fingerprint,
|
||||
};
|
||||
|
||||
@ -720,6 +728,7 @@ pub extern "C" fn proxmox_restore_new(
|
||||
backup_time,
|
||||
keyfile,
|
||||
key_password,
|
||||
master_keyfile: None,
|
||||
fingerprint,
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user