[PATCH] show and edit: Option to show/edit everything except first line
Pelle Nilsson
pellenilsson at fastmail.fm
Sat Feb 18 23:11:00 CET 2017
Makes it possible to view or edit the less sensitive data (like URL and
username) without exposing the password to bystanders.
---
man/pass.1 | 7 +++++--
src/completion/pass.bash-completion | 3 ++-
src/completion/pass.fish-completion | 2 ++
src/completion/pass.zsh-completion | 12 +++++++++--
src/password-store.sh | 40 ++++++++++++++++++++++++++++---------
5 files changed, 50 insertions(+), 14 deletions(-)
diff --git a/man/pass.1 b/man/pass.1
index 71bfc7e..db9d4f4 100644
--- a/man/pass.1
+++ b/man/pass.1
@@ -90,7 +90,7 @@ List names of passwords inside the tree that match \fIpass-names\fP by using the
.BR tree (1)
program. This command is alternatively named \fBsearch\fP.
.TP
-\fBshow\fP [ \fI--clip\fP[=\fIline-number\fP], \fI-c\fP[\fIline-number\fP] ] [ \fI--qrcode\fP[=\fIline-number\fP], \fI-q\fP[\fIline-number\fP] ] \fIpass-name\fP
+\fBshow\fP [ \fI--clip\fP[=\fIline-number\fP], \fI-c\fP[\fIline-number\fP] ] [ \fI--qrcode\fP[=\fIline-number\fP], \fI-q\fP[\fIline-number\fP] ] [ \fI--without-password\fP, \fI-w\fP] \fIpass-name\fP
Decrypt and print a password named \fIpass-name\fP. If \fI--clip\fP or \fI-c\fP
is specified, do not print the password but instead copy the first (or otherwise specified)
line to the clipboard using
@@ -99,6 +99,7 @@ and then restore the clipboard after 45 (or \fIPASSWORD_STORE_CLIP_TIME\fP) seco
or \fI-q\fP is specified, do not print the password but instead display a QR code using
.BR qrencode (1)
either to the terminal or graphically if supported.
+If \fI--without-password\fP or \fI-w\fP is specified, print everything except for the first line.
.TP
\fBinsert\fP [ \fI--echo\fP, \fI-e\fP | \fI--multiline\fP, \fI-m\fP ] [ \fI--force\fP, \fI-f\fP ] \fIpass-name\fP
Insert a new password into the password store called \fIpass-name\fP. This will
@@ -109,7 +110,7 @@ EOF or Ctrl+D is reached. Otherwise, only a single line from standard in is read
before overwriting an existing password, unless \fI--force\fP or \fI-f\fP is specified. This
command is alternatively named \fBadd\fP.
.TP
-\fBedit\fP \fIpass-name\fP
+\fBedit\fP [ \fI--without-password\fP, \fI-w\fP] \fIpass-name\fP
Insert a new password or edit an existing password using the default text editor specified
by the environment variable \fIEDITOR\fP or using
.BR vi (1)
@@ -117,6 +118,8 @@ as a fallback. This mode makes use of temporary files for editing, but care is t
ensure that temporary files are created in \fI/dev/shm\fP in order to avoid writing to
difficult-to-erase disk sectors. If \fI/dev/shm\fP is not accessible, fallback to
the ordinary \fITMPDIR\fP location, and print a warning.
+If \fI--without-password\fP or \fI-w\fP is specified, edit everything except for the first line,
+and leave first line untouched.
.TP
\fBgenerate\fP [ \fI--no-symbols\fP, \fI-n\fP ] [ \fI--clip\fP, \fI-c\fP ] [ \fI--in-place\fP, \fI-i\fP | \fI--force\fP, \fI-f\fP ] \fIpass-name [pass-length]\fP
Generate a new password using \fB/dev/urandom\fP of length \fIpass-length\fP
diff --git a/src/completion/pass.bash-completion b/src/completion/pass.bash-completion
index 456485b..37f9558 100644
--- a/src/completion/pass.bash-completion
+++ b/src/completion/pass.bash-completion
@@ -95,10 +95,11 @@ _pass()
fi
;;
ls|list|edit)
+ COMPREPLY+=($(compgen -W "-w --without-password" -- ${cur}))
_pass_complete_entries
;;
show|-*)
- COMPREPLY+=($(compgen -W "-c --clip" -- ${cur}))
+ COMPREPLY+=($(compgen -W "-c --clip -w --without-password" -- ${cur}))
_pass_complete_entries 1
;;
insert)
diff --git a/src/completion/pass.fish-completion b/src/completion/pass.fish-completion
index c32a42c..42aa113 100644
--- a/src/completion/pass.fish-completion
+++ b/src/completion/pass.fish-completion
@@ -94,10 +94,12 @@ complete -c $PROG -f -A -n '__fish_pass_uses_command rm' -s f -l force -d 'Force
complete -c $PROG -f -A -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' -s w -l without-password -d 'Don't display password itself'
complete -c $PROG -f -A -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' -s w -l without-password -d 'Don't display password itself'
complete -c $PROG -f -A -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'
diff --git a/src/completion/pass.zsh-completion b/src/completion/pass.zsh-completion
index 27ce15a..fc5eae5 100644
--- a/src/completion/pass.zsh-completion
+++ b/src/completion/pass.zsh-completion
@@ -35,7 +35,13 @@ _pass () {
"--path[gpg-id will only be applied to this subfolder]"
_pass_complete_keys
;;
- ls|list|edit)
+ ls|list)
+ _pass_complete_entries_with_subdirs
+ ;;
+ edit)
+ _arguments : \
+ "-w[don't display password itself]" \
+ "--without-password[don't display password itself]"
_pass_complete_entries_with_subdirs
;;
insert)
@@ -117,7 +123,9 @@ _pass () {
_pass_cmd_show () {
_arguments : \
"-c[put it on the clipboard]" \
- "--clip[put it on the clipboard]"
+ "--clip[put it on the clipboard]" \
+ "-w[don't display password itself]" \
+ "--without-password[don't display password itself]"
_pass_complete_entries
}
_pass_complete_entries_helper () {
diff --git a/src/password-store.sh b/src/password-store.sh
index 081057a..6a268e1 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -257,7 +257,7 @@ cmd_usage() {
List passwords.
$PROGRAM find pass-names...
List passwords that match pass-names.
- $PROGRAM [show] [--clip[=line-number],-c[line-number]] pass-name
+ $PROGRAM [show] [--clip[=line-number],-c[line-number]] [--without-password,-w] pass-name
Show existing password and optionally put it on the clipboard.
If put on the clipboard, it will be cleared in $CLIP_TIME seconds.
$PROGRAM grep search-string
@@ -266,7 +266,7 @@ cmd_usage() {
Insert new password. Optionally, echo the password back to the console
during entry. Or, optionally, the entry may be multiline. Prompt before
overwriting existing password unless forced.
- $PROGRAM edit pass-name
+ $PROGRAM edit [--without-password,-w] pass-name
Insert a new password or edit an existing password using ${EDITOR:-vi}.
$PROGRAM generate [--no-symbols,-n] [--clip,-c] [--in-place,-i | --force,-f] pass-name [pass-length]
Generate a new password of pass-length (or $GENERATED_LENGTH if unspecified) with optionally no symbols.
@@ -338,24 +338,29 @@ cmd_init() {
}
cmd_show() {
- local opts selected_line clip=0 qrcode=0
- opts="$($GETOPT -o q::c:: -l qrcode::,clip:: -n "$PROGRAM" -- "$@")"
+ local opts selected_line clip=0 qrcode=0 without_password=0
+ opts="$($GETOPT -o q::c::,w -l qrcode::,clip::,without-password -n "$PROGRAM" -- "$@")"
local err=$?
eval set -- "$opts"
while true; do case $1 in
-q|--qrcode) qrcode=1; selected_line="${2:-1}"; shift 2 ;;
-c|--clip) clip=1; selected_line="${2:-1}"; shift 2 ;;
+ -w|--without-password) without_password=1; shift ;;
--) shift; break ;;
esac done
- [[ $err -ne 0 || ( $qrcode -eq 1 && $clip -eq 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--clip[=line-number],-c[line-number]] [--qrcode[=line-number],-q[line-number]] [pass-name]"
+ [[ $err -ne 0 || ( $qrcode -eq 1 && $clip -eq 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--clip[=line-number],-c[line-number]] [--qrcode[=line-number],-q[line-number]] [--without-password,-w] [pass-name]"
local path="$1"
local passfile="$PREFIX/$path.gpg"
check_sneaky_paths "$path"
if [[ -f $passfile ]]; then
if [[ $clip -eq 0 && $qrcode -eq 0 ]]; then
- $GPG -d "${GPG_OPTS[@]}" "$passfile" || exit $?
+ if [[ $without_password -eq 0 ]]; then
+ $GPG -d "${GPG_OPTS[@]}" "$passfile" || exit $?
+ else
+ $GPG -d "${GPG_OPTS[@]}" "$passfile" | tail -n +2 || exit $?
+ fi
else
[[ $selected_line =~ ^[0-9]+$ ]] || die "Clip location '$selected_line' is not a number."
local pass="$($GPG -d "${GPG_OPTS[@]}" "$passfile" | tail -n +${selected_line} | head -n 1)"
@@ -452,7 +457,16 @@ cmd_insert() {
}
cmd_edit() {
- [[ $# -ne 1 ]] && die "Usage: $PROGRAM $COMMAND pass-name"
+ local opts without_password=0
+ opts="$($GETOPT -o w -l without-password -n "$PROGRAM" -- "$@")"
+ local err=$?
+ eval set -- "$opts"
+ while true; do case $1 in
+ -w|--without-password) without_password=1; shift ;;
+ --) shift; break ;;
+ esac done
+
+ [[ $err -ne 0 || ( $# -ne 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--without-password,-w] pass-name"
local path="${1%/}"
check_sneaky_paths "$path"
@@ -462,15 +476,23 @@ cmd_edit() {
tmpdir #Defines $SECURE_TMPDIR
local tmp_file="$(mktemp -u "$SECURE_TMPDIR/XXXXXX")-${path//\//-}.txt"
-
+ local tmp_file2="$(mktemp -u "$SECURE_TMPDIR/XXXXXX")-${path//\//-}.txt"
local action="Add"
if [[ -f $passfile ]]; then
- $GPG -d -o "$tmp_file" "${GPG_OPTS[@]}" "$passfile" || exit 1
+ if [[ $without_password -eq 0 ]]; then
+ $GPG -d -o "$tmp_file" "${GPG_OPTS[@]}" "$passfile" || exit 1
+ else
+ $GPG -d -o - "${GPG_OPTS[@]}" "$passfile" | tail -n +2 > "$tmp_file" || exit 1
+ fi
action="Edit"
fi
${EDITOR:-vi} "$tmp_file"
[[ -f $tmp_file ]] || die "New password not saved."
+ if [[ $without_password -eq 1 ]]; then
+ $GPG -d -o - "${GPG_OPTS[@]}" "$passfile" 2>/dev/null | head -n 1 | cat - "$tmp_file" > "$tmp_file2"
+ mv -f "$tmp_file2" "$tmp_file"
+ fi
$GPG -d -o - "${GPG_OPTS[@]}" "$passfile" 2>/dev/null | diff - "$tmp_file" &>/dev/null && die "Password unchanged."
while ! $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" "$tmp_file"; do
yesno "GPG encryption failed. Would you like to try again?"
--
2.11.0
More information about the Password-Store
mailing list