| Crates.io | pwtool |
| lib.rs | pwtool |
| version | 0.12.0 |
| created_at | 2025-03-01 22:10:00.215267+00 |
| updated_at | 2025-12-27 19:13:28.481155+00 |
| description | pwtool, user account password tool |
| homepage | https://www.usenix.org.uk/content/pwtool.html |
| repository | https://gitlab.com/edneville/pwtool |
| max_upload_size | |
| id | 1574061 |
| size | 101,069 |
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).
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
lowercase, uppercase, numeric and extended will set requirements on the passwords.
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.
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"
--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.
KeePass DBs can be updated using --keepassdb and --keepassphrase/KEEPASSPHRASE. If the file does not exist, and the passphrase is not supplied the file will be created and new password written to output.
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 --createdatabase --mysqlfmt --number 1
create database thing; grant all privileges on thing.* to thingy@'%' identified with mysql_native_password as '*5d9d5f3aaf18e16ba7014f339697d841a736b133'; -- # epoEPMbATs
| variable | output |
|---|---|
| %{des} | traditional crypt |
| %{base32} | base32 of password |
| %{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} |
| %{wpinstfmt} | expands to wp core install --url=https://%{{servername}}/ --title=%{{servername}} --admin_email=%{{username}}@%{{servername}} --admin_user=%{{username}} --admin_password=%{{password}} --skip-email |
| %{wpuserfmt} | expands to update wp_users set user_pass = '%{bcrypt}' where user_login = '%{username}' |
| %{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 |
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.
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;
If you want to leave a TOTP authentication display in your terminal, it can run like this:
TOTP=metalisbest pwtool --totpfmt
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
617989 [################## ]
826783 [################## ]
This can be customised, to show a name aside each:
TOTP="key=metalisbest,name=metal;key=grungeisbest,name=grunge" pwtool --totpfmt
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 |
In some cases you might want to create a user, a DB and a WP and store the user account details in a DB called $USR.kdbx:
#!/bin/sh
PW=`pwtool --number 1 --createdatabase --database "$DB" --keepassdb "${USR}.kdbx" --username "$USR" --servername "$DOM" --userfmt --mysqlfmt --wpconfigfmt`
echo "$PW" | grep ^useradd | sh
echo "$PW" | grep ^create | mysql
CONF=`echo "$PW" | grep '^wp config'`
WPINST=`pwtool --number 1 --username "$USR" --keepassdb "${USR}.kdbx" --servername "$DOM" --wpinstfmt`
INST=`echo "$WPINST" | grep '^wp core'`
echo "mkdir public_html && cd public_html && wp core download && $CONF && $INST" | su - "$USR"
echo "$PW" | grep ^useradd
echo "$PW" | grep ^create
echo "$WPINST"
In a script, that can be called like so:
USR=fish DB=chips DOM=bigcookie.com KEEPASSPHRASE=wibble ./setup.sh
I've used a fixed passphrase, but there's nothing stopping that from being scripted too.