Linux Desktop:Password Management

I currently work in the world of devops, a hopelessly nebulous phrase that has evolved to mean many different things throughout its short existence. In this world of devops, I use Linux all day, every day. The servers I automate are Linux, the tools I use to automate infrastructure run on Linux, the configuration management infrastructure runs on Linux, and my desktop even runs Linux.

Most of the devs at my company also find developing on Linux to be much easier, since many of the tools were originally designed for Linux and Unix operating systems (eg: tomcat, eclipse, vim, git cli, shell (bash) scripts of various kinds, etc).

These folks however, are not full-time Linux folks. They see my workflows and [surprisingly] often make remarks about how I context switch so fast. Being in the world of automation, I can’t let them down with an answer like "I’m just that good" (plus, that’s kind of rude and also not true). Sure, practice comes into it quite a bit, but the real driver is the automatability of command line tools.

It occured to me however that since these people don’t spend all day every day drinking up Linux like a cold, light-colored alcoholic beverage on a hot day, they haven’t had the time, drive, or direction to research things like I have. With that [very] long intro, let’s get to talking about my (seems selfish saying that) password management process. Hopefully you will find it useful.

TL;DR Summary

For those of you who are short on time and/or don’t want to read my ramblings, here’s the gyst.

Install pass, xdotool, and a menu launcher like dmenu or rofi (your distro likely already has them in their repos).

Then download my script, quicktype, from my handy bin repo. Place that script somewhere in your PATH variable (I used \~/bin and added it to ${PATH} in my .bashrc file).

Use the menu launcher (mine is mapped to meta + space) to run quicktype <password>, when the cursor is on a username field. Quicktype will read the username and password from pass, and use xdotool to actually type the password (quickly) into the fields, pressing the tab key to switch between fields.

The Tool of Choice

I used to be a user of keepass(x) on Linux. However, once I heard about pass, I just had to try it.

Now to be clear, keepass is a fantastic product. I didn’t leave for any negative reasons. I just couldn’t resist a password manager that was intended for command line use, that encrypted passwords using gnupg, and stored your encrypted password change history in a git repo!

A Few Problems with Command Line

Now, a command line password utility is really useful in the command line, but it’s a real pain to copy and paste from it every time you want to use a password.

At first, I solved this problem by installing xclip and running pass -c <password-name>. That copied the specified password to the clipboard. This was much better, but it still required me to have a terminal to use it for other things, such as my web browser.

That’s where a menu launcher comes in handy. I’ve tried this with dmenu as well as rofi with great success.

With a menu launcher like these, you can type things like

  # Select username field
  # Type username

  # Start the menu launcher
  meta + space

  # Launcher window appears
  pass -c allbanks

  # Select empty password field and paste
  ctrl + v

  # Press enter to login

  # :)

Once you get that muscle memory down, you’ll be really fast. I used that for a while, but after some time I realized I could improve upon my process. For example, I still had to remember and type by hand my usernames, emails, and user ids.

Further Automating

To keep me from having to memorize all those pesky usernames [and passwords], I decided to use a combination of programs to have pass send the password and the username to a script, which passes it to a tool that sends keyboard commands to type my username, hit the tab key (to switch fields), and type my password.

To do this, we need a few tools…​

  • pass

  • xdotool

  • my script, quicktype, from my handy bin repo. You can of course write your own as well. It’s fairly simple.

With the new tools and process, you can use the following workflow

  # Select the username field

  # Bring up the menu launcher
  meta + space

  quicktype allbanks

  # Press enter
  # Fin!

Now that’s fast (at least, I think it is).

How the Script Works

At a high level, quicktype works by passing all arguments to itself, through to the pass script, and storing the output in a variable. This variable is then parsed for the first line ( | head -n 1), which contains the password; as well as the line that starts with username:, which obviously contains the username.

It then passes the cached username and password to xdotool, instructing it to type "${username}<tab>${password}". Note the tab character: it is required to change quickly from the initially selected username field to the password field.

Some questions and answers

Why not use ctrl+v to paste the username and password?

I originally tried something like this, but found that the rare website or application didn’t allow clipboard access to paste passwords. They had to be typed as if a human was typing it.

Are these two variables (username and password) being securely cleared?

Unfortunately, bash doesn’t offer any ways to store variables in a secure manner, nor does it provide a way to securely overwrite them in memory, to my knowledge at least. I have researched this and haven’t found any good ways to do it. That said, I have considered rewriting this in c to ensure I can securely free the memory.

Despite that though, your memory is a pretty safe place to store things. Other encryption keys are already stored there in fact, if you use something like dm-crypt/luks. Barring the possibility of a cold boot attack, I wouldn’t be too worried about someone trying to run a ram dump of your system to get your possibly cached passwords.

What about softwares that require the enter key to change fields rather than the tab key?

I have run into this scenario a few times, but it’s pretty rare. Unfortunately though, I haven’t found a good way [yet] of detecting which is needed and performing the appropriate action. For now, I just go back to typing the username and executing pass -c <password-name> for the password.

Last edited: July 05, 2016