summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2014-05-06 17:23:50 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2014-05-06 17:36:48 +0200
commit276fb973ab8517f3ec888b4ee2114d982131293c (patch)
tree7be1efa981272e8f9733b484cd2b7ef98df70b6c
parentbd8cbd12331cf965c54645a5397e0acfe90b4c96 (diff)
downloadpass-276fb973ab8517f3ec888b4ee2114d982131293c.tar.gz
pass-276fb973ab8517f3ec888b4ee2114d982131293c.tar.bz2
pass-276fb973ab8517f3ec888b4ee2114d982131293c.zip
generate: add --in-place option
Diffstat (limited to '')
-rw-r--r--man/pass.16
-rwxr-xr-xsrc/password-store.sh28
-rwxr-xr-xtests/pwgen2
-rwxr-xr-xtests/t0010-generate-tests.sh6
4 files changed, 33 insertions, 9 deletions
diff --git a/man/pass.1 b/man/pass.1
index 35c81ee..a433a72 100644
--- a/man/pass.1
+++ b/man/pass.1
@@ -110,7 +110,7 @@ ensure that temporary files are created in \fI/dev/shm\fP in order to avoid writ
difficult-to-erase disk sectors. If \fI/dev/shm\fP is not accessible, fallback to
the ordinary \fITMPDIR\fP location, and print a warning.
.TP
-\fBgenerate\fP [ \fI--no-symbols\fP, \fI-n\fP ] [ \fI--clip\fP, \fI-c\fP ] [ \fI--force\fP, \fI-f\fP ] \fIpass-name pass-length\fP
+\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
.BR pwgen (1)
of length \fIpass-length\fP and insert into \fIpass-name\fP. If \fI--no-symbols\fP or \fI-n\fP
@@ -120,7 +120,9 @@ it to the clipboard using
.BR xclip (1)
and then restore the clipboard after 45 (or \fIPASSWORD_STORE_CLIP_TIME\fP) seconds.
Prompt before overwriting an existing password,
-unless \fI--force\fP or \fI-f\fP is specified.
+unless \fI--force\fP or \fI-f\fP is specified. If \fI--in-place\fP or \fI-i\fP is
+specified, do not interactively prompt, and only replace the first line of the password
+file with the new generated password, keeping the remainder of the file intact.
.TP
\fBrm\fP [ \fI--recursive\fP, \fI-r\fP ] [ \fI--force\fP, \fI-f\fP ] \fIpass-name\fP
Remove the password named \fIpass-name\fP from the password store. This command is
diff --git a/src/password-store.sh b/src/password-store.sh
index 8e80798..8e1a124 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -230,10 +230,11 @@ cmd_usage() {
overwriting existing password unless forced.
$PROGRAM edit pass-name
Insert a new password or edit an existing password using ${EDITOR:-vi}.
- $PROGRAM generate [--no-symbols,-n] [--clip,-c] [--force,-f] pass-name pass-length
+ $PROGRAM generate [--no-symbols,-n] [--clip,-c] [--in-place,-i] [--force,-f] pass-name pass-length
Generate a new password of pass-length with optionally no symbols.
Optionally put it on the clipboard and clear board after 45 seconds.
Prompt before overwriting existing password unless forced.
+ Optionally replace only the first line of an existing file with a new password.
$PROGRAM rm [--recursive,-r] [--force,-f] pass-name
Remove existing password or directory, optionally forcefully.
$PROGRAM mv [--force,-f] old-path new-path
@@ -430,18 +431,19 @@ cmd_edit() {
}
cmd_generate() {
- local opts clip=0 force=0 symbols="-y"
- opts="$($GETOPT -o ncf -l no-symbols,clip,force -n "$PROGRAM" -- "$@")"
+ local opts clip=0 force=0 symbols="-y" inplace=0
+ opts="$($GETOPT -o ncif -l no-symbols,clip,in-place,force -n "$PROGRAM" -- "$@")"
local err=$?
eval set -- "$opts"
while true; do case $1 in
-n|--no-symbols) symbols=""; shift ;;
-c|--clip) clip=1; shift ;;
-f|--force) force=1; shift ;;
+ -i|--in-place) inplace=1; shift ;;
--) shift; break ;;
esac done
- [[ $err -ne 0 || $# -ne 2 ]] && die "Usage: $PROGRAM $COMMAND [--no-symbols,-n] [--clip,-c] [--force,-f] pass-name pass-length"
+ [[ $err -ne 0 || $# -ne 2 ]] && die "Usage: $PROGRAM $COMMAND [--no-symbols,-n] [--clip,-c] [--in-place,-i] [--force,-f] pass-name pass-length"
local path="$1"
local length="$2"
check_sneaky_paths "$path"
@@ -450,12 +452,24 @@ cmd_generate() {
set_gpg_recipients "$(dirname "$path")"
local passfile="$PREFIX/$path.gpg"
- [[ $force -eq 0 && -e $passfile ]] && yesno "An entry already exists for $path. Overwrite it?"
+ [[ $inplace -eq 0 && $force -eq 0 && -e $passfile ]] && yesno "An entry already exists for $path. Overwrite it?"
local pass="$(pwgen -s $symbols $length 1)"
[[ -n $pass ]] || exit 1
- $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" <<<"$pass"
- git_add_file "$passfile" "Add generated password for $path to store."
+ if [[ $inplace -eq 0 ]]; then
+ $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" <<<"$pass"
+ else
+ local passfile_temp="${passfile}.tmp.${RANDOM}.${RANDOM}.${RANDOM}.${RANDOM}.--"
+ if $GPG -d "${GPG_OPTS[@]}" "$passfile" | sed $'1c \\\n'"$(sed 's/[\/&]/\\&/g' <<<"$pass")"$'\n' | $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile_temp" "${GPG_OPTS[@]}"; then
+ mv "$passfile_temp" "$passfile"
+ else
+ rm -f "$passfile_temp"
+ die "Could not reencrypt new password."
+ fi
+ fi
+ local verb="Add"
+ [[ $inplace -eq 1 ]] && verb="Replace"
+ git_add_file "$passfile" "$verb generated password for ${path}."
if [[ $clip -eq 0 ]]; then
echo "The generated password to $path is:"
diff --git a/tests/pwgen b/tests/pwgen
new file mode 100755
index 0000000..c83eec9
--- /dev/null
+++ b/tests/pwgen
@@ -0,0 +1,2 @@
+#!/usr/bin/env bash
+echo "${FAKE_PWGEN_PASSWORD:-Hello World}"
diff --git a/tests/t0010-generate-tests.sh b/tests/t0010-generate-tests.sh
index da5e41f..cadb76f 100755
--- a/tests/t0010-generate-tests.sh
+++ b/tests/t0010-generate-tests.sh
@@ -10,4 +10,10 @@ test_expect_success 'Test "generate" command' '
[[ $("$PASS" show cred | wc -m) -eq 20 ]]
'
+test_expect_success 'Test replacement of first line' '
+ "$PASS" insert -m cred2 <<<"$(printf "this is a big\\npassword\\nwith\\nmany\\nlines\\nin it bla bla")" &&
+ PATH="$TEST_HOME:$PATH" FAKE_PWGEN_PASSWORD="This is a fake password" "$PASS" generate -i cred2 88 &&
+ [[ $("$PASS" show cred2) == "$(printf "This is a fake password\\npassword\\nwith\\nmany\\nlines\\nin it bla bla")" ]]
+'
+
test_done