Python Protected Password Store server application
Do you want to store and share passwords? With pstore you store the encrypted passwords on a remote server. All encryption is done locally by the command line interface, so the server never sees your unencrypted passwords.
pstore allows you to store and retrieve passwords and other sensitive data in a safe manner. The permission system allows you to share these secrets with others on the same pstore server.
For passwords and other secret items, you encrypt them on the client side automatically with the pstore client. This way the pstore server never has any knowledge of the secret content, and your data is secure (*) even when the server is breached.
Encryption is done using GPG. One of the admins installs your public key on the pstore server. After that you’re ready to go.
(*) Security of course depends on everyone using strong secret keys and everyone keeping them private.
You have set your .pstorerc:
$ cat ~/.pstorerc --store-url=https://my.pstore.server/
List all machines that contain example in the name:
$ pstore example Machine User access ------------------------------------------------------------------------ + new.example.com joe, walter + walter.example.com walter
List machine password for walter.example.com:
$ pstore walter.example.com ip-address = 22.214.171.124 password = wAlTeR!
Add a new machine password, also accessible for joe:
$ pstore -c walter2.example.com +joe Type new machine password: Type new machine password again: $ pstore example Machine User access ------------------------------------------------------------------------ + new.example.com joe, walter + walter.example.com walter + walter2.example.com joe, walter $ pstore walter2.example.com password = abc
Add a public (unencrypted) and shared (encrypted) property to the new machine:
$ printf walter2 | pstore walter2.example.com -ps ssh-username $ cat ssl-cert.key | pstore walter2.example.com -pe ssl-cert.key $ pstore walter2.example.com ssh-username = walter2 ssl-cert.key = (1533 byte encrypted) password = abc
See the contrib directory for bash completion scripts and a dirty hack to supply the password to the ssh client automatically.
Installing the pstore client is a matter of running pip install ./pstore-<version>.tar.gz. This will install the necessary requirements and install the pstore binary in your path.
Installing the pstore server is a little bit more work:
Set up users and keys:
If you used the supplied pstore/settings.py you’ll surf to localhost:8000 (or where the site is running). Supply your admin credentials.
Go to Auth -> Users. Add users as appropriate.
Go to Pstore -> Public keys. Add a single public key for every user that should be using the system. A GPG public key can be extracted from your keyring using gpg --export --armor firstname.lastname@example.org. The key value should look something like this. The description is for human consumption only.
-----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.11 (GNU/Linux) | mI0EULkssgEEAKeoPrMO5CHxoO8/KTXLA1FP2IQr4n3Og+DvsziIZ6vdcDmhtcsx ... AK968N1Yrw+ytDuus3s7xPXYAw== =TEm/ -----END PGP PUBLIC KEY BLOCK-----
If you have good reasons, you can go old style and use the SSH public key here, like this:
ssh-rsa AAAAq2qMaC2...fBPcPsqMcwqsMHnBCzA= myname@myserver
Using GPG is preferred however.
Set up the client:
You’re ready to go. Call the pstore client with --help and --help --verbose for more help and tips.
sudo pip install ./pstore-<version>.tar.gz sudo pip install ./django-pstore-<version>.tar.gz
For the client you’ll only need the first package.
Make sure you have a C compiler (gcc) and python development headers.
sudo apt-get install build-essential sudo apt-get install python-dev
Or you could install the dependencies manually.
# for the client and server sudo apt-get install python-gpgme python-pyasn1 python-crypto # for the server sudo apt-get install python-django python-mysqldb
pygpgme requires the libgpgme development headers.
sudo apt-get install libgpgme11-dev
Make sure you install the pstore package before installing django-pstore. This shouldn’t be necessary anymore, as we’ve uploaded that package to PyPI.
Uninstalling the client package is done using pip:
sudo pip uninstall pstore
You may need to rm /usr/local/bin/pstore manually.
For the server, you’ll probably need to do more than just uninstalling django-pstore. After all, you put the app in a Django project and you created a database for it.
Note that dependencies like Django, pyasn1, pycrypto, pygpgme, aren’t uninstalled automatically.
When running ./bin/pstore when developing, you’ll need to tell it where the packages are:
To make the application usable, decryption passphrase information has to be cached. Preferably, this is done using some kind of password agent like gpg-agent. If such an agent is unavailable, we cache the password in cleartext in memory for the duration of the pstore command.
The NOTICE is there to remind you that it is not as safe as it could be.
Your graphical desktop environment generally starts a password caching daemon. That could be seahorse-agent or gpg-agent or something else.
I couldn’t find a way to reliably clear the seahorse-agent password cache. I only found reliable ways to kill it by accident (on Ubuntu 10.04).
The gpg-agent (gnupg-agent package) seemed more stable. (Log out and in after install.) Making it forget your cached passphrase is a matter of sending it a SIGHUP.
pkill -HUP gpg-agent
(If you’re now wondering, like me, who then caches your decrypted private ssh key: it’s the ssh-agent, even though it’s the gnome-keyring who asked for the password. Clearing the ssh-agent cache is a matter of doing “ssh-add -D“.)
You’re probably trying to set a larger property on an object where an sshrsa user has permissions. Either convert all users to use GPG or upload the large property as public (unencrypted!) property.
When running the integration test, you could see something like this:
* Large file support (adding large public file): backend error: could not connect to http://127.0.0.1:8000 FAIL: could not write large unencrypted file > NOTICE: not encrypting the value
This is likely caused by apparmor(1) on the mysqld. We need read/write permissions in /tmp.
Further, you may need to increase the max_allowed_packet to something higher than 16MB if you want to store larger files.