pub fn wrap_sudo_command(command: &str, password: Option<&str>) -> String {
let escaped_command = escape_for_shell(command);
match password {
None => {
format!("sudo -n sh -c '{}'", escaped_command)
}
Some(pwd) => {
let escaped_pwd = escape_for_shell(pwd);
format!(
"printf '%s\\n' '{}' | sudo -S sh -c '{}'",
escaped_pwd, escaped_command
)
}
}
}
pub fn escape_for_shell(s: &str) -> String {
crate::shell_escape::escape_for_shell(s)
}
pub fn is_valid_password(password: &str) -> bool {
!password.trim().is_empty() && !password.contains('\0')
}
pub fn sanitize_password(password: Option<&str>) -> Option<String> {
password
.map(|p| p.trim())
.filter(|p| !p.is_empty())
.map(|p| p.to_string())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_wrap_sudo_command_without_password() {
let result = wrap_sudo_command("apt update", None);
assert_eq!(result, "sudo -n sh -c 'apt update'");
}
#[test]
fn test_wrap_sudo_command_with_password() {
let result = wrap_sudo_command("apt update", Some("secret123"));
assert_eq!(
result,
"printf '%s\\n' 'secret123' | sudo -S sh -c 'apt update'"
);
}
#[test]
fn test_wrap_sudo_command_with_quotes_in_command() {
let result = wrap_sudo_command("echo 'hello world'", None);
assert_eq!(result, "sudo -n sh -c 'echo '\"'\"'hello world'\"'\"''");
}
#[test]
fn test_wrap_sudo_command_with_quotes_in_password() {
let result = wrap_sudo_command("apt update", Some("pass'word"));
assert_eq!(
result,
"printf '%s\\n' 'pass'\"'\"'word' | sudo -S sh -c 'apt update'"
);
}
#[test]
fn test_wrap_sudo_command_complex() {
let result = wrap_sudo_command("cat /etc/shadow | grep root", Some("admin123"));
assert_eq!(
result,
"printf '%s\\n' 'admin123' | sudo -S sh -c 'cat /etc/shadow | grep root'"
);
}
#[test]
fn test_escape_for_shell_no_quotes() {
assert_eq!(escape_for_shell("hello world"), "hello world");
}
#[test]
fn test_escape_for_shell_single_quote() {
assert_eq!(escape_for_shell("it's"), "it'\"'\"'s");
}
#[test]
fn test_escape_for_shell_multiple_quotes() {
assert_eq!(
escape_for_shell("'a' and 'b'"),
"'\"'\"'a'\"'\"' and '\"'\"'b'\"'\"'"
);
}
#[test]
fn test_is_valid_password() {
assert!(is_valid_password("secret123"));
assert!(is_valid_password("with spaces"));
assert!(!is_valid_password(""));
assert!(!is_valid_password(" "));
assert!(!is_valid_password("has\0null"));
}
#[test]
fn test_sanitize_password() {
assert_eq!(
sanitize_password(Some("secret")),
Some("secret".to_string())
);
assert_eq!(
sanitize_password(Some(" secret ")),
Some("secret".to_string())
);
assert_eq!(sanitize_password(Some("")), None);
assert_eq!(sanitize_password(Some(" ")), None);
assert_eq!(sanitize_password(None), None);
}
}