diff --git a/src/backup/key_derivation.rs b/src/backup/key_derivation.rs index 2dfaafde..a76d95d2 100644 --- a/src/backup/key_derivation.rs +++ b/src/backup/key_derivation.rs @@ -142,7 +142,7 @@ pub fn store_key_with_passphrase( }) } -pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result, Error>) -> Result, Error> { +pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result, Error>) -> Result<[u8;32], Error> { let raw = crate::tools::file_get_contents(&path)?; let data = String::from_utf8(raw)?; @@ -151,7 +151,7 @@ pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result< let raw_data = key_config.data; - if let Some(kdf) = key_config.kdf { + let key = if let Some(kdf) = key_config.kdf { let passphrase = passphrase()?; if passphrase.len() < 5 { @@ -178,8 +178,13 @@ pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result< &tag, ).map_err(|err| format_err!("Unable to decrypt key - {}", err))?; - Ok(decr_data) + decr_data } else { - Ok(raw_data) - } + raw_data + }; + + let mut result = [0u8; 32]; + result.copy_from_slice(&key); + + Ok(result) } diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index 8cd2bf5f..0ff6bb91 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -407,6 +407,8 @@ fn create_backup( verify_chunk_size(size)?; } + let keyfile = param["keyfile"].as_str().map(|p| PathBuf::from(p)); + let backup_id = param["host-id"].as_str().unwrap_or(&tools::nodename()); let mut upload_list = vec![]; @@ -466,7 +468,13 @@ fn create_backup( println!("Client name: {}", tools::nodename()); println!("Start Time: {}", backup_time.to_rfc3339()); - let crypt_config = None; + let crypt_config = match keyfile { + None => None, + Some(path) => { + let key = load_and_decrtypt_key(&path, get_encryption_key_password)?; + Some(Arc::new(CryptConfig::new(key)?)) + } + }; let client = client.start_backup(repo.store(), "host", &backup_id, verbose).wait()?; @@ -884,7 +892,7 @@ fn key_change_passphrase( store_key_config(&path, true, KeyConfig { kdf: None, created, - data: key, + data: key.to_vec(), })?; Ok(Value::Null) @@ -951,6 +959,9 @@ fn main() { backup_source_schema, ).min_length(1) ) + .optional( + "keyfile", + StringSchema::new("Path to encryption key. All data will be encrypted using this key.")) .optional( "verbose", BooleanSchema::new("Verbose output.").default(false)) @@ -968,6 +979,7 @@ fn main() { .arg_param(vec!["repository", "backupspec"]) .completion_cb("repository", complete_repository) .completion_cb("backupspec", complete_backup_source) + .completion_cb("keyfile", tools::complete_file_name) .completion_cb("chunk-size", complete_chunk_size); let list_cmd_def = CliCommand::new(