[gnome-keyring] [daemon] Refactor the startup.



commit 087c7b561acd00f93e903fa3b7a9f2f26eddfba7
Author: Stef Walter <stef memberwebs com>
Date:   Sat Dec 19 22:37:52 2009 +0000

    [daemon] Refactor the startup.
    
     * Add support for initializing seperate parts of daemon separately.
     * Add autostart files for various components.
     * Use simpler control protocol.

 configure.in                                       |    7 +-
 daemon/.gitignore                                  |   11 +-
 daemon/Makefile.am                                 |    7 +-
 daemon/control/gkd-control-client.c                |   20 +-
 daemon/control/gkd-control-codes.h                 |   52 +----
 daemon/control/gkd-control-server.c                |   83 +++-----
 daemon/control/gkd-control.h                       |    1 +
 daemon/control/tests/Makefile.am                   |   26 ++-
 daemon/control/tests/test-control-change           |  Bin 96222 -> 0 bytes
 daemon/control/tests/test-control-init.c           |   30 +++
 daemon/control/tests/test-control-unlock           |  Bin 96149 -> 0 bytes
 daemon/data/gnome-keyring.schemas.in               |   32 ++-
 daemon/dbus/gkd-dbus-environment.c                 |   94 +++++----
 daemon/dbus/gkd-dbus-secrets.c                     |   38 +++-
 daemon/dbus/gkd-dbus.h                             |    6 +-
 daemon/gkd-main.c                                  |  213 +++++++++-----------
 daemon/gkd-main.h                                  |    4 +-
 daemon/gkd-util.c                                  |   28 +++
 daemon/gkd-util.h                                  |    7 +-
 ...op.in.in => gnome-keyring-pkcs11.desktop.in.in} |    6 +-
 ...p.in.in => gnome-keyring-secrets.desktop.in.in} |    6 +-
 ...sktop.in.in => gnome-keyring-ssh.desktop.in.in} |    6 +-
 daemon/org.gnome.keyring.service.in                |    2 +-
 pam/gkr-pam-client.c                               |   24 +--
 pam/gkr-pam-module.c                               |   90 +++------
 25 files changed, 408 insertions(+), 385 deletions(-)
---
diff --git a/configure.in b/configure.in
index a4bc774..3422cd5 100644
--- a/configure.in
+++ b/configure.in
@@ -67,9 +67,6 @@ AC_SUBST(GTK_CFLAGS)
 AC_SUBST(GTK_LIBS)
 
 AM_GCONF_SOURCE_2
-PKG_CHECK_MODULES(GCONF, gconf-2.0)
-DAEMON_CFLAGS="$DAEMON_CFLAGS $GCONF_CFLAGS"
-DAEMON_LIBS="$DAEMON_LIBS $GCONF_LIBS"
 
 GETTEXT_PACKAGE=gnome-keyring
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [The gettext domain name])
@@ -549,7 +546,9 @@ AC_SUBST(BINDIR)
 AC_OUTPUT([
 Makefile
 daemon/Makefile
-daemon/gnome-keyring-daemon.desktop.in
+daemon/gnome-keyring-pkcs11.desktop.in
+daemon/gnome-keyring-secrets.desktop.in
+daemon/gnome-keyring-ssh.desktop.in
 daemon/control/Makefile
 daemon/control/tests/Makefile
 daemon/data/Makefile
diff --git a/daemon/.gitignore b/daemon/.gitignore
index f6d0066..1fdb294 100644
--- a/daemon/.gitignore
+++ b/daemon/.gitignore
@@ -5,9 +5,16 @@ Makefile.in
 /gnome-keyring-ask
 /gnome-keyring-daemon
 /org.gnome.keyring.service
-/gnome-keyring-daemon.desktop
-/gnome-keyring-daemon.desktop.in
+/gnome-keyring-pkcs11.desktop
+/gnome-keyring-pkcs11.desktop.in
+/gnome-keyring-secrets.desktop
+/gnome-keyring-secrets.desktop.in
+/gnome-keyring-ssh.desktop
+/gnome-keyring-ssh.desktop.in
 *-marshal.[ch]
 gnome-keyring-prompt
 run-auto-test*
 
+/control/tests/test-control-change
+/control/tests/test-control-init
+/control/tests/test-control-unlock
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 7ddb1f2..1958193 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -58,7 +58,7 @@ EXTRA_DIST = \
 CLEANFILES = \
 	org.gnome.keyring.service \
 	$(desktop_DATA)
-	
+
 servicedir       = $(DBUS_SERVICES_DIR)
 service_in_files = org.gnome.keyring.service.in
 service_DATA     = $(service_in_files:.service.in=.service)
@@ -68,7 +68,10 @@ service_PATH     = $(VALGRIND_RUN)$(bindir)
 $(service_DATA): $(service_in_files) Makefile
 	@sed -e "s|\ PATH\@|$(service_PATH)|" $< > $@
 
-desktop_in_files = gnome-keyring-daemon.desktop.in
+desktop_in_files = \
+	gnome-keyring-pkcs11.desktop.in \
+	gnome-keyring-secrets.desktop.in \
+	gnome-keyring-ssh.desktop.in
 desktopdir       = $(sysconfdir)/xdg/autostart
 desktop_DATA     = $(desktop_in_files:.desktop.in=.desktop)
 
diff --git a/daemon/control/gkd-control-client.c b/daemon/control/gkd-control-client.c
index 43a7cc4..f7ad97e 100644
--- a/daemon/control/gkd-control-client.c
+++ b/daemon/control/gkd-control-client.c
@@ -180,7 +180,8 @@ control_chat (const gchar *directory, EggBuffer *buffer)
 
 
 gchar**
-gkd_control_initialize (const gchar *directory, const gchar **envp)
+gkd_control_initialize (const gchar *directory, const gchar *components,
+                        const gchar **envp)
 {
 	gchar **env = NULL;
 	EggBuffer buffer;
@@ -190,7 +191,8 @@ gkd_control_initialize (const gchar *directory, const gchar **envp)
 
 	egg_buffer_init_full (&buffer, 128, g_realloc);
 	egg_buffer_add_uint32 (&buffer, 0);
-	egg_buffer_add_uint32 (&buffer, GNOME_KEYRING_OP_PREPARE_ENVIRONMENT);
+	egg_buffer_add_uint32 (&buffer, GKD_CONTROL_OP_INITIALIZE);
+	egg_buffer_add_string (&buffer, components);
 	egg_buffer_add_stringv (&buffer, (const char**)envp);
 	egg_buffer_set_uint32 (&buffer, 0, buffer.len);
 
@@ -200,12 +202,12 @@ gkd_control_initialize (const gchar *directory, const gchar **envp)
 
 	if (ret)
 		ret = egg_buffer_get_uint32 (&buffer, offset, &offset, &res);
-	if (ret && res == GNOME_KEYRING_RESULT_OK)
+	if (ret && res == GKD_CONTROL_RESULT_OK)
 	      ret = egg_buffer_get_stringv (&buffer, offset, &offset, &env, g_realloc);
 
 	egg_buffer_uninit (&buffer);
 
-	if (!ret || res != GNOME_KEYRING_RESULT_OK) {
+	if (!ret || res != GKD_CONTROL_RESULT_OK) {
 		g_message ("couldn't initialize running daemon");
 		return NULL;
 	}
@@ -223,8 +225,7 @@ gkd_control_unlock (const gchar *directory, const gchar *password)
 
 	egg_buffer_init_full (&buffer, 128, egg_secure_realloc);
 	egg_buffer_add_uint32 (&buffer, 0);
-	egg_buffer_add_uint32 (&buffer, GNOME_KEYRING_OP_UNLOCK_KEYRING);
-	egg_buffer_add_string (&buffer, "login");
+	egg_buffer_add_uint32 (&buffer, GKD_CONTROL_OP_UNLOCK);
 	egg_buffer_add_string (&buffer, password);
 	egg_buffer_set_uint32 (&buffer, 0, buffer.len);
 
@@ -237,7 +238,7 @@ gkd_control_unlock (const gchar *directory, const gchar *password)
 
 	egg_buffer_uninit (&buffer);
 
-	if (!ret || res != GNOME_KEYRING_RESULT_OK) {
+	if (!ret || res != GKD_CONTROL_RESULT_OK) {
 		g_message ("couldn't unlock login keyring");
 		return FALSE;
 	}
@@ -256,8 +257,7 @@ gkd_control_change_lock (const gchar *directory, const gchar *original,
 
 	egg_buffer_init_full (&buffer, 128, egg_secure_realloc);
 	egg_buffer_add_uint32 (&buffer, 0);
-	egg_buffer_add_uint32 (&buffer, GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD);
-	egg_buffer_add_string (&buffer, "login");
+	egg_buffer_add_uint32 (&buffer, GKD_CONTROL_OP_CHANGE);
 	egg_buffer_add_string (&buffer, original);
 	egg_buffer_add_string (&buffer, password);
 	egg_buffer_set_uint32 (&buffer, 0, buffer.len);
@@ -271,7 +271,7 @@ gkd_control_change_lock (const gchar *directory, const gchar *original,
 
 	egg_buffer_uninit (&buffer);
 
-	if (!ret || res != GNOME_KEYRING_RESULT_OK) {
+	if (!ret || res != GKD_CONTROL_RESULT_OK) {
 		g_message ("couldn't change lock on login keyring");
 		return FALSE;
 	}
diff --git a/daemon/control/gkd-control-codes.h b/daemon/control/gkd-control-codes.h
index a982c14..159ac48 100644
--- a/daemon/control/gkd-control-codes.h
+++ b/daemon/control/gkd-control-codes.h
@@ -19,53 +19,19 @@
  * 02111-1307, USA.
  */
 
-#ifndef __GKD_CONTROL_PRIVATE_H__
-#define __GKD_CONTROL_PRIVATE_H__
+#ifndef __GKD_CONTROL_CODES_H__
+#define __GKD_CONTROL_CODES_H__
 
-/* All the old op codes, most are no longer used */
 enum {
-	GNOME_KEYRING_OP_LOCK_ALL,
-	GNOME_KEYRING_OP_SET_DEFAULT_KEYRING,
-	GNOME_KEYRING_OP_GET_DEFAULT_KEYRING,
-	GNOME_KEYRING_OP_LIST_KEYRINGS,
-	GNOME_KEYRING_OP_CREATE_KEYRING,
-	GNOME_KEYRING_OP_LOCK_KEYRING,
-	GNOME_KEYRING_OP_UNLOCK_KEYRING,
-	GNOME_KEYRING_OP_DELETE_KEYRING,
-	GNOME_KEYRING_OP_GET_KEYRING_INFO,
-	GNOME_KEYRING_OP_SET_KEYRING_INFO,
-	GNOME_KEYRING_OP_LIST_ITEMS,
-	GNOME_KEYRING_OP_FIND,
-	GNOME_KEYRING_OP_CREATE_ITEM,
-	GNOME_KEYRING_OP_DELETE_ITEM,
-	GNOME_KEYRING_OP_GET_ITEM_INFO,
-	GNOME_KEYRING_OP_SET_ITEM_INFO,
-	GNOME_KEYRING_OP_GET_ITEM_ATTRIBUTES,
-	GNOME_KEYRING_OP_SET_ITEM_ATTRIBUTES,
-	GNOME_KEYRING_OP_GET_ITEM_ACL,
-	GNOME_KEYRING_OP_SET_ITEM_ACL,
-	GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD,
-	GNOME_KEYRING_OP_SET_DAEMON_DISPLAY,
-	GNOME_KEYRING_OP_GET_ITEM_INFO_FULL,
-	GNOME_KEYRING_OP_PREPARE_ENVIRONMENT,
-
-	/* Add new ops here */
-
-	GNOME_KEYRING_NUM_OPS
+	GKD_CONTROL_OP_INITIALIZE,
+	GKD_CONTROL_OP_UNLOCK,
+	GKD_CONTROL_OP_CHANGE,
 };
 
-/* All the old result codes */
 enum {
-	GNOME_KEYRING_RESULT_OK,
-	GNOME_KEYRING_RESULT_DENIED,
-	GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON,
-	GNOME_KEYRING_RESULT_ALREADY_UNLOCKED,
-	GNOME_KEYRING_RESULT_NO_SUCH_KEYRING,
-	GNOME_KEYRING_RESULT_BAD_ARGUMENTS,
-	GNOME_KEYRING_RESULT_IO_ERROR,
-	GNOME_KEYRING_RESULT_CANCELLED,
-	GNOME_KEYRING_RESULT_KEYRING_ALREADY_EXISTS,
-	GNOME_KEYRING_RESULT_NO_MATCH
+	GKD_CONTROL_RESULT_OK,
+	GKD_CONTROL_RESULT_DENIED,
+	GKD_CONTROL_RESULT_FAILED
 };
 
-#endif /* __GKD_CONTROL_PRIVATE_H__ */
+#endif /* __GKD_CONTROL_CODES_H__ */
diff --git a/daemon/control/gkd-control-server.c b/daemon/control/gkd-control-server.c
index fcb4daa..db7ea29 100644
--- a/daemon/control/gkd-control-server.c
+++ b/daemon/control/gkd-control-server.c
@@ -68,85 +68,67 @@ control_data_free (gpointer data)
 }
 
 static guint32
-control_unlock_keyring (EggBuffer *buffer)
+control_unlock_login (EggBuffer *buffer)
 {
-	gchar *name;
 	gchar *master;
 	gsize offset = 8;
 	guint32 res;
 
-	if (!egg_buffer_get_string (buffer, offset, &offset, &name, g_realloc))
-		return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+	if (!egg_buffer_get_string (buffer, offset, &offset, &master, egg_secure_realloc))
+		return GKD_CONTROL_RESULT_FAILED;
 
-	if (!egg_buffer_get_string (buffer, offset, &offset, &master, egg_secure_realloc)) {
-		g_free (name);
-		return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
-	}
-
-	if (!name || g_str_equal (name, "login")) {
-		if (gkd_login_unlock (master))
-			res = GNOME_KEYRING_RESULT_OK;
-		else
-			res = GNOME_KEYRING_RESULT_DENIED;
-	} else {
-		g_message ("keyring request not supported");
-		res = GNOME_KEYRING_RESULT_NO_SUCH_KEYRING;
-	}
+	if (gkd_login_unlock (master))
+		res = GKD_CONTROL_RESULT_OK;
+	else
+		res = GKD_CONTROL_RESULT_DENIED;
 
 	egg_secure_strfree (master);
-	g_free (name);
 	return res;
 }
 
 static guint32
-control_change_keyring_password (EggBuffer *buffer)
+control_change_login (EggBuffer *buffer)
 {
 	gsize offset = 8;
 	guint32 res;
-	gchar *name;
 	gchar *master;
 	gchar *original;
 
-	if (!egg_buffer_get_string (buffer, offset, &offset, &name, g_realloc))
-		return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
-
 	if (!egg_buffer_get_string (buffer, offset, &offset, &original, egg_secure_realloc)) {
-		g_free (name);
-		return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+		return GKD_CONTROL_RESULT_FAILED;
 	}
 
 	if (!egg_buffer_get_string (buffer, offset, &offset, &master, egg_secure_realloc)) {
 		egg_secure_strfree (original);
-		g_free (name);
-		return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+		return GKD_CONTROL_RESULT_FAILED;
 	}
 
-	if (!name || g_str_equal (name, "login")) {
-		if (gkd_login_change_lock (original, master))
-			res = GNOME_KEYRING_RESULT_OK;
-		else
-			res = GNOME_KEYRING_RESULT_DENIED;
-	} else {
-		g_message ("keyring request not supported");
-		res = GNOME_KEYRING_RESULT_NO_SUCH_KEYRING;
-	}
+	if (gkd_login_change_lock (original, master))
+		res = GKD_CONTROL_RESULT_OK;
+	else
+		res = GKD_CONTROL_RESULT_DENIED;
 
 	egg_secure_strfree (master);
 	egg_secure_strfree (original);
-	g_free (name);
 	return res;
 }
 
 static guint32
-control_prepare_environment (EggBuffer *buffer)
+control_initialize_components (EggBuffer *buffer)
 {
+	gchar *components;
 	gchar **environment, **e;
 	gsize offset = 8;
 	gchar *x;
 	int i;
 
-	if (!egg_buffer_get_stringv (buffer, offset, &offset, &environment, g_realloc))
-		return GNOME_KEYRING_RESULT_BAD_ARGUMENTS;
+	if (!egg_buffer_get_string (buffer, offset, &offset, &components, g_realloc))
+		return GKD_CONTROL_RESULT_FAILED;
+
+	if (!egg_buffer_get_stringv (buffer, offset, &offset, &environment, g_realloc)) {
+		g_free (components);
+		return GKD_CONTROL_RESULT_FAILED;
+	}
 
 	/* Accept environment from outside */
 	for (e = environment; *e; ++e) {
@@ -169,8 +151,10 @@ control_prepare_environment (EggBuffer *buffer)
 	 * We've now definitely received everything we need to run. Ask
 	 * the daemon to complete the initialization.
 	 */
-	gkd_main_complete_initialization ();
-	return GNOME_KEYRING_RESULT_OK;
+	gkd_main_complete_initialization (components);
+	g_free (components);
+
+	return GKD_CONTROL_RESULT_OK;
 }
 
 static gboolean
@@ -213,21 +197,20 @@ control_process (EggBuffer *req, GIOChannel *channel)
 	}
 
 	switch (op) {
-	case GNOME_KEYRING_OP_CREATE_KEYRING:
-	case GNOME_KEYRING_OP_UNLOCK_KEYRING:
-		res = control_unlock_keyring (req);
+	case GKD_CONTROL_OP_UNLOCK:
+		res = control_unlock_login (req);
 		cdata = control_data_new ();
 		egg_buffer_add_uint32 (&cdata->buffer, 0);
 		egg_buffer_add_uint32 (&cdata->buffer, res);
 		break;
-	case GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD:
-		res = control_change_keyring_password (req);
+	case GKD_CONTROL_OP_CHANGE:
+		res = control_change_login (req);
 		cdata = control_data_new ();
 		egg_buffer_add_uint32 (&cdata->buffer, 0);
 		egg_buffer_add_uint32 (&cdata->buffer, res);
 		break;
-	case GNOME_KEYRING_OP_PREPARE_ENVIRONMENT:
-		res = control_prepare_environment (req);
+	case GKD_CONTROL_OP_INITIALIZE:
+		res = control_initialize_components (req);
 		cdata = control_data_new ();
 		egg_buffer_add_uint32 (&cdata->buffer, 0);
 		egg_buffer_add_uint32 (&cdata->buffer, res);
diff --git a/daemon/control/gkd-control.h b/daemon/control/gkd-control.h
index 796dd6b..d7f7e66 100644
--- a/daemon/control/gkd-control.h
+++ b/daemon/control/gkd-control.h
@@ -27,6 +27,7 @@
 gboolean          gkd_control_listen        (void);
 
 gchar**           gkd_control_initialize    (const gchar *directory,
+                                             const gchar *components,
                                              const gchar **env);
 
 gboolean          gkd_control_unlock        (const gchar *directory,
diff --git a/daemon/control/tests/Makefile.am b/daemon/control/tests/Makefile.am
index 36f9e24..78f8ae8 100644
--- a/daemon/control/tests/Makefile.am
+++ b/daemon/control/tests/Makefile.am
@@ -12,25 +12,35 @@ LIBS = \
 	$(P11_TESTS_LIBS)
 
 noinst_PROGRAMS= \
-	test-control-unlock \
-	test-control-change
+	test-control-change \
+	test-control-init \
+	test-control-unlock
 
 # ------------------------------------------------------------------------------
 # Test unlocking the login keyring
 
-test_control_unlock_SOURCES = \
-	test-control-unlock.c
+test_control_change_SOURCES = \
+	test-control-change.c
 
-test_control_unlock_LDADD = \
+test_control_change_LDADD = \
 	$(top_builddir)/daemon/control/libgkd-control-client.la \
 	$(top_builddir)/egg/libegg-buffer.la \
 	$(top_builddir)/egg/libegg-creds.la \
 	$(top_builddir)/egg/libegg-secure.la
 
-test_control_change_SOURCES = \
-	test-control-change.c
+test_control_init_SOURCES = \
+	test-control-init.c
 
-test_control_change_LDADD = \
+test_control_init_LDADD = \
+	$(top_builddir)/daemon/control/libgkd-control-client.la \
+	$(top_builddir)/egg/libegg-buffer.la \
+	$(top_builddir)/egg/libegg-creds.la \
+	$(top_builddir)/egg/libegg-secure.la
+
+test_control_unlock_SOURCES = \
+	test-control-unlock.c
+
+test_control_unlock_LDADD = \
 	$(top_builddir)/daemon/control/libgkd-control-client.la \
 	$(top_builddir)/egg/libegg-buffer.la \
 	$(top_builddir)/egg/libegg-creds.la \
diff --git a/daemon/control/tests/test-control-init.c b/daemon/control/tests/test-control-init.c
new file mode 100644
index 0000000..c059477
--- /dev/null
+++ b/daemon/control/tests/test-control-init.c
@@ -0,0 +1,30 @@
+
+#include "control/gkd-control.h"
+#include "tests/gtest-helpers.h"
+
+#include <pwd.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int
+run (void)
+{
+	const char *directory;
+	const gchar *env[] = { NULL };
+	gchar **envp, **e;
+
+	directory = g_getenv ("GNOME_KEYRING_CONTROL");
+	g_return_val_if_fail (directory, 1);
+
+	envp = gkd_control_initialize (directory, "pkcs11,ssh,secret", env);
+	if (envp == NULL)
+		return 1;
+
+	for (e = envp; *e; ++e)
+		g_printerr ("%s\n", *e);
+	g_strfreev (envp);
+
+	return 0;
+}
+
+#include "tests/gtest-helpers.c"
diff --git a/daemon/data/gnome-keyring.schemas.in b/daemon/data/gnome-keyring.schemas.in
index 18ee14a..f0e845f 100644
--- a/daemon/data/gnome-keyring.schemas.in
+++ b/daemon/data/gnome-keyring.schemas.in
@@ -1,16 +1,16 @@
 <gconfschemafile>
 	<schemalist>
 		<schema>
-			<key>/schemas/apps/gnome-keyring/daemon-components/ssh</key>
-			<applyto>/apps/gnome-keyring/daemon-components/ssh</applyto>
+			<key>/schemas/apps/gnome-keyring/daemon-components/secrets</key>
+			<applyto>/apps/gnome-keyring/daemon-components/secrets</applyto>
 			<owner>gnome-keyring</owner>
 			<type>bool</type>
 			<default>TRUE</default>
 			<locale name="C">
-				<short>Whether the gnome-keyring SSH agent is enabled.</short>
-				<long>This option enables the SSH agent in the gnome-keyring 
-				daemon. It only takes effect as gnome-keyring-daemon starts, 
-				(ie: when the user logs in). This setting may be overridden 
+				<short>Whether the gnome-keyring secret service is enabled.</short>
+				<long>This option enables the secret service component in the gnome-keyring
+				daemon. It only takes effect during startup with gnome-session,
+				(ie: when the user logs in). This setting may be overridden
 				when certain command line arguments are passed to the daemon.</long>
 			</locale>
 		</schema>
@@ -22,9 +22,23 @@
 			<default>TRUE</default>
 			<locale name="C">
 				<short>Whether the gnome-keyring PKCS#11 component is enabled.</short>
-				<long>This option enables the PKCS#11 component in the gnome-keyring 
-				daemon. It only takes effect as gnome-keyring-daemon starts, 
-				(ie: when the user logs in). This setting may be overridden 
+				<long>This option enables the PKCS#11 component in the gnome-keyring
+				daemon. It only takes effect during startup with gnome-session,
+				(ie: when the user logs in). This setting may be overridden
+				when certain command line arguments are passed to the daemon.</long>
+			</locale>
+		</schema>
+		<schema>
+			<key>/schemas/apps/gnome-keyring/daemon-components/ssh</key>
+			<applyto>/apps/gnome-keyring/daemon-components/ssh</applyto>
+			<owner>gnome-keyring</owner>
+			<type>bool</type>
+			<default>TRUE</default>
+			<locale name="C">
+				<short>Whether the gnome-keyring SSH agent is enabled.</short>
+				<long>This option enables the SSH agent in the gnome-keyring
+				daemon. It only takes effect as gnome-keyring-daemon starts,
+				(ie: when the user logs in). This setting may be overridden
 				when certain command line arguments are passed to the daemon.</long>
 			</locale>
 		</schema>
diff --git a/daemon/dbus/gkd-dbus-environment.c b/daemon/dbus/gkd-dbus-environment.c
index 3513e31..b1fa033 100644
--- a/daemon/dbus/gkd-dbus-environment.c
+++ b/daemon/dbus/gkd-dbus-environment.c
@@ -58,56 +58,72 @@ on_setenv_reply (DBusPendingCall *pending, void *user_data)
 	dbus_message_unref (reply);
 }
 
-void
-gkd_dbus_environment_init (DBusConnection *conn)
+static void
+setenv_request (DBusConnection *conn, const gchar *env)
 {
 	DBusPendingCall *pending = NULL;
 	DBusError derr = DBUS_ERROR_INIT;
 	DBusMessage *msg;
-	const gchar **envp;
 	const gchar *value;
 	gchar *name;
 
+	/* Find the value part of the environment variable */
+	value = strchr (env, '=');
+	if (!value)
+		return;
+
+	name = g_strndup (env, value - env);
+	++value;
+
+	msg = dbus_message_new_method_call (SERVICE_SESSION_MANAGER,
+	                                    PATH_SESSION_MANAGER,
+	                                    IFACE_SESSION_MANAGER,
+	                                    "Setenv");
+	g_return_if_fail (msg);
+
+	if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
+	                               DBUS_TYPE_STRING, &value,
+	                               DBUS_TYPE_INVALID))
+		g_return_if_reached ();
+
+	g_free (name);
+	value = name = NULL;
+
+	/* Send message and get a handle for a reply */
+	dbus_connection_send_with_reply (conn, msg, &pending, -1);
+	dbus_message_unref (msg);
+	if (pending) {
+		dbus_pending_call_set_notify (pending, on_setenv_reply, NULL, NULL);
+		dbus_pending_call_unref (pending);
+	} else {
+		g_warning ("couldn't send dbus message: %s",
+		           derr.message ? derr.message : "");
+		dbus_error_free (&derr);
+	}
+}
+
+static void
+on_watch_environment (gpointer data, gpointer user_data)
+{
+	DBusConnection *conn = user_data;
+	const gchar *env = data;
+	setenv_request (conn, env);
+}
+
+void
+gkd_dbus_environment_init (DBusConnection *conn)
+{
+	const gchar **envp;
+
 	/*
 	 * The list of all environment variables registered by
 	 * various components in the daemon.
 	 */
 	envp = gkd_util_get_environment ();
 
-	for (; *envp; ++envp) {
-
-		/* Find the value part of the environment variable */
-		value = strchr (*envp, '=');
-		if (!value)
-			continue;
-
-		name = g_strndup (*envp, value - *envp);
-		++value;
-
-		msg = dbus_message_new_method_call (SERVICE_SESSION_MANAGER,
-		                                    PATH_SESSION_MANAGER,
-		                                    IFACE_SESSION_MANAGER,
-		                                    "Setenv");
-		g_return_if_fail (msg);
-
-		if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
-		                               DBUS_TYPE_STRING, &value,
-		                               DBUS_TYPE_INVALID))
-			g_return_if_reached ();
-
-		g_free (name);
-		value = name = NULL;
-
-		/* Send message and get a handle for a reply */
-		dbus_connection_send_with_reply (conn, msg, &pending, -1);
-		dbus_message_unref (msg);
-		if (pending) {
-			dbus_pending_call_set_notify (pending, on_setenv_reply, NULL, NULL);
-			dbus_pending_call_unref (pending);
-		} else {
-			g_warning ("couldn't send dbus message: %s",
-			           derr.message ? derr.message : "");
-			dbus_error_free (&derr);
-		}
-	}
+	for (; *envp; ++envp)
+		setenv_request (conn, *envp);
+
+	gkd_util_watch_environment (on_watch_environment, dbus_connection_ref (conn),
+	                            (GDestroyNotify)dbus_connection_unref);
 }
diff --git a/daemon/dbus/gkd-dbus-secrets.c b/daemon/dbus/gkd-dbus-secrets.c
index 68ab9f7..277e9c5 100644
--- a/daemon/dbus/gkd-dbus-secrets.c
+++ b/daemon/dbus/gkd-dbus-secrets.c
@@ -23,13 +23,17 @@
 
 #include "config.h"
 
+#include "gkd-dbus.h"
 #include "gkd-dbus-private.h"
 #include "gkd-secret-service.h"
 
 #include "daemon/pkcs11/gkd-pkcs11.h"
 
+#include "egg/egg-cleanup.h"
+
 #include "gp11/gp11.h"
 
+static DBusConnection *dbus_conn = NULL;
 static GkdSecretService *secrets_service = NULL;
 
 static GP11Slot*
@@ -62,19 +66,21 @@ calculate_secrets_slot (void)
 	return slot;
 }
 
-void
-gkd_dbus_secrets_init (DBusConnection *conn)
+gboolean
+gkd_dbus_secrets_startup (void)
 {
 	DBusError error = DBUS_ERROR_INIT;
 	dbus_uint32_t result = 0;
 	GP11Slot *slot;
 
+	g_return_val_if_fail (dbus_conn, FALSE);
+
 	/* Figure out which slot to use */
 	slot = calculate_secrets_slot ();
-	g_return_if_fail (slot);
+	g_return_val_if_fail (slot, FALSE);
 
 	/* Try and grab our name */
-	result = dbus_bus_request_name (conn, SECRET_SERVICE, 0, &error);
+	result = dbus_bus_request_name (dbus_conn, SECRET_SERVICE, 0, &error);
 	if (dbus_error_is_set (&error)) {
 		g_message ("couldn't request name '%s' on session bus: %s",
 		           SECRET_SERVICE, error.message);
@@ -89,7 +95,7 @@ gkd_dbus_secrets_init (DBusConnection *conn)
 
 		/* We already acquired the service name. Odd */
 		case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
-			g_return_if_reached ();
+			g_return_val_if_reached (FALSE);
 			break;
 
 		/* Another daemon is running */
@@ -99,16 +105,32 @@ gkd_dbus_secrets_init (DBusConnection *conn)
 			break;
 
 		default:
-			g_return_if_reached ();
+			g_return_val_if_reached (FALSE);
 			break;
 		};
 	}
 
-	g_return_if_fail (!secrets_service);
+	g_return_val_if_fail (!secrets_service, FALSE);
 	secrets_service = g_object_new (GKD_SECRET_TYPE_SERVICE,
-	                                "connection", conn, "pkcs11-slot", slot, NULL);
+	                                "connection", dbus_conn, "pkcs11-slot", slot, NULL);
 
 	g_object_unref (slot);
+	return TRUE;
+}
+
+static void
+cleanup_dbus_conn (gpointer unused)
+{
+	g_assert (dbus_conn);
+	dbus_connection_unref (dbus_conn);
+	dbus_conn = NULL;
+}
+
+void
+gkd_dbus_secrets_init (DBusConnection *conn)
+{
+	dbus_conn = dbus_connection_ref (conn);
+	egg_cleanup_register (cleanup_dbus_conn, NULL);
 }
 
 void
diff --git a/daemon/dbus/gkd-dbus.h b/daemon/dbus/gkd-dbus.h
index 77283e2..ed20138 100644
--- a/daemon/dbus/gkd-dbus.h
+++ b/daemon/dbus/gkd-dbus.h
@@ -24,6 +24,10 @@
 #ifndef GKD_DBUS_H
 #define GKD_DBUS_H
 
-void   gkd_dbus_setup (void);
+#include <glib.h>
+
+void      gkd_dbus_setup            (void);
+
+gboolean  gkd_dbus_secrets_startup  (void);
 
 #endif /* GKD_DBUS_H */
diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c
index f88362f..e1455b4 100644
--- a/daemon/gkd-main.c
+++ b/daemon/gkd-main.c
@@ -59,9 +59,6 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 
-#include <gconf/gconf.h>
-#include <gconf/gconf-client.h>
-
 #include <gcrypt.h>
 
 /* preset file descriptors */
@@ -77,18 +74,22 @@
  * COMMAND LINE
  */
 
-/* All the components to run on startup if not set in gconf */
+/* All the components to run on startup if not specified on command line */
 #ifdef WITH_SSH
-#define DEFAULT_COMPONENTS  "ssh,pkcs11"
+#define DEFAULT_COMPONENTS  "pkcs11,secrets,ssh"
 #else
-#define DEFAULT_COMPONENTS  "pkcs11"
+#define DEFAULT_COMPONENTS  "pkcs11,secrets"
 #endif
 
+static gchar* run_components = DEFAULT_COMPONENTS;
+static gboolean pkcs11_started = FALSE;
+static gboolean secrets_started = FALSE;
+static gboolean ssh_started = FALSE;
+
 static gboolean run_foreground = FALSE;
 static gboolean run_daemonized = FALSE;
 static gboolean run_for_login = FALSE;
 static gboolean run_for_start = FALSE;
-static gchar* run_components = NULL;
 static gchar* login_password = NULL;
 static const gchar* control_directory = NULL;
 static gboolean initialization_completed = FALSE;
@@ -125,8 +126,9 @@ parse_arguments (int *argc, char** argv[])
 		g_clear_error (&err);
 	}
 
-	/* Take ownership of the string */
-	if (run_components) {
+	if (!run_components || !run_components[0]) {
+		run_components = DEFAULT_COMPONENTS;
+	} else {
 		run_components = g_strdup (run_components);
 		egg_cleanup_register (g_free, run_components);
 	}
@@ -140,71 +142,6 @@ parse_arguments (int *argc, char** argv[])
 	g_option_context_free (context);
 }
 
-static gboolean
-check_conf_component (const gchar* component, gboolean *enabled)
-{
-	GConfClient *client;
-	GConfValue *value;
-	GError *err = NULL;
-	gchar *key;
-
-	*enabled = FALSE;
-
-	client = gconf_client_get_default ();
-	g_return_val_if_fail (client, FALSE);
-
-	key = g_strdup_printf ("/apps/gnome-keyring/daemon-components/%s", component);
-	value = gconf_client_get (client, key, &err);
-	g_free (key);
-	g_object_unref (client);
-
-	if (err) {
-		g_printerr ("gnome-keyring-daemon: couldn't lookup %s component setting: %s",
-		            component, err->message ? err->message : "");
-		g_clear_error (&err);
-		return FALSE;
-	}
-
-	/* Value is unset */
-	if (!value)
-		return FALSE;
-
-	/* Should be a list of type string */
-	if (value->type != GCONF_VALUE_BOOL) {
-		g_printerr ("gnome-keyring-daemon: bad gconf value type for daemon-components");
-		g_clear_error (&err);
-		gconf_value_free (value);
-		return FALSE;
-	}
-
-	*enabled = gconf_value_get_bool (value);
-	gconf_value_free (value);
-	return TRUE;
-}
-
-static gboolean
-check_run_component (const char* component)
-{
-	const gchar *run = run_components;
-	gboolean enabled;
-
-	if (run == NULL) {
-
-		/* Use gconf to determine whether the component should be enabled */
-		if (check_conf_component (component, &enabled))
-			return enabled;
-
-		/* No gconf, error or unset, use built in defaults */
-		run = DEFAULT_COMPONENTS;
-	}
-
-	/*
-	 * Note that this assumes that no components are substrings of
-	 * one another. Which makes things quick, and simple.
-	 */
-	return strstr (run, component) ? TRUE : FALSE;
-}
-
 /* -----------------------------------------------------------------------------
  * MEMORY
  */
@@ -527,7 +464,8 @@ start_or_initialize_daemon (const gchar *directory)
 
 	/* Exchange environment variables, and try to initialize daemon */
 	ourenv = gkd_util_build_environment (GKD_UTIL_IN_ENVIRONMENT);
-	daemonenv = gkd_control_initialize (directory, (const gchar**)ourenv);
+	daemonenv = gkd_control_initialize (directory, run_components,
+	                                    (const gchar**)ourenv);
 	g_strfreev (ourenv);
 
 	/* Initialization failed, start this process up as a daemon */
@@ -626,63 +564,105 @@ fork_and_print_environment (void)
 }
 
 static gboolean
-gkr_daemon_startup_steps (void)
+gkr_daemon_startup_steps (const gchar *components)
 {
-	/* Startup the appropriate components, creates sockets etc.. */
+	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 (check_run_component ("ssh")) {
-		if (!gkd_pkcs11_startup_ssh ())
-			return FALSE;
+	if (strstr (components, "ssh")) {
+		if (ssh_started) {
+			g_message ("The SSH agent was already initialized");
+		} else {
+			ssh_started = TRUE;
+			if (!gkd_pkcs11_startup_ssh ()) {
+				ssh_started = FALSE;
+				return FALSE;
+			}
+		}
 	}
 #endif
 
-	if (check_run_component ("pkcs11")) {
-		if (!gkd_pkcs11_startup_pkcs11 ())
-			return FALSE;
-	}
-
-	initialization_completed = TRUE;
 	return TRUE;
 }
 
 static gboolean
-gkr_daemon_initialize_steps (void)
+gkr_daemon_initialize_steps (const gchar *components)
 {
-	/* Initialize new style PKCS#11 components */
-	if (!gkd_pkcs11_initialize ())
-		return FALSE;
+	g_assert (components);
 
 	/*
-	 * Unlock the login keyring if we were given a password on STDIN.
-	 * If it does not exist. We create it.
+	 * Startup that can run after forking.
+	 * Note that we set initialized flags early so that two
+	 * initializations don't overlap
 	 */
-	if (login_password) {
-		if (!gkd_login_unlock (login_password))
-			g_message ("Failed to unlock login on startup");
-		egg_secure_strclear (login_password);
+
+	if (!initialization_completed) {
+		initialization_completed = TRUE;
+
+		/* Initialize new style PKCS#11 components */
+		if (!gkd_pkcs11_initialize ())
+			return FALSE;
+
+		/*
+		 * Unlock the login keyring if we were given a password on STDIN.
+		 * If it does not exist. We create it.
+		 */
+		if (login_password) {
+			if (!gkd_login_unlock (login_password))
+				g_message ("Failed to unlock login on startup");
+			egg_secure_strclear (login_password);
+		}
+
+		gkd_dbus_setup ();
+	}
+
+	/* The Secret Service API */
+	if (strstr (components, "secret") || strstr (components, "keyring")) {
+		if (secrets_started) {
+			g_message ("The Secret Service was already initialized");
+		} else {
+			secrets_started = TRUE;
+			if (!gkd_dbus_secrets_startup ()) {
+				secrets_started = FALSE;
+				return FALSE;
+			}
+		}
+	}
+
+	/* The PKCS#11 remoting */
+	if (strstr (components, "pkcs11")) {
+		if (pkcs11_started) {
+			g_message ("The PKCS#11 component was already initialized");
+		} else {
+			pkcs11_started = TRUE;
+			if (!gkd_pkcs11_startup_pkcs11 ()) {
+				pkcs11_started = FALSE;
+				return FALSE;
+			}
+		}
 	}
 
-	gkd_dbus_setup ();
 	return TRUE;
 }
 
 void
-gkd_main_complete_initialization (void)
+gkd_main_complete_initialization (const gchar *components)
 {
+	g_assert (components);
+
 	/*
 	 * Sometimes we don't initialize the full daemon right on
 	 * startup. When run with --login is one such case.
 	 */
 
-	if (initialization_completed) {
-		g_message ("The daemon was already initialized.");
-		return;
-	}
-
-	/* Set this early so that two initializations don't overlap */
-	initialization_completed = TRUE;
-	gkr_daemon_startup_steps ();
-	gkr_daemon_initialize_steps ();
+	gkr_daemon_startup_steps (components);
+	gkr_daemon_initialize_steps (components);
 }
 
 int
@@ -695,8 +675,8 @@ 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 primidoral stages of a session, where
-	 * there's no DBus, no GConf, and no proper X display. This is the
-	 * strange world of PAM.
+	 * 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
@@ -765,7 +745,7 @@ main (int argc, char *argv[])
 	/* Not a login daemon. Startup stuff now.*/
 	} else {
 		/* These are things that can run before forking */
-		if (!gkr_daemon_startup_steps ())
+		if (!gkr_daemon_startup_steps (run_components))
 			cleanup_and_exit (1);
 	}
 
@@ -779,18 +759,7 @@ main (int argc, char *argv[])
 
 	/* Remainder initialization after forking, if initialization not delayed */
 	if (!run_for_login) {
-		initialization_completed = TRUE;
-		gkr_daemon_initialize_steps ();
-	}
-
-	/*
-	 * Unlock the login keyring if we were given a password on STDIN.
-	 * If it does not exist. We create it.
-	 */
-	if (login_password) {
-		if (!gkd_login_unlock (login_password))
-			g_message ("Failed to unlock login on startup");
-		egg_secure_strclear (login_password);
+		gkr_daemon_initialize_steps (run_components);
 	}
 
 	g_main_loop_run (loop);
diff --git a/daemon/gkd-main.h b/daemon/gkd-main.h
index 4b14f4d..d382755 100644
--- a/daemon/gkd-main.h
+++ b/daemon/gkd-main.h
@@ -24,8 +24,8 @@
 
 #include <glib.h>
 
-void           gkd_main_quit (void);
+void           gkd_main_quit                    (void);
 
-void           gkd_main_complete_initialization (void);
+void           gkd_main_complete_initialization (const gchar *components);
 
 #endif /* GKD_MAIN_H_ */
diff --git a/daemon/gkd-util.c b/daemon/gkd-util.c
index 23e6144..83e9ee3 100644
--- a/daemon/gkd-util.c
+++ b/daemon/gkd-util.c
@@ -72,6 +72,10 @@ const gchar *GKD_UTIL_IN_ENVIRONMENT[] = {
 static gchar* master_directory = NULL;
 static GArray* published_environ = NULL;
 
+static GFunc watch_environ = NULL;
+static gpointer watch_user_data = NULL;
+static GDestroyNotify watch_destroy_notify = NULL;
+
 static void
 uninit_master_directory (gpointer data)
 {
@@ -148,6 +152,12 @@ uninit_environment (gpointer data)
 	}
 
 	published_environ = NULL;
+
+	if (watch_destroy_notify && watch_user_data)
+		(watch_destroy_notify) (watch_user_data);
+	watch_user_data = NULL;
+	watch_destroy_notify = NULL;
+	watch_environ = NULL;
 }
 
 static void
@@ -168,6 +178,9 @@ gkd_util_push_environment (const gchar *name, const gchar *value)
 
 	env = g_strdup_printf ("%s=%s", name, value);
 	g_array_append_val (published_environ, env);
+
+	if (watch_environ)
+		(watch_environ) (env, watch_user_data);
 }
 
 void
@@ -180,6 +193,9 @@ gkd_util_push_environment_full (const gchar *var)
 
 	env = g_strdup (var);
 	g_array_append_val (published_environ, env);
+
+	if (watch_environ)
+		(watch_environ) (env, watch_user_data);
 }
 
 const gchar**
@@ -189,6 +205,18 @@ gkd_util_get_environment (void)
 	return (const gchar**)published_environ->data;
 }
 
+void
+gkd_util_watch_environment (GFunc func, gpointer user_data,
+                            GDestroyNotify destroy_notify)
+{
+	g_return_if_fail (func);
+	g_return_if_fail (!watch_environ);
+
+	watch_environ = func;
+	watch_user_data = user_data;
+	watch_destroy_notify = destroy_notify;
+}
+
 gchar**
 gkd_util_build_environment (const gchar **names)
 {
diff --git a/daemon/gkd-util.h b/daemon/gkd-util.h
index d17bd2b..fc88c51 100644
--- a/daemon/gkd-util.h
+++ b/daemon/gkd-util.h
@@ -35,10 +35,15 @@ void            gkd_util_init_master_directory   (const gchar *replace);
 
 const gchar*    gkd_util_get_master_directory    (void);
 
-void            gkd_util_push_environment        (const gchar *name, const gchar *value);
+void            gkd_util_push_environment        (const gchar *name,
+                                                  const gchar *value);
 
 void            gkd_util_push_environment_full   (const gchar *env);
 
+void            gkd_util_watch_environment       (GFunc func,
+                                                  gpointer user_data,
+                                                  GDestroyNotify destroy_notify);
+
 const gchar**   gkd_util_get_environment         (void);
 
 gchar**         gkd_util_build_environment       (const gchar **names);
diff --git a/daemon/gnome-keyring-daemon.desktop.in.in b/daemon/gnome-keyring-pkcs11.desktop.in.in
similarity index 57%
copy from daemon/gnome-keyring-daemon.desktop.in.in
copy to daemon/gnome-keyring-pkcs11.desktop.in.in
index c4a653f..ecc361f 100644
--- a/daemon/gnome-keyring-daemon.desktop.in.in
+++ b/daemon/gnome-keyring-pkcs11.desktop.in.in
@@ -1,8 +1,10 @@
 [Desktop Entry]
 Type=Application
-_Name=GNOME Keyring Daemon
-Exec= VALGRIND_RUN@ gnome-keyring-daemon --start
+_Name=Certificate and Key Storage
+_Comment=GNOME Keyring: PKCS#11 Component
+Exec= VALGRIND_RUN@ gnome-keyring-daemon --start --components=pkcs11
 OnlyShowIn=GNOME;
+AutostartCondition=GNOME /apps/gnome-keyring/daemon-components/pkcs11
 X-GNOME-Autostart-Phase=Initialization
 X-GNOME-AutoRestart=false
 X-GNOME-Autostart-Notify=true
diff --git a/daemon/gnome-keyring-daemon.desktop.in.in b/daemon/gnome-keyring-secrets.desktop.in.in
similarity index 57%
copy from daemon/gnome-keyring-daemon.desktop.in.in
copy to daemon/gnome-keyring-secrets.desktop.in.in
index c4a653f..c81a05f 100644
--- a/daemon/gnome-keyring-daemon.desktop.in.in
+++ b/daemon/gnome-keyring-secrets.desktop.in.in
@@ -1,8 +1,10 @@
 [Desktop Entry]
 Type=Application
-_Name=GNOME Keyring Daemon
-Exec= VALGRIND_RUN@ gnome-keyring-daemon --start
+_Name=Secret Storage Service
+_Comment=GNOME Keyring: Secret Service
+Exec= VALGRIND_RUN@ gnome-keyring-daemon --start --components=secrets
 OnlyShowIn=GNOME;
+AutostartCondition=GNOME /apps/gnome-keyring/daemon-components/secrets
 X-GNOME-Autostart-Phase=Initialization
 X-GNOME-AutoRestart=false
 X-GNOME-Autostart-Notify=true
diff --git a/daemon/gnome-keyring-daemon.desktop.in.in b/daemon/gnome-keyring-ssh.desktop.in.in
similarity index 60%
rename from daemon/gnome-keyring-daemon.desktop.in.in
rename to daemon/gnome-keyring-ssh.desktop.in.in
index c4a653f..5f6cb04 100644
--- a/daemon/gnome-keyring-daemon.desktop.in.in
+++ b/daemon/gnome-keyring-ssh.desktop.in.in
@@ -1,8 +1,10 @@
 [Desktop Entry]
 Type=Application
-_Name=GNOME Keyring Daemon
-Exec= VALGRIND_RUN@ gnome-keyring-daemon --start
+_Name=SSH Key Agent
+_Comment=GNOME Keyring: SSH Agent
+Exec= VALGRIND_RUN@ gnome-keyring-daemon --start --components=ssh
 OnlyShowIn=GNOME;
+AutostartCondition=GNOME /apps/gnome-keyring/daemon-components/ssh
 X-GNOME-Autostart-Phase=Initialization
 X-GNOME-AutoRestart=false
 X-GNOME-Autostart-Notify=true
diff --git a/daemon/org.gnome.keyring.service.in b/daemon/org.gnome.keyring.service.in
index 84541c6..04dc017 100644
--- a/daemon/org.gnome.keyring.service.in
+++ b/daemon/org.gnome.keyring.service.in
@@ -1,3 +1,3 @@
 [D-BUS Service]
 Name=org.gnome.keyring
-Exec= PATH@/gnome-keyring-daemon --start --foreground --components=keyring
+Exec= PATH@/gnome-keyring-daemon --start --foreground --components=secrets
diff --git a/pam/gkr-pam-client.c b/pam/gkr-pam-client.c
index 0d441ae..f505c3f 100644
--- a/pam/gkr-pam-client.c
+++ b/pam/gkr-pam-client.c
@@ -221,7 +221,7 @@ write_part (int fd, const unsigned char *data, int len, int *res)
 	assert (res);
 	
 	/* Already an error present */
-	if (*res != GNOME_KEYRING_RESULT_OK)
+	if (*res != GKD_CONTROL_RESULT_OK)
 		return;
 	
 	assert (data);
@@ -233,7 +233,7 @@ write_part (int fd, const unsigned char *data, int len, int *res)
 				continue;
 			syslog (GKR_LOG_ERR, "couldn't send data to gnome-keyring-daemon: %s", 
 			        strerror (errno));
-			*res = GNOME_KEYRING_RESULT_IO_ERROR;
+			*res = GKD_CONTROL_RESULT_FAILED;
 			return;
 		}
 		data += r;
@@ -272,7 +272,7 @@ read_part (int fd, unsigned char *data, int len)
 static int
 keyring_daemon_op (const char *control, int op, int argc, const char* argv[])
 {
-	int ret = GNOME_KEYRING_RESULT_OK;
+	int ret = GKD_CONTROL_RESULT_OK;
 	unsigned char buf[4];
 	int i, sock = -1;
 	uint oplen, l;
@@ -284,9 +284,7 @@ keyring_daemon_op (const char *control, int op, int argc, const char* argv[])
 	 * and an empty (only result code) return. 
 	 */
 	 
-	assert (op == GNOME_KEYRING_OP_UNLOCK_KEYRING || 
-	        op == GNOME_KEYRING_OP_CREATE_KEYRING || 
-	        op == GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD);
+	assert (op == GKD_CONTROL_OP_CHANGE || op == GKD_CONTROL_OP_UNLOCK);
 
 	sock = connect_to_daemon (control);
 	if (sock < 0) {
@@ -317,12 +315,12 @@ keyring_daemon_op (const char *control, int op, int argc, const char* argv[])
 			write_part (sock, (unsigned char*)argv[i], l, &ret);
 	}
 	
-	if (ret != GNOME_KEYRING_RESULT_OK)
+	if (ret != GKD_CONTROL_RESULT_OK)
 		goto done;
 	    	
 	/* Read the response length */
 	if (read_part (sock, buf, 4) != 4) {
-		ret = GNOME_KEYRING_RESULT_IO_ERROR;
+		ret = GKD_CONTROL_RESULT_FAILED;
 		goto done;
 	}
 
@@ -330,12 +328,12 @@ keyring_daemon_op (const char *control, int op, int argc, const char* argv[])
 	l = egg_buffer_decode_uint32 (buf);
 	if (l != 8) {
 		syslog (GKR_LOG_ERR, "invalid length response from gnome-keyring-daemon: %d", l);
-		ret = GNOME_KEYRING_RESULT_IO_ERROR;
+		ret = GKD_CONTROL_RESULT_FAILED;
 		goto done;
 	}
 
 	if (read_part (sock, buf, 4) != 4) {
-		ret = GNOME_KEYRING_RESULT_IO_ERROR;
+		ret = GKD_CONTROL_RESULT_FAILED;
 		goto done;
 	}
 	ret = egg_buffer_decode_uint32 (buf);
@@ -380,7 +378,7 @@ gkr_pam_client_run_operation (struct passwd *pwd, const char *control,
 		case -1:
 			syslog (GKR_LOG_ERR, "gkr-pam: couldn't fork: %s", 
 			        strerror (errno));
-			res = GNOME_KEYRING_RESULT_IO_ERROR;
+			res = GKD_CONTROL_RESULT_FAILED;
 			break;
 			
 		case 0:
@@ -389,7 +387,7 @@ gkr_pam_client_run_operation (struct passwd *pwd, const char *control,
 			    setegid (pwd->pw_gid) < 0 || seteuid (pwd->pw_uid) < 0) {
 				syslog (GKR_LOG_ERR, "gkr-pam: couldn't switch to user: %s: %s", 
 				        pwd->pw_name, strerror (errno));
-				exit (GNOME_KEYRING_RESULT_IO_ERROR);
+				exit (GKD_CONTROL_RESULT_FAILED);
 			}
 	
 			res = keyring_daemon_op (control, op, argc, argv);
@@ -401,7 +399,7 @@ gkr_pam_client_run_operation (struct passwd *pwd, const char *control,
 			if (wait (&status) != pid) {
 				syslog (GKR_LOG_ERR, "gkr-pam: couldn't wait on child process: %s", 
 				        strerror (errno));
-				res = GNOME_KEYRING_RESULT_IO_ERROR;
+				res = GKD_CONTROL_RESULT_FAILED;
 			}
 			
 			res = WEXITSTATUS (status);
diff --git a/pam/gkr-pam-module.c b/pam/gkr-pam-module.c
index 4e561fd..bf3c844 100644
--- a/pam/gkr-pam-module.c
+++ b/pam/gkr-pam-module.c
@@ -66,8 +66,6 @@ enum {
 	ARG_USE_AUTHTOK	        = 1 << 2
 };
 
-#define LOGIN_KEYRING           "login"
-
 #define ENV_CONTROL             "GNOME_KEYRING_CONTROL"
 #define ENV_PID                 "GNOME_KEYRING_PID"
 
@@ -644,37 +642,6 @@ done:
 }
 
 static int
-create_keyring (pam_handle_t *ph, struct passwd *pwd, const char *password)
-{
-	const char *control;
-	int res;
-	const char *argv[2];
-	
-	assert (pwd);
-	assert (password);
-
-	control = get_any_env (ph, ENV_CONTROL);
-	if (!control) {
-		syslog (GKR_LOG_WARN, "gkr-pam: couldn't create '%s' keyring: %s", 
-		        LOGIN_KEYRING, "gnome-keyring-daemon is not running");
-		return PAM_SERVICE_ERR;
-	}
-	
-	argv[0] = LOGIN_KEYRING;
-	argv[1] = password;
-	
-	res = gkr_pam_client_run_operation (pwd, control, GNOME_KEYRING_OP_CREATE_KEYRING, 2, argv);
-	if (res != GNOME_KEYRING_RESULT_OK) {
-		syslog (GKR_LOG_ERR, "gkr-pam: couldn't create '%s' keyring: %d", LOGIN_KEYRING, res);
-		return PAM_SERVICE_ERR;
-	}
-	
-	
-	syslog (GKR_LOG_NOTICE, "gkr-pam: created '%s' keyring", LOGIN_KEYRING);
-	return PAM_SUCCESS; 
-}
-
-static int
 unlock_keyring (pam_handle_t *ph, struct passwd *pwd, const char *password)
 {
 	const char *control;
@@ -686,27 +653,25 @@ unlock_keyring (pam_handle_t *ph, struct passwd *pwd, const char *password)
 
 	control = get_any_env (ph, ENV_CONTROL);
 	if (!control) {
-		syslog (GKR_LOG_WARN, "gkr-pam: couldn't unlock '%s' keyring: %s", 
-		        LOGIN_KEYRING, "gnome-keyring-daemon is not running");
+		syslog (GKR_LOG_WARN, "gkr-pam: couldn't unlock login keyring: %s",
+		        "gnome-keyring-daemon is not running");
 		return PAM_SERVICE_ERR;
 	}
 	
-	argv[0] = LOGIN_KEYRING;
-	argv[1] = password;
-	
-	res = gkr_pam_client_run_operation (pwd, control, GNOME_KEYRING_OP_UNLOCK_KEYRING, 2, argv);
+	argv[0] = password;
 
-	/* 'login' keyring doesn't exist, create it */
-	if (res == GNOME_KEYRING_RESULT_NO_SUCH_KEYRING) {
-		return create_keyring (ph, pwd, password);
+	res = gkr_pam_client_run_operation (pwd, control, GKD_CONTROL_OP_UNLOCK, 1, argv);
 
 	/* An error unlocking */
-	} else if (res != GNOME_KEYRING_RESULT_OK) {
-		syslog (GKR_LOG_ERR, "gkr-pam: couldn't unlock '%s' keyring: %d", LOGIN_KEYRING, res);
+	if (res == GKD_CONTROL_RESULT_DENIED) {
+		syslog (GKR_LOG_ERR, "gkr-pam: the password for the login keyring was invalid.");
 		return PAM_SERVICE_ERR;
-	} 	
-		
-	syslog (GKR_LOG_INFO, "gkr-pam: unlocked '%s' keyring", LOGIN_KEYRING);
+	} else if (res != GKD_CONTROL_RESULT_OK) {
+		syslog (GKR_LOG_ERR, "gkr-pam: couldn't unlock the login keyring.");
+		return PAM_SERVICE_ERR;
+	}
+
+	syslog (GKR_LOG_INFO, "gkr-pam: unlocked login keyring");
 	return PAM_SUCCESS;
 }
 
@@ -724,29 +689,26 @@ change_keyring_password (pam_handle_t *ph, struct passwd *pwd,
 
 	control = get_any_env (ph, ENV_CONTROL);
 	if (!control) {
-		syslog (GKR_LOG_WARN, "gkr-pam: couldn't change password on '%s' keyring: %s", 
-		        LOGIN_KEYRING, "gnome-keyring-daemon is not running");
+		syslog (GKR_LOG_WARN, "gkr-pam: couldn't change password on login keyring: %s",
+		        "gnome-keyring-daemon is not running");
 		return PAM_SERVICE_ERR;
 	}
 	
-	argv[0] = LOGIN_KEYRING;
-	argv[1] = original;
-	argv[2] = password;	
+	argv[0] = original;
+	argv[1] = password;
 	
-	res = gkr_pam_client_run_operation (pwd, control, GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD, 3, argv);
+	res = gkr_pam_client_run_operation (pwd, control, GKD_CONTROL_OP_CHANGE, 2, argv);
 
 	/* No keyring, not an error. Will be created at initial authenticate. */
-	if (res == GNOME_KEYRING_RESULT_NO_SUCH_KEYRING) {
-		syslog (GKR_LOG_INFO, "gkr-pam: '%s' keyring does not exist, not changing password", LOGIN_KEYRING);
-		return PAM_SUCCESS;
-		
-	/* An error occured unlocking */
-	} else if (res != GNOME_KEYRING_RESULT_OK) {
-		syslog (GKR_LOG_ERR, "gkr-pam: couldn't change password for '%s' keyring: %d", LOGIN_KEYRING, res);
+	if (res == GKD_CONTROL_RESULT_DENIED) {
+		syslog (GKR_LOG_ERR, "gkr-pam: couldn't change password for the login keyring: the passwords didn't match.");
+		return PAM_SERVICE_ERR;
+	} else if (res != GKD_CONTROL_RESULT_OK) {
+		syslog (GKR_LOG_ERR, "gkr-pam: couldn't change password for the login keyring.");
 		return PAM_SERVICE_ERR;
 	}
-	
-	syslog (GKR_LOG_NOTICE, "gkr-pam: changed password for '%s' keyring", LOGIN_KEYRING);
+
+	syslog (GKR_LOG_NOTICE, "gkr-pam: changed password for login keyring");
 	return PAM_SUCCESS;
 }
  
@@ -1031,8 +993,8 @@ pam_chauthtok_update (pam_handle_t *ph, struct passwd *pwd, uint args)
 	
 	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 '%s' keyring password: %s", 
-		        LOGIN_KEYRING, "no old password was entered");
+		syslog (GKR_LOG_WARN, "gkr-pam: couldn't update the login keyring password: %s",
+		        "no old password was entered");
 		return PAM_IGNORE;
 	}
 		



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]