diff options
author | qkzk <qu3nt1n@gmail.com> | 2023-01-17 22:41:37 +0100 |
---|---|---|
committer | qkzk <qu3nt1n@gmail.com> | 2023-01-17 22:41:37 +0100 |
commit | fd909c5f6f5fb58d44ede2709b0eface96c59ca3 (patch) | |
tree | b34c8eea43fe49cd957053c6f9c8a31c689cf5e6 /src | |
parent | 945dc34a2450520060194280aa4b3ea99e33df78 (diff) |
fix: wrong sudo password panics. drop sudo rights and reset faillock
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptsetup.rs | 120 | ||||
-rw-r--r-- | src/main.rs | 30 |
2 files changed, 92 insertions, 58 deletions
diff --git a/src/cryptsetup.rs b/src/cryptsetup.rs index 7e88abb..e2518ae 100644 --- a/src/cryptsetup.rs +++ b/src/cryptsetup.rs @@ -81,6 +81,11 @@ impl PasswordHolder { pub fn has_cryptsetup(&self) -> bool { self.cryptsetup.is_some() } + + pub fn reset(&mut self) { + self.sudo = None; + self.cryptsetup = None; + } } /// get devices list from lsblk @@ -110,7 +115,7 @@ pub fn filter_crypto_devices_lines(output: String, key: &str) -> Vec<String> { /// 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)> { +fn sudo_password(args: &[String], password: &str) -> FmResult<(bool, String, String)> { info!("sudo {:?}", args); let mut child = Command::new("sudo") .args(args) @@ -128,6 +133,7 @@ fn sudo_password(args: &[String], password: &str) -> FmResult<(String, String)> let output = child.wait_with_output()?; Ok(( + output.status.success(), String::from_utf8(output.stdout)?, String::from_utf8(output.stderr)?, )) @@ -135,7 +141,7 @@ 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)> { +fn sudo(args: &[String]) -> FmResult<(bool, String, String)> { info!("sudo {:?}", args); let child = Command::new("sudo") .args(args) @@ -145,6 +151,7 @@ fn sudo(args: &[String]) -> FmResult<(String, String)> { .spawn()?; let output = child.wait_with_output()?; Ok(( + output.status.success(), String::from_utf8(output.stdout)?, String::from_utf8(output.stderr)?, )) @@ -231,7 +238,7 @@ impl CryptoDevice { ] } - pub fn open_mount(&mut self, username: &str, passwords: &PasswordHolder) -> FmResult<()> { + pub fn open_mount(&mut self, username: &str, passwords: &mut PasswordHolder) -> FmResult<bool> { if self.mount_point().is_some() { Err(FmError::custom( "luks open mount", @@ -239,42 +246,67 @@ impl CryptoDevice { )) } else { // sudo - sudo_password( + let (success, _, _) = sudo_password( &["-S".to_owned(), "ls".to_owned(), "/root".to_owned()], &passwords.sudo()?, )?; + if !success { + return Ok(false); + } // open - let output = + let (success, stdout, stderr) = sudo_password(&self.format_luksopen_parameters(), &passwords.cryptsetup()?)?; - info!("stdout: {}\nstderr: {}", output.0, output.1); + info!("stdout: {}\nstderr: {}", stdout, stderr); + if !success { + return Ok(false); + } // mkdir - let output = sudo(&self.format_mkdir_parameters(username))?; - info!("stdout: {}\nstderr: {}", output.0, output.1); + let (success, stdout, stderr) = sudo(&self.format_mkdir_parameters(username))?; + info!("stdout: {}\nstderr: {}", stdout, stderr); + if !success { + return Ok(false); + } // mount - let output = sudo(&self.format_mount_parameters(username))?; - info!("stdout: {}\nstderr: {}", output.0, output.1); - // sudo -t + let (success, stdout, stderr) = sudo(&self.format_mount_parameters(username))?; + info!("stdout: {}\nstderr: {}", stdout, stderr); + if !success { + return Ok(false); + } + // sudo -k sudo(&["-k".to_owned()])?; - Ok(()) + Ok(success) } } - pub fn umount_close(&mut self, username: &str, passwords: &PasswordHolder) -> FmResult<()> { + pub fn umount_close( + &mut self, + username: &str, + passwords: &mut PasswordHolder, + ) -> FmResult<bool> { // sudo - sudo_password( + let (success, _, _) = sudo_password( &["-S".to_owned(), "ls".to_owned(), "/root".to_owned()], &passwords.sudo()?, )?; + if !success { + return Ok(false); + } // unmount - let output = sudo(&self.format_umount_parameters(username))?; - info!("stdout: {}\nstderr: {}", output.0, output.1); + let (success, stdout, stderr) = sudo(&self.format_umount_parameters(username))?; + info!("stdout: {}\nstderr: {}", stdout, stderr); + if !success { + return Ok(false); + } // close - let output = sudo(&self.format_luksclose_parameters())?; - info!("stdout: {}\nstderr: {}", output.0, output.1); - // sudo -t - let output = sudo(&["-k".to_owned()])?; - info!("stdout: {}\nstderr: {}", output.0, output.1); - Ok(()) + let (success, stdout, stderr) = sudo(&self.format_luksclose_parameters())?; + info!("stdout: {}\nstderr: {}", stdout, stderr); + if !success { + return Ok(false); + } + // sudo -k + let (success, stdout, stderr) = sudo(&["-k".to_owned()])?; + info!("stdout: {}\nstderr: {}", stdout, stderr); + Ok(success) } fn mount_point(&self) -> Option<String> { @@ -342,19 +374,51 @@ impl DeviceOpener { pub fn mount_selected(&mut self) -> FmResult<()> { let username = current_username()?; - let passwords = self.content[self.index].password_holder.clone(); - self.content[self.index] + let mut passwords = self.content[self.index].password_holder.clone(); + let success = self.content[self.index] .cryptdevice - .open_mount(&username, &passwords)?; + .open_mount(&username, &mut passwords)?; + if !success { + self.content[self.index].password_holder.reset(); + Self::reset_faillock()? + } + Self::drop_sudo()?; Ok(()) } pub fn umount_selected(&mut self) -> FmResult<()> { let username = current_username()?; - let passwords = self.content[self.index].password_holder.clone(); - self.content[self.index] + let mut passwords = self.content[self.index].password_holder.clone(); + let success = self.content[self.index] .cryptdevice - .umount_close(&username, &passwords)?; + .umount_close(&username, &mut passwords)?; + if !success { + self.content[self.index].password_holder.reset(); + Self::reset_faillock()? + } + Self::drop_sudo()?; + Ok(()) + } + + fn reset_faillock() -> FmResult<()> { + Command::new("faillock") + .arg("--user") + .arg(current_username()?) + .arg("--reset") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn()?; + Ok(()) + } + + fn drop_sudo() -> FmResult<()> { + Command::new("sudo") + .arg("-k") + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn()?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index e7d9b71..3c9aa08 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,33 +48,3 @@ fn main() -> FmResult<()> { info!("fm is shutting down"); Ok(()) } - -fn _main() -> FmResult<()> { - use users::{get_current_uid, get_user_by_uid}; - - use fm::cryptsetup::{filter_crypto_devices_lines, get_devices, CryptoDevice, PasswordHolder}; - - let ret_val = get_devices()?; - println!("{}", ret_val); - let output = filter_crypto_devices_lines(ret_val, "crypto"); - println!("{:?}", output); - let mut crypto_device = CryptoDevice::from_line(&output[0])?; - let password_holder = PasswordHolder::default() - .with_sudo("aze") - .with_cryptsetup("aze"); - let user = get_user_by_uid(get_current_uid()) - .ok_or_else(|| fm::fm_error::FmError::custom("username", "couldn't read username"))?; - let username = user - .name() - .to_str() - .ok_or_else(|| fm::fm_error::FmError::custom("username", "couldn't read username"))?; - println!("{:?}", crypto_device); - crypto_device.open_mount(&username, &password_holder)?; - - // println!( - // "unmounted ? {}", - // crypto_device.umount_close("quentin", &password_holder)? - // ); - - Ok(()) -} |