You are not logged in.

#1 2012-07-10 18:11:19

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

gnome-keyring-daemon/pam: unlock "login" keyring

Despite having configured /etc/pam.d/login according to the Gnome Keyring: Automatic Unlocking / PAM directions, after logging in to the console, the "login" keyring is not unlocked, nor is gnome-keyring-daemon started:

/etc/pam.d/login:

#%PAM-1.0

auth       required     pam_securetty.so
auth       requisite    pam_nologin.so
auth       include      system-local-login
auth       optional     pam_gnome_keyring.so
account    include      system-local-login
session    include      system-local-login
session    optional    pam_gnome_keyring.so         auto_start

/var/log/auth.log: nothing about gnome-keyring-daemon

Everything else (/etc/pam/system-*) uses the default values, so there are no sufficient pam control keywords that could halt execution of the pam stack

Most obviously, the "login" keyring password matches my actual login password.

The keyring directory seems OK and I can manually unlock the "login" keyring later:

$  ls -h .gnome2/keyrings/
default  default.keyring  default.keyring.temp-50754670  login.keyring  user.keystore

GNOME_KEYRING_CONTROL environment variable is unset during boot (egrep -R GNOME_KEYRING_CONTROL /etc/rc* /etc/profile.d/) which would halt pam_gnome_keyring.so.

I can't really think of anything else to check. On the other hand, if pam_gnome_keyring.so were broken the "login" keyring would not be unlocked from GDM - works for everyone using GDM, right (use seahorse to check)?

Last edited by orbisvicis (2012-07-10 18:12:50)

Offline

#2 2012-07-11 05:46:13

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

When passing a bogus argument to pam_gnome_keyring, an error is logged to "/var/log/auth.log"

auth		required	pam_gnome_keyring.so try_first_pass auto_start
Jul 10 08:32:48 localhost login: gkr-pam: invalid option: try_first_pass

This means that control has been succesfully passed to the pam_gnome_keyring.so module in the pam stack. Similary, since login was successful:

Jul 10 08:33:04 localhost login: LOGIN ON tty1 BY orbisvicis

and I changed the control value from "optional" to "required", pam_gnome_keyring.so was successful. This means either no password was obtained by the module, or that it is not operating correctly, as per GnomeKeyring/Pam/Manual.

Further investigation into /etc/pam.d/passwd which contains

password	optional	pam_gnome_keyring.so
password	required	pam_unix.so sha512 shadow nullok

If "gnome-keyring-daemon" is running, using "passwd" to change my password also changes the "login" keyring password. Ironically, if authentication via "pam_unix.so" does not succeed, "pam_gnome_keyring.so" will nonetheless change the "login" keyring password, leaving it unsynchronized with the system password. Most likely the "use_authtok" argument to "pam_gnome.keyring.so prevents this behavior.

Jul 10 08:16:07 localhost passwd[5147]: gkr-pam: changed password for login keyring

However when "gnome-keyring-daemon" is not running, "pam_gnome_keyring.so" is unable change the "login" keyring password

Jul 10 08:38:48 localhost passwd[3035]: Couldn't access gnome keyring socket: /home/orbisvicis/.cache/keyring-uLeAQI/control: No such file or directory
Jul 10 08:38:48 localhost passwd[2900]: gkr-pam: couldn't change password for the login keyring.

Both messages suggest that the "pam_gnome_keyring.so" manages to retrieve the password, but is unable to spawn the "gnome-keyring-daemon". Once again, more testing.

Each new login session, "pam_gnome_keyring.so" (gkr-pam) exports two unique environment variables.

GNOME_KEYRING_CONTROL
GNOME_KEYRING

Since the "pam_gnome_keyring.so" module was unable to spawn the "gnome-keyring-daemon --daemonize --login" instance, the "gnome-keyring-daemon --start" instance started from xinitrc/start to fully initialize "gnome-keyring-daemon" is unable to connect to the socket specified by GNOME_KEYRING_CONTROL. The additional errors (last three lines) can be ignored, "gnome-keyring-daemon" is attempting to export the variables to the gnome session manager over dbus, which is not available.

Jul 10 14:13:24 localhost gnome-keyring-daemon[12728]: couldn't access conrol socket: /home/orbisvicis/.cache/keyring-uLeAQI/control: No such file or directory
Jul 10 14:13:24 localhost gnome-keyring-daemon[12729]: couldn't set environment variable in session: The name org.gnome.SessionManager was not provided by any .service files
Jul 10 14:13:24 localhost gnome-keyring-daemon[12729]: couldn't set environment variable in session: The name org.gnome.SessionManager was not provided by any .service files
Jul 10 14:13:24 localhost gnome-keyring-daemon[12729]: couldn't set environment variable in session: The name org.gnome.SessionManager was not provided by any .service files

What's weird is that when "pam_gnome_keyring.so" obtains incorrect credentials (when I type an incorrect password to login/console) and gkr-pam explicitly logs an error, "gnome-keyring-daemon --daemonize --login" is nonetheless executed. Of course the spawned daemon is useless and dies after a default 60 seconds (I think).

This is exactly what happens:

  • "pam_unix.so" fails

  • "pam_gnome_keyring.so" of type "session" displays a second login prompt, which it should not do

  • since it is only a session module, the new login prompt does not work

  • "gnome-keyring-daemon" is then spawned

  • the next login prompt is from "pam_unix.so", and can be used

  • of course, upon logging in the "gnome-keyring-daemon" process is now useless and dies shortly thereafter

Jul 10 13:22:44 localhost login: pam_unix(login:auth): authentication failure; logname=LOGIN uid=0 euid=0 tty=tty2 ruser= rhost=  user=orbisvicis
Jul 10 13:22:46 localhost login: FAILED LOGIN 1 FROM tty2 FOR orbisvicis, Authentication failure
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: Gck: gck_module_new: assertion `funcs != NULL' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: module_instances: assertion `module' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: egg_error_message: assertion `error' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: couldn't find secret store module: (unknown)
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: lookup_login_keyring: assertion `GCK_IS_SESSION (session)' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: create_credential: assertion `GCK_IS_SESSION (session)' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: egg_error_message: assertion `error' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: couldn't create login credential: (unknown)
Jul 10 13:22:48 localhost login: gkr-pam: the password for the login keyring was invalid.
Jul 10 13:22:51 localhost login: FAILED LOGIN SESSION FROM tty2 FOR orbisvicis, Error in service module

Offline

#3 2012-07-11 05:46:45

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

I think there is enough information to warrant a bug report.

edit::FS#30631

Last edited by orbisvicis (2012-07-11 05:53:55)

Offline

#4 2012-07-11 23:39:48

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

Is

$  gnome-keyring-daemon --daemonize --login

supposed to fork, or is bash supposed to wait indefinitely.

Edit:
This is the appropriate behavior, "gnome-keyring-daemon --login" will block reading a password - verified by "ltrace" and booting a liveCD.

Last edited by orbisvicis (2012-07-13 18:58:28)

Offline

#5 2012-07-13 19:05:12

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

Simulating pam_gnome_keyring.so forking outside of the X11/DBus session to launch "gnome-keyring-daemon":

eval $(gnome-keyring-daemon --login --daemonize <<<"ThePassword")
gnome-keyring-daemon --start

Result: no errors, and the "login" keyring created if necessary.

Then, patched "gkr-pam-module.c" to print for every function:

syslog (GKR_LOG_INFO, "gkr-pam: inside NAME_OF_FUNCTION");

and "gkd-main.c" to notify upon startup:

g_message("STARTING GNOME KEYRING DAEMON");

Result:

Jul 13 04:22:56 localhost login: gkr-pam: inside pam_sm_authenticate
Jul 13 04:22:56 localhost login: gkr-pam: inside parse_args
Jul 13 04:22:56 localhost login: gkr-pam: inside get_any_env
Jul 13 04:22:56 localhost login: gkr-pam: inside pam_sm_setcred
Jul 13 04:22:56 localhost login: pam_unix(login:session): session opened for user orbisvicis by LOGIN(uid=0)
Jul 13 04:22:57 localhost login: gkr-pam: inside pam_sm_open_session
Jul 13 04:22:57 localhost login: gkr-pam: inside parse_args
Jul 13 04:22:57 localhost login: gkr-pam: inside start_daemon_if_necessary
Jul 13 04:22:57 localhost login: gkr-pam: inside get_any_env
Jul 13 04:22:57 localhost login: gkr-pam: inside start_daemon
Jul 13 04:22:57 localhost login: gkr-pam: inside setup_child
Jul 13 04:22:57 localhost login: gkr-pam: inside setup_pam_env
Jul 13 04:22:57 localhost login: gnome-keyring-daemon[1790]: STARTING GNOME KEYRING DAEMON
Jul 13 04:22:59 localhost login: gkr-pam: inside setup_environment
Jul 13 04:22:59 localhost login: gkr-pam: inside setup_environment
Jul 13 04:22:59 localhost login: gkr-pam: inside get_any_env
Jul 13 04:22:59 localhost login: gkr-pam: inside pam_sm_setcred
Jul 13 04:22:59 localhost login: LOGIN ON tty1 BY orbisvicis

Notice how "gnome-keyring-daemon --daemonize --login" expects to output two lines - the environment variables GNOME_KEYRING_CONTROL and GNOME_KEYRING_PID - and "setup_environment" has been called twice.

gnome-keyring-daemon dies before strace can be attached.

$  while true; do gkd_pid="$(pgrep -f gnome-keyring-daemon)"; if ((${gkd_pid:-1}>0)); then echo -e "${gkd_pid}\n"; sudo strace -p"$gkd_pid"; break; fi; done
1696

attach: ptrace(PTRACE_ATTACH, ...): No such process

edit: thought this might be faster, guess not:

while true; do if gkd_pid="$(pgrep -f gnome-keyring-daemon)"; then printf "%s\n----------\n" "${gkd_pid}"; sudo strace -p"$gkd_pid"; break; fi; done

Init: disabled TTY2 for respawning too fast, heh.

Last edited by orbisvicis (2012-07-14 16:25:26)

Offline

#6 2012-07-14 16:22:39

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

Attempt running "gnome-keyring-daemon" in an empty environment without DBus, X11, or any environment variables:

sudo init 1
su orbisvicis
id -u   #euid->1000
id -ru  # ruid->1000
while IFS=: read -r var; do var="${var%%=*}"; if [[ "$var" != "PATH" ]]; then unset "${var%%=*}"; fi; done<<<"$(env)"
gnome-keyring-daemon --daemonize --login

Result: works fine. The PAM environment spawning "gnome-keyring-daemon" should not be an issue.

Offline

#7 2012-07-14 16:42:45

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

The shutdown sequence:

Jul 14 11:56:13 localhost login: pam_unix(login:session): session closed for user orbisvicis
Jul 14 11:56:13 localhost login: gkr-pam: inside pam_sm_close_session
Jul 14 11:56:13 localhost login: gkr-pam: inside stop_daemon

specifically the function "stop_daemon", shows no errors, so I must assume "gkr-pam-pid" was never stored. why?

-----

"When the PAM session is closed, if the PAM module started gnome-keyring-daemon it is killed." -- from GnomeKeyring/Pam
After a succesful login, "/sbin/agetty -8 -s 38400 tty2 linux" is replaced by "login -- orbisvicis" which runs for the duration of the session, until logout when auth.log reports "login:session: session closed" and "login" is once again replaced by "agetty".

If this is not the correct behavior, possibly "pam_gnome_keyring.so" is accidentally triggering the shutdown of "gnome-keyring-daemon". Any input?

Offline

#8 2012-07-14 16:46:57

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

Patched for more information:

--- daemon/gkd-main.c.bak	2012-07-14 11:36:22.977678410 -0400
+++ daemon/gkd-main.c	2012-07-14 11:37:02.909728023 -0400
@@ -388,16 +388,29 @@
 signal_thread (gpointer user_data)
 {
 	GMainLoop *loop = user_data;
-	int sig, err;
+	int err;
+    siginfo_t siginfo;
+    int fd;
+    char filename[24];
+    char arg_list[1024];
+    size_t length;
 
 	for (;;) {
-		err = sigwait (&signal_set, &sig);
-		if (err != EINTR && err != 0) {
-			g_warning ("couldn't wait for signals: %s", g_strerror (err));
+		err = sigwaitinfo (&signal_set, &siginfo);
+        if (err < 0 && errno!=EINTR){
+			g_warning ("couldn't wait for signals: %i:%s", err, g_strerror (errno));
 			return NULL;
 		}
+        g_message("GNOME KEYRING DAEMON: Got signal '%d' from process '%d' of user '%d'\n",
+            siginfo.si_signo, siginfo.si_pid, siginfo.si_uid);
+        snprintf(filename,sizeof(filename),"/proc/%d/cmdline",siginfo.si_pid);
+        fd = open(filename, O_RDONLY);
+        length = read(fd,arg_list,sizeof(arg_list));
+        close(fd);
+        g_message("GNOME KEYRING DAEMON: SENDING PID INFO: %.*s",length,arg_list);
 
-		switch (sig) {
+
+		switch (siginfo.si_signo) {
 		case SIGUSR1:
 #ifdef WITH_DEBUG
 			dump_diagnostics ();
@@ -413,7 +426,7 @@
 			g_main_loop_quit (loop);
 			return NULL;
 		default:
-			g_warning ("received unexpected signal when waiting for signals: %d", sig);
+			g_warning ("received unexpected signal when waiting for signals: %d", siginfo.si_signo);
 			break;
 		}
 	}

Resulting login/logout sequence shows in /var/log/auth.log as:

Jul 14 11:56:12 localhost login: gkr-pam: inside pam_sm_authenticate
Jul 14 11:56:12 localhost login: gkr-pam: inside parse_args
Jul 14 11:56:12 localhost login: gkr-pam: inside get_any_env
Jul 14 11:56:12 localhost login: gkr-pam: inside pam_sm_setcred
Jul 14 11:56:12 localhost login: pam_unix(login:session): session opened for user orbisvicis by LOGIN(uid=0)
Jul 14 11:56:12 localhost login: gkr-pam: inside pam_sm_open_session
Jul 14 11:56:12 localhost login: gkr-pam: inside parse_args
Jul 14 11:56:12 localhost login: gkr-pam: inside start_daemon_if_necessary
Jul 14 11:56:12 localhost login: gkr-pam: inside get_any_env
Jul 14 11:56:12 localhost login: gkr-pam: inside start_daemon
Jul 14 11:56:12 localhost login: gkr-pam: inside setup_child
Jul 14 11:56:12 localhost login: gkr-pam: inside setup_pam_env
Jul 14 11:56:12 localhost gnome-keyring-daemon[5903]: STARTING GNOME KEYRING DAEMON
Jul 14 11:56:12 localhost gnome-keyring-daemon[5903]: GNOME KEYRING DAEMON, JUST ADDED TIMEOUT CALLBACK
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: STARTING GNOME KEYRING DAEMON MAINLOOP
Jul 14 11:56:12 localhost login: gkr-pam: inside setup_environment
Jul 14 11:56:12 localhost login: gkr-pam: inside setup_environment
Jul 14 11:56:12 localhost login: gkr-pam: inside get_any_env
Jul 14 11:56:12 localhost login: gkr-pam: inside pam_sm_setcred
Jul 14 11:56:12 localhost login: LOGIN ON tty2 BY orbisvicis
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: GNOME KEYRING DAEMON: Got signal '1' from process '28840' of user '0'
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: GNOME KEYRING DAEMON: SENDING PID INFO: login -- orbisvicis
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: GNOME KEYRING DAEMON, SIGNAL THREAD CAUGHT SIGTERM
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: LEAVING GNOME KEYRING DAEMON MAINLOOP
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: EXITING GNOME KEYRING DAEMON
Jul 14 11:56:13 localhost login: gkr-pam: inside pam_sm_setcred
Jul 14 11:56:13 localhost login: pam_unix(login:session): session closed for user orbisvicis
Jul 14 11:56:13 localhost login: gkr-pam: inside pam_sm_close_session
Jul 14 11:56:13 localhost login: gkr-pam: inside stop_daemon

I can guarantee that neither the functions

stop_daemon    ::gkr-pam-module.c
gkd_main_quit   ::gkd-main.c

have been called since they've been patched to log function entry via syslog and would be present above. Furthermore, from grepping the source, these are the only functions in the entire package which shut down the gnome-keyring daemon.

From the log above, it is clear that the "/bin/login" process is terminating "gnome-keyring-daemon". However, this is a bit vague, because I believe "/bin/login" hosts "pam_gnome_keyring.so" as well as the entire pam stack. So it is possible any other pam module is responsible.

It is also possible for the child fork to die after the parent exits - How to make child process die after parent exits - but I didn't see anything like that in the "gnome-keyring-daemon" package.

So unfortunately, this fiasco is still a mystery...

Last edited by orbisvicis (2012-07-14 16:55:46)

Offline

#9 2012-07-14 18:35:58

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

Its actually a SIGHUP, not a SIGTERM, that shuts down gnome-keyring-daemon. However, according to strace the only process to receive SIGHUP is "/bin/login" (execve), once from the kernel, once from itself, and it shouldn't be propagated. There are no sigqueue/kill/system calls sending SIGHUP. There is, however, a sigtimedwait() from a gnome-keyring-daemon fork()/clone() which waits upon a signal set including SIGHUP, though I can't figure out where this system call comes from.

strace -f -e trace=process,signal -ff -o gkd -p"${AGETTY_TTY2_PID}"

Offline

#10 2012-07-14 21:20:34

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

More precisely:

gkd.8358:rt_sigaction(SIGHUP, {SIG_IGN, [HUP], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
gkd.8358:--- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
gkd.8358:rt_sigaction(SIGHUP, {SIG_DFL, [HUP], SA_RESTART}, {SIG_IGN, [HUP], SA_RESTART}, 8) = 0
gkd.8358:rt_sigaction(SIGHUP, {SIG_IGN, [], 0}, {SIG_DFL, [HUP], SA_RESTART}, 8) = 0
gkd.8358:--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=8358, si_uid=0} ---
gkd.8358:rt_sigaction(SIGHUP, {0x804c2d0, [], 0}, NULL, 8) = 0
gkd.9205:rt_sigtimedwait([HUP USR1 PIPE TERM], {si_signo=SIGHUP, si_code=SI_USER, si_pid=8358, si_uid=0}, NULL, 8) = 1
gkd.9206:rt_sigaction(SIGHUP, {SIG_DFL, [HUP], SA_RESTART}, NULL, 8) = 0
gkd.9206:rt_sigaction(SIGHUP, {0x8094c80, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 0}, {SIG_DFL, [], 0}, 8) = 0
gkd.9208:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9210:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9211:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9214:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9216:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9218:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9220:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
8358 -> agetty -> execve("/bin/login",...) -(which loads)-> pam_gnome_keyring.so -> rest of PAM stack
9202 -> (from pam_gnome_keyring.so) fork() -> execve("/usr/bin/gnome-keyring-daemon",[...,"--daemonize", "--login"],...)
9203 -> (from "/usr/bin/gnome-keyring-daemon --daemonize --login") fork()
9204 -> (from "/usr/bin/gnome-keyring-daemon" -> fork()
9205 -> (from "/usr/bin/gnome-keyring-daemon" -> rt_sigtimedwait([...],{si_signo=SIGHUP,...},...) -> exit
9206 -> execve("/bin/bash",...)
9208 -> execve("/usr/bin/tty"...)
...
bash profile / .xinitrc initialization

Edit::because it's easier to understand this way

8358: pam_gnome_keyring.so (loaded from /bin/login) which waitpid() on the initial fork()
9202: pam_gnome_keyring.so initial fork() which executes/becomes "gnome-keyring-daemon --daemonize --login" and waitpid() on the intermediate process
9203: gnome-keyring-daemon intermediate fork() which also write() the environment variables to the TTY, then fork() and exit() without waiting
9204: gnome-keyring-daemon final fork(), daemon which executes gdk::main() and starts the GMainLoop
9205: the parallel signal-thread which is responsible for handling signals, (all the other threads ignore the signals)

since "--daemonize" forks twice to ensure that it is reparented onto init, and to guarantee that it is not a session leader, ie unable to obtain a controlling TTY.

Last edited by orbisvicis (2012-07-15 00:41:18)

Offline

#11 2012-07-15 01:05:50

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

I can't figure out how the signal thread of gnome-keyring-daemon receives SIGHUP. Excerpt from strace:

set_robust_list(0xb7053bb0, 12)         = 0
rt_sigtimedwait([HUP USR1 PIPE TERM], {si_signo=SIGHUP, si_code=SI_USER, si_pid=9236, si_uid=0}, NULL, 8) = 1
--- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=9236, si_uid=0} ---
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0xb6653000

SIGHUP seems to magically appear as the argument to rt_sigtimedwait(), and isn't even logged by strace, unlike the subsequent SIGCONT.

Furthermore, "/bin/login" appears to ignore all SIGHUP signals that it receives:

  • from strace:

    rt_sigaction(SIGHUP, {SIG_IGN, [HUP], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
    vhangup()                               = 0
    --- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
    --- SIGCONT {si_signo=SIGCONT, si_code=SI_KERNEL} ---
    rt_sigaction(SIGHUP, {SIG_DFL, [HUP], SA_RESTART}, {SIG_IGN, [HUP], SA_RESTART}, 8) = 0

    corresponding login.c:

    signal(SIGHUP, SIG_IGN);	/* so vhangup() wont kill us */
    vhangup();
    signal(SIGHUP, SIG_DFL);
  • from strace:

    rt_sigaction(SIGHUP, {SIG_IGN, [], 0}, {SIG_DFL, [HUP], SA_RESTART}, 8) = 0
    ioctl(0, TIOCNOTTY)                     = 0
    --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=9236, si_uid=0} ---
    --- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=9236, si_uid=0} ---
    rt_sigaction(SIGHUP, {0x804c2d0, [], 0}, NULL, 8) = 0

    corresponding login.c:

    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = SIG_IGN;
    sigaction(SIGINT, &sa, NULL);
    
    sigaction(SIGHUP, &sa, &oldsa_hup);	/* ignore when TIOCNOTTY */
    
    /*
     * detach the controlling tty
     * -- we needn't the tty in parent who waits for child only.
     *    The child calls setsid() that detach from the tty as well.
     */
    ioctl(0, TIOCNOTTY, NULL);
    
    /*
     * We have care about SIGTERM, because leave PAM session without
     * pam_close_session() is pretty bad thing.
     */
    sa.sa_handler = sig_handler;
    sigaction(SIGHUP, &sa, NULL);
    sigaction(SIGTERM, &sa, &oldsa_term);
    static void sig_handler(int signal)
    {
    	if (child_pid)
    		kill(-child_pid, signal);
    	else
    		got_sig = 1;
    	if (signal == SIGTERM)
    		kill(-child_pid, SIGHUP);	/* because the shell often ignores SIGTERM */
    }

It also seems that sig_handler() is never called, so "/bin/login" in this particular codepath does not send any signals to its children.

------------

Several month ago, "gnome-keyring-daemon" integrated into "/bin/login" via pam_gnome_keyring.so without difficulty. If indeed a change in the behavior of "/bin/login" is responsible for the current failure of "gnome-keyring-daemon", I can't find any recent commits in the util-linux git repository that could be the culprit. These are the files I've checked:

$  find . \( -iname 'login*.c' -o -iname 'login*.h' \)
./login.c
./logindefs.c
./logindefs.h

Last edited by orbisvicis (2012-07-15 01:07:46)

Offline

#12 2012-07-15 01:24:46

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

Two possible theories about the SIGHUP signal:

  • Intermediate fork, by writing to the TTY, re-acquires the controlling terminal. When this fork exits(), it causes a SIGHUP.

  • When the first fork dies the gnome-keyring-daemon process group becomes orphaned, causing a SIGHUP/SIGCONT combination.

I really have no clue.

Offline

#13 2012-07-16 07:48:45

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

Couldn't reproduce either ideas:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stropts.h>
#include <sys/ioctl.h>
#include <sys/wait.h>

static void child(int* fd){
  fprintf(stdout,"child pid:    %i\n",getpid());
  fprintf(stdout,"child ppid:   %i\n",getppid());
  fprintf(stdout,"child pgid:   %i\n",getpgid(0));
  fprintf(stdout,"child sid:    %i\n",getsid(0));

  if( dup2(fd[0],0)<0 )
    exit(-1);

  for (int i=2; i < 64; ++i)
    close(i);

  close( fd[0] );
  close( fd[1] );
  fd[0] = -1;
  fd[1] = -1;

  char* const args[] = { strdup("/usr/bin/gnome-keyring-daemon"),strdup("--daemonize"),strdup("--login"), NULL};
  execv (args[0], args);
  for(int i=0; !args[i]; i++)
    free(args[i]);

  exit(-1);
}

static void parent(int* fd,pid_t pid){
  char passwd[] = "ThePassword\n";

  close( fd[0] );
  fd[0] = -1;

  if( write(fd[1],passwd,sizeof(passwd)) < 0 )
    exit(-1);
  close( fd[1] );
  fd[1] = -1;

  if( waitpid(pid,NULL,0)<0 )
    exit(-1);
}

int main(){
  if ((fork()) != 0)
    exit(0);
  setsid();
  if ((fork()) != 0)
    exit(0);

  vhangup();
	ioctl(0, TIOCNOTTY, NULL);

  fprintf(stdout,"\n");
  fprintf(stdout,"parent pid:    %i\n",getpid());
  fprintf(stdout,"parent ppid:   %i\n",getppid());
  fprintf(stdout,"parent pgid:   %i\n",getpgid(0));
  fprintf(stdout,"parent sid:    %i\n",getsid(0));

  int fd[2] = {-1,-1};
  pid_t pid;

  if( pipe(fd)<0 )
    exit(-1);

  switch( pid = fork() ){
    case -1:
      exit(-1);
      break;
    case 0:
      child(fd);
      break;
    default:
      parent(fd,pid);
      break;
  };
}

// vim:set ts=2 sw=2 et:

Edit::Clarification:
pam_sm_close_session() is called when login/pam_unix closses the login session, which occurs naturally from running logout/exit in the bash login shell... which is long after gnome-keyring-daemon receives the SIGHUP.

The SIGHUP occurs after log_syslog() in login.c (from util-linux) - after a login is committed. I assume the SIGHUP occurs before /bin/login/ executes/becomes /bin/bash - stemming from the assumption that execvp/kernel would update the information in /proc/pid/cmdline (according to /proc/pid/cmdline, "login" is responsible for the SIGHUP).

Last edited by orbisvicis (2012-07-16 15:43:41)

Offline

#14 2012-07-17 18:05:24

orbisvicis
Member
Registered: 2009-08-10
Posts: 23

Re: gnome-keyring-daemon/pam: unlock "login" keyring

For the record, the patch that fixes the problem:

--- daemon/gkd-main.c.bak	2012-07-17 13:49:35.951945395 -0400
+++ daemon/gkd-main.c	2012-07-17 13:49:38.235208426 -0400
@@ -677,6 +677,12 @@
 
 	if (run_daemonized) {
 
+        /* Become session leader of a new session, process group leader of a new
+         * process group, and detach from the controlling TTY, so that SIGHUP is
+         * not sent to this process when the previous session leader dies
+        */
+        setsid();
+
 		/* Double fork if need to daemonize properly */
 		pid = fork ();
 

I'm still not sure which session leader died, or how ptrace was unable to trace the signal, but it works.

Offline

#15 2012-07-21 09:21:07

bema
Member
Registered: 2010-02-12
Posts: 26

Re: gnome-keyring-daemon/pam: unlock "login" keyring

I had the same problem and wanted to thank you for your intensive investigation regarding this issue. It is very much appreciated smile.

Offline

#16 2012-08-27 15:18:55

siam
Member
Registered: 2011-07-13
Posts: 18

Re: gnome-keyring-daemon/pam: unlock "login" keyring

I'm having the same issue with a fresh install of Arch with Gnome 3 as my DE. I prefer to start Gnome with startx.
I have the same login and passwd files in my /etc/pam.d directory as the OP.
Adding the pam_gnome_keyring.so lines to the login file seemed to be sufficient to unlock the keyring upon login in the past.
Is anybody else experiencing this? Surely, we can't be the only ones.

The OP's awesome work seems to be a workaround to the problem.
I do not want to edit any sources.

Offline

#17 2012-10-16 18:15:39

dkasak
Member
Registered: 2012-01-18
Posts: 7

Re: gnome-keyring-daemon/pam: unlock "login" keyring

I'm also affected by this. I'll see if I can patch the sources when I have the time to see if it also fixes it for me.

EDIT: Tried the patch, it works.

Last edited by dkasak (2012-10-16 18:35:21)

Offline

#18 2013-05-16 21:18:38

snoxu
Member
Registered: 2010-01-24
Posts: 141

Re: gnome-keyring-daemon/pam: unlock "login" keyring

^Is this still the current working solution?

How does one go about applying the patch? (sorry for the newb question)

Last edited by snoxu (2013-05-16 21:20:32)

Offline

#19 2013-05-16 21:22:47

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: gnome-keyring-daemon/pam: unlock "login" keyring

snoxu wrote:

How does one go about applying the patch? (sorry for the newb question)

https://wiki.archlinux.org/index.php/Patching_in_ABS

Offline

Board footer

Powered by FluxBB