From bc18bca5c67b4a678a31198877e39d57d97b1e0c Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 6 Apr 2020 06:35:30 -0400 Subject: factor out into an agent --- src/pinentry.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/pinentry.rs (limited to 'src/pinentry.rs') diff --git a/src/pinentry.rs b/src/pinentry.rs new file mode 100644 index 0000000..610f52d --- /dev/null +++ b/src/pinentry.rs @@ -0,0 +1,49 @@ +use tokio::io::{AsyncBufReadExt as _, AsyncWriteExt as _}; + +// TODO result +pub async fn pinentry(prompt: &str, desc: &str, tty: Option<&str>) -> String { + let mut opts = tokio::process::Command::new("pinentry"); + let opts = opts + .stdin(std::process::Stdio::piped()) + .stdout(std::process::Stdio::piped()); + let opts = if let Some(tty) = tty { + opts.args(&["-T", tty]) + } else { + opts + }; + let mut child = opts.spawn().unwrap(); + { + let stdin = child.stdin.as_mut().unwrap(); + let mut stdout = + tokio::io::BufReader::new(child.stdout.as_mut().unwrap()); + let mut buf = String::new(); + + stdin.write_all(b"SETTITLE rbw\n").await.unwrap(); + stdout.read_line(&mut buf).await.unwrap(); + + stdin + .write_all(format!("SETPROMPT {}\n", prompt).as_bytes()) + .await + .unwrap(); + stdout.read_line(&mut buf).await.unwrap(); + + stdin + .write_all(format!("SETDESC {}\n", desc).as_bytes()) + .await + .unwrap(); + stdout.read_line(&mut buf).await.unwrap(); + + stdin.write_all(b"GETPIN\n").await.unwrap(); + } + let res = + String::from_utf8(child.wait_with_output().await.unwrap().stdout) + .unwrap(); + for line in res.lines() { + if line.starts_with("OK") { + continue; + } else if line.starts_with("D ") { + return line[2..line.len()].to_string(); + } + } + panic!("failed to parse pinentry output: {:?}", res) +} -- cgit v1.2.3-54-g00ecf