aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-05-25 21:37:07 -0400
committerJesse Luehrs <doy@tozt.net>2020-05-25 21:37:07 -0400
commitfe23507043d5d476e382d364270fcc9419475958 (patch)
treeff7c20b34a5e2ec97db978258186c623b83a2f31
parentbb9b1d9dbe9f1c098a538d729472d257c860fee3 (diff)
downloadrbw-fe23507043d5d476e382d364270fcc9419475958.tar.gz
rbw-fe23507043d5d476e382d364270fcc9419475958.zip
fix finding the active tty name
apparently $TTY is a shell builtin variable, and not set in the actual environment
-rw-r--r--CHANGELOG.md1
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--src/bin/rbw/actions.rs31
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<u32> {
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<String> {
+ 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() {