[pass] Provide symbol set as command line argument

Kenny Evitt kenny.evitt at gmail.com
Thu Nov 10 15:43:23 CET 2016


I thought it was pretty neat both because of its simplicity and its
'bruteness', but I can't take the credit. I grabbed it from this answer
<http://unix.stackexchange.com/a/230676/56148> to a question on generating
random strings on the Unix & Linux Stack Exchange site.

But I can't reproduce the bug you claimed exists. Here's how I tried to
reproduce it.

I created a text file named "test.txt" with the initial contents of
"0123456789".

I ran this and it worked as expected:

```
$ head test.txt | tr -dc '0-9' | head -c 10 && echo
0123456789
```

I then edited "test.txt", inserted a newline between the `4` and `5`, and
saved the file. I reran the same command as before:

```
$ head test.txt | tr -dc '0-9' | head -c 10 && echo
0123456789
```

Is running `head` with a text file containing newlines somehow different
than reading from /dev/urandom and reading bytes matching newline character
byte values?


On Wed, Nov 9, 2016 at 2:32 PM, Kevin Cox <kevincox at kevincox.ca> wrote:

> I'm not sure whether I am impressed by the simplicity or scared by the
> bruteness. Obviously the performance will drop as you have a smaller
> character set but that is probably not w problem as even with one character
> you will only need 256 bytes per character in the resulting password.
>
> You do have a bug though. You shouldn't use head because then if you
> happen to draw 10 newlines before the characters you need your generated
> password will be shorter then you expected. Try the following.
>
> tr -nd ... </dev/random | ...
>
> On Nov 9, 2016 16:56, "Kenny Evitt" <kenny.evitt at gmail.com> wrote:
>
>> Replacing `pwgen` shouldn't be a big deal. The only Pass command that
>> uses it is `generate` and the only options passed to are whether to include
>> symbols and the length of the password.
>>
>> Incidentally, I cobbled together a handy way of generating arbitrary
>> passwords of any length using only specific special characters. It should
>> work on most any Unix or Unix-like system. Here's an example for generating
>> a password of 32 characters with only a limited set of special characters:
>>
>> ```
>> head /dev/urandom | tr -dc 'A-Za-z0-9!@#$%^&*()' | head -c 32 && echo
>> ```
>>
>> Here's an example with all of the OWASP special characters, which would
>> be a good default if no set of { symbols / special characters } are
>> specified:
>>
>> ```
>> head /dev/urandom | tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~'
>> | head -c 32 && echo
>> ```
>>
>> `pwgen` by default "generates passwords which are designed to be easily
>> memorized by humans, while being as secure as possible". Pass hard-codes
>> the call to `pwgen` to use the 'secure' option which will "generate
>> completely random, hard-to-memorize passwords", so just reading from
>> */dev/urandom* is probably just as good (and likely pretty similar to
>> whatever `pwgen` is doing when the secure option is specified).
>>
>> Below is a patch with changes that replace `pwgen` with my above commands.
>>
>> Both `apg` and `mkpasswd` have some nice options for ensuring that
>> passwords definitely contain certain types of characters, which is
>> particularly useful for passwords that need to meet certain requirements,
>> e.g. always include a special character.
>>
>> But perhaps, instead of Pass depending directly on any particular
>> password generator, it simply call another specified program to do so. If
>> some passwords didn't (annoyingly) necessitate *excluding* certain special
>> characters `pwgen` should be more than good enough. But given that
>> generating arbitrary passwords for all of the possible sets of valid
>> passwords is (annoyingly) difficult, perhaps Pass shouldn't bother to try
>> to implement that itself beyond its current okay-ish default dependency on
>> `pwgen`.
>>
>>
>>
>> ```
>> diff --git a/src/password-store.sh b/src/password-store.sh
>> index 63be840..10463cb 100755
>> --- a/src/password-store.sh
>> +++ b/src/password-store.sh
>> @@ -16,6 +16,7 @@ PREFIX="${PASSWORD_STORE_DIR:-$HOME/.password-store}"
>>  X_SELECTION="${PASSWORD_STORE_X_SELECTION:-clipboard}"
>>  CLIP_TIME="${PASSWORD_STORE_CLIP_TIME:-45}"
>>  GENERATED_LENGTH="${PASSWORD_STORE_GENERATED_LENGTH:-25}"
>> +DEFAULT_SYMBOLS="${PASSWORD_STORE_DEFAULT_SYMBOLS:-\!\"#\$%
>> &\'()*+,-./:;<=>?@[\]^_\`{|\}~}"
>>
>>  export GIT_DIR="${PASSWORD_STORE_GIT:-$PREFIX}/.git"
>>  export GIT_WORK_TREE="${PASSWORD_STORE_GIT:-$PREFIX}"
>> @@ -235,8 +236,8 @@ cmd_usage() {
>>                 overwriting existing password unless forced.
>>             $PROGRAM edit pass-name
>>                 Insert a new password or edit an existing password using
>> ${EDITOR:-vi}.
>> -           $PROGRAM generate [--no-symbols,-n] [--clip,-c]
>> [--in-place,-i | --force,-f] pass-name [pass-length]
>> -               Generate a new password of pass-length (or
>> $GENERATED_LENGTH if unspecified) with optionally no symbols.
>> +           $PROGRAM generate [--clip,-c] [--in-place,-i | --force,-f]
>> pass-name [pass-length] [symbols]
>> +               Generate a new password of pass-length (or
>> $GENERATED_LENGTH if unspecified) with optional set of symbols to use (or
>> $DEFAULT_SYMBOLS if unspecified).
>>                 Optionally put it on the clipboard and clear board after
>> $CLIP_TIME seconds.
>>                 Prompt before overwriting existing password unless forced.
>>                 Optionally replace only the first line of an existing
>> file with a new password.
>> @@ -431,21 +432,21 @@ cmd_edit() {
>>  }
>>
>>  cmd_generate() {
>> -       local opts clip=0 force=0 symbols="-y" inplace=0
>> -       opts="$($GETOPT -o ncif -l no-symbols,clip,in-place,force -n
>> "$PROGRAM" -- "$@")"
>> +       local opts clip=0 force=0 inplace=0
>> +       opts="$($GETOPT -o cif -l clip,in-place,force -n "$PROGRAM" --
>> "$@")"
>>         local err=$?
>>         eval set -- "$opts"
>>         while true; do case $1 in
>> -               -n|--no-symbols) symbols=""; shift ;;
>>                 -c|--clip) clip=1; shift ;;
>>                 -f|--force) force=1; shift ;;
>>                 -i|--in-place) inplace=1; shift ;;
>>                 --) shift; break ;;
>>         esac done
>>
>> -       [[ $err -ne 0 || ( $# -ne 2 && $# -ne 1 ) || ( $force -eq 1 &&
>> $inplace -eq 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--no-symbols,-n]
>> [--clip,-c] [--in-place,-i | --force,-f] pass-name [pass-length]"
>> +       [[ $err -ne 0 || ( $# -ne 3 && $# -ne 2 && $# -ne 1 ) || ( $force
>> -eq 1 && $inplace -eq 1 ) ]] && die "Usage: $PROGRAM $COMMAND [--clip,-c]
>> [--in-place,-i | --force,-f] pass-name [pass-length] [symbols]"
>>         local path="$1"
>>         local length="${2:-$GENERATED_LENGTH}"
>> +       local symbols="${3:-$DEFAULT_SYMBOLS}"
>>         check_sneaky_paths "$path"
>>         [[ ! $length =~ ^[0-9]+$ ]] && die "Error: pass-length
>> \"$length\" must be a number."
>>         mkdir -p -v "$PREFIX/$(dirname "$path")"
>> @@ -454,7 +455,7 @@ cmd_generate() {
>>
>>         [[ $inplace -eq 0 && $force -eq 0 && -e $passfile ]] && yesno "An
>> entry already exists for $path. Overwrite it?"
>>
>> -       local pass="$(pwgen -s $symbols $length 1)"
>> +       local pass="$(head /dev/urandom | tr -dc "A-Za-z0-9$symbols" |
>> head -c "$length" && echo)"
>>         [[ -n $pass ]] || exit 1
>>         if [[ $inplace -eq 0 ]]; then
>>                 $GPG -e "${GPG_RECIPIENT_ARGS[@]}" -o "$passfile"
>> "${GPG_OPTS[@]}" <<<"$pass" || die "Password encryption aborted."
>> ```
>>
>> On Tue, Nov 8, 2016 at 5:23 PM, Diego Depaoli <trebestie at gmail.com>
>> wrote:
>>
>>> I agree.
>>> This is not a big issue, but sometimes limited pwgen features are
>>> annoying.
>>> Could apg or makepassword bè reliable replacements?
>>>
>>> My best regards
>>>
>>> Il mar 8 nov 2016 20:55 Michael Hoff <mail at michael-hoff.net> ha scritto:
>>>
>>> Hello,
>>>
>>> first of all: Really nice project!
>>>
>>> I very often encounter the problem that services do not allow all
>>> symbols used by pass/pwgen.
>>> "Your password has to contain at least one of the following symbols
>>> '*#_!'" (e.g. '<' is forbidden)
>>>
>>> This does hinder my work-flow as I have to manually adapt the password
>>> to match the criteria.
>>>
>>> Straight-forward solution to this problem would be to provide the symbol
>>> set via optional command line argument to the generate command.
>>>
>>> Example: pass generate *-s "*#_!"* path/to/password 20
>>>
>>> I already checked man page and source code of pwgen. Unfortunately this
>>> feature is not provided out of the box.
>>>
>>> I see multiple possible solutions to this:
>>> - Exchange pwgen with apg (possibly massive side-effects)
>>> - Extend pwgen
>>> - Let pass itself convert unwanted symbols generated by pwgen (hacky)
>>>
>>> What do you think?
>>>
>>> Cheers,
>>> Michael Hoff
>>>
>>> --
>>> S/MIME and PGP (0xA79D31C0) supportedhttps://michael-hoff.net
>>>
>>> _______________________________________________
>>> Password-Store mailing list
>>> Password-Store at lists.zx2c4.com
>>> http://lists.zx2c4.com/mailman/listinfo/password-store
>>>
>>> --
>>> Diego Depaoli
>>>
>>> _______________________________________________
>>> Password-Store mailing list
>>> Password-Store at lists.zx2c4.com
>>> http://lists.zx2c4.com/mailman/listinfo/password-store
>>>
>>>
>>
>> _______________________________________________
>> Password-Store mailing list
>> Password-Store at lists.zx2c4.com
>> http://lists.zx2c4.com/mailman/listinfo/password-store
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/password-store/attachments/20161110/ee570a9e/attachment-0001.html>


More information about the Password-Store mailing list