如何通过rpassword或Polkit实现无交互sudo命令执行?
过时的初始方案
我尝试通过sudo启动命令,并借助rpassword的BufRead实现向进程传递密码。
为避免在TTY上弹出密码提示,我使用了sudo的-S参数。启动命令时,我通过take()获取stdin,再启动一个线程将通过BufRead保存的密码写入stdin,这是按照Rust官方文档的建议操作的。
示例代码如下:
use rpassword::read_password_from_bufread; use std::{ io::{Cursor, Write}, process::{Command, Stdio}, thread, }; fn sudo_cmd(pw: String) { let mut cmd = Command::new("sudo") .arg("-S") .arg("ls") .stdin(Stdio::piped()) .stdout(Stdio::piped()) // .stderr(Stdio::null()) //<<== should hide password prompt .spawn() .ok() .expect("not spawned"); let mut stdin = cmd.stdin.take().expect("Couldnt take stdin"); thread::spawn(move || { stdin .write_all(pw.as_bytes()) .expect("Couldnt write stding"); }); let output = cmd.wait_with_output().expect("wheres the output"); println!( "Output:\n{}", String::from_utf8(output.stdout).expect("Cant read stdout") ); } fn main() { let mut mock_input = Cursor::new("my-password\n".as_bytes().to_owned()); let password = read_password_from_bufread(&mut mock_input).unwrap(); sudo_cmd(password); }
遗憾的是,该方案无法正常工作。进程等待片刻后退出,仿佛未提供密码一般:
Compiling testproject v0.1.0 (/home/lukeflo/Documents/projects/coding/testfiles/rust-tests/testproject) Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s Running `target/debug/testproject` Password: Sorry, try again. Password: sudo: no password was provided sudo: 1 incorrect password attempt Output:
暂不考虑安全问题,正确的实现方式是什么?我无法/不愿直接使用TTY提示(纯CLI应用可以做到),因为我想了解如何像密码管理器的GUI包装器那样“间接”收集密码。
编辑:使用Polkit
对于GUI/TUI应用,Polkit似乎是合适的方案。但据我所知,用于Polkit交互的Rust库很少,且文档不完善,或许我有所遗漏。希望能获得相关建议,整体代码结构保持不变,我只想通过Polkit完成sudo命令的认证。
内容的提问来源于stack exchange,提问作者lukeflo
相关产品推荐
相关产品推荐

