diff --git a/gnome-keyring-2.20-selinux-pam.patch b/gnome-keyring-2.20-selinux-pam.patch new file mode 100644 index 0000000..14f2630 --- /dev/null +++ b/gnome-keyring-2.20-selinux-pam.patch @@ -0,0 +1,291 @@ +diff -ur gnome-keyring-2.20.orig/daemon/gkr-daemon.c gnome-keyring-2.20/daemon/gkr-daemon.c +--- gnome-keyring-2.20.orig/daemon/gkr-daemon.c 2007-10-05 12:40:28.000000000 +0200 ++++ gnome-keyring-2.20/daemon/gkr-daemon.c 2007-10-05 12:55:26.000000000 +0200 +@@ -27,6 +27,7 @@ + #include "common/gkr-async.h" + #include "common/gkr-cleanup.h" + #include "common/gkr-unix-signal.h" ++#include "common/gkr-location.h" + + #include "keyrings/gkr-keyrings.h" + +@@ -183,6 +184,10 @@ + GIOChannel *channel; + GMainContext *ctx; + int i; ++ gboolean login; ++ char *login_password; ++ int len; ++ GkrKeyring *login_keyring; + + g_type_init (); + g_thread_init (NULL); +@@ -211,6 +216,7 @@ + + foreground = FALSE; + daemon = FALSE; ++ login = FALSE; + + if (argc > 1) { + for (i = 1; i < argc; i++) { +@@ -218,8 +224,19 @@ + foreground = TRUE; + if (strcmp (argv[i], "-d") == 0) + daemon = TRUE; ++ if (strcmp (argv[i], "--login") == 0) ++ login = TRUE; + } + } ++ ++ login_password = NULL; ++ if (login) { ++ login_password = gnome_keyring_memory_alloc (256); ++ fgets (login_password, 256, stdin); ++ len = strlen (login_password); ++ if (login_password[len-1] == '\n') ++ login_password[len-1] = 0; ++ } + + if (!foreground) { + pid = fork (); +@@ -315,6 +332,27 @@ + gkr_daemon_dbus_setup (loop, path); + #endif + ++ ++ if (login_password) { ++ login_keyring = gkr_keyrings_get_login (); ++ if (login_keyring) { ++ if (!gkr_keyring_unlock (login_keyring, ++ login_password)) { ++ g_warning ("Failed to unlock login keyring"); ++ } ++ } else { ++ login_keyring = ++ gkr_keyring_create (GKR_LOCATION_BASE_LOCAL, ++ "login", ++ login_password); ++ if (login_keyring) { ++ gkr_keyrings_add (login_keyring); ++ g_object_unref (login_keyring); ++ } ++ } ++ gnome_keyring_memory_free (login_password); ++ } ++ + g_main_loop_run (loop); + + /* Make sure no other threads are running */ +diff -ur gnome-keyring-2.20.orig/pam/gkr-pam-module.c gnome-keyring-2.20/pam/gkr-pam-module.c +--- gnome-keyring-2.20.orig/pam/gkr-pam-module.c 2007-10-05 12:40:28.000000000 +0200 ++++ gnome-keyring-2.20/pam/gkr-pam-module.c 2007-10-05 12:42:05.000000000 +0200 +@@ -249,15 +249,20 @@ + } + + static void +-setup_child (int outp[2], int errp[2], struct passwd *pwd) ++setup_child (int inp[2], int outp[2], int errp[2], struct passwd *pwd, const char *password) + { +- char *args[] = { GNOME_KEYRING_DAEMON, "-d", NULL}; +- ++ char *args[] = { GNOME_KEYRING_DAEMON, "-d", "--login", NULL}; ++ + assert (pwd); + assert (pwd->pw_dir); +- ++ ++ /* If no password, don't pas in --login */ ++ if (password == NULL) ++ args[2] = NULL; ++ + /* Fix up our end of the pipes */ +- if (dup2 (outp[WRITE_END], STDOUT) < 0 || ++ if (dup2 (inp[READ_END], STDIN) < 0 || ++ dup2 (outp[WRITE_END], STDOUT) < 0 || + dup2 (errp[WRITE_END], STDERR) < 0) { + syslog (GKR_LOG_ERR, "gkr-pam: couldn't setup pipes: %s", + strerror (errno)); +@@ -265,6 +270,8 @@ + } + + /* Close unnecessary file descriptors */ ++ close (inp[READ_END]); ++ close (inp[WRITE_END]); + close (outp[READ_END]); + close (outp[WRITE_END]); + close (errp[READ_END]); +@@ -348,9 +355,10 @@ + } + + static int +-start_daemon (pam_handle_t *ph, struct passwd *pwd) ++start_daemon (pam_handle_t *ph, struct passwd *pwd, const char *password) + { + struct sigaction defsact, oldsact; ++ int inp[2] = { -1, -1 }; + int outp[2] = { -1, -1 }; + int errp[2] = { -1, -1 }; + int ret = PAM_SERVICE_ERR; +@@ -372,7 +380,7 @@ + sigaction (SIGCHLD, &defsact, &oldsact); + + /* Create the necessary pipes */ +- if (pipe (outp) < 0 || pipe (errp) < 0) { ++ if (pipe (inp) < 0 || pipe (outp) < 0 || pipe (errp) < 0) { + syslog (GKR_LOG_ERR, "gkr-pam: couldn't create pipes: %s", + strerror (errno)); + goto done; +@@ -387,7 +395,7 @@ + + /* This is the child */ + case 0: +- setup_child (outp, errp, pwd); ++ setup_child (inp, outp, errp, pwd, password); + /* Should never be reached */ + break; + +@@ -397,9 +405,16 @@ + }; + + /* Close our unneeded ends of the pipes */ ++ close (inp[READ_END]); + close (outp[WRITE_END]); + close (errp[WRITE_END]); +- outp[WRITE_END] = errp[WRITE_END] = -1; ++ inp[READ_END] = outp[WRITE_END] = errp[WRITE_END] = -1; ++ ++ if (password) { ++ /* Write the login keyring password */ ++ write (inp[WRITE_END], password, strlen (password)); ++ write (inp[WRITE_END], "\n", 1); ++ } + + /* + * Note that we're not using select() or any such. We know how the +@@ -438,6 +453,8 @@ + /* Restore old handler */ + sigaction (SIGCHLD, &oldsact, NULL); + ++ close_safe (inp[0]); ++ close_safe (inp[1]); + close_safe (outp[0]); + close_safe (outp[1]); + close_safe (errp[0]); +@@ -450,7 +467,7 @@ + } + + static int +-start_daemon_if_necessary (pam_handle_t *ph, struct passwd *pwd) ++start_daemon_if_necessary (pam_handle_t *ph, struct passwd *pwd, const char *password) + { + const char *socket; + int ret; +@@ -470,7 +487,7 @@ + } + + /* Not running, start process */ +- return start_daemon (ph, pwd); ++ return start_daemon (ph, pwd, password); + } + + static int +@@ -691,6 +708,7 @@ + struct passwd *pwd; + const char *user, *password; + const char *socket; ++ int started_daemon; + uint args; + int ret; + +@@ -728,9 +746,11 @@ + } + + ++ started_daemon = 0; + /* Should we start the daemon? */ + if (args & ARG_AUTO_START) { +- ret = start_daemon_if_necessary (ph, pwd); ++ started_daemon = 1; ++ ret = start_daemon_if_necessary (ph, pwd, password); + if (ret != PAM_SUCCESS) + return ret; + } +@@ -739,10 +759,12 @@ + + /* If gnome keyring is running, then unlock now */ + if (socket) { +- ret = unlock_keyring (ph, pwd, password); +- if (ret != PAM_SUCCESS) +- return ret; +- ++ /* If we started the daemon, its already unlocked, since we passed the password */ ++ if (!started_daemon) { ++ ret = unlock_keyring (ph, pwd, password); ++ if (ret != PAM_SUCCESS) ++ return ret; ++ } + /* Otherwise start in open session, store password */ + } else { + if (pam_set_data (ph, "gkr_system_authtok", strdup (password), +@@ -762,6 +784,7 @@ + struct passwd *pwd; + int ret; + uint args = parse_args (argc, argv); ++ int started_daemon; + + /* Figure out the user name */ + ret = pam_get_user (ph, &user, NULL); +@@ -777,29 +800,32 @@ + return PAM_SERVICE_ERR; + } + +- /* Should we start the daemon? */ +- if (args & ARG_AUTO_START) { +- ret = start_daemon_if_necessary (ph, pwd); +- if (ret != PAM_SUCCESS) +- return ret; +- } +- + /* Get the stored authtok here */ + if (pam_get_data (ph, "gkr_system_authtok", (const void**)&password) != PAM_SUCCESS) { +- + /* + * No password, no worries, maybe this (PAM using) application + * didn't do authentication, or is hopeless and wants to call + * different PAM callbacks from different processes. + * + * No use complaining +- */ +- return PAM_SUCCESS; ++ */ ++ password = NULL; + } + +- if (unlock_keyring (ph, pwd, password) != PAM_SUCCESS) +- return PAM_SERVICE_ERR; ++ started_daemon = 0; ++ /* Should we start the daemon? */ ++ if (args & ARG_AUTO_START) { ++ started_daemon = 1; ++ ret = start_daemon_if_necessary (ph, pwd, password); ++ if (ret != PAM_SUCCESS) ++ return ret; ++ } + ++ if (!started_daemon && password != NULL) { ++ if (unlock_keyring (ph, pwd, password) != PAM_SUCCESS) ++ return PAM_SERVICE_ERR; ++ } ++ + return PAM_SUCCESS; + } + +@@ -897,7 +923,7 @@ + * argument. Because if the password is being changed, then making + * the 'login' keyring match it is a priority. + */ +- ret = start_daemon_if_necessary (ph, pwd); ++ ret = start_daemon_if_necessary (ph, pwd, password); + if (ret != PAM_SUCCESS) + return ret; + diff --git a/gnome-keyring.spec b/gnome-keyring.spec index 4515e1c..aa3e41c 100644 --- a/gnome-keyring.spec +++ b/gnome-keyring.spec @@ -3,7 +3,7 @@ Summary: A framework for managing user passwords and other secrets Name: gnome-keyring Version: 2.20 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv2+ and LGPLv2+ Group: System Environment/Libraries Source: http://download.gnome.org/sources/gnome-keyring/2.20/gnome-keyring-%{version}.tar.bz2 @@ -23,6 +23,7 @@ BuildRequires: perl(XML::Parser) Patch1: gnome-keyring-2.20-add_new_keyrings.patch Patch2: gnome-keyring-2.20-no-unset-default.patch Patch3: gnome-keyring-2.20-no_match.patch +Patch4: gnome-keyring-2.20-selinux-pam.patch %description gnome-keyring manages passwords and other types of secrets @@ -65,6 +66,7 @@ and start the keyring daemon. %patch1 -p0 -b .add_new_keyrings %patch2 -p1 -b .no_unset_default %patch3 -p0 -b .no_match +%patch4 -p1 -b .selinux_pam %build aclocal @@ -111,6 +113,10 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Thu Oct 4 2007 Alexander Larsson - 2.20-4 +- Have the pam module tell the daemon to init the login keyring + without using the socket as selinux limits access to that + * Thu Oct 4 2007 Alexander Larsson - 2.20-3 - Add NO_MATCH error patch from svn. Will fix apps that can't handle empty list matches