GNOME Bugzilla – Bug 738205
gnome-keyring doesn't unlock ssh keys under Wayland
Last modified: 2018-09-21 13:21:02 UTC
If I log in to a gnome-wayland session and start an ssh connection from gnome-terminal I'm asked for my passphrase. Fedora 21 root@latidude ~]# dnf info gnome-keyring Installed Packages Name : gnome-keyring Arch : x86_64 Epoch : 0 Version : 3.14.0 Release : 1.fc21 Size : 4.1 M
Same here, i first posted bits on old https://bugzilla.gnome.org/show_bug.cgi?id=662528, but it appears the issue does not raise on GNOME (X) session $ gnome-keyring-daemon -V gnome-keyring-daemon: 3.14.0 testing: enabled $ ssh-add -L Could not open a connection to your authentication agent. $ ps -aux | grep keyring buddho 1661 0.0 0.2 536484 8004 ? Sl 15:57 0:00 /usr/bin/gnome-keyring-daemon --daemonize --login $ dbus-send --session --dest=org.gnome.keyring --print-reply /org/gnome/keyring/daemon org.gnome.keyring.Daemon.GetEnvironment method return sender=:1.29 -> dest=:1.123 reply_serial=2 array [ dict entry( string "GPG_AGENT_INFO" string "/run/user/1000/keyring/gpg:0:1" ) dict entry( string "SSH_AUTH_SOCK" string "/run/user/1000/keyring/ssh" ) ] in case this helps: $ echo $SSH_AUTH_SOCK (i mean this is empty)
For me: gnome-keyring-daemon does actually start (appears in ps) Environment variables under X: GPG_AGENT_INFO=/run/user/1000/keyring/gpg:0:1 SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass SSH_AUTH_SOCK=/run/user/1000/keyring/ssh Environment variables under Wayland: SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass If I set the variables manually (they are static across logins -- no PID), ssh uses gnome-keyring / mutter to ask for a password. It's not necessary to start gnome-keyring-daemon, it's just necessary to export the shell variables. I've added to my ~/.bashrc: if [ -n "${WAYLAND_DISPLAY}" ] && \ [ ! -n "${SSH_AUTH_SOCK}" ] && \ [ -r "/run/user/${ID}/keyring/ssh" ]; then export SSH_AUTH_SOCK="/run/user/${ID}/keyring/ssh" fi if [ -n "${WAYLAND_DISPLAY}" ] && \ [ ! -n "${GPG_AGENT_INFO}" ] && \ [ -r "/run/user/${ID}/keyring/gpg" ]; then export GPG_AGENT_INFO="/run/user/${ID}/keyring/gpg:0:1" fi
I'm also seeing this. Is this a gnome-keyring-daemon issue, or maybe just a packaging issue in Fedora? If it has to do with which variables are available and/or which commands are run with the session startup, it might be an issue with distro-specific scripts.
Under fedora: /usr/share/xsessions/gnome.desktop: exec=gnome-session /usr/share/wayland-sessions/gnome-wayland.desktop: exec=gnome-session --session=gnome-wayland Digging further: /usr/share/gnome-session/sessions/gnome.session: RequiredComponents=gnome-shell;gnome-settings-daemon; /usr/share/gnome-session/sessions/gnome-wayland.session: RequiredComponents=gnome-shell-wayland;gnome-settings-daemon; /usr/share/applications/gnome-shell.desktop: Exec=/usr/bin/gnome-shell X-GNOME-Autostart-Phase=WindowManager /usr/share/application/gnome-shell-wayland.desktop: Exec=/usr/bin/gnome-shell --wayland --display-server X-GNOME-Autostart-Phase=DisplayServer /proc/[gnome-shell-pid]/environ confirms that gnome-shell has all the variables under X. /proc/[gnome-session-pid]/environ does not have the variables under X, so I assume gnome-session loads them to start gnome-shell with them set. ppid(gnome-shell) == pid(gnome-session). gnome-shell(1) lists neither --wayland nor --display-server as an option. gnome-keyring-daemon's parent is pid 1, so that doesn't immediately help me. gnome-shell appears to want to look for gnome-keyring according to /usr/lib64/libgnome-shell.so; but I haven't looked at the source yet. If gnome-shell crashes, it leaves a stray gnome-keyring-daemon laying around.
I have also workedaround this on Fedora 22, but would be interested in a proper fix. Any input on how session environment are supposed to work ?
@halfline - guessing this is due to not running Xsession, and/or part of the great environment variable purge, right?
so in a non wayland session we start gnome-shell in the Window Manager phase of start up and we start gnome-keyring in the Initialization phase. in a wayland session we start gnome-shell in the Display Server. The order is Display Server -> Initialization -> Window Manager gnome-keyring pushes its environment into gnome-session during the Initialization phase. Since gnome-shell is started before that, now, it doesn't get the updated environment. It's basically more of the same tragedy that is environment variables. gnome-shell could ask gnome-keyring for its environment before launching any programs, or we could hardcode the variable in gnome-session, or pam_gnome_keyring could set it up front or we could fix ssh to not require the environment variable and use a well known name in XDG_RUNTIME_DIR . Not sure what the right fix is.
probably, I guess, gnome-shell should reimport it's environment from gnome-session following the Initialization phase, since the gnome-session SetEnv call only works for programs started in the Initialization phase
so i think the best approach is to manage the environment centrally and resync it before launching applications. i'll attach a couple of patches to do that.
Created attachment 311515 [details] [review] gsm-util: save environment to $XDG_RUNTIME_DIR/gnome/environment Environment variables are problematic because they require a parent child inheritance model, but they're often used in a per-session scope. gnome-session provides a mechanism for children to affect the environment of future siblings via the SetEnv dbus method call. Unfortunately that change does not affect existing siblings, or their offspring. This commit centralizes gnome-session's environment into a file, $XDG_RUNTIME_DIR/gnome/environment so other components in the session can ensure their children get the most up to date environment possible.
Created attachment 311516 [details] [review] shell-global: import environment from $XDG_RUNTIME_DIR/gnome/environment environment variables are normally propagated from parent to child, but they're used to convey information that's typically scoped to the session. gnome-shell needs to know about environment variables that are set in the session after it's already been started. gnome-session now exports its environment to $XDG_RUNTIME_DIR/gnome/environment so that programs in the session can pick up on the latest environment variables. This commit changes gnome-shell to propagate the gnome-session's latest environment when launching new children.
Comment on attachment 311515 [details] [review] gsm-util: save environment to $XDG_RUNTIME_DIR/gnome/environment Attachment 311515 [details] pushed as db7ce81 - gsm-util: save environment to $XDG_RUNTIME_DIR/gnome/environment
Aren't you leaking the output of g_get_environ in the gsm-util patch?
yup, thanks!
(In reply to Ray Strode [halfline] from comment #10) > Created attachment 311515 [details] [review] [review] > gsm-util: save environment to $XDG_RUNTIME_DIR/gnome/environment > > Environment variables are problematic because they require a parent > child inheritance model, but they're often used in a per-session scope. > > gnome-session provides a mechanism for children to affect the > environment of future siblings via the SetEnv dbus method call. > Unfortunately that change does not affect existing siblings, or their > offspring. > > This commit centralizes gnome-session's environment into a file, > > $XDG_RUNTIME_DIR/gnome/environment > > so other components in the session can ensure their children get the > most up to date environment possible. Eek. gnome-keyring already has a way to export its information, which gnome-settings-daemon uses to pass down to the application it launches: https://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/media-keys/gsd-media-keys-manager.c#n231
i know that, I actually alluded to it in comment 7, but that's not as complete a solution, and it wouldn't be any less code. I think having a global place to store environment variables makes more sense, honestly.
Created attachment 311548 [details] [review] gsm-util: fix leak in new gsm_util_save_environment function gsm_util_save_environment calls g_get_environ() without calling g_strfreev() on the result. This commit addresses the problem by using the environ external variable, directly, instead, and avoiding the allocation altogether.
Comment on attachment 311548 [details] [review] gsm-util: fix leak in new gsm_util_save_environment function (we're in code freeze now, so this will have to wait, I guess)
(In reply to Ray Strode [halfline] from comment #16) > i know that, I actually alluded to it in comment 7, but that's not as > complete a solution, and it wouldn't be any less code. > > I think having a global place to store environment variables makes more > sense, honestly. I don't think it's particularly clean to dump the envp variable in a format that needs further parsing (an array of string pairs would have reduced the work on the shell side), and I don't understand where gnome-shell (not the apps launched by gnome-shell) will get the env either.
(In reply to Bastien Nocera from comment #19) > I don't think it's particularly clean to dump the envp variable in a format > that needs further parsing It's not that messy. we're talking about g_strsplit ... but it's not too late to change the variant format to aayay or whatever if that really bothers you. > and I don't understand where gnome-shell (not the > apps launched by gnome-shell) will get the env either. if gnome-shell needed the updated environment for itself specifically, it could putenv/setenv() the results before it needed them, but I don't think that's necessary and doing setenv in the middle of a multithreaded program is always iffy since getenv() isn't thread safe.
Comment on attachment 311548 [details] [review] gsm-util: fix leak in new gsm_util_save_environment function Attachment 311548 [details] pushed as a50a182 - gsm-util: fix leak in new gsm_util_save_environment function (but will still investigate doing a more structured gvariant patch later)
I don't understand why we're patching gnome-shell. This won't work for DBus activated applications, nor for other session components, will it?
gnome-session already updates the bus activation environment when another component calls SetEnv. This issue arises because gnome-shell is started first now, before the SetEnv calls happen, so things started directly from the shell won't have the right environment.
( I think other session components should probably do the same thing, too, or maybe it should be in GdkApplicationLaunchContext )
(In reply to Ray Strode [halfline] from comment #24) > ( I think other session components should probably do the same thing, too, > or maybe it should be in GdkApplicationLaunchContext ) If it makes any difference, audio is also not working under Wayland on my system. Is that likely a similar and/or the same problem?
(In reply to Ray Strode [halfline] from comment #23) > gnome-session already updates the bus activation environment when another > component calls SetEnv. This issue arises because gnome-shell is started > first now, before the SetEnv calls happen, so things started directly from > the shell won't have the right environment. In practice, this is still racy, and can end up with early started daemons that miss the right environment variables. Indeed, on my system right now I can verify that goa-daemon, goa-identity-services, evolution-source-registry and gnome-shell-calendar-service (all started by gnome-shell early at startup) lack the right env vars, while other dbus activated daemons have them. Worse than that, gvfsd does not have a DISPLAY or WAYLAND_DISPLAY at all, because they are started implicitly by gio when gnome-session touches it. And just to mess everything up, gnome-terminal does its own environment handling, pushing the environment from the gnome-terminal command to the dbus activated gnome-terminal-server. So UpdateActivationEnvironment calls have no effect if the shell or the media-keys plugin do not spawn gnome-terminal with the right vars. (which by the way explains why .profile was kind of working on x11, even though the dbus-daemon is not started under it) All in all, this shows that environment variables are significantly broken, but if we are to continue supporting them, we must do so with consistent ordered initialization, not just patching them here and there.
The thing to remember is we don't need every process started early in start up to have every environment variable that gets set later in start up. If we needed that, we'd be sunk, because we can't know all the variable values a priori. Also, it's not just a case of things getting started in the wrong order. There isn't a directed graph of processes you can start to get things right. for instance, gnome-shell has to start first, but at the end of login, all processes started by gnome-shell have to have all the environment variables. But, we know what components we're starting, and we know what environment variables they need set during initialization, so that's a contained, manageable problem. What can happen though, after startup, is that some of those processes can spawn arbitrary children. That's where the unknown comes into play, and there's where having a complete view of the final environment is important. We need to make sure that processes started after the Initialization phase finishes use the latest gnome-session environment. that includes processes started by dbus-daemon, processes started by gnome-shell, processes started by gnome-settings-daemon, and of course processes started by gnome-session itself. So we need a central place to track the environment, that processes can reference and use when starting children (thus $XDG_RUNTIME_DIR/gnome/environment ).
(In reply to Ray Strode [halfline] from comment #27) <snip> > What can happen though, after startup, is that some of those processes can > spawn arbitrary children. That's where the unknown comes into play, and > there's where having a complete view of the final environment is important. > We need to make sure that processes started after the Initialization phase > finishes use the latest gnome-session environment. that includes processes > started by dbus-daemon, processes started by gnome-shell, processes started > by gnome-settings-daemon, and of course processes started by gnome-session > itself. FWIW, gnome-settings-daemon already does a very small portion of that, already dealing with the gnome-keyring problem: https://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/media-keys/gsd-media-keys-manager.c#n231 But, as you mentioned looking at the problem as a whole, which daemons do we have that would rely on this functionality? goa, gsd, gnome-shell itself, gvfs, e-d-s, all to access gnome-keyring. Maybe xdg-user-dirs needs to run in a way before some other daemons. Is that it?
Ray, I absolutely agree with you that the problem is only manageable if we know what processes start, and what components set what variables. So let's be concrete here. The interesting environment variables (ie, the ones that get set later from various components) in question are: - DBUS_SESSION_BUS_ADDRESS - DISPLAY/WAYLAND_DISPLAY - SSH_AUTH_SOCK - the LC_* family (and QT_IM_MODULE/XMODIFIERS) - XDG_SESSION_DESKOP/XDG_CURRENT_DESKTOP/XDG_MENU_PREFIX Everything needs DBUS_SESSION_BUS_ADDRESS, starting with gnome-session, so the dbus-daemon needs to be started first. gnome-session does not need DISPLAY or WAYLAND_DISPLAY. It might need LC_* for error messages, but it's not a big deal. It does not need SSH_AUTH_SOCK. gnome-keyring currently sends DISPLAY for whatever reason, but it does not need it (it does not link to gtk or libX11). It obviously does not need SSH_AUTH_SOCK, and it also does not need LC_* anything. gnome-settings-daemon needs DISPLAY. A settings-daemon without x11 would be nice, but we're not quite there yet. It does not need SSH_AUTH_SOCK, but it needs the XDG stuff and the LC_*. gnome-shell needs the XDG stuff and the LC_* (especially LC_TIME), but not SSH_AUTH_SOCK. gvfs does not need DISPLAY, but it needs all the others. It needs SSH_AUTH_SOCK for sftp, it needs LC_* for dialogs, and it needs the XDG stuff to pick the proxy implementation. goa only needs the LC_* stuff really (but it practice it helps if it runs after gnome-keyring because it wants to talk to the keyring over dbus) gnome-shell-calendar-server/evolution-data-server needs the LC_* stuff and that's it dconf-writer needs nothing. Other dbus activated processes, or other apps directly started by the shell or settings-daemon, need all the variables. How do we solve this? Well, how about: - gdm-wayland-session starts dbus-daemon, no changes there - gnome-session, before doing anything else, takes the LC_* variables from GSettings and sets them (if applicable), then reexecs itself - gnome-session sets the XDG stuff to itself and dbus - gnome-session will set gio to only use the local vfs (and thus not start gvfs at all) - gnome-session runs xdg autostart apps in EarlyInitialization phase (gnome-initial-setup-copy-worker) These apps run will have nothing but the bus address and locale in the environment (+ PATH/HOME/LOGNAME/HOSTNAME/etc.) xdg-user-dirs is moved here - gnome-session runs xdg autostart apps in a new phase, let's call it PreDisplayServer gnome-keyring is put here, it will send out SSH_AUTH_SOCK to gnome-session and dbus Hopefully, nothing has been started by now except maybe dconf-writer - gnome-session runs xdg autostart apps in DisplayServer phase in wayland, this is gnome-shell-wayland, that sets out DISPLAY/WAYLAND_DISPLAY when gnome-shell is ready, _all the environment variables are stable_ - gnome-session runs xdg autostart apps in Initialization phase on my system a lot of stuff falls here (spice-vdagent, gsettings-data-convert, seahorse-sharing, at-spi-dbus-bus, orca-autostart, pulseaudio), but none of it needs to set env vars - not even gnome-settings-daemon after we gut the LC_* from it - gnome-session runs WindowManager/Panel/Application stuff (we should probably gut this from GNOME 3, or at least merge WindowManager and Panel) - gnome-shell runs applications - dbus-activated services get started - profit At no point we need gnome/environment, at no point we have races. Does this make sense? Should we start filing bugs left and right to move to this world?
I filed bug 756324 as RFC with the gnome-session changes needed to implement this, and somehow it seems cleaner to me than all the hacks that emerged over the years, or this gnome/environment binary blob, but let's keep the discussion here.
okay so my understanding was there wasn't a directed graph of dependencies that would work. It seems like you've looked into it more in-depth than me and discovered there is a way to make it work. It is clear that the reordering processes outlined above is more in line with the parent->child inheritance model of environment variables as they're currently designed. I think the model is fundamentally a bad fit for sessions which have lots of sibling processes, but it's a problem that's slowly vanishing anyway as we reduce our dependencies on environment variables. Reordering everything is a no-go for 3.18. Let's do this: 1) add a shortterm hack for keyring in particular for 3.18.1 2) look into reordering things for 3.20
Created attachment 313273 [details] [review] main: set SSH_AUTH_SOCK explicitly in wayland sessions Until we can get a more complete environment variable propagation story figured, implement a quick hack for the most pressing one, SSH_AUTH_SOCK.
Comment on attachment 313273 [details] [review] main: set SSH_AUTH_SOCK explicitly in wayland sessions Attachment 313273 [details] pushed as a8896cc - main: set SSH_AUTH_SOCK explicitly in wayland sessions
Hi, FYI, I think this problem happens also with xorg and not wayland, we would be in need of a fix if possible before 3.20 :) What happens here is that only *sometimes* the variables set by gnome-keyring are made available in gnome-shell. Sometimes it works, and sometimes not. This has been discussed by multiple people on Archlinux here: https://bugs.archlinux.org/task/44583 In the logs, there is the following message: oct. 28 09:32:58 jamon gnome-keyring-daemon[831]: couldn't register in session: The name org.gnome.SessionManager was not provided by any .service files oct. 28 09:32:58 jamon gnome-session[842]: SSH_AUTH_SOCK=/run/user/1000/keyring/ssh oct. 28 09:32:58 jamon gnome-session[842]: SSH_AUTH_SOCK=/run/user/1000/keyring/ssh oct. 28 09:32:58 jamon gnome-session[842]: GPG_AGENT_INFO=/run/user/1000/keyring/gpg:0:1 But then the variables are not there… and sometimes, I'm not sure why, they are… I hope it's the right place to report this, or do you prefer I open another issue? Thanks :)
I observe the same symptoms running X session: $ rpm -qf `which gnome-keyring-daemon` gnome-keyring-3.18.3-1.fc24.x86_64
this got taken care of in bug 756324
Hi, I'm using Gnome 3.20 with Xorg on Debian Stretch (gnome-keyring 3.20.0) and I'm occasionally still seeing this problem (Debian bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=804703 ): $ echo $SSH_AUTH_SOCK /tmp/ssh-3ymBpl68cNYk/agent.2019 $ dbus-send --session --dest=org.gnome.keyring --print-reply /org/gnome/keyring/daemon org.gnome.keyring.Daemon.GetEnvironment method return time=1505550164.345498 sender=:1.25 -> destination=:1.636 serial=10249 reply_serial=2 array [ dict entry( string "SSH_AUTH_SOCK" string "/run/user/1000/keyring/ssh" ) ] $ ps aux | grep gnome-keyring luca 2000 0.3 0.0 299844 21224 ? SLl 08:37 0:09 /usr/bin/gnome-keyring-daemon --daemonize --login $ ssh-add -L The agent has no identities. $ SSH_AUTH_SOCK=/run/user/1000/keyring/ssh ssh-add -L ssh-rsa AAAAB3 <cut>
Hi, I am using Gnome 3.28.2 on Fedora 28 and this is affecting me more than intermittently. With exactly the same results as, Luca Boccassi. cat /etc/redhat-release Fedora release 28 (Twenty Eight) env | grep -i wayland WAYLAND_DISPLAY=wayland-0 XDG_SESSION_TYPE=wayland sudo dnf info mutter | perl -n -E '/^Installed/ and $i = 1; /^Available/ and $i = 0; $i and /^Version/ and do { print; exit }' Version : 3.28.3 echo $SSH_AUTH_SOCK /tmp/ssh-P7DgkAjhuUjP/agent.3692 dbus-send --session --dest=org.gnome.keyring --print-reply /org/gnome/keyring/daemon org.gnome.keyring.Daemon.GetEnvironment method return time=1537533008.306961 sender=:1.14 -> destination=:1.86 serial=8 reply_serial=2 array [ dict entry( string "SSH_AUTH_SOCK" string "/run/user/1000/keyring/ssh" ) ] ps aux | grep gnome-keyring michael 2978 0.0 0.0 489808 7288 ? Sl 14:26 0:00 /usr/bin/gnome-keyring-daemon --daemonize --login ssh-add -L The agent has no identities. ssh-add -L ssh-rsa AAAAB3<cut>
Sorry missed line before last: set SSH_AUTH_SOCK /run/user/1000/keyring/ssh
Actually not at all sure that this was the issue I was seeing. I had configured an ssh-agent to start with my shell because gnome-keyring didn't seem to want to do it. eval (ssh-agent -c >/dev/null) This had been working until recently, but was now regularly failing to find keys. Looking at this advice on an Ubuntu bug for issues with ssh-agent and gnome-keyring, the following seems to have sorted it: https://bugs.launchpad.net/ubuntu/+source/gnome-keyring/+bug/1586835#yui_3_10_3_1_1537535838895_317 if test -z $SSH_AUTH_SOCK export (/usr/bin/gnome-keyring-daemon --start) end By the way I am using fish shell, hence the slightly unusual shell commands.