This past week I played around with some code to help build a new workflow to manage multiple passwords. The tools included were Ruby, ccrypt, and pbcopy.

In my daily routine, I need to log into different password protected websites maintained by different trading partners. These sites follow the same paradigm of asking a user to present a username and password to authenticate and login. Instead of trying to have to remember these passwords or just resetting them, one can store passwords in an encrypted text file and pull out the required password when needed and stuff it into the Mac OS clipboard for easy pasting.

The first tool in this workflow uses the ccyrpt program, which provides encryption for files and streams. Jon Black has an excellent post on the tool and his solution for a password manager. I extended his idea with a Ruby script to handle the grep, awk, and sed functions. Since I didn’t have ccrypt installed on my Mac, I used Homebrew to install it.

$ brew update

$ brew install ccrypt

The ccrypt program is a straight forward tool. Use the ‘-e’ option to encrypt a file and the ‘-d’ to decrypt. The accompanying ccat tool allows you to dump the encrypted file as plain text to standard output “STDOUT” on the fly.

In my workflow, I followed Jon’s lead and built a text file called my_passwords that contains five columns of data delimited by the pipe ‘|’ character: resource name, username, password, tags and comments.

With Vim, I use the Align function to re-align the file after each edit, followed by the sort command. Below is an example of editing the password file with Vim.

In my first attempt, I tried to build an alias called “pass” in my ~/.bashrc file that would take a single search argument, run the ccat command, grep on the search term, and return the password from the third column to the Mac clipboard.

$ ccat my_passwords.cpt | grep books | awk -F "|" '{print $3;}' | sed 's/^ *//' | sed 's/ *$//‘

The above command works great, but fails when I tried to build it as as Bash alias.

In my next attempt, I tried building a Bash function where I could accept a single argument, my search term, and then using pipes, string along all of my commands. This worked again wonderfully on the command line, but failed again when trying to call it as a Bash function.

In my third attempt, I used a Ruby script to manage the workflow, making system calls to ccat and pbcopy. This solution did work and I polished it up by setting up a Bash alias called ‘pass’ so I could call the pass.rb script from any terminal window.

$ alias pass="~/code/ruby/passwords/pass.rb"

$ pass “search term”

Happy hacking.

–Chris

Resources