Passmenu for Accessing Passwords Using Pass [2022-01-02]


dwm, dmenu, and pass

I have recently made the switch to dwm (see my personal config of dwm here) as my main window manager. Its default menu is dmenu (see my personal config of dmenu here), which is also similarly written in C. One of the advantages of dmenu is that it manages user-defined scripts in a straightforward manner. Since it is written in C, it is quite efficient and decently easy to configure.

My free time during school break has also led me to explore using a variety of other password managers than KeePassXC, which I have been using for at least a year now. The most promising of them is pass, an extensively documented CLI password manager.

Pass is quite unique as it uses PGP standards to encrypt each password as its own file. For example, this would be the result of tree ~/.password-store

user@machine ~ $ tree ~/.password-store
.password-store
├── Email
│   ├── outlook.com.gpg
│   └── gmail.com.gpg
├── Bank Accounts
│   ├── Bank of America
│   │   ├── cc number.gpg
│   │   └── password.gpg
│   ├── Discover
│   │   ├── cc number.gpg
│   │   └── password.gpg
└── Steam
    ├── username.gpg
    └── password.gpg

passmenu

Since it is highly extensible, it's quite easy to create your own script to handle pass through dmenu. Below is my configuration of passmenu, which is a bash script that uses dmenu to view and copy over your passwords into your clipboard. I am quite fond of pass's approach to password management, and binding passmenu (which is now a part of pass itself) to a keyboard shortcut saves me a significant amount of time.

#!/usr/bin/env bash

shopt -s nullglob globstar

typeit=0
if [[ $1 == "--type" ]]; then
    typeit=1
    shift
fi

if [[ -n $WAYLAND_DISPLAY ]]; then
    dmenu=dmenu-wl
    xdotool="ydotool type --file -"
elif [[ -n $DISPLAY ]]; then
    dmenu="dmenu -fn FiraMono:size=12 -nb #282828 -nf #ebdbb2 -sb #3c3836 -sf #d79921"
    xdotool="xdotool type --clearmodifiers --file -"
else
    echo "Error: No Wayland or X11 display detected" >&2
    exit 1
fi

prefix=${PASSWORD_STORE_DIR-~/.password-store}
password_files=( "$prefix"/**/*.gpg )
password_files=( "${password_files[@]#"$prefix"/}" )
password_files=( "${password_files[@]%.gpg}" )

password=$(printf '%s\n' "${password_files[@]}" | $dmenu "$@")

[[ -n $password ]] || exit

if [[ $typeit -eq 0 ]]; then
    pass show -c "$password" 2>/dev/null
else
    pass show "$password" | { IFS= read -r pass; printf %s "$pass"; } | $xdotool
fi

Notes

I have spent some time "ricing" and "patching" my dwm and dmenu linux environment. For example, dmenu does not come with fuzzy match out of the box. This does make using pass and passmenu more annoying. For a quick and easy setup, keepassxc may be the more preferable option, however the extra work goes a very long way.