---
 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

_______________________________________________
Password-Store mailing list
Password-Store@lists.zx2c4.com
https://lists.zx2c4.com/mailman/listinfo/password-store

Reply via email to