[PATCH] Add support for XKCD-style wordlist passwords

Lenz Weber mail at lenzw.de
Tue Oct 30 08:25:54 CET 2018


Hi,

I want to bring up the question:

Is this something that pass needs? Or, more crass: should it offer this
feature or should it be considered harmful?

The point of pass, or any password manager, is not having to remember or
even know your password.

The default character set of pass has 31+26+26+10 = 93 characters, the
alphanumeric has at least 62.

Assuming a 6-word diceware password (approx. 30 characters) has 7776^6 ~
10^23 combinations, a password created with the default password set of
the same length has 10^59 combinations, or 10^53 for the alphanumeric
character set.

Assuming the use cases stated above (not having to ever remember your
password), using a diceware password just for a "nice looking" password
would sacrifice entropy somewhere between 10^30 and 10^36, bringing it
down to the complexity of a 12-character password with the default
character set.

I do not think this should be encouraged in any way.

Of course, there is nothing speaking against saving a diceware password
that has been generated elsewhere in pass - as a fallback, in case one
forgets it.

But this is an edge use case, not a core use case and the stance on edge
use cases has always been that there
* are other unix tools for it
* can always be a pass extension to offer it for those users that want
it in pass

What are other people's opinions on this?

Regards,
Lenz




On 10/30/18 6:00 AM, Adhityaa Chandrasekar wrote:
> ---
>  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
> 


More information about the Password-Store mailing list