Valid HTML 4.01 Transitional
Prev: Bootable USB Flash Drive Next: Avahi-daemon Loses Addresses
Jim Carter's Bugfixes

Gnome Keyring Daemon in Pentagram

James F. Carter

You would like to start Gnome Keyring Daemon from PAM so it can decrypt your login keyring, SSH private key, and possibly GPG key, using your authtok (login password). But whatever you do, it exits having done nothing, or worse, it holds up the login process for a 120 second timeout, then exits having done nothing.

Specifically, NetworkManager stores the password for the 802.11 wireless net in the login keyring. Finding no Gnome Keyring Daemon for the session, it starts its own, which asks (again) for the passord, which most likely didn't get changed the last time you changed your login password.

What's happening:

The daemon needs various resources which become available at various times and which need to be communicated to the daemon.

The interaction between these items is very neatly worked around in Gnome Keyring Daemon, and it may be obvious to the developers how to make it work, but I had to use my privilege in an open source project and read the source code, to figure it out.

How to fix:

Likely there are variations that will also work, but this design works for my use-case. I have a PAM stack specialized for doing a full console login, and the X-Windows display manager service scripts are linked to it. After a successful login, the display manager execs /etc/X11/xdm/Xsession which (after complications and customization hooks) execs a stack of service daemons, which have their various ways of exiting when the session leader exits (e.g. xfce4-session).

  1. In the auth stack: auth optional, without auto_start. This saves the authtok (login password) in PAM's secure storage area. We don't want to start the daemon yet because the user is not yet authenticated (and the daemon runs as user), and we don't even know what the home directory is, so it would botch decrypting the login keyring. In insecure cases where there is no login password, you may need use_authtok to head it off from asking for the non-available password.

  2. In the session stack: auth optional auto_start. Now we are sure of the user and we know the home directory. The daemon is always started with the --login --daemonize options. This means that it expects the password on stdin, which sends it, and it decrypts the login keyring but doesn't do any other initialization yet.

  3. In Xsession: You need to start the dbus daemon first. Then execute gnome-keyring-daemon --start. This means that it will locate the running daemon from environment variable GNOME_KEYRING_CONTROL (or start one if missing), then feed environmental data to it, specifically the DBUS_SESSION_BUS_ADDRESS and DISPLAY. The daemon will emit GPG_AGENT_INFO and SSH_AUTH_SOCK (unless suppressed) and these should be set into the session's environment.

    Here is the code I use (bash syntax):

    if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then
        command+=(/usr/bin/dbus-launch --exit-with-session)
    if test -n "$GNOME_KEYRING_CONTROL" ; then
        command+=(/bin/sh -c 'eval `/usr/bin/gnome-keyring-daemon --start` ; \
            export SSH_AUTH_SOCK GPG_AGENT_INFO ; exec "$@"' ARG0)
    command+=(${0%/*}/user.xsession "$@")
    exec "${command[@]}"

    Several features are omitted, specifically ck-launch-session, and gpg-agent and ssh-agent if gnome-keyring-agent is not going to provide that service. I could also provide a standalone Gnome Keyring Daemon if PAM failed to provide it, e.g. if we're coming from a PAM stack that is for other than a full console login.

    What is ARG0? When a Bourne shell does -c, non-option arguments are assigned to $0, $1… so if we want to exec the subsequent arguments, a dummy argument must be provided to go into $0 (and to not be used).

With these additions, Gnome Keyring Daemon starts up, decrypts the login keyring, and does the job of the SSH and GPG agents.

Prev: Bootable USB Flash Drive Next: Avahi-daemon Loses Addresses