Skip to content

Instantly share code, notes, and snippets.

@atoponce
Last active November 30, 2017 17:20
Show Gist options
  • Save atoponce/4351bbabe251dca29f8e472de5e1bb0f to your computer and use it in GitHub Desktop.
Save atoponce/4351bbabe251dca29f8e472de5e1bb0f to your computer and use it in GitHub Desktop.
Syntax for setting up Vim as a secure password manager, with syntax highlighting and shoulder surfing security.

Introduction

This allows you to use Vim as a secure password manager. It was inspired and mostly lifted from http://pig-monkey.com/2013/04/password-management-vim-gnupg/. It differs in that a specification is now defined, and a syntax highlighting file is provided to highlight keywords and hide passwords. Additionally, this Gist uses *.pw file extensions to trigger the syntax highlighting, in addition to some custom GPG config.

GnuPG.vim

Save in ~/.vim/plugin/gnupg.vim. Grab from https://github.com/jamessan/vim-gnupg.

Vimrc

Save in ~/.vimrc:

if has("autocmd")
    " Tell the GnuPG plugin to armor new files.
    let g:GPGPreferArmor=1
    
    " Tell the GnuPG plugin to sign new files.
    let g:GPGPreferSign=1
    
    " Use gpg(2) to take advantage of the agent.
    let g:GPGExecutable="/usr/bin/gpg2"
    
    " Take advantage of the running agent
    let g:GPGUseAgent=1
    
    " Override default set of file patterns
    let g:GPGFilePattern='*.\(gpg\|asc\|pgp\|pw\)'
    
    augroup GnuPGExtra
        " Set extra file options.
        autocmd BufReadCmd,FileReadCmd *.\(pw\) call SetGPGOptions()
        
        " Automatically close unmodified files after inactivity.
        autocmd CursorHold *.\(pw\) quit
    augroup END
    function SetGPGOptions()
        " Set the filetype for syntax highlighting.
        set filetype=gpgpass
        
        " Set updatetime to 5 minutes.
        set updatetime=300000
        
        " Fold at markers.
        set foldmethod=marker
        
        " Automatically close all folds.
        set foldclose=all
        
        " Only open folds with insert commands.
        set foldopen=insert
    endfunction
endif " has ("autocmd")

Vim syntax file

Save in ~/.vim/syntax/gpgpass.vim.

" Vim syntax file
" Language: GPG Passwords
" Maintainer: Aaron Toponce
" Latest Revision: 01 Augist 2016
if exists("b:current_syntax")
    finish
endif

let b:current_syntax = "gpgpass"

syntax case ignore

syntax match gpgpassPasswords "\%(^\s*.*pass.*:\s\+\)\@<=.*"
highlight gpgpassPasswords ctermbg=red ctermfg=red

syntax match gpgpassKeyword "\v^\s*old-(pass|password):"
syntax match gpgpassKeyword "\v^\s*(pass|password|user|username):"
syntax match gpgpassKeyword "\v^\s*(expire|comment|tag)s?:"
syntax match gpgpassKeyword "\v^\s*(type|url):"
highlight link gpgpassKeyword Keyword

Password file syntax

Saving passwords should be wrapped in {{{ and }}} for auto-folding in Vim. This is the default fold marker. Files should be saved with the *.pw extension to prevent *.(gpg|pgp|asc) files from getting syntax highlighting for passwords.

I keep this at the top of my password file as a reminder:

Syntax Help {{{         
    comment: {{{                                
        Valid fields are:                             
            comment:                              
            comments:                               
            expire:                               
            expires:                              
            pass:                                 
            password:                               
            old-pass:                               
            old-password:                             
            tag:                                
            tags:                                 
            type:                                 
            url:                                
            user:                                 
            username:                               

        Comments can obviously be multi-line.                   
        Expire can be free form, but preferrably ISO 8601.            
        Type can be "ssh", "http", "sql", etc.                  
        Tags can be space or comma-separated for searching.           
        Keep only one old-password, incase of problems.             
        
        No field is required, although not having a "password" field doesn't   
        make much sense, now does it?                       
    }}}                                     
}}}

Test password file

The following example shows an example of a password entry for the "Super ISP" account, a residential internet service provider. By default, the entry will be folded, and will look like:

+--- 12 lines: Super ISP ----------------------------------------

Pressing the spacebar will expand entry. Below the entry fully expanded:

Super ISP {{{
    comment: {{{
        Account#: 5133479A
        Order Date: 2011-12-03
        Service Activation Date: 2011-12-16
    }}}
    username: atoponce
    password: nk2j7afaebf5rpxnbx3346-w
    old-password: Clarke.budget.Dixon
    tags: internet isp
    url: https://isp.example.com
}}}

If the gpgpass.vim syntax file is installed, the password and old-password entries will be hidden with red foreground text on top of red background text (a full red bar). The text will still be selectable to copy/paste. Or you can use standard Vim tools to copy to the clipboard. The keywords will be blue.

See https://imgur.com/a/7v3gy for screenshot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment