diff options
author | qkzk <qu3nt1n@gmail.com> | 2023-01-16 20:49:33 +0100 |
---|---|---|
committer | qkzk <qu3nt1n@gmail.com> | 2023-01-16 20:49:33 +0100 |
commit | 2c32aab22bf1b2ec09676045e122dbf532f529fc (patch) | |
tree | 71387e654e312a3fd0151b889fd035c85af867a8 | |
parent | 52e428ef72126b26dfccc3b353326641751b073f (diff) |
menu for crypto devices first step
-rw-r--r-- | src/action_map.rs | 2 | ||||
-rw-r--r-- | src/cryptsetup.rs | 24 | ||||
-rw-r--r-- | src/event_exec.rs | 11 | ||||
-rw-r--r-- | src/keybindings.rs | 1 | ||||
-rw-r--r-- | src/main.rs | 39 | ||||
-rw-r--r-- | src/mode.rs | 12 | ||||
-rw-r--r-- | src/status.rs | 19 | ||||
-rw-r--r-- | src/term_manager.rs | 21 |
8 files changed, 80 insertions, 49 deletions
diff --git a/src/action_map.rs b/src/action_map.rs index 91220c1..103cd5a 100644 --- a/src/action_map.rs +++ b/src/action_map.rs @@ -24,6 +24,7 @@ pub enum ActionMap { DeleteFile, DisplayFull, DragNDrop, + EncryptedDrive, End, Enter, Exec, @@ -97,6 +98,7 @@ impl ActionMap { ActionMap::DeleteFile => EventExec::event_delete_file(status), ActionMap::DisplayFull => EventExec::event_toggle_display_full(status), ActionMap::DragNDrop => EventExec::event_drag_n_drop(status), + ActionMap::EncryptedDrive => EventExec::event_encrypted_drive(status), ActionMap::End => EventExec::event_end(status), ActionMap::Enter => EventExec::event_enter(status), ActionMap::Exec => EventExec::event_exec(current_tab), diff --git a/src/cryptsetup.rs b/src/cryptsetup.rs index 70ce9d9..9b199d5 100644 --- a/src/cryptsetup.rs +++ b/src/cryptsetup.rs @@ -10,16 +10,19 @@ pub struct PasswordHolder { } impl PasswordHolder { + /// Set the sudo password pub fn with_sudo(mut self, password: &str) -> Self { self.sudo = Some(password.to_owned()); self } + /// Set the cryptsetup password pub fn with_cryptsetup(mut self, passphrase: &str) -> Self { self.cryptsetup = Some(passphrase.to_owned()); self } + /// Reads the cryptsetup password pub fn cryptsetup(&self) -> FmResult<String> { Ok(self .cryptsetup @@ -27,6 +30,7 @@ impl PasswordHolder { .ok_or_else(|| FmError::custom("PasswordHolder", "sudo password isn't set"))?) } + /// Reads the sudo password pub fn sudo(&self) -> FmResult<String> { Ok(self .sudo @@ -60,6 +64,8 @@ pub fn filter_crypto_devices_lines(output: String, key: &str) -> Vec<String> { .collect() } +/// run a sudo command requiring a password (generally to establish the password.) +/// Since I can't send 2 passwords at a time, it will only work with the sudo password fn sudo_password(args: &[String], password: &str) -> FmResult<(String, String)> { println!("sudo {:?}", args); let mut child = Command::new("sudo") @@ -83,6 +89,8 @@ fn sudo_password(args: &[String], password: &str) -> FmResult<(String, String)> )) } +/// Run a passwordless sudo command. +/// Returns stdout & stderr fn sudo(args: &[String]) -> FmResult<(String, String)> { println!("sudo {:?}", args); let child = Command::new("sudo") @@ -139,10 +147,6 @@ impl CryptoDevice { Ok(()) } - pub fn is_mounted(&self) -> bool { - self.mountpoints.is_some() - } - fn format_luksopen_parameters(&self) -> [String; 4] { [ "cryptsetup".to_owned(), @@ -184,7 +188,7 @@ impl CryptoDevice { } pub fn open_mount(&mut self, username: &str, passwords: &PasswordHolder) -> FmResult<bool> { - if self.is_mounted() { + if self.is_mounted()? { Err(FmError::custom( "luks open mount", "device is already mounted", @@ -210,9 +214,7 @@ impl CryptoDevice { sudo(&["-k".to_owned()])?; println!("wait a few seconds..."); std::thread::sleep(std::time::Duration::from_secs(10)); - let mut block = Self::default(); - block.update_from_line(&filter_crypto_devices_lines(get_devices()?, &self.uuid)[0])?; - Ok(block.is_mounted()) + self.is_mounted() } } @@ -234,8 +236,12 @@ impl CryptoDevice { println!("stdout: {}\nstderr: {}", output.0, output.1); println!("wait a few seconds..."); std::thread::sleep(std::time::Duration::from_secs(5)); + Ok(!self.is_mounted()?) + } + + pub fn is_mounted(&self) -> FmResult<bool> { let mut block = Self::default(); block.update_from_line(&filter_crypto_devices_lines(get_devices()?, &self.uuid)[0])?; - Ok(!block.is_mounted()) + Ok(block.mountpoints.is_some()) } } diff --git a/src/event_exec.rs b/src/event_exec.rs index 90f4a55..c4e834a 100644 --- a/src/event_exec.rs +++ b/src/event_exec.rs @@ -16,6 +16,7 @@ use crate::copy_move::CopyMove; use crate::fileinfo::FileKind; use crate::filter::FilterKind; use crate::fm_error::{FmError, FmResult}; +use crate::mode::EncryptedDrive; use crate::mode::Navigate; use crate::mode::{InputSimple, MarkAction, Mode, NeedConfirmation}; use crate::opener::execute_in_child; @@ -1275,6 +1276,7 @@ impl EventExec { | Mode::InputCompleted(InputCompleted::Nothing) | Mode::InputSimple(InputSimple::Sort) | Mode::InputSimple(InputSimple::Marks(_)) => (), + Mode::InputSimple(InputSimple::EncryptedDrive(_)) => (), }; status.selected().input.reset(); @@ -1540,6 +1542,15 @@ impl EventExec { Ok(()) } } + + pub fn event_encrypted_drive(status: &mut Status) -> FmResult<()> { + status + .selected() + .set_mode(Mode::InputSimple(InputSimple::EncryptedDrive( + EncryptedDrive::PickDevices, + ))); + Ok(()) + } } fn string_to_path(path_string: &str) -> FmResult<path::PathBuf> { diff --git a/src/keybindings.rs b/src/keybindings.rs index ae430e9..304f5a2 100644 --- a/src/keybindings.rs +++ b/src/keybindings.rs @@ -77,6 +77,7 @@ impl Bindings { (Key::Char('w'), ActionMap::RegexMatch), (Key::Char('x'), ActionMap::DeleteFile), (Key::Char('z'), ActionMap::TreeFold), + (Key::Char('E'), ActionMap::EncryptedDrive), (Key::Char('Z'), ActionMap::TreeUnFoldAll), (Key::Alt('z'), ActionMap::TreeFoldAll), (Key::Alt('d'), ActionMap::DragNDrop), diff --git a/src/main.rs b/src/main.rs index aa21d42..5c719e8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -78,44 +78,5 @@ fn main() -> FmResult<()> { // crypto_device.umount_close("quentin", &password_holder)? // ); - // std::env::set_var("SUDO_ASKPASS", "/usr/lib/ssh/ssh-askpass"); - // let mut child = Command::new("sudo") - // .args(&["-S", "ls"]) - // .stdin(Stdio::piped()) - // .stdout(Stdio::piped()) - // .stderr(Stdio::piped()) - // .spawn()?; - // let stdin = child.stdin.as_mut().expect("Failed to open stdin"); - // stdin - // .write_all("aze\n".as_bytes()) - // .expect("Failed to write to stdin"); - // drop(stdin); - // let output = child.wait_with_output()?; - // println!( - // "status {:?} out {:?} err {:?}", - // output.status, - // String::from_utf8_lossy(&output.stdout), - // String::from_utf8_lossy(&output.stderr) - // ); - // - // let mut child = Command::new("sudo") - // .args(&["cryptsetup", "luksOpen", "/dev/sdb", "test_luks"]) - // .stdin(Stdio::piped()) - // .stdout(Stdio::piped()) - // .stderr(Stdio::piped()) - // .spawn()?; - // let stdin = child.stdin.as_mut().expect("Failed to open stdin"); - // stdin - // .write_all("aze\n".as_bytes()) - // .expect("Failed to write to stdin"); - // drop(stdin); - // - // let output = child.wait_with_output()?; - // println!( - // "status {:?} out {:?} err {:?}", - // output.status, - // String::from_utf8_lossy(&output.stdout), - // String::from_utf8_lossy(&output.stderr) - // ); Ok(()) } diff --git a/src/mode.rs b/src/mode.rs index 0eba6dc..d0fe54c 100644 --- a/src/mode.rs +++ b/src/mode.rs @@ -52,6 +52,13 @@ impl std::fmt::Display for NeedConfirmation { } } +#[derive(Clone, Copy, Debug)] +pub enum EncryptedDrive { + PickDevices, + OpenMount, + UmountClose, +} + /// Different modes in which the user is expeted to type something. /// It may be a new filename, a mode (aka an octal permission), /// the name of a new file, of a new directory, @@ -75,6 +82,8 @@ pub enum InputSimple { Marks(MarkAction), /// Filter by extension, name, directory or no filter Filter, + /// + EncryptedDrive(EncryptedDrive), } /// Different modes in which we display a bunch of possible destinations. @@ -126,6 +135,9 @@ impl fmt::Display for Mode { Mode::InputSimple(InputSimple::Sort) => { write!(f, "Sort: Kind Name Modif Size Ext Rev :") } + Mode::InputSimple(InputSimple::EncryptedDrive(EncryptedDrive)) => { + write!(f, "{:?}", EncryptedDrive) + } Mode::InputSimple(InputSimple::Marks(_)) => write!(f, "Marks jump:"), Mode::InputSimple(InputSimple::Filter) => write!(f, "Filter: "), Mode::InputCompleted(InputCompleted::Exec) => write!(f, "Exec: "), diff --git a/src/status.rs b/src/status.rs index 85ba2ff..9856663 100644 --- a/src/status.rs +++ b/src/status.rs @@ -14,6 +14,7 @@ use crate::args::Args; use crate::config::{Colors, Config}; use crate::constant_strings_paths::OPENER_PATH; use crate::copy_move::{copy_move, CopyMove}; +use crate::cryptsetup::{filter_crypto_devices_lines, get_devices, CryptoDevice}; use crate::flagged::Flagged; use crate::fm_error::{FmError, FmResult}; use crate::marks::Marks; @@ -59,6 +60,7 @@ pub struct Status { /// The trash pub trash: Trash, pub config_colors: Colors, + pub encrypted_devices: Option<Vec<CryptoDevice>>, } impl Status { @@ -84,6 +86,7 @@ impl Status { tab.shortcut .extend_with_mount_points(&Self::disks_mounts(sys.disks())); let trash = Trash::new()?; + let encrypted_devices = None; Ok(Self { tabs: [tab.clone(), tab], @@ -100,6 +103,7 @@ impl Status { opener, help, trash, + encrypted_devices, }) } @@ -315,4 +319,19 @@ impl Status { self.selected().directory = Directory::empty(&path, users_cache)?; Ok(()) } + + pub fn read_encrypted_devices(&mut self) -> FmResult<()> { + self.encrypted_devices = Some( + filter_crypto_devices_lines(get_devices()?, "crypto") + .iter() + .map(|line| CryptoDevice::from_line(line)) + .filter_map(|r| r.ok()) + .collect(), + ); + Ok(()) + } + + pub fn drop_encrypted_devices(&mut self) { + self.encrypted_devices = None; + } } diff --git a/src/term_manager.rs b/src/term_manager.rs index 25637e4..ce0545e 100644 --- a/src/term_manager.rs +++ b/src/term_manager.rs @@ -15,7 +15,7 @@ use crate::constant_strings_paths::{ use crate::content_window::ContentWindow; use crate::fileinfo::{fileinfo_attr, FileInfo}; use crate::fm_error::{FmError, FmResult}; -use crate::mode::{InputSimple, MarkAction, Mode, Navigate, NeedConfirmation}; +use crate::mode::{EncryptedDrive, InputSimple, MarkAction, Mode, Navigate, NeedConfirmation}; use crate::preview::{Preview, TextKind, Window}; use crate::selectable_content::SelectableContent; use crate::status::Status; @@ -371,6 +371,9 @@ impl<'a> Draw for WinSecondary<'a> { } Mode::InputCompleted(_) => self.completion(self.tab, canvas), Mode::InputSimple(InputSimple::Marks(_)) => self.marks(self.status, self.tab, canvas), + Mode::InputSimple(InputSimple::EncryptedDrive(EncryptedDrive::PickDevices)) => { + self.encrypted_devices(self.status, self.tab, canvas) + } _ => Ok(()), }?; self.cursor(self.tab, canvas)?; @@ -510,6 +513,22 @@ impl<'a> WinSecondary<'a> { Ok(()) } + fn encrypted_devices( + &self, + status: &Status, + tab: &Tab, + canvas: &mut dyn Canvas, + ) -> FmResult<()> { + canvas.print_with_attr(2, 1, "encrypted devices", Self::ATTR_YELLOW)?; + if let Some(encrypted_devices) = status.encrypted_devices { + for (i, device) in encrypted_devices.iter().enumerate() { + let row = calc_line_row(i, tab) + 2; + canvas.print(row, 3, device.as_string())?; + } + } + Ok(()) + } + /// Display a list of edited (deleted, copied, moved) files for confirmation fn confirmation( &self, |