cleansys_core/auth.rs
1//! Sudo/root authentication helpers shared by the TUI password prompt and the
2//! GUI authentication dialog.
3//!
4//! This module contains no UI framework code — front-ends own their own
5//! widgets/state and call into these functions to perform the actual
6//! authentication.
7
8use anyhow::Result;
9use std::io::Write;
10use std::process::{Command, Stdio};
11
12/// Attempt to authenticate as root using `sudo -S -v` with the given password
13/// piped over stdin. Returns `Ok(true)` if authentication succeeded, `Ok(false)`
14/// if the password was rejected, and `Err` if `sudo` could not be invoked at all.
15pub fn authenticate_sudo(password: &str) -> Result<bool> {
16 let mut child = Command::new("sudo")
17 .arg("-S")
18 .arg("-v")
19 .stdin(Stdio::piped())
20 .stdout(Stdio::null())
21 .stderr(Stdio::null())
22 .spawn()?;
23
24 if let Some(mut stdin) = child.stdin.take() {
25 writeln!(stdin, "{}", password)?;
26 }
27
28 let status = child.wait()?;
29 Ok(status.success())
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35
36 #[test]
37 #[cfg(unix)]
38 fn authenticate_sudo_with_wrong_password_does_not_panic() {
39 // We can't guarantee the outcome (depends on the test machine's sudo
40 // config and cached credentials), just that the call completes.
41 let _ = authenticate_sudo("definitely-not-the-real-password-12345");
42 }
43}