-use anyhow::{bail, format_err, Error};
+use anyhow::{bail, format_err, Context, Error};
use serde::{Deserialize, Serialize};
use chrono::{Local, TimeZone, DateTime};
})
}
-pub fn load_and_decrypt_key(path: &std::path::Path, passphrase: &dyn Fn() -> Result<Vec<u8>, Error>) -> Result<([u8;32], DateTime<Local>), Error> {
+pub fn load_and_decrypt_key(
+ path: &std::path::Path,
+ passphrase: &dyn Fn() -> Result<Vec<u8>, Error>,
+) -> Result<([u8;32], DateTime<Local>), Error> {
+ do_load_and_decrypt_key(path, passphrase)
+ .with_context(|| format!("failed to load decryption key from {:?}", path))
+}
+fn do_load_and_decrypt_key(
+ path: &std::path::Path,
+ passphrase: &dyn Fn() -> Result<Vec<u8>, Error>,
+) -> Result<([u8;32], DateTime<Local>), Error> {
let raw = file_get_contents(&path)?;
let data = String::from_utf8(raw)?;
Ok(match (keyfile, crypt_mode) {
// no parameters:
- (None, None) => (key::optional_default_key_path()?, CryptMode::Encrypt),
+ (None, None) => (key::find_default_encryption_key()?, CryptMode::Encrypt),
// just --crypt-mode=none
(None, Some(CryptMode::None)) => (None, CryptMode::None),
// just --crypt-mode other than none
- (None, Some(crypt_mode)) => match key::optional_default_key_path()? {
+ (None, Some(crypt_mode)) => match key::find_default_encryption_key()? {
None => bail!("--crypt-mode without --keyfile and no default key file available"),
Some(path) => (Some(path), crypt_mode),
}
use std::path::PathBuf;
-use anyhow::{bail, Error};
+use anyhow::{bail, format_err, Context, Error};
use chrono::{Local, TimeZone};
use serde::{Deserialize, Serialize};
use xdg::BaseDirectories;
};
use proxmox_backup::tools;
+pub const DEFAULT_ENCRYPTION_KEY_FILE_NAME: &str = "encryption-key.json";
+
pub fn master_pubkey_path() -> Result<PathBuf, Error> {
let base = BaseDirectories::with_prefix("proxmox-backup")?;
Ok(path)
}
-pub fn default_encryption_key_path() -> Result<PathBuf, Error> {
- let base = BaseDirectories::with_prefix("proxmox-backup")?;
-
- // usually $HOME/.config/proxmox-backup/encryption-key.json
- let path = base.place_config_file("encryption-key.json")?;
+pub fn find_default_encryption_key() -> Result<Option<PathBuf>, Error> {
+ BaseDirectories::with_prefix("proxmox-backup")
+ .map(|base| base.find_config_file(DEFAULT_ENCRYPTION_KEY_FILE_NAME))
+ .with_context(|| "error searching for default encryption key file")
+}
- Ok(path)
+pub fn place_default_encryption_key() -> Result<PathBuf, Error> {
+ BaseDirectories::with_prefix("proxmox-backup")
+ .map_err(Error::from)
+ .and_then(|base| {
+ base.place_config_file(DEFAULT_ENCRYPTION_KEY_FILE_NAME).map_err(Error::from)
+ })
+ .with_context(|| "failed to place default encryption key file in xdg home")
}
pub fn get_encryption_key_password() -> Result<Vec<u8>, Error> {
bail!("no password input mechanism available");
}
-/// Convenience helper to get the default key file path only if it exists.
-pub fn optional_default_key_path() -> Result<Option<PathBuf>, Error> {
- let path = default_encryption_key_path()?;
- Ok(if path.exists() {
- Some(path)
- } else {
- None
- })
-}
-
#[api(
default: "scrypt",
)]
fn create(kdf: Option<Kdf>, path: Option<String>) -> Result<(), Error> {
let path = match path {
Some(path) => PathBuf::from(path),
- None => default_encryption_key_path()?,
+ None => place_default_encryption_key()?,
};
let kdf = kdf.unwrap_or_default();
fn change_passphrase(kdf: Option<Kdf>, path: Option<String>) -> Result<(), Error> {
let path = match path {
Some(path) => PathBuf::from(path),
- None => default_encryption_key_path()?,
+ None => find_default_encryption_key()?
+ .ok_or_else(|| format_err!("no encryption file provided and no default file found"))?,
};
let kdf = kdf.unwrap_or_default();