diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/completion/pass.bash-completion | 2 | ||||
-rw-r--r-- | src/completion/pass.fish-completion | 124 | ||||
-rw-r--r-- | src/completion/pass.zsh-completion | 2 | ||||
-rwxr-xr-x | src/password-store.sh | 27 | ||||
-rw-r--r-- | src/platform/darwin.sh | 6 |
5 files changed, 79 insertions, 82 deletions
diff --git a/src/completion/pass.bash-completion b/src/completion/pass.bash-completion index 95d3e1e..2d23cbf 100644 --- a/src/completion/pass.bash-completion +++ b/src/completion/pass.bash-completion @@ -72,7 +72,7 @@ _pass_complete_folders () { _pass_complete_keys () { local GPG="gpg" - which gpg2 &>/dev/null && GPG="gpg2" + command -v gpg2 &>/dev/null && GPG="gpg2" local IFS=$'\n' # Extract names and email addresses from gpg --list-keys diff --git a/src/completion/pass.fish-completion b/src/completion/pass.fish-completion index 8637874..0f57dd2 100644 --- a/src/completion/pass.fish-completion +++ b/src/completion/pass.fish-completion @@ -1,28 +1,22 @@ -#!/usr/bin/env fish - # Copyright (C) 2012-2014 Dmitry Medvinsky <me@dmedvinsky.name>. All Rights Reserved. # This file is licensed under the GPLv2+. Please see COPYING for more information. -set PROG 'pass' +set -l PROG 'pass' function __fish_pass_get_prefix - set -l prefix "$PASSWORD_STORE_DIR" - if [ -z "$prefix" ] - set prefix "$HOME/.password-store" + if set -q PASSWORD_STORE_DIR + realpath -- "$PASSWORD_STORE_DIR" + else + echo "$HOME/.password-store" end - echo "$prefix" end function __fish_pass_needs_command - set -l cmd (commandline -opc) - if [ (count $cmd) -eq 1 -a $cmd[1] = $PROG ] - return 0 - end - return 1 + [ (count (commandline -opc)) -eq 1 ] end function __fish_pass_uses_command - set cmd (commandline -opc) + set -l cmd (commandline -opc) if [ (count $cmd) -gt 1 ] if [ $argv[1] = $cmd[2] ] return 0 @@ -39,7 +33,8 @@ function __fish_pass_print set -l ext $argv[1] set -l strip $argv[2] set -l prefix (__fish_pass_get_prefix) - printf '%s\n' "$prefix"/**"$ext" | sed "s#$prefix/\(.*\)$strip#\1#" + set -l matches $prefix/**$ext + printf '%s\n' $matches | sed "s#$prefix/\(.*\)$strip#\1#" end function __fish_pass_print_entry_dirs @@ -55,63 +50,66 @@ function __fish_pass_print_entries_and_dirs __fish_pass_print_entries end +function __fish_pass_git_complete + set -l prefix (__fish_pass_get_prefix) + set -l git_cmd (commandline -opc) (commandline -ct) + set -e git_cmd[1 2] # Drop "pass git". + complete -C"git -C $prefix $git_cmd" +end -complete -c $PROG -e -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a help -d 'Command: show usage help' -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a version -d 'Command: show program version' +complete -c $PROG -f -n '__fish_pass_needs_command' -a help -d 'Command: show usage help' +complete -c $PROG -f -n '__fish_pass_needs_command' -a version -d 'Command: show program version' -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a init -d 'Command: initialize new password storage' -complete -c $PROG -f -A -n '__fish_pass_uses_command init' -s p -l path -d 'Assign gpg-id for specified sub folder of password store' +complete -c $PROG -f -n '__fish_pass_needs_command' -a init -d 'Command: initialize new password storage' +complete -c $PROG -f -n '__fish_pass_uses_command init' -s p -l path -d 'Assign gpg-id for specified sub folder of password store' -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a ls -d 'Command: list passwords' -complete -c $PROG -f -A -n '__fish_pass_uses_command ls' -a "(__fish_pass_print_entry_dirs)" +complete -c $PROG -f -n '__fish_pass_needs_command' -a ls -d 'Command: list passwords' +complete -c $PROG -f -n '__fish_pass_uses_command ls' -a "(__fish_pass_print_entry_dirs)" -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a insert -d 'Command: insert new password' -complete -c $PROG -f -A -n '__fish_pass_uses_command insert' -s e -l echo -d 'Echo the password on console' -complete -c $PROG -f -A -n '__fish_pass_uses_command insert' -s m -l multiline -d 'Provide multiline password entry' -complete -c $PROG -f -A -n '__fish_pass_uses_command insert' -s f -l force -d 'Do not prompt before overwritting' -complete -c $PROG -f -A -n '__fish_pass_uses_command insert' -a "(__fish_pass_print_entry_dirs)" +complete -c $PROG -f -n '__fish_pass_needs_command' -a insert -d 'Command: insert new password' +complete -c $PROG -f -n '__fish_pass_uses_command insert' -s e -l echo -d 'Echo the password on console' +complete -c $PROG -f -n '__fish_pass_uses_command insert' -s m -l multiline -d 'Provide multiline password entry' +complete -c $PROG -f -n '__fish_pass_uses_command insert' -s f -l force -d 'Do not prompt before overwritting' +complete -c $PROG -f -n '__fish_pass_uses_command insert' -a "(__fish_pass_print_entry_dirs)" -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a generate -d 'Command: generate new password' -complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s n -l no-symbols -d 'Do not use special symbols' -complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s c -l clip -d 'Put the password in clipboard' -complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s f -l force -d 'Do not prompt before overwritting' -complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -s i -l in-place -d 'Replace only the first line with the generated password' -complete -c $PROG -f -A -n '__fish_pass_uses_command generate' -a "(__fish_pass_print_entry_dirs)" +complete -c $PROG -f -n '__fish_pass_needs_command' -a generate -d 'Command: generate new password' +complete -c $PROG -f -n '__fish_pass_uses_command generate' -s n -l no-symbols -d 'Do not use special symbols' +complete -c $PROG -f -n '__fish_pass_uses_command generate' -s c -l clip -d 'Put the password in clipboard' +complete -c $PROG -f -n '__fish_pass_uses_command generate' -s f -l force -d 'Do not prompt before overwritting' +complete -c $PROG -f -n '__fish_pass_uses_command generate' -s i -l in-place -d 'Replace only the first line with the generated password' +complete -c $PROG -f -n '__fish_pass_uses_command generate' -a "(__fish_pass_print_entry_dirs)" -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a mv -d 'Command: rename existing password' -complete -c $PROG -f -A -n '__fish_pass_uses_command mv' -s f -l force -d 'Force rename' -complete -c $PROG -f -A -n '__fish_pass_uses_command mv' -a "(__fish_pass_print_entries_and_dirs)" +complete -c $PROG -f -n '__fish_pass_needs_command' -a mv -d 'Command: rename existing password' +complete -c $PROG -f -n '__fish_pass_uses_command mv' -s f -l force -d 'Force rename' +complete -c $PROG -f -n '__fish_pass_uses_command mv' -a "(__fish_pass_print_entries_and_dirs)" -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a cp -d 'Command: copy existing password' -complete -c $PROG -f -A -n '__fish_pass_uses_command cp' -s f -l force -d 'Force copy' -complete -c $PROG -f -A -n '__fish_pass_uses_command cp' -a "(__fish_pass_print_entries_and_dirs)" +complete -c $PROG -f -n '__fish_pass_needs_command' -a cp -d 'Command: copy existing password' +complete -c $PROG -f -n '__fish_pass_uses_command cp' -s f -l force -d 'Force copy' +complete -c $PROG -f -n '__fish_pass_uses_command cp' -a "(__fish_pass_print_entries_and_dirs)" -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a rm -d 'Command: remove existing password' -complete -c $PROG -f -A -n '__fish_pass_uses_command rm' -s r -l recursive -d 'Remove password groups recursively' -complete -c $PROG -f -A -n '__fish_pass_uses_command rm' -s f -l force -d 'Force removal' -complete -c $PROG -f -A -n '__fish_pass_uses_command rm' -a "(__fish_pass_print_entries_and_dirs)" +complete -c $PROG -f -n '__fish_pass_needs_command' -a rm -d 'Command: remove existing password' +complete -c $PROG -f -n '__fish_pass_uses_command rm' -s r -l recursive -d 'Remove password groups recursively' +complete -c $PROG -f -n '__fish_pass_uses_command rm' -s f -l force -d 'Force removal' +complete -c $PROG -f -n '__fish_pass_uses_command rm' -a "(__fish_pass_print_entries_and_dirs)" -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a edit -d 'Command: edit password using text editor' -complete -c $PROG -f -A -n '__fish_pass_uses_command edit' -a "(__fish_pass_print_entries)" +complete -c $PROG -f -n '__fish_pass_needs_command' -a edit -d 'Command: edit password using text editor' +complete -c $PROG -f -n '__fish_pass_uses_command edit' -a "(__fish_pass_print_entries)" -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a show -d 'Command: show existing password' -complete -c $PROG -f -A -n '__fish_pass_uses_command show' -s c -l clip -d 'Put password in clipboard' -complete -c $PROG -f -A -n '__fish_pass_uses_command show' -a "(__fish_pass_print_entries)" +complete -c $PROG -f -n '__fish_pass_needs_command' -a show -d 'Command: show existing password' +complete -c $PROG -f -n '__fish_pass_uses_command show' -s c -l clip -d 'Put password in clipboard' +complete -c $PROG -f -n '__fish_pass_uses_command show' -a "(__fish_pass_print_entries)" # When no command is given, `show` is defaulted. -complete -c $PROG -f -A -n '__fish_pass_needs_command' -s c -l clip -d 'Put password in clipboard' -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a "(__fish_pass_print_entries)" -complete -c $PROG -f -A -n '__fish_pass_uses_command -c' -a "(__fish_pass_print_entries)" -complete -c $PROG -f -A -n '__fish_pass_uses_command --clip' -a "(__fish_pass_print_entries)" - -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a git -d 'Command: execute a git command' -complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'init' -d 'Initialize git repository' -complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'status' -d 'Show status of the repo' -complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'add' -d 'Add changes to the index' -complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'commit' -d 'Commit changes to the repo' -complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'push' -d 'Push changes to remote repo' -complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'pull' -d 'Pull changes from remote repo' -complete -c $PROG -f -A -n '__fish_pass_uses_command git' -a 'log' -d 'View changelog' - -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a find -d 'Command: find a password file or directory matching pattern' -complete -c $PROG -f -A -n '__fish_pass_needs_command' -a grep -d 'Command: search inside of decrypted password files for matching pattern' +complete -c $PROG -f -n '__fish_pass_needs_command' -s c -l clip -d 'Put password in clipboard' +complete -c $PROG -f -n '__fish_pass_needs_command' -a "(__fish_pass_print_entries)" +complete -c $PROG -f -n '__fish_pass_uses_command -c' -a "(__fish_pass_print_entries)" +complete -c $PROG -f -n '__fish_pass_uses_command --clip' -a "(__fish_pass_print_entries)" + +complete -c $PROG -f -n '__fish_pass_needs_command' -a git -d 'Command: execute a git command' +complete -c $PROG -f -n '__fish_pass_uses_command git' -a '(__fish_pass_git_complete)' +complete -c $PROG -f -n '__fish_pass_needs_command' -a find -d 'Command: find a password file or directory matching pattern' +complete -c $PROG -f -n '__fish_pass_needs_command' -a grep -d 'Command: search inside of decrypted password files for matching pattern' +complete -c $PROG -f -n '__fish_pass_uses_command grep' -a '(begin + set -l cmd (commandline -opc) (commandline -ct) + set -e cmd[1 2] # Drop "pass grep". + complete -C"grep $cmd" +end)' diff --git a/src/completion/pass.zsh-completion b/src/completion/pass.zsh-completion index 27ce15a..d911e12 100644 --- a/src/completion/pass.zsh-completion +++ b/src/completion/pass.zsh-completion @@ -124,7 +124,7 @@ _pass_complete_entries_helper () { local IFS=$'\n' local prefix zstyle -s ":completion:${curcontext}:" prefix prefix || prefix="${PASSWORD_STORE_DIR:-$HOME/.password-store}" - _values -C 'passwords' ${$(find -L "$prefix" \( -name .git -o -name .gpg-id \) -prune -o $@ -print 2>/dev/null | sed -e "s#${prefix}/\{0,1\}##" -e 's#\.gpg##' -e 's#\\#\\\\#' | sort):-""} + _values -C 'passwords' ${$(find -L "$prefix" \( -name .git -o -name .gpg-id \) -prune -o $@ -print 2>/dev/null | sed -e "s#${prefix}/\{0,1\}##" -e 's#\.gpg##' -e 's#\\#\\\\#g' -e 's#:#\\:#g' | sort):-""} } _pass_complete_entries_with_subdirs () { diff --git a/src/password-store.sh b/src/password-store.sh index 1d119f2..22e818f 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -9,7 +9,7 @@ set -o pipefail GPG_OPTS=( $PASSWORD_STORE_GPG_OPTS "--quiet" "--yes" "--compress-algo=none" "--no-encrypt-to" ) GPG="gpg" export GPG_TTY="${GPG_TTY:-$(tty 2>/dev/null)}" -which gpg2 &>/dev/null && GPG="gpg2" +command -v gpg2 &>/dev/null && GPG="gpg2" [[ -n $GPG_AGENT_INFO || $GPG == "gpg2" ]] && GPG_OPTS+=( "--batch" "--use-agent" ) PREFIX="${PASSWORD_STORE_DIR:-$HOME/.password-store}" @@ -20,6 +20,7 @@ GENERATED_LENGTH="${PASSWORD_STORE_GENERATED_LENGTH:-25}" CHARACTER_SET="${PASSWORD_STORE_CHARACTER_SET:-[:punct:][:alnum:]}" CHARACTER_SET_NO_SYMBOLS="${PASSWORD_STORE_CHARACTER_SET_NO_SYMBOLS:-[:alnum:]}" +unset GIT_DIR GIT_WORK_TREE GIT_NAMESPACE GIT_INDEX_FILE GIT_INDEX_VERSION GIT_OBJECT_DIRECTORY GIT_COMMON_DIR export GIT_CEILING_DIRECTORIES="$PREFIX/.." # @@ -69,6 +70,7 @@ verify_file() { set_gpg_recipients() { GPG_RECIPIENT_ARGS=( ) GPG_RECIPIENTS=( ) + local gpg_id if [[ -n $PASSWORD_STORE_KEY ]]; then for gpg_id in $PASSWORD_STORE_KEY; do @@ -97,8 +99,9 @@ set_gpg_recipients() { verify_file "$current" - local gpg_id while read -r gpg_id; do + gpg_id="${gpg_id%%#*}" # strip comment + [[ -n $gpg_id ]] || continue GPG_RECIPIENT_ARGS+=( "-r" "$gpg_id" ) GPG_RECIPIENTS+=( "$gpg_id" ) done < "$current" @@ -126,7 +129,7 @@ reencrypt_path() { done gpg_keys="$($GPG $PASSWORD_STORE_GPG_OPTS --list-keys --with-colons "${GPG_RECIPIENTS[@]}" | sed -n 's/^sub:[^idr:]*:[^:]*:[^:]*:\([^:]*\):[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[a-zA-Z]*e[a-zA-Z]*:.*/\1/p' | LC_ALL=C sort -u)" fi - current_keys="$(LC_ALL=C $GPG $PASSWORD_STORE_GPG_OPTS -v --no-secmem-warning --no-permission-warning --decrypt --list-only --keyid-format long "$passfile" 2>&1 | sed -n 's/^gpg: public key is \([A-F0-9]\+\)$/\1/p' | LC_ALL=C sort -u)" + current_keys="$(LC_ALL=C $GPG $PASSWORD_STORE_GPG_OPTS -v --no-secmem-warning --no-permission-warning --decrypt --list-only --keyid-format long "$passfile" 2>&1 | sed -nE 's/^gpg: public key is ([A-F0-9]+)$/\1/p' | LC_ALL=C sort -u)" if [[ $gpg_keys != "$current_keys" ]]; then echo "$passfile_display: reencrypting to ${gpg_keys//$'\n'/ }" @@ -134,7 +137,7 @@ reencrypt_path() { mv "$passfile_temp" "$passfile" || rm -f "$passfile_temp" fi prev_gpg_recipients="${GPG_RECIPIENTS[*]}" - done < <(find "$1" -path '*/.git' -prune -o -iname '*.gpg' -print0) + done < <(find "$1" -path '*/.git' -prune -o -path '*/.extensions' -prune -o -iname '*.gpg' -print0) } check_sneaky_paths() { local path @@ -152,7 +155,7 @@ check_sneaky_paths() { # clip() { - if [[ -n $WAYLAND_DISPLAY ]]; then + if [[ -n $WAYLAND_DISPLAY ]] && command -v wl-copy &> /dev/null; then local copy_cmd=( wl-copy ) local paste_cmd=( wl-paste -n ) if [[ $X_SELECTION == primary ]]; then @@ -160,12 +163,12 @@ clip() { paste_cmd+=( --primary ) fi local display_name="$WAYLAND_DISPLAY" - elif [[ -n $DISPLAY ]]; then + elif [[ -n $DISPLAY ]] && command -v xclip &> /dev/null; then local copy_cmd=( xclip -selection "$X_SELECTION" ) local paste_cmd=( xclip -o -selection "$X_SELECTION" ) local display_name="$DISPLAY" else - die "Error: No X11 or Wayland display detected" + die "Error: No X11 or Wayland display and clipper detected" fi local sleep_argv0="password store sleep on display $display_name" @@ -259,7 +262,7 @@ cmd_version() { ============================================ = pass: the standard unix password manager = = = - = v1.7.3 = + = v1.7.4 = = = = Jason A. Donenfeld = = Jason@zx2c4.com = @@ -352,7 +355,7 @@ cmd_init() { signing_keys+=( --default-key $key ) done $GPG "${GPG_OPTS[@]}" "${signing_keys[@]}" --detach-sign "$gpg_id" || die "Could not sign .gpg_id." - key="$($GPG --verify --status-fd=1 "$gpg_id.sig" "$gpg_id" 2>/dev/null | sed -n 's/^\[GNUPG:\] VALIDSIG [A-F0-9]\{40\} .* \([A-F0-9]\{40\}\)$/\1/p')" + key="$($GPG "${GPG_OPTS[@]}" --verify --status-fd=1 "$gpg_id.sig" "$gpg_id" 2>/dev/null | sed -n 's/^\[GNUPG:\] VALIDSIG [A-F0-9]\{40\} .* \([A-F0-9]\{40\}\)$/\1/p')" [[ -n $key ]] || die "Signing of .gpg_id unsuccessful." git_add_file "$gpg_id.sig" "Signing new GPG id with ${key//[$IFS]/,}." fi @@ -399,7 +402,7 @@ cmd_show() { else echo "${path%\/}" fi - tree -C -l --noreport "$PREFIX/$path" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors + tree -N -C -l --noreport "$PREFIX/$path" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors elif [[ -z $path ]]; then die "Error: password store is empty. Try \"pass init\"." else @@ -411,7 +414,7 @@ cmd_find() { [[ $# -eq 0 ]] && die "Usage: $PROGRAM $COMMAND pass-names..." IFS="," eval 'echo "Search Terms: $*"' local terms="*$(printf '%s*|*' "$@")" - tree -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' + tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' } cmd_grep() { @@ -427,7 +430,7 @@ cmd_grep() { passfile="${passfile##*/}" printf "\e[94m%s\e[1m%s\e[0m:\n" "$passfile_dir" "$passfile" echo "$grepresults" - done < <(find -L "$PREFIX" -path '*/.git' -prune -o -iname '*.gpg' -print0) + done < <(find -L "$PREFIX" -path '*/.git' -prune -o -path '*/.extensions' -prune -o -iname '*.gpg' -print0) } cmd_insert() { diff --git a/src/platform/darwin.sh b/src/platform/darwin.sh index 342ecce..9a1fda8 100644 --- a/src/platform/darwin.sh +++ b/src/platform/darwin.sh @@ -34,15 +34,11 @@ tmpdir() { qrcode() { if type imgcat >/dev/null 2>&1; then echo -n "$1" | qrencode --size 10 -o - | imgcat - elif type gm >/dev/null 2>&1; then - echo -n "$1" | qrencode --size 10 -o - | gm display -title "pass: $2" -geometry +200+200 - - elif type display >/dev/null 2>&1; then - echo -n "$1" | qrencode --size 10 -o - | display -title "pass: $2" -geometry +200+200 - else echo -n "$1" | qrencode -t utf8 fi } -GETOPT="$(brew --prefix gnu-getopt 2>/dev/null || { which port &>/dev/null && echo /opt/local; } || echo /usr/local)/bin/getopt" +GETOPT="$({ test -x /usr/local/opt/gnu-getopt/bin/getopt && echo /usr/local/opt/gnu-getopt; } || brew --prefix gnu-getopt 2>/dev/null || { command -v port &>/dev/null && echo /opt/local; } || echo /usr/local)/bin/getopt" SHRED="srm -f -z" BASE64="openssl base64" |