dotfiles

configuration files for shell, text editor, graphical environment, etc.
git clone git://src.adamsgaard.dk/dotfiles # fast
git clone https://src.adamsgaard.dk/dotfiles.git # slow
Log | Files | Refs | README | LICENSE Back to index

passmenu (2865B)


      1 #!/bin/sh
      2 # requirements: dmenu(1), xdotool(1) (for -t, -n and -u options)
      3 
      4 pass_dir="$HOME/.password-store"
      5 
      6 show_help()
      7 {
      8 	echo "usage: ${0##*/} [OPTIONS] [QUERY]"
      9 	echo "shows all passwords from pass(1) and allows interactive selection"
     10 	echo "via dmenu(1). By default, the password is copied to the X clipboard."
     11 	echo
     12 	echo "OPTIONS are one or more of the following:"
     13 	echo "   -h      show this message"
     14 	echo "   -t      type out the password instead of copying to clipboard"
     15 	echo "   -n      type out newline character after password type out (-t)"
     16 	echo "   -u VAL  type out VAL before copying password or typing it out"
     17 	echo "   --      do not consider any following args as options"
     18 	echo
     19 	echo "EXAMPLES:"
     20 	echo "Open interactive menu with all passwords:"
     21 	echo "	${0##*/}"
     22 	echo
     23 	echo "Type out password matching 'newyorktimes':"
     24 	echo "	${0##*/} newyorktimes"
     25 	echo
     26 	echo "Type out username, tab character, and password selected from menu,"
     27 	echo "and hit return:"
     28 	echo "	${0##*/} -n -t -u \"myusername\\t\""
     29 }
     30 
     31 die()
     32 {
     33 	printf '%s: error: %s\n' "${0##*/}" "$1" >&2
     34 	exit 1
     35 }
     36 
     37 get_password_files()
     38 {
     39 	find "$pass_dir" -type f -iname "*.gpg"
     40 	printf 'primary\nclipboard\n'
     41 }
     42 
     43 strip_root_dir()
     44 {
     45 	sed "s,${pass_dir%/}/,,"
     46 }
     47 
     48 match_password_file()
     49 {
     50 	_passfiles="$(get_password_files | strip_root_dir | sed 's/\.gpg$//')"
     51 	if [ "$#" -gt 0 ]; then
     52 		_passfile="$(printf '%s' "$_passfiles" | grep -i "$@")"
     53 		if [ "$(printf '%s\n' "$_passfile" | wc -l)" -eq 0 ]; then
     54 			die "no password matches '$@'"
     55 		elif [ "$(printf '%s\n' "$_passfile" | wc -l)" -gt 1 ]; then
     56 			die "more than one password matches '$@': $_passfile"
     57 		fi
     58 	else
     59 		_passfile="$(printf '%s\n' "$_passfiles" | dmenu -i)"
     60 		if [ $? -ne 0 ]; then
     61 			die 'aborted by user'
     62 		fi
     63 	fi	
     64 	printf '%s\n' "$_passfile"
     65 }
     66 
     67 retrieve_password()
     68 {
     69 	if [ "$1" = "clipboard" ] || [ "$1" = "primary" ]; then
     70 		xdotool type "$(xclip -o -selection "$1")"
     71 		exit 0
     72 	fi
     73 
     74 	_passfile="${pass_dir}/${1}.gpg"
     75 	if [ -n "$prefix" ]; then
     76 		xdotool type "$prefix"
     77 	fi
     78 	case "${_passfile}" in
     79 		*/2fa-*)
     80 			f="$(printf '%s' "${_passfile}" | sed "s,$pass_dir/,,;s,.gpg,,")"
     81 			p="$(pass otp "$f")";;
     82 		*)
     83 			p="$(gpg2 -q -d "${_passfile}")";;
     84 	esac
     85 
     86 	if [ "$typeout" = 1 ]; then
     87 		printf '%s' "$p" | \
     88 			{ IFS= read -r pass; printf %s "$pass"; } | \
     89 			xdotool type --clearmodifiers --file -
     90 		if [ "$newline" = 1 ]; then
     91 			xdotool key Return
     92 		fi
     93 	else
     94 		printf '%s' "$p" | xclip
     95 	fi
     96 }
     97 
     98 typeout=0
     99 newline=0
    100 prefix=""
    101 while :; do
    102 	case "$1" in
    103 		-h)
    104 			show_help
    105 			exit 0
    106 			;;
    107 		-t)
    108 			typeout=1
    109 			;;
    110 		-n)
    111 			newline=1
    112 			;;
    113 		-u)
    114 			prefix="$2"
    115 			shift
    116 			;;
    117 		--) # end all options
    118 			shift
    119 			break
    120 			;;
    121 		-?*)
    122 			die 'unknown option specified'
    123 			;;
    124 		*)  # No more options
    125 			break
    126 	esac
    127 	shift
    128 done
    129 
    130 pass="$(match_password_file "$@")"
    131 if [ -n "$pass" ]; then
    132 	retrieve_password "$pass"
    133 else
    134 	exit 1
    135 fi