summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorqkzk <qu3nt1n@gmail.com>2023-01-17 22:41:37 +0100
committerqkzk <qu3nt1n@gmail.com>2023-01-17 22:41:37 +0100
commitfd909c5f6f5fb58d44ede2709b0eface96c59ca3 (patch)
treeb34c8eea43fe49cd957053c6f9c8a31c689cf5e6 /src
parent945dc34a2450520060194280aa4b3ea99e33df78 (diff)
fix: wrong sudo password panics. drop sudo rights and reset faillock
Diffstat (limited to 'src')
-rw-r--r--src/cryptsetup.rs120
-rw-r--r--src/main.rs30
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(())
-}