#!/usr/bin/env bash-hammer require /toolbox/system require /args # Alias some stuff die() { Toolbox::System.die "$@"; } err() { Toolbox::System.err "$@"; } # Helpers vault_is_json() { pass "$1" | jshon -Q &>/dev/null; } vault_exists() [[ -f "${Opts[store]}/$1.gpg" ]] check_argn() { # Check for the number of args the dumb way. (( $# < 2 )) && die 113 (( $# > 3 )) && die 113 declare length=$1 min=$2 max=$3 (( length < min )) && die 1 "Too few arguments" [[ "$max" ]] && { (( length > max )) && die 1 "Too many arguments" } return 0 } # Our options declare -A Opts Flags # Default Opts Opts[pw_len]=16 Opts[login]='fbt@fleshless.org' Opts[selection]="${X_SELECTION:-clipboard}" Opts[store]="$HOME/.password-store" Opts[tmp_dir]='/tmp' # Default flags Flags[clip]=0 Flags[edit]=0 Args "$@" -- error argv \ -l,p,"Opts[pw_len]" \ -u,p,"Opts[login]" \ -s,p,"Opts[selection]" \ -c,f,"Flags[clip]" \ -e,f,"Flags[edit]" \ || { die 1 "$error"; } set -- "${argv[@]}" case "$1" in (new|insert|show|add) Opts[action]=$1 shift ;; (cp|edit|git|grep|help|init|insert|ls|mv|rm) exec pass "$@";; esac case "${Opts[action]:-show}" in (new) check_argn "${#@}" 1 1; vault="$1" # Check if the damn thing already exists vault_exists "$vault" && die 1 "Vault '$vault' already exists" new_pass=$(pwgen "${Opts[pw_len]}" 1) pass insert -m "$vault" < <( jshon -Q -n {} \ -s "$new_pass" -i "password" \ -s "${Opts[login]}" -i "login" ) (( "${Flags[edit]}" )) && { pass edit "$vault" } (( "${Flags[clip]}" )) && { printf '%s' "$new_pass" | xclip -selection "${Opts[selection]}" } ;; (show) check_argn "${#@}" 1 2; vault=$1 field=${2:-password} vault_exists "$vault" || die 1 "Vault does not exist: $1" if vault_is_json "$vault"; then pass=$(pass "$vault" | jshon -e "$field" -u) else [[ "$2" ]] && err "Warning: ignoring '$field', because '$vault' is not a json vault" pass=$(pass "$vault") fi if (( "${Flags[clip]}" )); then printf '%s' "$pass" | xclip -selection "${Opts[selection]}" else printf '%s\n' "$pass" fi ;; (add) check_argn "${#@}" 2 3; vault=$1 field=$2; data=$3 vault_exists "$vault" || die 1 "Vault does not exist: $1" vault_is_json "$vault" || die 1 "Not a valid json vault: $1" json=$( pass "$vault" ) jshon -s "$data" -i "$field" <<< "$json" | pass insert -m "$vault" ;; (*) pass "$action" "$@";; esac