pinentry-dmenu

a pinentry program based on dmenu
git clone anongit@rnpnr.xyz:pinentry-dmenu.git
Log | Files | Refs | Feed | README | LICENSE

Commit: 58d82d032b92d2373bbdb8d8743ad27702276684
Parent: 57666e75c695ac9cc34fbc8db71da9ea5614ff8a
Author: Randy Palamar
Date:   Fri,  4 Nov 2022 23:48:20 -0600

cleanup some of the remaining differences from upstream dmenu

additionally revert a lot of the useless style changes

Diffstat:
Mconfig.def.h | 22+++++++++++++---------
Mpinentry-dmenu.1 | 5-----
Mpinentry-dmenu.c | 255+++++++++++++++++++++++++++++++++++--------------------------------------------
3 files changed, 127 insertions(+), 155 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -1,20 +1,24 @@ /* See LICENSE file for copyright and license details. */ -/* Default settings; can be overriden by command line. */ -static int bottom = 0; -static int embedded = 0; -static int minpwlen = 32; -static int mon = -1; -static int lineheight = 0; +/* minimum length to use for displaying the pw field */ +static int minpwflen = 16; +/* character to be used as a replacement for typed characters */ static const char *asterisk = "*"; + +/* if 0, pinentry-dmenu appears at bottom */ +static int topbar = 1; + +/* default X11 font or font set */ static const char *fonts[] = { "monospace:size=10" }; + static const char *prompt = NULL; -static const char *colors[SchemeLast][4] = { +static const char *colors[SchemeLast][2] = { + /* fg bg */ [SchemePrompt] = { "#bbbbbb", "#222222" }, - [SchemeNormal] = { "#bbbbbb", "#222222" }, - [SchemeSelect] = { "#eeeeee", "#005577" }, + [SchemeNorm] = { "#bbbbbb", "#222222" }, + [SchemeSel] = { "#eeeeee", "#005577" }, [SchemeDesc] = { "#bbbbbb", "#222222" } }; diff --git a/pinentry-dmenu.1 b/pinentry-dmenu.1 @@ -138,11 +138,6 @@ and uses the api of .B pinentry-dmenu itself was written by Moritz Lüdecke <ritze@skweez.net>. - -.SH REPORTING BUGS -Report pinentry-dmenu bugs to <BUGREPORT> - - .SH SEE ALSO .BR dmenu (1), .BR dwm (1), diff --git a/pinentry-dmenu.c b/pinentry-dmenu.c @@ -24,30 +24,29 @@ #include "pinentry/pinentry.h" #include "pinentry/memory.h" -#define CONFIG_DIR "/.gnupg" -#define CONFIG_FILE "/pinentry-dmenu.conf" #define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \ * MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org))) #define LENGTH(X) (sizeof(X) / sizeof(X[0])) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) #define MINDESCLEN 8 -enum { SchemePrompt, SchemeNormal, SchemeSelect, SchemeDesc, SchemeLast }; +/* enums */ +enum { SchemePrompt, SchemeNormal, SchemeSelect, SchemeDesc, SchemeLast }; /* color schemes */ enum { WinPin, WinConfirm }; -enum { Ok, NotOk, Cancel }; enum { Nothing, Yes, No }; +/* FIXME: this can't currently be set */ +static char *embed; static int bh, mw, mh; static int sel; static int promptw, pdescw; -/* Sum of left and right padding */ -static int lrpad; +static int lrpad; /* sum of left and right padding */ static size_t cursor; -static int screen; +static int mon = -1, screen; -static char* pin; +static char *pin; static int pin_len; -static char* pin_repeat; +static char *pin_repeat; static int pin_repeat_len; static int repeat; @@ -66,7 +65,8 @@ pinentry_t pinentry_info; #include "config.h" static int -drawitem(const char* text, Bool sel, int x, int y, int w) { +drawitem(const char* text, Bool sel, int x, int y, int w) +{ unsigned int i = (sel) ? SchemeSelect : SchemeNormal; drw_setscheme(drw, scheme[i]); @@ -75,57 +75,54 @@ drawitem(const char* text, Bool sel, int x, int y, int w) { } static void -grabfocus(void) { +grabfocus(void) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 }; Window focuswin; int i, revertwin; for (i = 0; i < 100; ++i) { XGetInputFocus(dpy, &focuswin, &revertwin); - if (focuswin == win) { + if (focuswin == win) return; - } XSetInputFocus(dpy, win, RevertToParent, CurrentTime); - usleep(1000); + nanosleep(&ts, NULL); } - die("cannot grab focus"); } static void -grabkeyboard(void) { +grabkeyboard(void) +{ + struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 }; int i; - if (embedded) { + if (embed) return; - } - - /* Try to grab keyboard, - * we may have to wait for another process to ungrab */ + /* try to grab keyboard, we may have to wait for another process to ungrab */ for (i = 0; i < 1000; i++) { if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), True, GrabModeAsync, - GrabModeAsync, CurrentTime) == GrabSuccess) { + GrabModeAsync, CurrentTime) == GrabSuccess) return; - } - usleep(1000); + nanosleep(&ts, NULL); } - die("cannot grab keyboard"); } static size_t -nextrune(int cursor, int inc) { +nextrune(int inc) +{ ssize_t n; - /* Return location of next utf8 rune in the given direction (+1 or -1) */ - for (n = cursor + inc; - n + inc >= 0 && (pin[n] & 0xc0) == 0x80; - n += inc); - + /* return location of next utf8 rune in the given direction (+1 or -1) */ + for (n = cursor + inc; n + inc >= 0 && (pin[n] & 0xc0) == 0x80; n += inc) + ; return n; } static void -setup_pin(char* pin_ptr, int len, int reset) { +setup_pin(char *pin_ptr, int len, int reset) +{ pin = pin_ptr; pin_len = len; @@ -133,14 +130,14 @@ setup_pin(char* pin_ptr, int len, int reset) { promptw = (prompt) ? TEXTW(prompt) - lrpad / 4 : 0; cursor = 0; - if (pin) { + if (pin) pin[0] = '\0'; - } } } static void -insert(const char *str, ssize_t n) { +insert(const char *str, ssize_t n) +{ size_t len = strlen(pin); // FIXME: Pinentry crashes when increasing the pin buffer the second time. @@ -150,15 +147,13 @@ insert(const char *str, ssize_t n) { pin_repeat_len = 2 * pin_repeat_len; pin_repeat = secmem_realloc(pin_repeat, pin_repeat_len); setup_pin(pin_repeat, pin_repeat_len, 0); - if (!pin_repeat) { + if (!pin_repeat) pin_len = 0; - } } else { - if (!pinentry_setbufferlen(pinentry_info, 2 * pinentry_info->pin_len)) { + if (!pinentry_setbufferlen(pinentry_info, 2 * pinentry_info->pin_len)) pin_len = 0; - } else { + else setup_pin(pinentry_info->pin, pinentry_info->pin_len, 0); - } } if (pin_len == 0) { printf("Error: Couldn't allocate secure memory\n"); @@ -166,27 +161,27 @@ insert(const char *str, ssize_t n) { } } - /* Move existing text out of the way, insert new text, and update cursor */ + /* move existing text out of the way, insert new text, and update cursor */ memmove(&pin[cursor + n], &pin[cursor], pin_len - cursor - MAX(n, 0)); - if (n > 0) { + if (n > 0) memcpy(&pin[cursor], str, n); - } cursor += n; pin[len + n] = '\0'; } static void -drawwin(void) { +drawmenu(void) +{ unsigned int curpos; int x = 0, fh = drw->fonts->h, pb, pbw = 0, i; size_t asterlen = strlen(asterisk); size_t pdesclen; int leftinput; - char* censort; + char *censort; - char* pprompt = (repeat) ? pinentry_info->repeat_passphrase : pinentry_info->prompt; + char *pprompt = (repeat) ? pinentry_info->repeat_passphrase : pinentry_info->prompt; int ppromptw = (pprompt) ? TEXTW(pprompt) : 0; unsigned int censortl = minpwlen * TEXTW(asterisk) / strlen(asterisk); @@ -220,11 +215,9 @@ drawwin(void) { pbw = MIN(pbw, pb); pb = mw - pbw; - for (i = 0; i < pdesclen; i++) { - if (pinentry_info->description[i] == '\n') { + for (i = 0; i < pdesclen; i++) + if (pinentry_info->description[i] == '\n') pinentry_info->description[i] = ' '; - } - } drw_setscheme(drw, scheme[SchemeDesc]); drw_text(drw, pb, 0, pbw, bh, lrpad / 2, pinentry_info->description, @@ -241,9 +234,8 @@ drawwin(void) { if (winmode == WinPin) { censort = ecalloc(1, asterlen * pin_len); - for (i = 0; i < asterlen * strlen(pin); i += asterlen) { + for (i = 0; i < asterlen * strlen(pin); i += asterlen) memcpy(&censort[i], asterisk, asterlen); - } censort[i+1] = '\n'; leftinput = mw - x - pbw; @@ -261,7 +253,6 @@ drawwin(void) { x = drawitem("No", (sel == No), x, 0, TEXTW("No")); x = drawitem("Yes", (sel == Yes), x, 0, TEXTW("Yes")); } - drw_map(drw, win, 0, 0, mw, mh); } @@ -289,52 +280,45 @@ setup(void) /* Calculate menu geometry */ bh = drw->fonts->h + 2; - bh = MAX(bh, lineheight); mh = bh; #ifdef XINERAMA i = 0; - info = XineramaQueryScreens(dpy, &n); - - if (parentwin == root && info) { + if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) { XGetInputFocus(dpy, &w, &di); - if (mon >= 0 && mon < n) { + if (mon >= 0 && mon < n) i = mon; - } else if (w != root && w != PointerRoot && w != None) { - /* Find top-level window containing current input focus */ + else if (w != root && w != PointerRoot && w != None) { + /* find top-level window containing current input focus */ do { - if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) { + if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws) XFree(dws); - } } while (w != root && w != pw); - /* Find xinerama screen with which the window intersects most */ - if (XGetWindowAttributes(dpy, pw, &wa)) { - for (j = 0; j < n; j++) { - a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j]); - if (a > area) { + /* find xinerama screen with which the window intersects most */ + if (XGetWindowAttributes(dpy, pw, &wa)) + for (j = 0; j < n; j++) + if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) { area = a; i = j; } - } - } } - /* No focused window is on screen, so use pointer location instead */ + /* no focused window is on screen, so use pointer location instead */ if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) for (i = 0; i < n; i++) if (INTERSECT(x, y, 1, 1, info[i]) != 0) break; x = info[i].x_org; - y = info[i].y_org + (bottom ? info[i].height - mh : 0); + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); mw = info[i].width; XFree(info); } else #endif { - if (!XGetWindowAttributes(dpy, parentwin, &wa)) { - die("could not get embedding window attributes: 0x%lx", parentwin); - } + if (!XGetWindowAttributes(dpy, parentwin, &wa)) + die("could not get embedding window attributes: 0x%lx", + parentwin); x = 0; - y = bottom ? wa.height - mh : 0; + y = topbar ? 0 : wa.height - mh; mw = wa.width; } @@ -356,36 +340,35 @@ setup(void) xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, XNFocusWindow, win, NULL); XMapRaised(dpy, win); - if (embedded) { + if (embed) { XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask); if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) { - for (i = 0; i < du && dws[i] != win; ++i) { + for (i = 0; i < du && dws[i] != win; ++i) XSelectInput(dpy, dws[i], FocusChangeMask); - } - XFree(dws); } grabfocus(); } - drw_resize(drw, mw, mh); } static void -cleanup(void) { +cleanup(void) +{ + size_t i; + XUngrabKey(dpy, AnyKey, AnyModifier, root); - free(scheme[SchemeDesc]); - free(scheme[SchemeSelect]); - free(scheme[SchemeNormal]); - free(scheme[SchemePrompt]); + for (i = 0; i < SchemeLast; i++) + free(scheme[i]); drw_free(drw); XSync(dpy, False); XCloseDisplay(dpy); } static int -keypress_confirm(XKeyEvent *ev, KeySym ksym) { +keypress_confirm(XKeyEvent *ev, KeySym ksym) +{ if (ev->state & ControlMask) { switch(ksym) { case XK_c: @@ -400,9 +383,8 @@ keypress_confirm(XKeyEvent *ev, KeySym ksym) { switch(ksym) { case XK_KP_Enter: case XK_Return: - if (sel != Nothing) { + if (sel != Nothing) return 1; - } break; case XK_y: case XK_Y: @@ -446,7 +428,8 @@ keypress_confirm(XKeyEvent *ev, KeySym ksym) { } static int -keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) { +keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) +{ int old; if (ev->state & ControlMask) { @@ -485,31 +468,27 @@ keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) { switch(ksym) { case XK_Delete: case XK_KP_Delete: - if (pin[cursor] == '\0') { + if (pin[cursor] == '\0') return 0; - } - cursor = nextrune(cursor, +1); + cursor = nextrune(+1); /* Fallthrough */ case XK_BackSpace: - if (cursor == 0) { + if (cursor == 0) return 0; - } - insert(NULL, nextrune(cursor, -1) - cursor); + insert(NULL, nextrune(-1) - cursor); break; case XK_Escape: pinentry_info->canceled = 1; return 1; case XK_Left: case XK_KP_Left: - if (cursor > 0) { - cursor = nextrune(cursor, -1); - } + if (cursor > 0) + cursor = nextrune(-1); break; case XK_Right: case XK_KP_Right: - if (pin[cursor] != '\0') { - cursor = nextrune(cursor, +1); - } + if (pin[cursor] != '\0') + cursor = nextrune(+1); break; case XK_Home: case XK_KP_Home: @@ -532,7 +511,8 @@ keypress_pin(XKeyEvent *ev, KeySym ksym, char* buf, int len) { } static int -keypress(XKeyEvent *ev) { +keypress(XKeyEvent *ev) +{ char buf[32]; int len; int ret = 1; @@ -542,15 +522,13 @@ keypress(XKeyEvent *ev) { len = XmbLookupString(xic, ev, buf, sizeof(buf), &ksym, &status); if (status != XBufferOverflow) { - if (winmode == WinConfirm) { + if (winmode == WinConfirm) ret = keypress_confirm(ev, ksym); - } else { + else ret = keypress_pin(ev, ksym, buf, len); - } - if (ret == 0) { - drawwin(); - } + if (ret == 0) + drawmenu(); } return ret; @@ -571,7 +549,7 @@ paste(void) insert(p, (q = strchr(p, '\n')) ? q - p : (ssize_t)strlen(p)); XFree(p); } - drawwin(); + drawmenu(); } void @@ -579,7 +557,7 @@ run(void) { XEvent ev; - drawwin(); + drawmenu(); while (!XNextEvent(dpy, &ev)) { if (XFilterEvent(&ev, win)) @@ -591,38 +569,36 @@ run(void) cleanup(); exit(1); case Expose: - if (ev.xexpose.count == 0) { + if (ev.xexpose.count == 0) drw_map(drw, win, 0, 0, mw, mh); - } break; case KeyPress: - if (keypress(&ev.xkey)) { + if (keypress(&ev.xkey)) return; - } break; case SelectionNotify: - if (ev.xselection.property == utf8) { + if (ev.xselection.property == utf8) paste(); - } break; case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) { + if (ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dpy, win); - } break; } } } +/* FIXME: this does nothing */ static void -catchsig(int sig) { - if (sig == SIGALRM) { +catchsig(int sig) +{ + if (sig == SIGALRM) timed_out = 1; - } } static void -password(void) { +password(void) +{ winmode = WinPin; repeat = 0; setup_pin(pinentry_info->pin, pinentry_info->pin_len, 1); @@ -653,7 +629,8 @@ password(void) { } static void -confirm(void) { +confirm(void) +{ winmode = WinConfirm; sel = Nothing; run(); @@ -661,29 +638,26 @@ confirm(void) { } static int -cmdhandler(pinentry_t received_pinentry) { +cmdhandler(pinentry_t received_pinentry) +{ struct sigaction sa; XWindowAttributes wa; pinentry_info = received_pinentry; - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) { + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fputs("warning: no locale support\n", stderr); - } - if (!(dpy = XOpenDisplay(pinentry_info->display))) { + if (!(dpy = XOpenDisplay(pinentry_info->display))) die("cannot open display"); - } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - embedded = (pinentry_info->parent_wid) ? embedded : 0; - parentwin = (embedded) ? pinentry_info->parent_wid : root; - if (!XGetWindowAttributes(dpy, parentwin, &wa)) { + embed = (pinentry_info->parent_wid) ? embed : 0; + parentwin = (embed) ? pinentry_info->parent_wid : root; + if (!XGetWindowAttributes(dpy, parentwin, &wa)) die("could not get embedding window attributes: 0x%lx", parentwin); - } drw = drw_create(dpy, screen, root, wa.width, wa.height); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) { + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) die("no fonts could be loaded."); - } lrpad = drw->fonts->h; #ifdef __OpenBSD__ @@ -703,14 +677,13 @@ cmdhandler(pinentry_t received_pinentry) { grabkeyboard(); setup(); - if (pinentry_info->pin) { + if (pinentry_info->pin) do { password(); } while (!pinentry_info->canceled && pinentry_info->repeat_passphrase - && !pinentry_info->repeat_okay); - } else { + && !pinentry_info->repeat_okay); + else confirm(); - } cleanup(); @@ -720,13 +693,13 @@ cmdhandler(pinentry_t received_pinentry) { pinentry_cmd_handler_t pinentry_cmd_handler = cmdhandler; int -main(int argc, char *argv[]) { +main(int argc, char *argv[]) +{ pinentry_init("pinentry-dmenu"); pinentry_parse_opts(argc, argv); - if (pinentry_loop()) { + if (pinentry_loop()) return 1; - } return 0; }