Wednesday October 20 2021
SSH Askpass and dmenu – dmenu_askpass
Why? I run dwm almost exclusively and I wanted something that integrated well.
Also, because I’ve deployed modern ecdsa-sk
and ed25519-sk
SSH keys to all of my infrastructure askpass becomes a lot more
important. Before It’d just be used to unlock a key and load it into my SSH
agent, now it’s much more important than that since any time I log into a
machine it will require me to tap my authenticator–it’s not always obvious that
I should and without askpass with a forwarded agent I may not get prompted.
It’s easy enough to use, assuming you’re already starting an ssh agent on login, simply set the environment variables:
SSH_ASKPASS=dmenu_askpass
SSH_ASKPASS_REQUIRE=force
The SSH_ASKPASS_REQUIRE
is optional, though it’s my preference.
You clone it from my git server:
git clone -b dmenu_askpass https://git.riedstra.dev/x/dmenu
Alternatively a fresh checkout of dmenu from their git server and the following patch will apply: ( Or a direct download )
From 34ffa30edc8ae60e83c538c5d8809d1981e5a9e5 Mon Sep 17 00:00:00 2001
From: Mitchell Riedstra <mitch@riedstra.dev>
Date: Wed, 20 Oct 2021 20:45:53 -0400
Subject: SSH askpass suppport
dmenu_askpass has been added and can be used to read in SSH key
passwords, useful for if your agent is forwarded. Full support for
prompting from security keys, often requiring you to tap the
authenticator. This unlike some other askpass variants does not stick
around after you tap the button.
---
Makefile | 3 ++-
dmenu.c | 13 +++++++++++--
dmenu_askpass | 3 +++
3 files changed, 16 insertions(+), 3 deletions(-)
create mode 100755 dmenu_askpass
diff --git a/Makefile b/Makefile
index a03a95c..2a4cd96 100644
--- a/Makefile
+++ b/Makefile
@@ -42,10 +42,11 @@ dist: clean
install: all
mkdir -p $(DESTDIR)$(PREFIX)/bin
- cp -f dmenu dmenu_path dmenu_run stest $(DESTDIR)$(PREFIX)/bin
+ cp -f dmenu dmenu_path dmenu_run dmenu_askpass stest $(DESTDIR)$(PREFIX)/bin
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_path
chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_run
+ chmod 755 $(DESTDIR)$(PREFIX)/bin/dmenu_askpass
chmod 755 $(DESTDIR)$(PREFIX)/bin/stest
mkdir -p $(DESTDIR)$(MANPREFIX)/man1
sed "s/VERSION/$(VERSION)/g" < dmenu.1 > $(DESTDIR)$(MANPREFIX)/man1/dmenu.1
diff --git a/dmenu.c b/dmenu.c
index 98507d9..8c12e4b 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -35,6 +35,7 @@ struct item {
};
static char text[BUFSIZ] = "";
+static int echo = 1;
static char *embed;
static int bh, mw, mh;
static int inputw = 0, promptw;
@@ -143,7 +144,11 @@ drawmenu(void)
/* draw input field */
w = (lines > 0 || !matches) ? mw - x : inputw;
drw_setscheme(drw, scheme[SchemeNorm]);
- drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
+
+ if (echo)
+ drw_text(drw, x, 0, w, bh, lrpad / 2, text, 0);
+ else
+ drw_text(drw, x, 0, w, bh, lrpad / 2, "(no echo)", 0);
curpos = TEXTW(text) - TEXTW(&text[cursor]);
if ((curpos += lrpad / 2 - 1) < w) {
@@ -262,6 +267,7 @@ match(void)
}
curr = sel = matches;
calcoffsets();
+ memset(buf, '\0', sizeof(text));
}
static void
@@ -474,6 +480,7 @@ insert:
case XK_Return:
case XK_KP_Enter:
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
+ memset(text, '\0', sizeof text);
if (!(ev->state & ControlMask)) {
cleanup();
exit(0);
@@ -700,7 +707,7 @@ setup(void)
static void
usage(void)
{
- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
+ fputs("usage: dmenu [-bfivE] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
" [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr);
exit(1);
}
@@ -720,6 +727,8 @@ main(int argc, char *argv[])
topbar = 0;
else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
fast = 1;
+ else if (!strcmp(argv[i], "-E")) /* no Echo, for use with passphrases */
+ echo = 0;
else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
fstrncmp = strncasecmp;
fstrstr = cistrstr;
diff --git a/dmenu_askpass b/dmenu_askpass
new file mode 100755
index 0000000..9f61844
--- /dev/null
+++ b/dmenu_askpass
@@ -0,0 +1,3 @@
+#!/bin/sh
+exec <&-
+exec dmenu -E -p "${1:-OpenSSH Passphrase: }"
--
2.33.0
In the next few days I’ll be seeing if I can get this listed as one of the patches on the Suckless website. In the mean time I figure my readers will enjoy the patch and for those glancing over my work it’s easier to see it on my blog than scattered across the internet.