Pass and Rofi
Context
Last time I described how I use Pass, a unix password manager, to add a bit of convenience and security to my life. Like all things in life, I opted for the DIY version of a tool that is also commercially available. Why? Because life is suffering! (If you want to actually know why then go read the post, it won’t take long).
What are we doing here…?
Well I can’t speak for you, but I am trying to have my cake and eat it too. I want a system that
- is highly (perhaps completely) configurable
- has no unwanted bells and whistles
- is rippin’ fast!
- assumes I know what I’m doing and lets me do it myself
This is why I opt for solutions that often involve a bit more setup. Things that work out-of-the-box are nice at first, but often leave me wanting more, navigating through feature bloat, or insecure to a degree that I find unsettling.
Enter Rofi
Rofi is a wildly useful tool. I use it for launching applications, opening SSH sessions, and a whole lot more. You can style it and use it to streamline a lot of workflows. Let’s take a look at how it could help us here.
With Pass, my workflow might look something like this:
- go to website
somesite.com
- enter username in appropriate field
- open a terminal window
- ponder what folder I saved that password in
- open a terminal
- type
pass find somesite
and hit the return key - ah… that’s where it is…
- execute the full
pass
command to copy the password to my clipboard - enter my GPG password in the system dialog
- close the terminal window
- go back to the web browser and paste the password
There’s a better way!
Rofi is really good at selecting one thing from a list of many. Seems perfect for this! I’m only trying to streamline the use case for copying an existing password to the clipboard, so something like this project that I found is a bit overkill for my needs (but I dig that someone did that). The workflow should look as such:
- go to website
somesite.com
- enter username in appropriate field
- run a script that interacts with Rofi (using a system keybinding)
- type
somesite
or just enough to filter and select the right option - press enter
- enter my GPG password in the system dialog
- go back to the web browser and paste the password
That’s a lot better! Let’s see how we can get Rofi to streamline this workflow.
The Script
Rofi has a dmenu
option that helps us out tremendously for this use case. From
the documentation:
-dmenu
Run rofi in dmenu mode. This allows for interactive scripts. In dmenu mode,
rofi reads from STDIN, and output to STDOUT. A simple example, displaying three
pre-defined options:
echo -e "Option #1\nOption #2\nOption #3" | rofi -dmenu
Or get the options from a script:
~/my_script.sh | rofi -dmenu
Armed with that knowledge, we can begin writing a script. Let’s start by defining a function that will get the options from Pass:
function menu(){
cd ~/.password-store
find -iregex .*\.gpg | cut -c 3- | sed s/\.gpg\$//
}
This lists all the GPG files in our password store (that is, all the encrypted
passwords) and prints them out in a nice format. The cut -c 3-
removes the
leading ./
in the file names. The sed
command replaces any .gpg
substring
found at the end of the string with nothing.
Like the documentation says, we can Pass that right into Rofi with the -dmenu
option.
choice="$( menu | rofi -dmenu -i -p 'pass:' -matching fuzzy)"
Let’s create a variable choice
to hold what the user chooses. Let’s also use
the -i
flag for a case-insensitive search, the -p
flag to specify a prompt,
and -matching
to make the search fuzzy (because fuzzy searches are great when
you organize things deeply in subdirectories like I do).
After that, all we have to do is execute the user’s choice (if there is any) with Pass.
# user cancelled - bail with no-op
if [ -z $choice ]
then
exit
fi
pass -c $choice
That’s it! The whole script looks like so:
#!/bin/bash
function menu(){
cd ~/.password-store
find -iregex .*\.gpg | cut -c 3- | sed s/\.gpg\$//
}
choice="$( menu | rofi -dmenu -i -p 'pass:' -matching fuzzy)"
# user cancelled - bail with no-op
if [ -z $choice ]
then
exit
fi
pass -c $choice
Thanks For Reading!
If you have any questions or improvements please feel free to drop me a line. You can reach me by sending an email to blog [at] this domain.