Update to 3.18.1

This commit is contained in:
Kalev Lember 2015-10-17 16:26:20 +02:00
parent cce4de0892
commit 058244c7ef
5 changed files with 8 additions and 666 deletions

1
.gitignore vendored
View File

@ -58,3 +58,4 @@ gnome-keyring-2.31.4.tar.bz2
/gnome-keyring-3.16.0.tar.xz
/gnome-keyring-3.17.91.tar.xz
/gnome-keyring-3.18.0.tar.xz
/gnome-keyring-3.18.1.tar.xz

View File

@ -1,56 +0,0 @@
From 3cf744f67939dc23c2cc8715cda999a7ec13f1b6 Mon Sep 17 00:00:00 2001
From: "Jan Alexander Steffens (heftig)" <jan.steffens@gmail.com>
Date: Tue, 6 Oct 2015 21:12:49 +0200
Subject: [PATCH] dbus: Initialize secret service before claiming name
Otherwise incoming calls can race with our initialization. Activating
calls are even guaranteed to arrive before we have set up the service.
https://bugzilla.gnome.org/show_bug.cgi?id=756006
---
daemon/dbus/gkd-dbus-secrets.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/daemon/dbus/gkd-dbus-secrets.c b/daemon/dbus/gkd-dbus-secrets.c
index 2712a33..207524b 100644
--- a/daemon/dbus/gkd-dbus-secrets.c
+++ b/daemon/dbus/gkd-dbus-secrets.c
@@ -74,6 +74,7 @@ gkd_dbus_secrets_startup (void)
guint res;
g_return_val_if_fail (dbus_conn, FALSE);
+ g_return_val_if_fail (!secrets_service, FALSE);
#ifdef WITH_DEBUG
service = g_getenv ("GNOME_KEYRING_TEST_SERVICE");
@@ -86,6 +87,9 @@ gkd_dbus_secrets_startup (void)
/* Figure out which slot to use */
slot = calculate_secrets_slot ();
g_return_val_if_fail (slot, FALSE);
+ secrets_service = g_object_new (GKD_SECRET_TYPE_SERVICE,
+ "connection", dbus_conn, "pkcs11-slot", slot, NULL);
+ g_object_unref (slot);
/* Try and grab our name */
request_variant = g_dbus_connection_call_sync (dbus_conn,
@@ -120,16 +124,12 @@ gkd_dbus_secrets_startup (void)
g_message ("another secret service is running");
break;
default:
+ g_clear_object (&secrets_service);
g_return_val_if_reached (FALSE);
break;
};
}
- g_return_val_if_fail (!secrets_service, FALSE);
- secrets_service = g_object_new (GKD_SECRET_TYPE_SERVICE,
- "connection", dbus_conn, "pkcs11-slot", slot, NULL);
-
- g_object_unref (slot);
return TRUE;
}
--
2.5.0

View File

@ -1,602 +0,0 @@
From 662d241e78319b431d60be7a3b8d9eccb1cc7cf5 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 15 Oct 2015 14:37:33 -0400
Subject: [PATCH 1/2] daemon: fork before threads are spawned
It's not really a good idea to fork after glib has initialized,
since it has helper threads that may have taken locks etc.
This commit forks really early to prevent locks from leaking
and causing deadlock.
---
daemon/gkd-main.c | 88 +++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 69 insertions(+), 19 deletions(-)
diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c
index f567633..4925ee2 100644
--- a/daemon/gkd-main.c
+++ b/daemon/gkd-main.c
@@ -98,60 +98,61 @@ EGG_SECURE_DECLARE (daemon_main);
# else
# define DEFAULT_COMPONENTS GKD_COMP_PKCS11 "," GKD_COMP_SECRETS
# endif
#endif
/*
* If --login is used and then daemon is not initialized within LOGIN_TIMEOUT
* seconds, then we exit. See on_login_timeout() below.
*/
#define LOGIN_TIMEOUT 120
static gchar* run_components = DEFAULT_COMPONENTS;
static gboolean pkcs11_started = FALSE;
static gboolean secrets_started = FALSE;
static gboolean ssh_started = FALSE;
static gboolean dbus_started = FALSE;
static gboolean run_foreground = FALSE;
static gboolean run_daemonized = FALSE;
static gboolean run_version = FALSE;
static gboolean run_for_login = FALSE;
static gboolean perform_unlock = FALSE;
static gboolean run_for_start = FALSE;
static gboolean run_for_replace = FALSE;
static gchar* login_password = NULL;
static gchar* control_directory = NULL;
static guint timeout_id = 0;
static gboolean initialization_completed = FALSE;
static GMainLoop *loop = NULL;
+static int parent_wakeup_fd = -1;
static GOptionEntry option_entries[] = {
{ "start", 's', 0, G_OPTION_ARG_NONE, &run_for_start,
"Start a dameon or initialize an already running daemon." },
{ "replace", 'r', 0, G_OPTION_ARG_NONE, &run_for_replace,
"Replace the daemon for this desktop login environment." },
{ "foreground", 'f', 0, G_OPTION_ARG_NONE, &run_foreground,
"Run in the foreground", NULL },
{ "daemonize", 'd', 0, G_OPTION_ARG_NONE, &run_daemonized,
"Run as a daemon", NULL },
{ "login", 'l', 0, G_OPTION_ARG_NONE, &run_for_login,
"Run by PAM for a user login. Read login password from stdin", NULL },
{ "unlock", 0, 0, G_OPTION_ARG_NONE, &perform_unlock,
"Prompt for login keyring password, or read from stdin", NULL },
{ "components", 'c', 0, G_OPTION_ARG_STRING, &run_components,
"The optional components to run", DEFAULT_COMPONENTS },
{ "control-directory", 'C', 0, G_OPTION_ARG_FILENAME, &control_directory,
"The directory for sockets and control data", NULL },
{ "version", 'V', 0, G_OPTION_ARG_NONE, &run_version,
"Show the version number and exit.", NULL },
{ NULL }
};
static void
parse_arguments (int *argc, char** argv[])
{
GError *err = NULL;
GOptionContext *context;
context = g_option_context_new ("- The Gnome Keyring Daemon");
@@ -474,60 +475,110 @@ read_login_password (int fd)
}
egg_secure_free (buf);
return ret;
}
static void
cleanup_and_exit (int code)
{
egg_cleanup_perform ();
exit (code);
}
static void
clear_login_password (void)
{
if(login_password)
egg_secure_strfree (login_password);
login_password = NULL;
}
static void
print_environment (void)
{
const gchar **env;
for (env = gkd_util_get_environment (); *env; ++env)
printf ("%s\n", *env);
fflush (stdout);
}
+
+static void
+print_environment_from_fd (int fd)
+{
+ char *output;
+ gsize output_size;
+ gsize bytes_read;
+
+ bytes_read = read (fd, &output_size, sizeof (output_size));
+
+ if (bytes_read < sizeof (output_size))
+ exit (1);
+
+ output = g_malloc0 (output_size);
+ bytes_read = read (fd, output, output_size);
+
+ if (bytes_read < output_size)
+ exit (1);
+
+ printf ("%s\n", output);
+ fflush (stdout);
+ g_free (output);
+}
+
+static void
+send_environment_and_finish_parent (int fd)
+{
+ char *output;
+ gsize output_size;
+ gsize bytes_written;
+
+ if (fd < 0) {
+ print_environment ();
+ return;
+ }
+
+ output = g_strjoinv ("\n", (gchar **) gkd_util_get_environment ());
+ output_size = strlen (output) + 1;
+ bytes_written = write (fd, &output_size, sizeof (output_size));
+
+ if (bytes_written < sizeof (output_size))
+ exit (1);
+
+ bytes_written = write (fd, output, output_size);
+ if (bytes_written < output_size)
+ exit (1);
+
+ g_free (output);
+}
+
static gboolean
initialize_daemon_at (const gchar *directory)
{
gchar **ourenv, **daemonenv, **e;
/* Exchange environment variables, and try to initialize daemon */
ourenv = gkd_util_build_environment (GKD_UTIL_IN_ENVIRONMENT);
daemonenv = gkd_control_initialize (directory, run_components,
(const gchar**)ourenv);
g_strfreev (ourenv);
/* Initialization failed, start this process up as a daemon */
if (!daemonenv)
return FALSE;
/* Setup all the environment variables we were passed */
for (e = daemonenv; *e; ++e)
gkd_util_push_environment_full (*e);
g_strfreev (daemonenv);
return TRUE;
}
static gboolean
replace_daemon_at (const gchar *directory)
{
gboolean ret;
/*
* The first control_directory is the environment one, always
@@ -577,136 +628,126 @@ discover_other_daemon (DiscoverFunc callback, gboolean acquire)
/* Or the default location when no evironment variable */
control_env = g_getenv ("XDG_RUNTIME_DIR");
if (control_env) {
control = g_build_filename (control_env, "keyring", NULL);
ret = (callback) (control);
g_free (control);
if (ret == TRUE)
return TRUE;
}
/* See if we can contact a daemon running, that didn't set an env variable */
if (acquire && !gkd_dbus_singleton_acquire (&acquired))
return FALSE;
/* We're the main daemon */
if (acquired)
return FALSE;
control = gkd_dbus_singleton_control ();
if (control) {
ret = (callback) (control);
g_free (control);
if (ret == TRUE)
return TRUE;
}
return FALSE;
}
-static void
+static int
fork_and_print_environment (void)
{
int status;
pid_t pid;
- int fd, i;
+ int wakeup_fds[2] = { -1, -1 };
- if (run_foreground) {
- print_environment ();
- return;
- }
+ g_unix_open_pipe (wakeup_fds, FD_CLOEXEC, NULL);
pid = fork ();
if (pid != 0) {
-
/* Here we are in the initial process */
if (run_daemonized) {
/* Initial process, waits for intermediate child */
if (pid == -1)
exit (1);
waitpid (pid, &status, 0);
if (WEXITSTATUS (status) != 0)
exit (WEXITSTATUS (status));
} else {
/* Not double forking */
- print_environment ();
+ print_environment_from_fd (wakeup_fds[0]);
}
/* The initial process exits successfully */
exit (0);
}
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 ();
if (pid != 0) {
-
/* Here we are in the intermediate child process */
/*
* This process exits, so that the final child will inherit
* init as parent to avoid zombies
*/
if (pid == -1)
exit (1);
/* We've done two forks. */
- print_environment ();
+ print_environment_from_fd (wakeup_fds[0]);
/* The intermediate child exits */
exit (0);
}
}
/* Here we are in the resulting daemon or background process. */
-
- for (i = 0; i < 3; ++i) {
- fd = open ("/dev/null", O_RDONLY);
- sane_dup2 (fd, i);
- close (fd);
- }
+ return wakeup_fds[1];
}
static gboolean
gkr_daemon_startup_steps (const gchar *components)
{
g_assert (components);
/*
* Startup that must run before forking.
* Note that we set initialized flags early so that two
* initializations don't overlap
*/
#ifdef WITH_SSH
if (strstr (components, GKD_COMP_SSH)) {
if (ssh_started) {
g_message ("The SSH agent was already initialized");
} else {
ssh_started = TRUE;
if (!gkd_daemon_startup_ssh ()) {
ssh_started = FALSE;
return FALSE;
}
}
}
#endif
return TRUE;
}
@@ -802,159 +843,168 @@ gkd_main_complete_initialization (const gchar *components)
static gboolean
on_login_timeout (gpointer data)
{
if (!initialization_completed)
cleanup_and_exit (0);
return FALSE;
}
int
main (int argc, char *argv[])
{
/*
* The gnome-keyring startup is not as simple as I wish it could be.
*
* It's often started in the primordial stages of a session, where
* there's no DBus, and no proper X display. This is the strange world
* of PAM.
*
* When started with the --login option, we do as little initialization
* as possible. We expect a login password on the stdin, and unlock
* or create the login keyring.
*
* Then later we expect gnome-keyring-dameon to be run again with the
* --start option. This second gnome-keyring-daemon will hook the
* original daemon up with environment variables necessary to initialize
* itself and bring it into the session. This second daemon usually exits.
*
* Without either of these options, we follow a more boring and
* predictable startup.
*/
+ int fd, i;
/*
* Before we do ANYTHING, we drop privileges so we don't become
* a security issue ourselves.
*/
gkd_capability_obtain_capability_and_drop_privileges ();
#ifdef WITH_STRICT
g_setenv ("DBUS_FATAL_WARNINGS", "1", FALSE);
if (!g_getenv ("G_DEBUG"))
g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
#endif
#if !GLIB_CHECK_VERSION(2,35,0)
g_type_init ();
#endif
#ifdef HAVE_LOCALE_H
/* internationalisation */
setlocale (LC_ALL, "");
#endif
#ifdef HAVE_GETTEXT
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
textdomain (GETTEXT_PACKAGE);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif
egg_libgcrypt_initialize ();
/* Send all warning or error messages to syslog */
prepare_logging ();
parse_arguments (&argc, &argv);
/* The --version option. This is machine parseable output */
if (run_version) {
g_print ("gnome-keyring-daemon: %s\n", VERSION);
g_print ("testing: %s\n",
#ifdef WITH_DEBUG
"enabled");
#else
"disabled");
#endif
exit (0);
}
+ /* The whole forking and daemonizing dance starts here. */
+ parent_wakeup_fd = fork_and_print_environment();
+
/* The --start option */
if (run_for_start) {
if (discover_other_daemon (initialize_daemon_at, TRUE)) {
/*
* Another daemon was initialized, print out environment
* for any callers, and quit or go comatose.
*/
- print_environment ();
+ send_environment_and_finish_parent (parent_wakeup_fd);
if (run_foreground)
while (sleep(0x08000000) == 0);
cleanup_and_exit (0);
}
/* The --replace option */
} else if (run_for_replace) {
discover_other_daemon (replace_daemon_at, FALSE);
if (control_directory)
g_message ("Replacing daemon, using directory: %s", control_directory);
else
g_message ("Could not find daemon to replace, staring normally");
}
/* Initialize the main directory */
gkd_util_init_master_directory (control_directory);
/* Initialize our daemon main loop and threading */
loop = g_main_loop_new (NULL, FALSE);
/* Initialize our control socket */
if (!gkd_control_listen ())
return FALSE;
if (perform_unlock) {
login_password = read_login_password (STDIN);
atexit (clear_login_password);
}
/* The --login option. Delayed initialization */
if (run_for_login) {
timeout_id = g_timeout_add_seconds (LOGIN_TIMEOUT, (GSourceFunc) on_login_timeout, NULL);
/* Not a login daemon. Startup stuff now.*/
} else {
/* These are things that can run before forking */
if (!gkr_daemon_startup_steps (run_components))
cleanup_and_exit (1);
}
signal (SIGPIPE, SIG_IGN);
- /* The whole forking and daemonizing dance starts here. */
- fork_and_print_environment();
+ for (i = 0; i < 3; ++i) {
+ fd = open ("/dev/null", O_RDONLY);
+ sane_dup2 (fd, i);
+ close (fd);
+ }
+
+ send_environment_and_finish_parent (parent_wakeup_fd);
g_unix_signal_add (SIGTERM, on_signal_term, loop);
g_unix_signal_add (SIGHUP, on_signal_term, loop);
g_unix_signal_add (SIGUSR1, on_signal_usr1, loop);
/* Prepare logging a second time, since we may be in a different process */
prepare_logging();
/* Remainder initialization after forking, if initialization not delayed */
if (!run_for_login) {
gkr_daemon_initialize_steps (run_components);
/*
* Close stdout and so that the caller knows that we're
* all initialized, (when run in foreground mode).
*
* However since some logging goes to stdout, redirect that
* to stderr. We don't want the caller confusing that with
* valid output anyway.
*/
if (dup2 (2, 1) < 1)
g_warning ("couldn't redirect stdout to stderr");
g_debug ("initialization complete");
}
g_main_loop_run (loop);
/* This wraps everything up in order */
egg_cleanup_perform ();
--
2.5.0
From cfdb233e75f444ee7ab780b888f0928f175c4f73 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 15 Oct 2015 16:07:22 -0400
Subject: [PATCH 2/2] daemon: kill off foreground proceses when session dies
Right now gnome-keyring will keep processes around forever
in some cases. They need to die when the session goes away,
at least.
---
daemon/gkd-main.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c
index 4925ee2..db32fa2 100644
--- a/daemon/gkd-main.c
+++ b/daemon/gkd-main.c
@@ -902,62 +902,70 @@ main (int argc, char *argv[])
egg_libgcrypt_initialize ();
/* Send all warning or error messages to syslog */
prepare_logging ();
parse_arguments (&argc, &argv);
/* The --version option. This is machine parseable output */
if (run_version) {
g_print ("gnome-keyring-daemon: %s\n", VERSION);
g_print ("testing: %s\n",
#ifdef WITH_DEBUG
"enabled");
#else
"disabled");
#endif
exit (0);
}
/* The whole forking and daemonizing dance starts here. */
parent_wakeup_fd = fork_and_print_environment();
/* The --start option */
if (run_for_start) {
if (discover_other_daemon (initialize_daemon_at, TRUE)) {
/*
* Another daemon was initialized, print out environment
* for any callers, and quit or go comatose.
*/
send_environment_and_finish_parent (parent_wakeup_fd);
- if (run_foreground)
- while (sleep(0x08000000) == 0);
+ if (run_foreground) {
+ GDBusConnection *connection;
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION,
+ NULL,
+ NULL);
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+ loop = NULL;
+ }
cleanup_and_exit (0);
}
/* The --replace option */
} else if (run_for_replace) {
discover_other_daemon (replace_daemon_at, FALSE);
if (control_directory)
g_message ("Replacing daemon, using directory: %s", control_directory);
else
g_message ("Could not find daemon to replace, staring normally");
}
/* Initialize the main directory */
gkd_util_init_master_directory (control_directory);
/* Initialize our daemon main loop and threading */
loop = g_main_loop_new (NULL, FALSE);
/* Initialize our control socket */
if (!gkd_control_listen ())
return FALSE;
if (perform_unlock) {
login_password = read_login_password (STDIN);
atexit (clear_login_password);
}
/* The --login option. Delayed initialization */
if (run_for_login) {
timeout_id = g_timeout_add_seconds (LOGIN_TIMEOUT, (GSourceFunc) on_login_timeout, NULL);
--
2.5.0

View File

@ -5,14 +5,12 @@
Summary: Framework for managing passwords and other secrets
Name: gnome-keyring
Version: 3.18.0
Release: 4%{?dist}
Version: 3.18.1
Release: 1%{?dist}
License: GPLv2+ and LGPLv2+
Group: System Environment/Libraries
#VCS: git:git://git.gnome.org/gnome-keyring
Source: https://download.gnome.org/sources/%{name}/3.15/%{name}-%{version}.tar.xz
Patch0: 0001-dbus-Initialize-secret-service-before-claiming-name.patch
Patch1: fix-autologin.patch
Source: https://download.gnome.org/sources/%{name}/3.18/%{name}-%{version}.tar.xz
URL: https://wiki.gnome.org/Projects/GnomeKeyring
BuildRequires: pkgconfig(dbus-1) >= %{dbus_version}
@ -53,8 +51,6 @@ automatically unlock the "login" keyring when the user logs in.
%prep
%setup -q -n gnome-keyring-%{version}
%patch0 -p1
%patch1 -p1
%build
%configure \
@ -111,6 +107,9 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas >&/dev/null || :
%changelog
* Sat Oct 17 2015 Kalev Lember <klember@redhat.com> - 3.18.1-1
- Update to 3.18.1
* Thu Oct 15 2015 Ray Strode <rstrode@redhat.com> 3.18.0-4
- Fix password handoff in non-autologin case
- Remove unneccessary part of autologin fix

View File

@ -1 +1 @@
6bdefb3f3ec851d800040c029fdf3f86 gnome-keyring-3.18.0.tar.xz
329c75f452028e7dc20b3542ffcb9714 gnome-keyring-3.18.1.tar.xz