# pwtool

Generate passwords from random characters or words and optionally show their cryptographic hash.

The default generated password set is copy/paste friendly without extended characters that would break the default copy selection you get when double-clicking a word. They also are don't break quotation strings (quote marks, double quotes or backticks).

# installing

From cargo, ensuring that the install path (normally ~/.cargo/bin) is in your `PATH` environment.

```
cargo install pwtool
```


source code

```
git clone https://gitlab.com/edneville/pwtool.git
cd pwtool
cargo build --release
```

please or sudo

```
please install -m0755 -o0 -g0 target/release/pwtool /usr/local/bin/
```

snap

```
please snap install pwtool
```

# modifiers

`lowercase`, `uppercase`, `numeric` and `extended` will set requirements on the passwords.

# word lists

If you want a password generated from words rather than a mixture of letters and numbers, use the `words` option, which by default uses the file `/usr/share/dict/words`. Use `wordsfile` to specify a different list.

# cryptographic hash

The `--md5`, `--bcrypt`, `--des`, `--sha1`, `--sha256` and `--sha512` options will print the cryptographic hash which can be used instead of storing the password in some systems.

The hash output can be used with `useradd`/`usermod` or `.htaccess`:

```
LINE=`pwtool --number 1 --sha256`
PW="${LINE% *}"
HASH="${LINE##* }"
USR=newuser
useradd -m -p "$HASH" -s /bin/bash $USR
echo "Password for $USR  is $PW"
```

Or issue a new password to an existing user with `usermod`:

```
LINE=`pwtool --number 1 --sha256`
PW=`echo "$LINE" | sed -e 's/ .*//g'`
HASH=`echo "$LINE" | sed -e 's/.* //g'`
USR=newuser
usermod -p "$HASH" $USR
echo "Password for $USR is now $PW"
```

# options

`--userfmt`, `--mysqlfmt`, `--pgfmt`, `--htauthfmt`, `--usermodfmt`, `--totpfmt` are convenience options for format variables below, with the exception that they will also print the password in a comment:

    pwtool --username thingy --userfmt

This then outputs like this:

    useradd -m -s /bin/bash -p '$5$YLtTnPhYiQ891nAz$SHzSCc5vMIARxd4PYtxIOZ7mGICNsLGEGimMyFpRjE7' thingy # 8OtQUoUjV9

`--createdatabase` when combined with one of the database options will prefix with a `create database %{database};` string.

The `--totp`, `--totpstep` options are for the key (base32), length of digits and step.

# format strings

With `--format` the variables can be used to output a custom string.

The variables (below) can be used within a `--format` string to output in a convenient way:

    pwtool --username thingy --format "useradd -m -s /bin/bash -p '%{sha256}' %{username} # %{password}\n"

This then outputs like this:

    useradd -m -s /bin/bash -p '$5$YLtTnPhYiQ891nAz$SHzSCc5vMIARxd4PYtxIOZ7mGICNsLGEGimMyFpRjE7' thingy # 8OtQUoUjV9

You can then copy/paste that around different systems where people need the same account.

Another common way is to use it for mysql setup at the same time:

    pwtool --username thingy --database thing --format "grant all privileges on %{database}.* to %{username}@'%' identified with mysql_native_password as '%{mysql}';\n";

| variable | output |
|----------|--------|
| %{des}       | traditional crypt |
| %{bcrypt}    | BSD standard hash |
| %{md5}       | MD5 hash |
| %{sha1}      | HMAC SHA1 |
| %{sha256}    | SHA256 |
| %{sha512}    | SHA512 |
| %{mysql}     | password in mysql_native format |
| %{password}  | cleartext password |
| %{username}  | placeholder for --username |
| %{database}  | placeholder for --database |
| %{postgres}  | postgres SCRAM-SHA-256 password |
| %{userfmt}   | expands to `useradd -m -s /bin/bash -p '%{sha256}' %{username}` |
| %{usermodfmt}   | expands to `usermod -p '%{sha256}' %{username}` |
| %{mysqlfmt}  | expands to `grant all privileges on %{database}.* to %{username}@'%' identified with mysql_native_password as '%{mysql}';` |
| %{mysqluserfmt} | expands to `create user %{username}@'%'; alter user %{username}@'%' identified with 'caching_sha2_password' as %{mysql_caching_sha2}; grant all privileges on %{database}.* to %{username}@'%';` |
| %{pgfmt}     | expands to `create user %{username} password '%{postgres}';` |
| %{htauthfmt} | expands to `%{username}:%{sha256}` |
| %{totp} | displays the current TOTP SHA1 | 
| %{totpfmt} | an alias for the TOTP number and remaining time progress | 
| %{totpsecs} | displays the remaining seconds | 
| %{totpsecsmax} | displays the max sec step | 
| %{totpprogress} | displays a progress bar for remaining secs | 
| %{totpalgo} | displays the TOTP algorithm used | 

# executing output

Should you want to execute the output, `tee` is quite handy as it will print to stdout and an elevated file descriptor:

    pwtool --username moo --format "useradd -m -s /bin/bash -p '%{sha256}' %{username} # %{password}\n" --number 1 | tee >( please /bin/bash )
    useradd -m -s /bin/bash -p '$5$pZxFddWqXpBuozZF$l1Eyw2HqsGP0E9pdQctqeCPTOL3eJOPq4pNiI6MoZG5' moo # 6nIFhAKJSC

This will both add the user and print the password in the shell.

# http basic authentication

You can populate entries in basic authentication files too:

    pwtool --username moo --format '%{htauthfmt}'

Not the output has the password in a comment prior to the auth line as data after the `:` is normally treated as the hashed password. You can store this in `/etc/apache2/restricted`:

    AuthType Basic
    AuthName "Keep out!"
    AuthUserFile "/etc/apache2/restricted"
    Require valid-user

or with nginx, in `/etc/nginx/restricted`:

    auth_basic "Keep out!";
    auth_basic_user_file /etc/nginx/restricted;

# as a totp authenticator program

If you want to leave a TOTP authentication display in your terminal, it can run like this:

    TOTP=metalisbest pwtool --totpfmt --loopdelay 1

It will then run and leave a display like this:

    202924 [#########################     ]

If you have multiple accounts, they can be displayed like this:

  TOTP="metalisbest;grungeisbest" pwtool --totpfmt --loopdelay 1

    617989 [##################            ]
    826783 [##################            ]

That doesn't show you the names, so you can include that with key=value strings:

    TOTP="key=metalisbest,name=metal;key=grungeisbest,name=grunge" pwtool --format "%{totpfmt} %{username}\n" --loopdelay 1

    488833 [#################             ] metal
    967495 [#################             ] grunge

The following key=value pairs are supported:

| key | definition |
|----------|--------|
| key / totp | the totp string | 
| name / username | a meaningful name for this key | 
| step | number of step seconds | 
| digits | the length of the output | 
| algo | which hmac to use (sha1, sha256, sha512) | 
| seconds | a user-defined time | 

