})
}
-pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result<Vec<u8>, Error>) -> Result<Vec<u8>, Error> {
+pub fn load_and_decrtypt_key(path: &std::path::Path, passphrase: fn() -> Result<Vec<u8>, Error>) -> Result<[u8;32], Error> {
let raw = crate::tools::file_get_contents(&path)?;
let data = String::from_utf8(raw)?;
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 {
&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)
}
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![];
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()?;
store_key_config(&path, true, KeyConfig {
kdf: None,
created,
- data: key,
+ data: key.to_vec(),
})?;
Ok(Value::Null)
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))
.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(