PrePAN

Sign in to PrePAN

Passwd::Keyring::* Secure password storage using OS APis

Good

Synopsis

use Passwd::Keyring::Auto;  # get_keyring

# Gets proper keyring for current environment
my $keyring = get_keyring(app=>"My super scraper", group=>"Social passwords");

my $username = "someuser";  # Or from argv, or from some config file, ...

my $password = $keyring->get_password($username, "mylostspace.com");
unless($password) {
        # ... somehow interactively prompt for password
        $keyring->set_password($username, $password, "mylostspace.com");
}
login_somewhere_using($username, $password);
if( password_was_wrong ) {
        $keyring->clear_password($username, "mylostspace.com");
}

Description

I started implementing in perl modules which provide secure storage for passwords applications/scripts/scrappers/whatever need to operate (I don't like clear password in ~/.pause for example...). The idea (borrowed from python keyring library) is to use appropriate operating system API's, like Gnome Keyring, KDE KWallet, OS/X Keychain, Windows Vault etc, to provide transparent save/restore for sensitive data without the need to harass the user (in most cases those storages either are open by desktop login, or open once per desktop session). I also aim to (as far as it is possible) make those passwords editable (and easy to identify) in interfaces like seahorse or KWallet.

I already implemented a few such APIs and look forward to adding more.

My questions:

a) I'd be grateful for review of current state of the code and documentation (there are a few modules but they are all fairly compact), especially the suggested API ( KeyringAPI ). Code is on CPAN and on bitbucket (visit Mekk@bitbucket and filter repositories list on the right using word "keyring", or just look at cpan )

b) I am looking for the best idea to enumerate "available backends" (so Passwd::Keyring::Auto can ask "what Passwd::Keyring backends are available"?). In Python I'd use some entrypoint. What is the best Perl approach to enumerate all installed modules that handle some API?

c) At the moment I use simple logic "if Passwd::Keyring::Something->new croaks/dies, then it is unavailable". Would it be better to use some specific exception classes? If so, what is the current fashion (aka which Exception modules should I use)?

d) I am Linux guy. Still, I wrote initial OS/X Keychain attempt, and hope to write initial Windows implementation, but I have no access to Mac, and problematic access to Windows. Is this a good place to look for somebody who could test code on such platforms?

e) Most cpantesters reports I get are from non-GUI environments. While I took some effort to fail/skip sensibly, this is not a main point of the library. Is there any way to find GUI-using testers (who actually have this Gnome/KDE/whichever session running while testing)? And is there any way to distinguish their reports from the rest?

f) I have practical POD problem: I wrote already mentioned document ( Passwd::Keyring::Auto::KeyringAPI ). I link this doc from a few places using L«Passwd::Keyring::Auto::KeyringAPI» and this link is leading nowhere, at least on search.cpan.org (see Passwd::Keyring::Gnome for example). What am I doing wrong?

g) I was granted namespace Passwd::Keyring. What should I do to make it possible for somebody else to publish Passwd::Keyring::BlahBlah in case such a person appears?

Comments

I will answer the easy question: f) CPAN does not index .pod files. It indexes only packages in .pm files and files in bin/. Just add a empty package in lib/Passwd/Keyring/Auto/KeyringAPI.pm (a package line and a true value) and your problem is solved.

Besides that, your Keyring API might be interesting for my github-keygen tool. I have to investigate how OpenSSH (or directly Git) can interact with system keyrings...
I don't know about Git, but for Mercurial I myself wrote so called mercurial_keyring extension which uses (pythonic) keyring library to avoid repeating password prompts. Core mercurial just prompts for password every time it needs one (or allows the user to save it plaintext in hgrc).

OpenSSH also interactively prompts for passphrases, but keeps unlocked keys (AFAIK keys, not passphrases) in ssh-agent (if present). One of the ideas I contemplate for keyring backend is to use GPG-encrypted file (here gpg-agent may keep master password), but the main point is to use native desktop solutions which are present on most popular systems, seamless to use (once you logged in, your gnome keyring is unlocked and you need not unlock it again, same for KWallet etc) and provide GUI for password review/management (so my script/app need not to reimplement this)...
> I don't like clear password in ~/.pause for example...

Me either. [My solution](http://prepan.org/module/429En4oFgc) looks more old-school, but could complement a library providing keyring-sourced passwords.

Would you consider using it? I'm quite expecting the answer no. 8-]

* b) There are modules to scan @INC for modules in a namespace. As I remember it can be slow, but that may be because I scanned a large tree over NFS. You'd want a subtree..?
* c) If the constructor dies then it is unavailable, yes.
* Maybe you can make some sense of the error in some cases, and make some rescue, but shouldn't the Passwd::Keyring::Foo be doing that already?
* You can still show the error to your user, for retry or bail out & run again later. Even cronjobs have to accept, sometimes that password is not there to be had (e.g. user not logged in just now).
* You could detect the difference between "backend doesn't work" and "the backend I used last time has just stopped working" with a config file, but I can't see this gives you much that "bail if we don't have a working backend" doesn't.

hth,
If I understand correctly, you are more about protecting password in memory while app is running. My main concern is at the moment to avoid plaintext password on disk. Once I achieve this there will be time to look further...
Exactly so. I was planning to take password from terminal.

Please sign up to post a review.