diff options
author | Roland Vet <RlndVt@protonmail.com> | 2024-02-18 09:32:19 +0100 |
---|---|---|
committer | Roland Vet <RlndVt@protonmail.com> | 2024-02-22 21:12:49 +0100 |
commit | d67643f24cf3b47d89ddf889a87de656e50be8bb (patch) | |
tree | 813b63b1c046469b0f4594f1d81283974d80439f /src/commands | |
parent | 0ff96b2a0fda48df57bbb47573aabeb493995a94 (diff) |
Add decryption by key_file
- Add key_file option to Cli
- Rework decryption flow logic to first attempt key_file
- Read password from file and pass to decrypt_master_key
Explicity specify '-k' for key_location
Signed-off-by: Roland Vet <RlndVt@protonmail.com>
Diffstat (limited to 'src/commands')
-rw-r--r-- | src/commands/cmd_mount.rs | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/src/commands/cmd_mount.rs b/src/commands/cmd_mount.rs index eef7e1d6..0462cbde 100644 --- a/src/commands/cmd_mount.rs +++ b/src/commands/cmd_mount.rs @@ -128,6 +128,14 @@ fn get_devices_by_uuid(uuid: Uuid) -> anyhow::Result<Vec<(PathBuf, bch_sb_handle #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] pub struct Cli { + /// Path to password key file + /// + /// Precedes key_location: if the filesystem can be decrypted by the + /// specified key_file; it is decrypted. (i.e. Regardless if "fail" + /// is specified for key_location.) + #[arg(short = 'f', long)] + key_file: Option<PathBuf>, + /// Where the password would be loaded from. /// /// Possible values are: @@ -143,7 +151,7 @@ pub struct Cli { /// Where the filesystem should be mounted. If not set, then the filesystem /// won't actually be mounted. But all steps preceeding mounting the /// filesystem (e.g. asking for passphrase) will still be performed. - mountpoint: Option<std::path::PathBuf>, + mountpoint: Option<PathBuf>, /// Mount options #[arg(short, default_value = "")] @@ -196,8 +204,31 @@ fn cmd_mount_inner(opt: Cli) -> anyhow::Result<()> { if sbs.len() == 0 { Err(anyhow::anyhow!("No device found from specified parameters"))?; - } else if unsafe { bcachefs::bch2_sb_is_encrypted(sbs[0].sb) } { - key::prepare_key(&sbs[0], opt.key_location)?; + } + // Check if the filesystem's master key is encrypted + if unsafe { bcachefs::bch2_sb_is_encrypted(sbs[0].sb) } { + // Filesystem's master key is encrypted, attempt to decrypt + // First by key_file, if available + let fallback_to_prepare_key = if let Some(key_file) = &opt.key_file { + match key::read_from_key_file(&sbs[0], key_file.as_path()) { + Ok(()) => { + // Decryption succeeded + false + } + Err(err) => { + // Decryption failed, fall back to prepare_key + error!("Failed to decrypt using key_file: {}", err); + true + } + } + } else { + // No key_file specified, fall back to prepare_key + true + }; + // If decryption by key_file was unsuccesful, prompt for password (or follow key_policy) + if fallback_to_prepare_key { + key::prepare_key(&sbs[0], opt.key_location)?; + }; } if let Some(mountpoint) = opt.mountpoint { |