mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-10 00:00:04 +03:00
Merge pull request #320 from WhatAmISupposedToPutHere/master
Ask for password via systemd-ask-password
This commit is contained in:
commit
6958dd8df2
@ -331,8 +331,9 @@ fn handle_unlock(cli: &Cli, sb: &bch_sb_handle) -> Result<KeyHandle> {
|
|||||||
return Passphrase::new_from_file(path).and_then(|p| KeyHandle::new(sb, &p));
|
return Passphrase::new_from_file(path).and_then(|p| KeyHandle::new(sb, &p));
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyHandle::new_from_search(&sb.sb().uuid())
|
let uuid = sb.sb().uuid();
|
||||||
.or_else(|_| Passphrase::new().and_then(|p| KeyHandle::new(sb, &p)))
|
KeyHandle::new_from_search(&uuid)
|
||||||
|
.or_else(|_| Passphrase::new(&uuid).and_then(|p| KeyHandle::new(sb, &p)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cmd_mount_inner(cli: &Cli) -> Result<()> {
|
fn cmd_mount_inner(cli: &Cli) -> Result<()> {
|
||||||
|
39
src/key.rs
39
src/key.rs
@ -7,7 +7,7 @@ use std::{
|
|||||||
ptr, thread,
|
ptr, thread,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
use anyhow::{anyhow, ensure, Result};
|
use anyhow::{anyhow, ensure, Result};
|
||||||
use bch_bindgen::{
|
use bch_bindgen::{
|
||||||
bcachefs::{self, bch_key, bch_sb_handle},
|
bcachefs::{self, bch_key, bch_sb_handle},
|
||||||
@ -15,7 +15,7 @@ use bch_bindgen::{
|
|||||||
keyutils::{self, keyctl_search},
|
keyutils::{self, keyctl_search},
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
use log::info;
|
use log::{debug, info};
|
||||||
use rustix::termios;
|
use rustix::termios;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use zeroize::{ZeroizeOnDrop, Zeroizing};
|
use zeroize::{ZeroizeOnDrop, Zeroizing};
|
||||||
@ -46,7 +46,7 @@ impl UnlockPolicy {
|
|||||||
match self {
|
match self {
|
||||||
Self::Fail => KeyHandle::new_from_search(&uuid),
|
Self::Fail => KeyHandle::new_from_search(&uuid),
|
||||||
Self::Wait => Ok(KeyHandle::wait_for_unlock(&uuid)?),
|
Self::Wait => Ok(KeyHandle::wait_for_unlock(&uuid)?),
|
||||||
Self::Ask => Passphrase::new_from_prompt().and_then(|p| KeyHandle::new(sb, &p)),
|
Self::Ask => Passphrase::new_from_prompt(&uuid).and_then(|p| KeyHandle::new(sb, &p)),
|
||||||
Self::Stdin => Passphrase::new_from_stdin().and_then(|p| KeyHandle::new(sb, &p)),
|
Self::Stdin => Passphrase::new_from_stdin().and_then(|p| KeyHandle::new(sb, &p)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,16 +142,43 @@ impl Passphrase {
|
|||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new(uuid: &Uuid) -> Result<Self> {
|
||||||
if stdin().is_terminal() {
|
if stdin().is_terminal() {
|
||||||
Self::new_from_prompt()
|
Self::new_from_prompt(uuid)
|
||||||
} else {
|
} else {
|
||||||
Self::new_from_stdin()
|
Self::new_from_stdin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The outer result represents a failure when trying to run systemd-ask-password,
|
||||||
|
// it is non-critical and will cause the password to be asked internally.
|
||||||
|
// The inner result represent a successful request that returned an error
|
||||||
|
// this one results in an error.
|
||||||
|
fn new_from_askpassword(uuid: &Uuid) -> Result<Result<Self>> {
|
||||||
|
let output = Command::new("systemd-ask-password")
|
||||||
|
.arg("--icon=drive-harddisk")
|
||||||
|
.arg(format!("--id=bcachefs:{}", uuid.as_hyphenated()))
|
||||||
|
.arg("-n")
|
||||||
|
.arg("Enter passphrase: ")
|
||||||
|
.stdin(Stdio::inherit())
|
||||||
|
.stderr(Stdio::inherit())
|
||||||
|
.output()?;
|
||||||
|
Ok(if output.status.success() {
|
||||||
|
match CString::new(output.stdout) {
|
||||||
|
Ok(cstr) => Ok(Self(cstr)),
|
||||||
|
Err(e) => Err(e.into())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(anyhow!("systemd-ask-password returned an error"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// blocks indefinitely if no input is available on stdin
|
// blocks indefinitely if no input is available on stdin
|
||||||
pub fn new_from_prompt() -> Result<Self> {
|
pub fn new_from_prompt(uuid: &Uuid) -> Result<Self> {
|
||||||
|
match Self::new_from_askpassword(uuid) {
|
||||||
|
Ok(phrase) => return phrase,
|
||||||
|
Err(_) => debug!("Failed to start systemd-ask-password, doing the prompt ourselves"),
|
||||||
|
}
|
||||||
let old = termios::tcgetattr(stdin())?;
|
let old = termios::tcgetattr(stdin())?;
|
||||||
let mut new = old.clone();
|
let mut new = old.clone();
|
||||||
new.local_modes.remove(termios::LocalModes::ECHO);
|
new.local_modes.remove(termios::LocalModes::ECHO);
|
||||||
|
Loading…
Reference in New Issue
Block a user