Introduction
pwdb is a command-line-based password manager, designed to work well when the password database is stored in a version control system.
In order to do this, it stores each account's details in a separate file. Other password managers tend to store everything in a single encrypted database file; if you add two different accounts from two different machines, then the resulting commits will conflict on a binary file, requiring some level of manual work to merge them!
Other interesting features include:
- Accounts have an arbitrary number of key=value fields, to support things like credit cards as well as traditional username/password accounts.
- Any of those fields may be marked as "obscured", meaning pwdb never displays them onscreen unless you force it to.
- Highly scriptable.
- Support for generating new accounts from configurable templates.
- Support for arbitrarily nested encryption, requiring extra authentication to access more sensitive accounts' details.
Getting Started
Install pwdb by installing Chicken Scheme, then running:
chicken-install pwdb
Go to the directory where you'll store your password files.
Set up a basic template:
echo '(account (url "FIXME") (username "FIXME") (password ,(make-passphrase) obscured))' | pwdb -n TEMPLATE.pwdb
You'll be prompted for a new passphrase; enter it twice. This will be used to encrypt all your accounts (by default), because it's used to encrypt the template.
Now create a new account from that template:
pwdb -ne Amazon.pwdb TEMPLATE.pwdb
You'll be prompted for the passphrase to decrypt the template, then an editor (your choice in $EDITOR) will pop up with the template for you to edit (with a random passphrase generated for you). When you save it, the same passphrase you used to decrypt the template will be used to encrypt the new account file.
To look at an account, do this:
pwdb Amazon.pwdb
You'll see that anything marked "obscured" isn't displayed (unless you add the -a flag to the command line).
You can pull out a specific field, which is handy in scripts:
pwdb Amazon.pwdb url
If you specify -a, you can even pull out obscured fields. A good trick is:
pwdb -a Amazon.pwdb password | xclip
If you've installed xclip, that will put your Amazon password in your X selection buffer, so a middle-click in that password box will paste it for you. However, it'll be left in the selection buffer afterwards, so a better idea is;
pwdb -i xclip Amazon.pwdb
That will list the un-obscured fields, and then prompt you for a number. If you enter the number of the password field, it will pipe the password into xclip for you to paste. But when you enter q to quit interactive mode, it'll clear the selection buffer for you by feeding an empty string to xclip.
If you want to edit an account:
pwdb -e Amazon.pwdb
That won't show you the contents of obscured fields, but you can add, remove, or change obscured fields - any field left as <obscured> will just pick up the value it had originally; if you replace <obscured> with "Secret Password" then the obscured field will be changed!
Or you can do:
pwdb -ea Amazon.pwdb
...to edit the entire account, obscured fields and all.
Multi-layer encryption
Let's make a template for bank cards, which requires an additional passphrase for extra security. Don't think of that in terms of "more encryption is harder to brute-force"; think of it in terms of "the passphrase you enter a few times a day to get into social networking web-sites isn't enough to also get your credit card numbers".
echo '(account (card-number "FIXME") (expiry "FIXME") (cvv "FIXME" obscured) (pin "FIXME" obscured))' | pwdb -n BANK-CARDS-TEMPLATE.pwdb cards
Note that as well as changing the template layout, we've added an extra argument to pwdb -n: "cards". This is a tag we have chosen to name the extra passphrase.
When creating the template account, pwdb will now ask us for the usual passphrase, and also a passphrase "for cards". Use something different for this one!
The storage format for pwdb files is always encrypted by the "general" passphrase, but if additional passphrases are used, then they are layered; only after undoing the outer "general" encryption will pwdb even know that the contents are further encrypted, and with what passphrase. So when you use that template, you will be prompted for the normal passphrase, then you'll be prompted for the passphrase "for cards"; only when both are entered correctly will pwdb be able to read the actual template within; and that encryption setup is inherited by accounts created from this template.
Templates
Templates aren't special - they're just pwdb files like any other, and you can use any pwdb file as a template to create another. However, when a template is used to create a new pwdb file, some special field values cause the random generation of passwords and passphrases:
,(make-passphrase)
...creates a passphrase from four random Lojban gismu words.
,(make-password LEN)
...creates a random password of LEN random characters, chosen from a hardcoded reasonable set (avoiding easy-to-confuse symbols such as 0OoIl).
Scripting
pwdb won't prompt for a passphrase if it finds it in the environment. Set the environment variable PWDB to your passphrase, and PWDB_..tag... (eg, PWDB_cards) for a multi-layer encryption tag passphrase, to avoid being prompted for them. This is handy when scripting bulk operations over all your accounts, but be careful of who else is running code on your machine, as they may be able to access values stored in environment variables.
Command Reference
pwdb -p
Generates a random passphrase, and prints it out.
pwdb -n NEW-FILENAME TAGS...
Creates a new pwdb file from an account sexpression on standard input. If TAGS... are given, then they're the passphrase-tags for extra layers of encryption, from outermost to innermost.
pwdb -ne NEW-FILENAME TEMPLATE-FILENAME
Reads a file to use as a template, expands any ,(...) commands in it, asks the user to edit it with $EDITOR, then saves it to the new filename (with the same encryption keys as the template).
pwdb -a FILENAME
Displays the account on stdout; unless -a is specified, fields marked as obscured will have their values obscured.
pwdb -a FILENAME FIELD...
Dumps the values of the named fields to stdout, one per line; unless -a is specified, fields marked as obscured will have their values obscured.
pwdb -e -a FILENAME
Opens up the specified account in $EDITOR; unless -a is specified, fields marked as obscured will have their values obscured in the editable text, and any obscured fields in the saved text will have their values filled in from the same-named fields in the original account data. This means that if you deleted obscured fields, or add new ones or edit existing ones to have values, those values will be saved to the new account.
pwdb -i CLIP-COMMAND FILENAME
Opens up the specified account and enters interactive mode. A list of the fields of the account gets printed out, prefixed by numbers, with obscured field values hidden. The user is then prompted to enter a number; if they do so, then the value of that field (even if obscured) is piped into the CLIP-COMMAND (xclip works great for this). The user may also enter quit to quit, help for some help, or reveal NUMBER to print out the value of the numbered field (even if it's obscured).
Account sexpr format
An account is stored like so:
(account (KEY "VALUE" OPTIONS...)...)
Options can either be a bare symbol, or a property of the form (KEY "VALUE").
The only supported option at this time is obscured, which marks the field so that its value is not displayed by default.
Bugs
- Doesn't use a proper key derivation function; the key is just based on the SHA hash of the passphrase entered, which makes it easier to brute-force.
- Doesn't make any effort to prevent plaintext or keys from being swapped out to disk.
- No easy way to re-encrypt a file to change the passphrase (but it can be easily added).
- Not enough configurability for password/passphrase generation.
- sexpr format exposed by -e (edit) and -n (create new) commands is ugly when formatted all onto one line by pp.
- When dumping specified named fields to stdout, any that are missing in the account will just be skipped, and a script has no way of knowing which one(s) were skipped.
Release history
- 1.3: Added 'web' command to interactive mode to fire up a web browser from a stored URL, 'edit'/'editall' commands in interactive mode to edit the account, and made pwdb ask again if you get a passphrase wrong rather than quitting.
- 1.2: Fix broken edit mode (I need to write a test suite!), "reveal" command and help in interactive mode.
- 1.1: Fix broken release metadata
- 1.0: Initial release