#!/bin/bash # pwgrep v0.7-pre-1 (c) 2009, 2010 by Paul C. Buetow # pwgrep helps you to manage all your passwords using GnuGP # for encryption and a versioning system (subversion by default) # for keeping track all changes of your password database. In # combination to GnuPG you should use the versioning system in # combination with SSL or SSH encryption. # If you are using a *BSD, you may want to edit the shebang line. # # Usage: # # Searching for a database value: # ./pwgrep.sh searchstring # # Editing the database (same but without args): # ./pwgrep.sh # # For more reasonable commands the following symlinks are recommended: # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/fwipe # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwdbls # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwedit # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwfadd # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwfcat # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwfdel # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwfls # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwgrep # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwhelp # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwldb # ln -s ~/svn/pwgrep/v?.?/pwgrep.sh ~/bin/pwupdate # Replace ?.? with the version of pwgrep you want to use. Your PATH variable # should also include ~/bin then. # You can overwrite the default values by setting env. variables # or by just editing this file. DEFAULTPWGREPDB=mydb [ -z $SVN_EDITOR ] && export SVN_EDITOR=ex [ -z $PWGREPDB ] && PWGREPDB=$DEFAULTPWGREPDB.gpg # The PWGREPWORDIR should be in its own versioning repository. # For password revisions. [ -z $PWGREPWORKDIR ] && PWGREPWORKDIR=~/svn/pwdb [ -z $PWFILEDIREXT ] && PWFILEDIREXT=files # Enter here your GnuPG key ID #[ -z $GPGKEYID ] && GPGKEYID=F4B6FFF0 [ -z $GPGKEYID ] && GPGKEYID=37EC5C1D # Customizing the versioning commands (i.e. if you want to use another # versioning system). [ -z $VERSIONCOMMIT ] && VERSIONCOMMIT="svn commit" [ -z $VERSIONUPDATE ] && VERSIONUPDATE="svn update" [ -z $VERSIONADD ] && VERSIONADD="svn add" [ -z $VERSIONDEL ] && VERSIONDEL="svn delete" # Only use mawk or gawk, but if possible not nawk. On *BSD awk=nawk. So try # awk/nawk last. You can use nawk but nawk will not match case insensitive. [ -z $TRYAWKLIST ] && TRYAWKLIST="mawk gawk awk nawk" # Find the correct command to wipe temporaly files after usage [ -z $TRYWIPELIST ] && TRYWIPELIST="destroy shred" # Same for sed [ -z $TRYSEDLIST ] && TRYSEDLIST="sed gsed" # From here, do not change stuff! PWFILEWORKDIR=$PWGREPWORKDIR/$PWFILEDIREXT CWD=`pwd` umask 177 cd $PWGREPWORKDIR || error "No such file or directory: $PWGREPWORKDIR" function out { echo "$@" 1>&2 } function info { out "=====> $@" } function error { echo "ERROR: $@" exit 666 } function findbin { trylist=$1 found="" for bin in $trylist; do if [ -z $found ]; then which=$(which $bin) [ ! -z $which ] && found=$bin fi done echo $found } function setawkcmd { AWK=`findbin "$TRYAWKLIST"` [ -z $AWK ] && error No awk found in $PATH #info Using $AWK } function setsedcmd { SED=`findbin "$TRYSEDLIST"` [ -z $SED ] && error No sed found in $PATH #info Using $SED } function setwipecmd { WIPE=`findbin "$TRYWIPELIST"` if [ -z $WIPE ]; then # FreeBSDs rm includes -P which is secure enough if [ `uname` = 'FreBSD' ]; then WIPE="rm -v -P" else error "No wipe command found in $PATH, please install shred or destroy" fi fi info Using $WIPE for secure file deletion } function pwgrep () { search=$1 info Searching for $search gpg --decrypt $PWGREPDB | $AWK -v search="$search" ' BEGIN { flag=0 IGNORECASE=1 } !/^\t/ { if (!flag && $0 ~ search) { flag=1 print $0 } else if (flag && $0 ~ search) { print $0 } else if (flag) { flag=0 } } /^\t/ && flag { print $0 }' } function pwupdate () { if [ -z $NOVERSIONING ]; then info Updating repository $VERSIONUPDATE 2>&1 >/dev/null fi } function pwedit () { pwupdate cp -vp $PWGREPDB $PWGREPDB.`date +'%s'`.snap && \ gpg --decrypt $PWGREPDB > .database && \ vim --cmd 'set noswapfile' --cmd 'set nobackup' \ --cmd 'set nowritebackup' .database && \ gpg --output .$PWGREPDB -e -r $GPGKEYID .database && \ $WIPE .database && \ mv .$PWGREPDB $PWGREPDB && \ [ -z $NOVERSIONING ] && $VERSIONCOMMIT } function pwdbls () { pwupdate echo Available Databases: ls *.gpg | sed 's/\.gpg$//' echo Default database: $DEFAULTPWGREPDB } function pwfls () { name=`echo $1 | sed 's/.gpg$//'` [ ! -e $PWFILEDIREXT ] && error $PWFILEDIREXT does not exist if [ -z $name ]; then ls $PWFILEDIREXT | sed -n '/.gpg$/ { s/.gpg$//; p; }' | sort exit 0 fi gpg --decrypt $PWFILEWORKDIR/${name}.gpg } function pwfadd () { name=`echo $1 | sed 's/.gpg$//'` srcfile=$1 if [ `echo "$srcfile" | grep -v '^/'` ]; then srcfile=$CWD/$srcfile fi if [ ! -z $2 ]; then outfile=`basename $2` else outfile=`basename $name` fi pwupdate [ ! -e $PWFILEWORKDIR ] && error $PWFILEWORKDIR does not exist [ -z $name ] && error Missing argument gpg --output $PWFILEDIREXT/${outfile}.gpg -e -r $GPGKEYID $srcfile && \ if [ -z $NOVERSIONING ]; then $VERSIONADD $PWFILEDIREXT/${outfile}.gpg && $VERSIONCOMMIT fi } function pwfdel () { name=`echo $1 | sed 's/.gpg$//'` pwupdate [ ! -e $PWFILEWORKDIR ] && error $PWFILEWORKDIR does not exist [ -z $name ] && error Missing argument if [ -z $NOVERSIONING ]; then # Wipe even encrypted file securely $WIPE $PWFILEDIREXT/${name}.gpg && \ touch $PWFILEDIREXT/${name}.gpg && $VERSIONCOMMIT && \ $VERSIONDEL $PWFILEDIREXT/${name}.gpg && $VERSIONCOMMIT else $WIPE $PWFILEDIREXT/${name}.gpg fi } function fwipe () { [ -z $1 ] && error Missing argument $WIPE $CWD/$1 } function pwhelp () { info Possible operations are: cat < - Wiping a file pwdbls - Listing available DBs pwedit [OPTS] - Editing current DB pwfadd - Adding a file to FDB pwfcat - Printing a file from FDB to stdout pwfdel - Deleting a file from FDB pwgrep [OPTS] - Grepping current DB pwldb - Synonym for pwdbls pwupdate - Updating FDB and all DBs pwhelp - Printing this help screen Where OPTS are: -o - Offline mode -d - Using a specific DB END } setawkcmd setsedcmd setwipecmd BASENAME=`basename $0` ARGS=$@ function set_opts () { case $ARGS in -o*) # Offlinemode NOVERSIONING=1 ARGS=${ARGS[@]:2} set_opts ;; -d*) # Alternate DB PWGREPDB=`echo $ARGS | $AWK '{ print $2 }'` ARGS=`echo $ARGS | $SED "s/-d $PWGREPDB//"` PWGREPDB=$PWGREPDB.gpg set_opts ;; *) esac } set_opts $ARGS case $BASENAME in pwgrep) pwgrep $ARGS ;; pwupdate) pwupdate ;; pwedit) pwedit ;; pwdbls) pwdbls ;; pwldb) pwdbls ;; pwfls) pwfls $ARGS ;; pwfcat) pwfls $ARGS ;; pwfadd) pwfadd $ARGS ;; pwfdel) pwfdel $ARGS ;; fwipe) fwipe $ARGS ;; *) pwhelp esac