Failures happen at random points in the code when GNOME keyring is active but not accessible
I'd like to summarize some problems I've seen when using the keyring library to access the GNOME keyring in situations other than the standard "local desktop" situation.
These situations all have in common that the GNOME keyring is active (so keyring tries to use it instead of falling back to KWallet or a file on disk), but when it comes time to actually use the keyring, something goes wrong:
a) the keyring turns out to be inaccessible, causing an error.
b) the keyring claims it can't find a key, even though it didn't look (the keyring was never unlocked, so it couldn't have looked).
c) the keyring library crashes when trying to write a new key to the keyring.
d) the keyring hangs when it should be presenting a GUI for unlocking the keyring
I don't expect all these problems to be solved by new code in the keyring library. In fact, I'd be satisfied if we could figure out workarounds for all of these problems (I do have workarounds for the first two, which are the most common problems, and the third one, which is kind of a dumb mistake).
But, it would be nice if the keyring library had a consistent way of dealing with these situation: either deciding that the GNOME keyring wasn't available after all, and falling back, or raising an exception that an application could catch and use to advice the end-user which workaround to apply.
Let me apologize in advance for not describing these problems in a way that's easy to understand. I don't understand DBus very well. That said, it's pretty easy to duplicate the first three problems yourself and to use dbus-monitor to see what's going on behind the scenes.
Here are the problem scenarios I've discovered:
1. Start a GNOME desktop session, then 'ssh -X' in from another computer. The keyring library will try to access the GNOME keyring, but since it can't communicate over dbus, gnomekeyring.find_network_password_sync will fail with a gnomekeyring.IOError.
(The workaround is to activate DBus in the SSH session by running `export dbus-launch`.)
2. The same error occurs if you SSH in without setting up X forwarding. (The solution is to use ssh -X and `export dbus-launch`.)
3. If DBus is set up for a SSH session, but X forwarding is not, get_password() returns None rather than returning a key known to be in the keyring, and set_password() crashes with a keyring.backend.PasswordSetError.
Here's the DBus traffic for this case: http://paste.ubuntu.com/573649/
As you can see, the member=Completed event is sent out, even though I never get the GUI popup asking me to unlock the keyring.
4. When running in a chroot, set_password() sends a DBus event to prompt the user to unlock their keyring. Here's the DBus traffic for this case (interspersed with a little Python code):
Here's the interesting call:
method call sender=:1.3 -> dest=org.freedesktop.secrets serial=7 path=/org/freedesktop/secrets/prompt/p2; interface=org.freedesktop.Secret.Prompt; member=Prompt
This is supposed to trigger the GUI prompt to unlock the GNOME keyring. set_password() hangs after sending this event. The GUI prompt never shows up, even if $DISPLAY is set properly in the chroot.