aboutsummaryrefslogtreecommitdiffstats
path: root/src/pinentry.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-04-06 06:35:30 -0400
committerJesse Luehrs <doy@tozt.net>2020-04-06 06:35:30 -0400
commitbc18bca5c67b4a678a31198877e39d57d97b1e0c (patch)
tree3dc31608586cbe0f7973d7aa730267d57224e6a1 /src/pinentry.rs
parent4ad2f0a0dc3abb4cb10a6b82ca6a1f3a829eb1fb (diff)
downloadrbw-bc18bca5c67b4a678a31198877e39d57d97b1e0c.tar.gz
rbw-bc18bca5c67b4a678a31198877e39d57d97b1e0c.zip
factor out into an agent
Diffstat (limited to 'src/pinentry.rs')
-rw-r--r--src/pinentry.rs49
1 files changed, 49 insertions, 0 deletions
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)
+}