diff --git a/SOURCES/0001-pam-Fix-issue-with-changed-password-not-unlocking-ke.patch b/SOURCES/0001-pam-Fix-issue-with-changed-password-not-unlocking-ke.patch new file mode 100644 index 0000000..c757170 --- /dev/null +++ b/SOURCES/0001-pam-Fix-issue-with-changed-password-not-unlocking-ke.patch @@ -0,0 +1,106 @@ +From 9c45ba07d6ff03ef7a2e67d25c75a4e3fa6179fa Mon Sep 17 00:00:00 2001 +From: Stef Walter +Date: Fri, 14 Mar 2014 11:08:02 +0100 +Subject: [PATCH] pam: Fix issue with changed password not unlocking keyring + +This is a backport of fix on master with the same subject. There's +a bit of strange code in the are of this fix, but lets keep it as +minimal as possible. + +If a user (needs to) change their password while authenticating (via +GDM for example), and pam_gnome_keyring is configured to start the +daemon from the session PAM stage, then we were failing to pass the +changed password to our session handler. + +Fix this issue so that this workflow works. + +https://bugzilla.gnome.org/show_bug.cgi?id=726196 +--- + pam/gkr-pam-module.c | 40 ++++++++++++++++++++++++++++++---------- + 1 file changed, 30 insertions(+), 10 deletions(-) + +diff --git a/pam/gkr-pam-module.c b/pam/gkr-pam-module.c +index 8ad814c..52514b8 100644 +--- a/pam/gkr-pam-module.c ++++ b/pam/gkr-pam-module.c +@@ -824,6 +824,19 @@ parse_args (pam_handle_t *ph, int argc, const char **argv) + return args; + } + ++static int ++stash_password_for_session (pam_handle_t *ph, ++ const char *password) ++{ ++ if (pam_set_data (ph, "gkr_system_authtok", strdup (password), ++ cleanup_free_password) != PAM_SUCCESS) { ++ syslog (GKR_LOG_ERR, "gkr-pam: error stashing password for session"); ++ return PAM_AUTHTOK_RECOVER_ERR; ++ } ++ ++ return PAM_SUCCESS; ++} ++ + PAM_EXTERN int + pam_sm_authenticate (pam_handle_t *ph, int unused, int argc, const char **argv) + { +@@ -886,11 +899,9 @@ pam_sm_authenticate (pam_handle_t *ph, int unused, int argc, const char **argv) + + /* Otherwise start later in open session, store password */ + } else { +- if (pam_set_data (ph, "gkr_system_authtok", strdup (password), +- cleanup_free_password) != PAM_SUCCESS) { +- syslog (GKR_LOG_ERR, "gkr-pam: error storing authtok"); ++ ret = stash_password_for_session (ph, password); ++ if (ret != PAM_SUCCESS) + return PAM_AUTHTOK_RECOVER_ERR; +- } + } + + return PAM_SUCCESS; +@@ -1017,18 +1028,20 @@ pam_chauthtok_update (pam_handle_t *ph, struct passwd *pwd, uint args) + { + const char *password, *original; + int ret, started_daemon = 0; +- ++ ++ ret = pam_get_item (ph, PAM_AUTHTOK, (const void**)&password); ++ if (ret != PAM_SUCCESS) ++ password = NULL; ++ + ret = pam_get_item (ph, PAM_OLDAUTHTOK, (const void**)&original); + if (ret != PAM_SUCCESS || original == NULL) { + syslog (GKR_LOG_WARN, "gkr-pam: couldn't update the login keyring password: %s", + "no old password was entered"); ++ if (password) ++ stash_password_for_session (ph, password); + return PAM_IGNORE; + } + +- ret = pam_get_item (ph, PAM_AUTHTOK, (const void**)&password); +- if (ret != PAM_SUCCESS) +- password = NULL; +- + if (password == NULL) { + /* No password was set, and we can't prompt for it */ + if (args & ARG_USE_AUTHTOK) { +@@ -1064,9 +1077,16 @@ pam_chauthtok_update (pam_handle_t *ph, struct passwd *pwd, uint args) + + /* if not auto_start, kill the daemon if we started it: we don't want + * it to stay */ +- if (started_daemon && !(args & ARG_AUTO_START)) ++ if (started_daemon && !(args & ARG_AUTO_START)) { + stop_daemon (ph, pwd); + ++ /* ++ * Likely the daemon is being started later in the session if we weren't ++ * allowed to autostart it here. Store the password for our session handler ++ */ ++ stash_password_for_session (ph, password); ++ } ++ + if (ret != PAM_SUCCESS) + return ret; + +-- +1.8.5.3 + diff --git a/SOURCES/daemon-Exit-gnome-keyring-daemon-when-the-DBus-con.patch b/SOURCES/daemon-Exit-gnome-keyring-daemon-when-the-DBus-con.patch new file mode 100644 index 0000000..bc74533 --- /dev/null +++ b/SOURCES/daemon-Exit-gnome-keyring-daemon-when-the-DBus-con.patch @@ -0,0 +1,286 @@ +From 992b1e1dcbf9402f8064990a064f1b5928a2cfe8 Mon Sep 17 00:00:00 2001 +From: Stef Walter +Date: Thu, 6 Mar 2014 16:11:12 +0100 +Subject: [PATCH] daemon: Exit gnome-keyring-daemon when the DBus connection + closes + +We don't do this via the standard mechanism, as it means that libdbus +just calls _exit() (not even exit()) when the connection goes away. + +This can lead to inconsistent state. Shutdown should be orderly. + +https://bugzilla.gnome.org/show_bug.cgi?id=708765 + +Conflicts: + daemon/Makefile.am + daemon/dbus/gkd-dbus.c +--- + daemon/dbus/gkd-dbus.c | 11 ++++- + daemon/gkd-main.c | 4 +- + daemon/test-shutdown.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ + egg/egg-dbus.c | 21 +++++++-- + egg/egg-dbus.h | 4 +- + 5 files changed, 147 insertions(+), 8 deletions(-) + create mode 100644 daemon/test-shutdown.c + +diff --git a/daemon/dbus/gkd-dbus.c b/daemon/dbus/gkd-dbus.c +index 92daafb..36cacfa 100644 +--- a/daemon/dbus/gkd-dbus.c ++++ b/daemon/dbus/gkd-dbus.c +@@ -27,6 +27,8 @@ + #include "gkd-dbus-private.h" + + #include "gkd-util.h" ++#include "daemon/gkd-main.h" ++#include "daemon/gkd-util.h" + + #include "egg/egg-cleanup.h" + #include "egg/egg-dbus.h" +@@ -55,6 +57,13 @@ cleanup_session_bus (gpointer unused) + dbus_conn = NULL; + } + ++static void ++on_connection_close (gpointer user_data) ++{ ++ g_debug ("dbus connection closed, exiting"); ++ gkd_main_quit (); ++} ++ + static gboolean + connect_to_session_bus (void) + { +@@ -73,7 +82,7 @@ connect_to_session_bus (void) + return FALSE; + } + +- egg_dbus_connect_with_mainloop (dbus_conn, NULL); ++ egg_dbus_connect_with_mainloop (dbus_conn, NULL, on_connection_close); + dbus_connection_set_exit_on_disconnect (dbus_conn, FALSE); + egg_cleanup_register (cleanup_session_bus, NULL); + return TRUE; +diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c +index 1d10132..df0ef91 100644 +--- a/daemon/gkd-main.c ++++ b/daemon/gkd-main.c +@@ -81,6 +81,8 @@ typedef int socklen_t; + + EGG_SECURE_DECLARE (daemon_main); + ++static GMainLoop *loop = NULL; ++ + /* ----------------------------------------------------------------------------- + * COMMAND LINE + */ +@@ -878,8 +880,6 @@ on_idle_initialize (gpointer data) + int + main (int argc, char *argv[]) + { +- GMainLoop *loop; +- + /* + * The gnome-keyring startup is not as simple as I wish it could be. + * +diff --git a/daemon/test-shutdown.c b/daemon/test-shutdown.c +new file mode 100644 +index 0000000..b2fdb0c +--- /dev/null ++++ b/daemon/test-shutdown.c +@@ -0,0 +1,115 @@ ++/* ++ Copyright (C) 2014 Red Hat Inc ++ ++ The Gnome Keyring Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Library General Public License as ++ published by the Free Software Foundation; either version 2 of the ++ License, or (at your option) any later version. ++ ++ The Gnome Keyring Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Library General Public License for more details. ++ ++ You should have received a copy of the GNU Library General Public ++ License along with the Gnome Library; see the file COPYING.LIB. If not, ++ . ++ ++ Author: Stef Walter ++*/ ++ ++#include "config.h" ++ ++#include "gkd-test.h" ++ ++#include "daemon/control/gkd-control.h" ++ ++#include "egg/egg-testing.h" ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++typedef struct { ++ GTestDBus *dbus; ++ gchar *directory; ++ GPid pid; ++} Test; ++ ++static void ++setup (Test *test, ++ gconstpointer unused) ++{ ++ test->dbus = g_test_dbus_new (G_TEST_DBUS_NONE); ++ g_test_dbus_up (test->dbus); ++ ++ test->directory = egg_tests_create_scratch_directory (NULL, NULL); ++} ++ ++static void ++teardown (Test *test, ++ gconstpointer unused) ++{ ++ if (test->pid) { ++ if (waitpid (test->pid, NULL, WNOHANG) != test->pid) { ++ kill (test->pid, SIGTERM); ++ g_assert_cmpint (waitpid (test->pid, NULL, 0), ==, test->pid); ++ } ++ g_spawn_close_pid (test->pid); ++ } ++ ++ egg_tests_remove_scratch_directory (test->directory); ++ g_free (test->directory); ++ ++ if (test->dbus) { ++ g_test_dbus_down (test->dbus); ++ g_object_unref (test->dbus); ++ } ++} ++ ++static void ++test_close_connection (Test *test, ++ gconstpointer unused) ++{ ++ const gchar *argv[] = { ++ BUILDDIR "/gnome-keyring-daemon", "--foreground", ++ "--components=secrets,pkcs11", NULL ++ }; ++ ++ const gchar *control; ++ gchar **output; ++ gint status; ++ GPid pid; ++ ++ output = gkd_test_launch_daemon (test->directory, argv, &pid, NULL); ++ ++ control = g_environ_getenv (output, "GNOME_KEYRING_CONTROL"); ++ g_assert_cmpstr (control, !=, NULL); ++ ++ g_assert (gkd_control_unlock (control, "booo")); ++ g_strfreev (output); ++ ++ /* Now close the dbus connection */ ++ g_test_dbus_down (test->dbus); ++ g_object_unref (test->dbus); ++ test->dbus = NULL; ++ ++ /* Daemon should exit */ ++ g_assert_cmpint (waitpid (pid, &status, 0), ==, pid); ++ g_assert_cmpint (status, ==, 0); ++} ++ ++int ++main (int argc, char **argv) ++{ ++ g_test_init (&argc, &argv, NULL); ++ ++ g_test_add ("/daemon/shutdown/dbus-connection", Test, NULL, ++ setup, test_close_connection, teardown); ++ ++ return g_test_run (); ++} +diff --git a/egg/egg-dbus.c b/egg/egg-dbus.c +index 353f6ce..f6323b8 100644 +--- a/egg/egg-dbus.c ++++ b/egg/egg-dbus.c +@@ -38,13 +38,21 @@ + typedef struct { + GSource source; /* the parent GSource */ + DBusConnection *connection; /* the connection to dispatch */ ++ GDestroyNotify closed_cb; /* Callback when closed */ + } DBusGMessageQueue; + + static gboolean + message_queue_prepare (GSource *source, gint *timeout) + { +- DBusConnection *connection = ((DBusGMessageQueue *)source)->connection; ++ DBusGMessageQueue *queue = ((DBusGMessageQueue *)source); ++ DBusConnection *connection = queue->connection; + *timeout = -1; ++ if (queue->closed_cb) { ++ if (!dbus_connection_get_is_connected (connection)) { ++ (queue->closed_cb) (connection); ++ queue->closed_cb = NULL; ++ } ++ } + return (dbus_connection_get_dispatch_status (connection) == DBUS_DISPATCH_DATA_REMAINS); + } + +@@ -96,7 +104,9 @@ typedef struct { + } TimeoutHandler; + + static ConnectionSetup* +-connection_setup_new (GMainContext *context, DBusConnection *connection) ++connection_setup_new (GMainContext *context, ++ DBusConnection *connection, ++ GDestroyNotify closed_cb) + { + ConnectionSetup *cs = g_new0 (ConnectionSetup, 1); + g_assert (context != NULL); +@@ -109,6 +119,7 @@ connection_setup_new (GMainContext *context, DBusConnection *connection) + cs->message_queue_source = g_source_new ((GSourceFuncs *) &message_queue_funcs, + sizeof (DBusGMessageQueue)); + ((DBusGMessageQueue*)cs->message_queue_source)->connection = connection; ++ ((DBusGMessageQueue*)cs->message_queue_source)->closed_cb = closed_cb; + g_source_attach (cs->message_queue_source, cs->context); + } + +@@ -369,13 +380,15 @@ wakeup_main (void *data) + } + + void +-egg_dbus_connect_with_mainloop (DBusConnection *connection, GMainContext *context) ++egg_dbus_connect_with_mainloop (DBusConnection *connection, ++ GMainContext *context, ++ GDestroyNotify close_callback) + { + ConnectionSetup *cs; + + if (context == NULL) + context = g_main_context_default (); +- cs = connection_setup_new (context, connection); ++ cs = connection_setup_new (context, connection, close_callback); + the_setup = cs; + + if (!dbus_connection_set_watch_functions (connection, add_watch, +diff --git a/egg/egg-dbus.h b/egg/egg-dbus.h +index ed87e20..4d328ca 100644 +--- a/egg/egg-dbus.h ++++ b/egg/egg-dbus.h +@@ -28,7 +28,9 @@ + #include + #include + +-void egg_dbus_connect_with_mainloop (DBusConnection *connection, GMainContext *context); ++void egg_dbus_connect_with_mainloop (DBusConnection *connection, ++ GMainContext *context, ++ GDestroyNotify close_callback); + + void egg_dbus_disconnect_from_mainloop (DBusConnection *connection, GMainContext *context); + +-- +1.8.5.3 + diff --git a/SPECS/gnome-keyring.spec b/SPECS/gnome-keyring.spec index cfba2a7..5dc27cc 100644 --- a/SPECS/gnome-keyring.spec +++ b/SPECS/gnome-keyring.spec @@ -7,7 +7,7 @@ Summary: Framework for managing passwords and other secrets Name: gnome-keyring Version: 3.8.2 -Release: 3%{?dist} +Release: 7%{?dist} License: GPLv2+ and LGPLv2+ Group: System Environment/Libraries #VCS: git:git://git.gnome.org/gnome-keyring @@ -18,6 +18,8 @@ Patch0: 0002-daemon-Add-gnome-keyring-daemon-manual-page.patch Patch1: 0001-Some-man-page-updates-for-gnome-keyring-daemon.patch Patch2: 0002-Add-a-man-page-for-the-gnome-keyring-tool.patch Patch3: 0003-Add-an-alias-man-page-for-gnome-keyring-3.patch +Patch4: daemon-Exit-gnome-keyring-daemon-when-the-DBus-con.patch +Patch5: 0001-pam-Fix-issue-with-changed-password-not-unlocking-ke.patch BuildRequires: glib2-devel >= %{glib2_version} BuildRequires: gcr-devel >= %{gcr_version} @@ -65,6 +67,8 @@ automatically unlock the "login" keyring when the user logs in. %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 +%patch5 -p1 autoreconf -i -f @@ -127,6 +131,19 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas >&/dev/null || : %changelog +* Tue Mar 18 2014 Zeeshan Ali - 3.8.2-7 +- Fix issue with changed password not unlocking keyring (related: rhbz#1075715). + +* Tue Mar 11 2014 Zeeshan Ali - 3.8.2-6 +- daemon: Exit gnome-keyring-daemon when the DBus connection + closes (related: rhbz#1030671). + +* Fri Jan 24 2014 Daniel Mach - 3.8.2-5 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 3.8.2-4 +- Mass rebuild 2013-12-27 + * Wed Nov 6 2013 Matthias Clasen - 3.8.2-3 - Add man pages - Resolves: #948922