Fri, 11 Aug 2006

vi based encrypted password manager

I've played around with quite a few different password managers, most of them
being GUI based. They all worked fine, but I always wanted something I could
use easily from the console since I use SSH quite a bit from remote terminals.

The other reason I was never satisifed with a GUI solution was that the program
always had to be running. I know that some of them can sit unobtrusively in
your taskbar, but I'm not much on having lots of things running on my desktop
when I don't need them. On the other hand, I always have an xterm up, so using
the command line for password management seemed a logical approach.

So for a while I simply used vi to edit a text file that I encrypted with
bcrypt. On top of this I wrote a small shell script that would combine the
bcrypt decryption and grep'ing for a password into one comand line operation.
This worked too, but was still lacked something.

Eventually I stumbled on bits and pieces of other people's work that allowed me
to put together an console based solution that I'm now quite pleased with. It
involves the following:

    * modications to your .vimrc file specifically for .gpg files
    * active use of folding in your password file
    * a nice function for your .bashrc config file
    * and a powerful little shell script using nawk to get your password info easily

To create you own vi based encrypted password manager, do the following:

   1. Create a public/private key pair on the machine where the password file
      will reside. To create this key, make sure you have the package xxxxx. Logged
      in as yourself, issue the command

      ssh-keygen -t rsa

      It will prompt you for a passphrase. Enter something you can remember but
      is not too obvious. Accept the default (/home/username/.ssh) with regard to
      where the keys will be saved.

   2. Edit your .vimrc file and include the following:

      ----------------------------------------
      augroup encrypted
      au!
      " First make sure nothing is written to ~/.viminfo while editing
      " an encrypted file.
      autocmd BufReadPre,FileReadPre *.gpg set viminfo=
      " We don't want a swap file, as it writes unencrypted data to disk
      autocmd BufReadPre,FileReadPre *.gpg set noswapfile
      " Switch to binary mode to read the encrypted file
      autocmd BufReadPre,FileReadPre *.gpg set bin
      autocmd BufReadPre,FileReadPre *.gpg let ch_save = &ch|set ch=2
      autocmd BufReadPost,FileReadPost *.gpg '[,']!gpg --decrypt 2> /dev/null
      " Switch to normal mode for editing
      autocmd BufReadPost,FileReadPost *.gpg set nobin
      autocmd BufReadPost,FileReadPost *.gpg let &ch = ch_save|unlet ch_save
      autocmd BufReadPost,FileReadPost *.gpg execute ":doautocmd BufReadPost " . expand("%:r")

      " Convert all text to encrypted text before writing
      autocmd BufWritePre,FileWritePre *.gpg '[,']!gpg --default-recipient-self -ae 2>/dev/null
      " Undo the encryption so we are back in the normal text, directly
      " after the file has been written.
      autocmd BufWritePost,FileWritePost *.gpg u
      augroup END
      ----------------------------------------

   3. Using vi, create a new file called passwords.gpg.
      Set up your entries something like this:

      Forums
          UserID: myID_1
          Password: secret_1
          URL: http://www.domain_1.com
          More stuff in any format

          UserID: myID_2
          Password: secret_2
          URL: http://www.domain_2.com
          More stuff in any format

      Memberships
          UserID: myID_3
          Password: secret_3
          URL: http://www.domain_3.com
           More stuff in any format

          UserID: myID_4
          Password: secret_4
          URL: http://www.domain_4.com
          More stuff in any format

      You can experiment with the layout later, but start with this format of
      indenting. It's what makes the folding in vi look nice, which we'll set up in
      the next step. Save the file and close it.

   4. Open the file again with vi. This time, automatically, you should be
      prompted for the passphrase you used when you created your key. Enter the
      passphrase and you should be in your password.gpg file again.

   5. In this new password file, add the following line:

      vi: noswapfile bufhidden=wipe tw=0 fdm=indent nobackup nowritebackup foldclose=all

      Leave this line in place at all times and never edit it unless you know
      what you want to achieve. It sets up vi formatting, specifically the ability to
      fold lines. To learn more about folding type :help folding in a vi session

   6. Some important folding commands:
      zo open fold
      zc close fold
      zr open all folds
      zm close all folds

   7. You are now at a point where you're file is encrypted and you should be
      able to edit it at will with vi after entering your passphrase. The next step
      will give you quick command line access to query your password file.

   8. Somewhere in your path (echo $PATH), create a new shell script called searchWord.sh. Cut and paste the following:

      ---------------------------------
      #!/bin/sh
      usage()
      {
      [ $# -ne 0 ] && {
      echo "$0: $@" 1>&2
      }
      echo "usage: $0 pattern [file ...]" 1>&2
      exit 1

      }

      if [ $# -lt 1 ] ;then
      usage "missing pattern"
      fi
      pattern=$1
      shift

      nawk '

      BEGIN {IGNORECASE=1}

      NF==0 {
      if (paragraph ~ "'$pattern'") {
      print paragraph
      }
      paragraph=""

      }

      NF != 0 {
      paragraph=paragraph $0 "\n"

      }' "$@"
      ---------------------------------

      Save it and chmod 755 the file.
   9. In your .bashrc file add the following:

      ---------------------------------
      ### used for password program
      function qpass () {
      /usr/bin/gpg -d < ~/docs/passwords.gpg | ~/bin/searchWord.sh "$@"
      }
      ---------------------------------

  10. That's pretty much it. Test it out at the command line by typing a query, like ...

      $> qpass domain.com

      You should be prompted for your passphrase. Enter it, and the
      searchWord.sh script will search your password file for the term
      "domain.com". It will return multiple finds if such exist. 

      I hope this makes sense and works as well for others as it has for me.

      Credits: Thanks to Serge Roux and Wouter Hanegraaff for portions of the code.

Posted at: 09:06 | category: /vi | Comments ()