GNOME Bugzilla – Bug 547272
Find a good way to synchronize the environment of gnome-keyring-daemon and gnome-session
Last modified: 2008-11-14 16:26:37 UTC
Using 2.23.6-0ubuntu2 on ubuntu/intrepid, the ssh agent feature appears to be broken for me. However, this appears to be different than bug #544554 as I had this problem in 2.22.2 on intrepid as well. Please let me know what info you need. Thanks! Here the symptoms: asac@hector:~$ ssh senica -lalex Agent admitted failure to sign using the key. Permission denied (publickey). asac@hector:~$ echo $SSH_AUTH_SOCK /tmp/keyring-iKhxfK/ssh $ lsof -n | grep /tmp/keyring-iKhxfK/ssh gnome-key 11893 asac 13u unix 0xffff81002afb1600 78684 /tmp/keyring-iKhxfK/ssh gnome-key 11893 asac 21u unix 0xffff81007eeef9c0 38507 /tmp/keyring-iKhxfK/ssh
Do any messages show up in your auth.log? Could you post them into this ticket?
$ tail -f -n0 /var/log/auth.log Aug 25 11:41:20 hector gnome-keyring-daemon[11539]: missing dialog response from ask tool Aug 25 11:41:20 hector gnome-keyring-daemon[11539]: couldn't get private signing key
hi there, looks like I've been having the same problem: Aug 27 22:21:52 keitaro gnome-keyring-daemon[1532]: missing dialog response from ask tool Aug 27 22:21:52 keitaro gnome-keyring-daemon[1532]: couldn't get private signing key Aug 27 22:25:28 keitaro gnome-keyring-daemon[1926]: couldn't get private signing key and the cause of this is that when g-k-d is started automatically by pam stack, it doesn't work properly as a ssh agent anymore because it can't seem to display the dialog. I've disabled automatic unlocking on my box for now, but this is a major regression for me since I've been using this stuff since 2.18 :)
Could you post the shell environment of the gnome-keyring-daemon process, and the shell environment of an arbitrary gnome-terminal process? Use something like this replacing <PID> with the relevant PIDs. cat /proc/<PID>/environ | tr '\0' '\n' Thanks!
Created attachment 117768 [details] [review] Patch to gnome-session which may fix the problem Could you try this patch (to gnome-session) which might fix the problem you're experiencing?
sorry for not getting back with proper env info but the patch does indeed fix my problem.
and the env of gnome-keyring-daemon (with gnome-session patch) is : TMPDIR=/tmp/.private/eva TMP=/tmp/.private/eva HOME=/home/eva DISPLAY:=0 the one for of nautilus or gnome-terminal is a lot more crowded, has DISPLAY, GPG_AGENT_INFO, SSH_AUTH_SOCK, ...
Created attachment 117784 [details] [review] Updated patch with ChangeLog Okay to commit this patch?
Stef, don't we also need to set GNOME_KEYRING_SOCKET?
Well the daemon needs to be able to set a number of environment variables in gnome-keyring like: GNOME_KEYRING_SOCKET SSH_AUTH_SOCKET GPG_AGENT_INFO These are set via a g_setenv call from within the gnome_keyring_daemon_prepare_environment_sync(). Perhaps there's a better way to do all of this in the future. At this point this is just fixing a regression in the new gnome-session.
Stef: okay, so, the issue is that the gnome-keyring code in the gnome-session module is not running in the gnome-session program anymore, but in a small helper. So g_setenv won't help us at all. You could use the gnome-session Setenv dbus method. Or we should handle this another way.
Bummer, it would have been nice to know about this change earlier, as it affects a lot of stuff on different distros. But I'll try to work on it as it looks like we can't do without it. In any case the above patch still needs to be committed. As the daemon needs to get the environment from gnome-session (think DBUS, X related environment variables). Could you point me to the documentation for the Setenv dbus method? In particular I'd need to know how ownership and override behavior works.
I've committed the patch. See http://svn.gnome.org/svn/gnome-session/trunk/gnome-session/org.gnome.SessionManager.xml for documentation about the gnome-session dbus methods. I don't think there's any notion of ownership...
Ok, so a quick workaround would be to copy the environment variables before and after the call to gnome_keyring_daemon_prepare_environment_sync(), and then compare what's different.
Created attachment 117817 [details] [review] Untested patch Okay, this patch is untested, but it should synchronize the gnome-session environment to the one of the keyring wrapper process. This is of course assuming there's no clash between what the gnome-keyring daemon changes and what other processes might change in the environment.
Seems to be working, so I'm committing this. I'm keeping this bug open so we can decide on how to fix this the right way.
Thanks. Applying both patches on top of gnome-session 2.23.90-0ubuntu2 fixed this.
Vincent, I think what's required is that the gnome-keyring-daemon would need to use the Setenv Dbus call to setup it's variables with the startup environment directly, is that correct? Or is this considered an 'internal' Dbus API used by the compat wrapper programs and not robust enough to be used arbitarily by other daemons. The real bummer in all of this is that gnome-session still needs to help an already running gnome-keyring-daemon (when started by PAM) get onto its feet, by sending gkd the DBUS environment variable. It'd be awesome if we could find a better solution to all of this. I'm open to ideas from anyone who's been thinking about the Desktop session a lot. gnome-keyring sits at the junction of a lot of different technologies, and the environment variables are the only way to communicate with some of them.
I think we would be better off if g-k-d could loose its special status of 'started by pam before the session even exists' and become a regular session client. Of course, then you have trouble with unlocking the login keyring.
Stef: the Setenv dbus call can be used by gnome-keyring-daemon, I guess. But I wouldn't rush to do this for 2.24 since we have a working workaround now, and it's a bit late to change this for 2.24. So we should just take time to think on how to properly fix this for 2.26.
btw I guess this env sync problem is what's causing g-k-d to show me dialogs in english instead of my locale (in auto unlock setup).
Yeah, thats obviously another side-effect of running UI showing programs 'too early'.
(In reply to comment #18) > Vincent, I think what's required is that the gnome-keyring-daemon would need to > use the Setenv Dbus call to setup it's variables with the startup environment > directly, is that correct? Or is this considered an 'internal' Dbus API used by > the compat wrapper programs and not robust enough to be used arbitarily by > other daemons. The compat wrapper programs were only supposed to be temporary, until the actual applications get ported to use the new APIs themselves.
Stef, I think one way to approach the dbus-is-started-after-keyring-daemon problem would be to not start the keyring-daemon early. Instead start a smaller daemon that just holds on to the password and passes it along to the keyring-daemon once the keyring-daemon is started from within the session. The smaller daemon would have to pam_putenv its address so gnome-keyring could know how to contact it and it would have to be careful about checking peer credentials, etc.
Yes that's a good idea which I was considering as well. However the security implications of the dialog between the two daemons is what worries me. In the case of the PAM module starting gkd it's starting a process at a well known root owned path, and then sending the login password to it. However the above dialog would be harder to secure, whether you use pull or push. I haven't figured out a way to do it without the possibility that any of the user's desktop programs could get the login password. Checking socket peer credentials is so varied across OS's that basically the only thing we can rely on checking is the UID of a socket peer. Or am I missing something?
Programs can get the login password today *anyway* (any program connected to the X11 display can snoop keystrokes after all and any program can ptrace any other program and get access to it's internal data structures). We sort of implicitly assume that apps running in the user's session are trusted (SELinux muddies this a little, but that's orthogonal) Anyway the program could die as soon as the hand off happened.
*** Bug 548183 has been marked as a duplicate of this bug. ***
So the problem with starting g-k-d from pam is that we don't have the necessary environment set up, we are missing at a minimum LANG DISPLAY DBUS_SESSION_BUS_ADDRESS (looking in proc, I see only HOME in the environment of my pam-started g-k-d). So, we want to pass the login password from the pam module to some temporary daemon that would hold it until such a time that we can set up the necessary environment for a full-blown g-k-d. However, we don't want a 'random' process contact the temporary daemon and just ask for the login password. How about the following idea: The temporary daemon will not give out the login password to anybody but the hardcoded g-k-d (ie as current), but it will allow another process to tell it about the necessary environment that it should set up before starting g-k-d ? The other process that passes the environment to the temporary daemon could be the current session-helper, more or less.
well the temporary daemon doesn't need to start g-k-d. We let the session manager start it and then the right environment variables are already set. The only missing bit is how do we get gnome-keyring-daemon talking to the temporary daemon? One answer is to put the address of the temporary daemon in the environment with pam_putenv. We can make the temporary daemon only talk to the keyring daemon by checking the pid of the keyring daemon from peer credentials and then looking at /proc/the-pid/exe That's not an unreasonable thing to do, but it doesn't prevent other processes from ptracing to the temporary daemon. I don't think that's really a problem though. We pretty much have to assume the processes running in a users session as the user are trusted, since they have full access to the users data. Even all the secrets in the user's kernel keyring are fully accessible with /bin/keyctl. If malicious programs have invaded the user's session, the user's already lost.
(In reply to comment #28) > How about the following idea: > > The temporary daemon will not give out the login password to anybody but the > hardcoded g-k-d (ie as current), but it will allow another process to tell it > about the necessary environment that it should set up before starting g-k-d ? > The other process that passes the environment to the temporary daemon could be > the current session-helper, more or less. It would certainly work, but it's unclear what we would gain above the current situation. That is, whether gnome-keyring-daemon is started early and then gets the full environment, or a temporary daemon is started early gets the environment and starts the daemon. In either case the result and complexity is the same. There are certainly things we can do better in the current approach. For example I just committed a change which adds LANG to the list of environment variables that are imported into the daemon environment. In addition (although too late for 2.24) the following is something I was thinking about: * 'gnome-keyring-daemon --login' is run by PAM (as is currently the case). This accepts a login password on stdin, etc... * Have 'gnome-keyring-daemon --start' be run by both gnome-session and/or DBus autostart. If a gnome-keyring-daemon is already running (visible through environment) it connects to that daemon, and passes the environment over. * At the point when gnome-keyring-daemon receives a DBUS_XXX environment variable, it registers (via SetEnv DBus call) its environment variables with the session.
> It would certainly work, but it's unclear what we would gain above the current > situation. That is, whether gnome-keyring-daemon is started early and then gets > the full environment, or a temporary daemon is started early gets the > environment and starts the daemon. In either case the result and complexity is > the same. Pretty much, yeah. Your plan sounds like it will work. Although some things are not easy to inject later in the environment. E.g. LANG and DISPLAY should really be set before you call gtk_init. I wonder if LANG set correctly when the pam module starts the daemon.
gnome-keyring-daemon doesn't call gtk_init(). It uses a one or more helper programs for all UI. So that's not a worry.
I've done a bunch of work on this and committed the changes to gnome-keyring trunk. However things aren't working exactly as I imagined they would, and I'd like to ask for some advice or help (or pointers to such). Currently gnome-keyring-daemon subscribes to the SessionOver signal on org.gnome.SessionManager, however it never received the signal, and gnome-session complains about it 'not responding'. I'm not too familiar with DBus or the new session management APIs, so I hope I've gotten this right. http://svn.gnome.org/viewvc/gnome-keyring/trunk/daemon/gkr-daemon-dbus.c?revision=1369&view=markup Using org.gnome.SessionManager.RegisterClient to register in session. Dbus in the keyring daemon is only initialized once we receive the prerequisite environment variables.
Created attachment 122294 [details] [review] Patch to disable gnome-keyring compat wrapper This removes gnome-keyring-daemon-wrapper from gnome-session. Okay to commit?
(In reply to comment #33) > Currently gnome-keyring-daemon subscribes to the SessionOver signal on > org.gnome.SessionManager, however it never received the signal, and > gnome-session complains about it 'not responding'. > > I'm not too familiar with DBus or the new session management APIs, so I hope > I've gotten this right. I didn't write this, but as I understand it, when you call RegisterClient, gnome-session creates a client-specific interface for you to use after that, which it returns the dbus path to in the RegisterClient response. So then connect to that object's QueryEndSession signal, and respond by calling EndSessionResponse to tell it whether or not you can quit, and then when you get the EndSession signal, quit. You won't need to use the generic SessionOver signal. libegg/libegg/smclient/eggsmclient-dbus.c has sample code. (In reply to comment #34) > Created an attachment (id=122294) [edit] > Patch to disable gnome-keyring compat wrapper > > This removes gnome-keyring-daemon-wrapper from gnome-session. Okay to commit? Yes, please do.
(In reply to comment #35) > signal. libegg/libegg/smclient/eggsmclient-dbus.c has sample code. Of course, you could also just use EggSMClient and not worry about the details :-) You can build it with only the DBus backend if you want.
Cool thanks for the advice. The with EggSMClient is that, as far as I can tell it depends on X. gnome-keyring-daemon doesn't link to gtk+ or X. Although it spawns programs that do.
Committed. Dan, I see what you mean now... The Dbus backend isn't included in gnome-session and that's where I was looking at the EggSMClient code.
Yes, although the dbus backend still calls gdk_set_sm_client_id() (though you could rip that out in a local copy). I need to figure out a better story in terms of dependencies.
Committed code with correct session management behavior to gnome-keyring. 2008-11-14 Stef Walter <stef@memberwebs.com> * daemon/gkr-daemon-dbus.c: Register and unregister with the session properly using correct interfaces and signals. See bug #547272 I ended up implementing this as low-level DBus calls. A while back a gnome-keyring dependency on dbus-glib was vetoed due to no API stability guarantees. Although perhaps things have changed in the meantime.