From fe23507043d5d476e382d364270fcc9419475958 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 25 May 2020 21:37:07 -0400 Subject: fix finding the active tty name apparently $TTY is a shell builtin variable, and not set in the actual environment --- CHANGELOG.md | 1 + Cargo.lock | 2 ++ Cargo.toml | 2 ++ src/bin/rbw/actions.rs | 31 ++++++++++++++++++++++++++----- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a18b99..a3f8a1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixed +* Terminal-based pinentry methods should now work correctly (Glandos). * Further error message improvements. ## [0.3.4] - 2020-05-24 diff --git a/Cargo.lock b/Cargo.lock index 8f671c9..b9e56a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1129,7 +1129,9 @@ dependencies = [ "directories", "env_logger", "humantime 2.0.0", + "libc", "log", + "memchr", "nix", "openssl", "paw", diff --git a/Cargo.toml b/Cargo.toml index d636716..1a4d1b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,9 @@ daemonize = "0.4" directories = "2.0" env_logger = "0.7" humantime = "2.0" +libc = "0.2" log = "0.4" +memchr = "2.3" nix = "0.17" openssl = "0.10" paw = "1.0" diff --git a/src/bin/rbw/actions.rs b/src/bin/rbw/actions.rs index 035ebe6..8eabdd6 100644 --- a/src/bin/rbw/actions.rs +++ b/src/bin/rbw/actions.rs @@ -25,7 +25,7 @@ pub fn quit() -> anyhow::Result<()> { std::fs::File::open(pidfile)?.read_to_string(&mut pid)?; let pid = nix::unistd::Pid::from_raw(pid.parse()?); sock.send(&rbw::protocol::Request { - tty: std::env::var("TTY").ok(), + tty: ttyname(), action: rbw::protocol::Action::Quit, })?; wait_for_exit(pid)?; @@ -48,7 +48,7 @@ pub fn decrypt( let mut sock = crate::sock::Sock::connect() .context("failed to connect to rbw-agent")?; sock.send(&rbw::protocol::Request { - tty: std::env::var("TTY").ok(), + tty: ttyname(), action: rbw::protocol::Action::Decrypt { cipherstring: cipherstring.to_string(), org_id: org_id.map(std::string::ToString::to_string), @@ -72,7 +72,7 @@ pub fn encrypt( let mut sock = crate::sock::Sock::connect() .context("failed to connect to rbw-agent")?; sock.send(&rbw::protocol::Request { - tty: std::env::var("TTY").ok(), + tty: ttyname(), action: rbw::protocol::Action::Encrypt { plaintext: plaintext.to_string(), org_id: org_id.map(std::string::ToString::to_string), @@ -93,7 +93,7 @@ pub fn version() -> anyhow::Result { let mut sock = crate::sock::Sock::connect() .context("failed to connect to rbw-agent")?; sock.send(&rbw::protocol::Request { - tty: std::env::var("TTY").ok(), + tty: ttyname(), action: rbw::protocol::Action::Version, })?; @@ -112,7 +112,7 @@ fn simple_action(action: rbw::protocol::Action) -> anyhow::Result<()> { .context("failed to connect to rbw-agent")?; sock.send(&rbw::protocol::Request { - tty: std::env::var("TTY").ok(), + tty: ttyname(), action, })?; @@ -126,6 +126,27 @@ fn simple_action(action: rbw::protocol::Action) -> anyhow::Result<()> { } } +// TODO: it'd be great if ttyname_r was exposed via nix, so i didn't have to +// manually deal with unsafe here +fn ttyname() -> Option { + const PATH_MAX: usize = libc::PATH_MAX as usize; + let mut buf = [0_u8; PATH_MAX]; + let c_buf = buf.as_mut_ptr() as *mut libc::c_char; + + let ret = unsafe { libc::ttyname_r(0, c_buf, PATH_MAX) }; + if ret != 0 { + return None; + } + + let nul = memchr::memchr(b'\0', &buf)?; + if nul == 0 { + return None; + } + + let s = std::str::from_utf8(&buf[..nul]).ok()?; + Some(s.to_string()) +} + fn wait_for_exit(pid: nix::unistd::Pid) -> anyhow::Result<()> { loop { if nix::sys::signal::kill(pid, None).is_err() { -- cgit v1.2.3