[PATCH] Add support for XKCD-style wordlist passwords
Adhityaa Chandrasekar
pass at adtac.in
Tue Oct 30 06:00:36 CET 2018
---
man/pass.1 | 17 ++++++++++-------
src/password-store.sh | 16 +++++++++++-----
2 files changed, 21 insertions(+), 12 deletions(-)
This is my first time contributing to pass as a long-time user. In this
patch, I'm adding support for XKCD-style passwords [1] composed of words
from a wordlist. Since there is no standardised location for a
dictionary of words, the user has to specify a path to a file with the
--wordlist argument.
I don't know much bash/zsh/fish completions, so I'm afraid someone else
will have to help with that.
[1] https://xkcd.com/936/
- Adhityaa
diff --git a/man/pass.1 b/man/pass.1
index 01a3fbe..72a83fc 100644
--- a/man/pass.1
+++ b/man/pass.1
@@ -122,15 +122,18 @@ 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--in-place\fP, \fI-i\fP | \fI--force\fP, \fI-f\fP ] \fIpass-name [pass-length]\fP
+\fBgenerate\fP [ \fI--no-symbols\fP, \fI-n\fP ] [ \fI--wordlist /path/to/wordlist\fP, \fI-w /path/to/wordlist\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
(or \fIPASSWORD_STORE_GENERATED_LENGTH\fP if unspecified) and insert into
-\fIpass-name\fP. If \fI--no-symbols\fP or \fI-n\fP is specified, do not use
-any non-alphanumeric characters in the generated password. The character sets used
-in generating passwords can be changed with the \fIPASSWORD_STORE_CHARACTER_SET\fP and
-\fIPASSWORD_STORE_CHARACTER_SET_NO_SYMBOLS\fP environment variables, described below.
-If \fI--clip\fP or \fI-c\fP is specified, do not print the password but instead copy
-it to the clipboard using
+\fIpass-name\fP. If \fI--no-symbols\fP or \fI-n\fP is specified, do not use any
+non-alphanumeric characters in the generated password. If \fI--wordlist\fP is
+specified, along with a file as argument containing a list of words to choose
+from, four words will be randomly chosen and used as password. The character
+sets used in generating passwords can be changed with the
+\fIPASSWORD_STORE_CHARACTER_SET\fP and
+\fIPASSWORD_STORE_CHARACTER_SET_NO_SYMBOLS\fP environment variables, described
+below. If \fI--clip\fP or \fI-c\fP is specified, do not print the password but
+instead copy it to the clipboard using
.BR xclip (1)
and then restore the clipboard after 45 (or \fIPASSWORD_STORE_CLIP_TIME\fP) seconds. If \fI--qrcode\fP
or \fI-q\fP is specified, do not print the password but instead display a QR code using
diff --git a/src/password-store.sh b/src/password-store.sh
index d89d455..2778c26 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -491,12 +491,13 @@ cmd_edit() {
}
cmd_generate() {
- local opts qrcode=0 clip=0 force=0 characters="$CHARACTER_SET" inplace=0 pass
- opts="$($GETOPT -o nqcif -l no-symbols,qrcode,clip,in-place,force -n "$PROGRAM" -- "$@")"
+ local opts qrcode=0 clip=0 force=0 characters="$CHARACTER_SET" wordlist=0 inplace=0 pass
+ opts="$($GETOPT -o nw:qcif -l no-symbols,wordlist:,qrcode,clip,in-place,force -n "$PROGRAM" -- "$@")"
local err=$?
eval set -- "$opts"
while true; do case $1 in
-n|--no-symbols) characters="$CHARACTER_SET_NO_SYMBOLS"; shift ;;
+ -w|--wordlist) wordlist=$2; shift; shift ;;
-q|--qrcode) qrcode=1; shift ;;
-c|--clip) clip=1; shift ;;
-f|--force) force=1; shift ;;
@@ -504,7 +505,7 @@ cmd_generate() {
--) shift; break ;;
esac done
- [[ $err -ne 0 || ( $# -ne 2 && $# -ne 1 ) || ( $force -eq 1 && $inplace -eq 1 ) || ( $qrcode -eq 1 && $clip -eq 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--no-symbols,-n] [--clip,-c] [--qrcode,-q] [--in-place,-i | --force,-f] pass-name [pass-length]"
+ [[ $err -ne 0 || ( $# -ne 2 && $# -ne 1 ) || ( $force -eq 1 && $inplace -eq 1 ) || ( $qrcode -eq 1 && $clip -eq 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--no-symbols,-n] [--wordlist,-w /path/to/wordlist] [--clip,-c] [--qrcode,-q] [--in-place,-i | --force,-f] pass-name [pass-length]"
local path="$1"
local length="${2:-$GENERATED_LENGTH}"
check_sneaky_paths "$path"
@@ -517,8 +518,13 @@ cmd_generate() {
[[ $inplace -eq 0 && $force -eq 0 && -e $passfile ]] && yesno "An entry already exists for $path. Overwrite it?"
- read -r -n $length pass < <(LC_ALL=C tr -dc "$characters" < /dev/urandom)
- [[ ${#pass} -eq $length ]] || die "Could not generate password from /dev/urandom."
+ if [[ "$wordlist" != "" ]]; then
+ pass=$(shuf -n 4 "$wordlist" | paste -sd "-" -)
+ else
+ read -r -n $length pass < <(LC_ALL=C tr -dc "$characters" < /dev/urandom)
+ [[ ${#pass} -eq $length ]] || die "Could not generate password from /dev/urandom."
+ fi
+
if [[ $inplace -eq 0 ]]; then
echo "$pass" | $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile" "${GPG_OPTS[@]}" || die "Password encryption aborted."
else
--
2.19.1
More information about the Password-Store
mailing list