aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2012-09-11 04:50:41 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2012-09-11 05:02:19 +0200
commit3fc5b0c09ba3293d6b0d041bd09d6cc260c1efde (patch)
treeaedf41583c26e1880177b785c27fa1d499a4ad1a
parentdefault to 'show' command for zsh completion (diff)
downloadpassword-store-3fc5b0c09ba3293d6b0d041bd09d6cc260c1efde.tar.xz
password-store-3fc5b0c09ba3293d6b0d041bd09d6cc260c1efde.zip
Add an edit mode that uses $EDITOR.
This allows users to edit password files using temporary files created in /dev/shm. This commit also tidies other things up and fixes minor bugs and griviences that should be separate commits but aren't. Reported-by: rupa <rupa@lrrr.us>
-rw-r--r--man/pass.19
-rwxr-xr-xsrc/password-store.sh94
2 files changed, 80 insertions, 23 deletions
diff --git a/man/pass.1 b/man/pass.1
index b17acd9..95b4f92 100644
--- a/man/pass.1
+++ b/man/pass.1
@@ -77,6 +77,15 @@ disable keyboard echo when the password is entered and confirm the password by a
for it twice. If \fI--multiline\fP or \fI-m\fP is specified, lines will be read until
EOF or Ctrl+D is reached. Otherwise, only a single line from standard in is read.
.TP
+\fBedit\fP \fIpass-name\fP
+Insert a new password or edit an existing password using the default text editor specified
+by the environment variable \fBEDITOR\fP or using
+.BR vi (1)
+as a fallback. This mode makes use of temporary files for editing, but care is taken to
+ensure that temporary files are created in \fB/dev/shm\fP in order to avoid writing to
+difficult-to-erase disk sectors. If \fB/dev/shm\fP is not accessible, fallback to
+the ordinary \fBTMPDIR\fP location, and print a warning.
+.TP
\fBgenerate\fP [ \fI--no-symbols\fP, \fI-n\fP ] [ \fI--clip\fP, \fI-c\fP ] \fIpass-name pass-length\fP
Generate a new password using
.BR pwgen (1)
diff --git a/src/password-store.sh b/src/password-store.sh
index 2e1d14b..0fecc79 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -29,6 +29,8 @@ Usage:
$program insert [--no-echo,-n | --multiline,-m] pass-name
Insert new password. Optionally, the console can be enabled to not
echo the password back. Or, optionally, it may be multiline.
+ $program edit pass-name
+ Insert a new password or edit an existing password using ${EDITOR:-vi}.
$program generate [--no-symbols,-n] [--clip,-c] 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.
@@ -47,7 +49,7 @@ _EOF
}
isCommand() {
case "$1" in
- init|ls|list|show|insert|generate|remove|rm|delete|push|pull|git|help) return 0 ;;
+ init|ls|list|show|insert|edit|generate|remove|rm|delete|push|pull|git|help|--help) return 0 ;;
*) return 1 ;;
esac
}
@@ -93,7 +95,7 @@ case "$command" in
echo "Password store initialized for $gpg_id."
exit 0
;;
- help)
+ help|--help)
usage
exit 0
;;
@@ -132,9 +134,9 @@ case "$command" in
exit 1
fi
if [ $clip -eq 0 ]; then
- exec gpg -q -d "$passfile"
+ exec gpg -q -d --yes "$passfile"
else
- clip "$(gpg -q -d "$passfile" | head -n 1)" "$path"
+ clip "$(gpg -q -d --yes "$passfile" | head -n 1)" "$path"
fi
fi
;;
@@ -163,30 +165,76 @@ case "$command" in
if [[ $ml -eq 1 ]]; then
echo "Enter contents of $path and press Ctrl+D when finished:"
echo
- cat | gpg -e -r "$ID" > "$passfile"
+ cat | gpg -e -r "$ID" -o "$passfile" --yes
elif [[ $noecho -eq 1 ]]; then
- stty -echo
+ while true; do
+ stty -echo
+ echo -n "Enter password for $path: "
+ read password
+ echo
+ echo -n "Retype password for $path: "
+ read password_again
+ echo
+ stty echo
+ if [[ $password == $password_again ]]; then
+ gpg -q -e -r "$ID" -o "$passfile" --yes <<<"$password"
+ break
+ else
+ echo "Error: the entered passwords do not match."
+ fi
+ done
+ else
echo -n "Enter password for $path: "
- read password
- echo
- echo -n "Retype password for $path: "
- read password_again
- echo
- stty echo
- if [[ $password == $password_again ]]; then
- gpg -e -r "$ID" > "$passfile" <<<"$password"
- else
- echo "Error: the entered passwords do not match."
+ head -n 1 | gpg -q -e -r "$ID" -o "$passfile" --yes
+ fi
+ if [[ -d $GIT ]]; then
+ git add "$passfile"
+ git commit -m "Added given password for $path to store."
+ fi
+ ;;
+ edit)
+ if [[ $# -ne 1 ]]; then
+ echo "Usage $program $command pass-name"
+ exit 1
+ fi
+
+ path="$1"
+ mkdir -p -v "$PREFIX/$(dirname "$path")"
+ passfile="$PREFIX/$path.gpg"
+
+ if [ -d /dev/shm -a -w /dev/shm -a -x /dev/shm ]; then
+ tmp_dir="$(mktemp -d --tmpdir=/dev/shm)"
+ else
+ echo "Your system does not have /dev/shm, which means that it may"
+ echo "be difficult to entirely erase the temporary non-encrypted"
+ echo "password file after editing. Are you sure you would like to"
+ echo -n "continue? [y/N] "
+ read yesno
+ if ! [[ $yesno == "y" || $yesno == "Y" ]]; then
exit 1
fi
+ tmp_dir="$(mktemp -d)"
+ fi
+ tmp_file="$(mktemp --tmpdir="$tmp_dir")"
- else
- echo -n "Enter password for $path: "
- head -n 1 | gpg -e -r "$ID" > "$passfile"
+ action="Added"
+ if [[ -f $passfile ]]; then
+ if ! gpg -q -d -o "$tmp_file" --yes "$passfile"; then
+ rm -rf "$tmp_file" "$tmp_dir"
+ exit 1
+ fi
+ action="Edited"
fi
+ "${EDITOR:-vi}" "$tmp_file"
+ while ! gpg -q -e -r "$ID" -o "$passfile" --yes "$tmp_file"; do
+ echo "GPG encryption failed. Retrying."
+ sleep 1
+ done
+ rm -rf "$tmp_file" "$tmp_dir"
+
if [[ -d $GIT ]]; then
git add "$passfile"
- git commit -m "Added given password for $path to store."
+ git commit -m "$action password for $path using ${EDITOR:-vi}."
fi
;;
generate)
@@ -216,7 +264,7 @@ case "$command" in
mkdir -p -v "$PREFIX/$(dirname "$path")"
pass="$(pwgen -s $symbols $length 1)"
passfile="$PREFIX/$path.gpg"
- echo $pass | gpg -e -r "$ID" > "$passfile"
+ gpg -q -e -r "$ID" -o "$passfile" --yes <<<"$pass"
if [[ -d $GIT ]]; then
git add "$passfile"
git commit -m "Added generated password for $path to store."
@@ -248,7 +296,7 @@ case "$command" in
;;
push|pull)
if [[ -d $GIT ]]; then
- exec git $command $@
+ exec git $command "$@"
else
echo "Error: the password store is not a git repository."
exit 1
@@ -256,7 +304,7 @@ case "$command" in
;;
git)
if [[ $1 == "init" ]] || [[ -d $GIT ]]; then
- exec git $@
+ exec git "$@"
else
echo "Error: the password store is not a git repository."
exit 1