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