[gnome-keyring] [daemon] Use new control protocol for daemon.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring] [daemon] Use new control protocol for daemon.
- Date: Wed, 16 Dec 2009 00:42:14 +0000 (UTC)
commit 8919b91a25d29bd74b079ab169d0fb174786a16d
Author: Stef Walter <stef memberwebs com>
Date: Wed Dec 16 00:40:27 2009 +0000
[daemon] Use new control protocol for daemon.
Test new control protocol, and use in pam and startup. Refactor
the names of some of the daemon files.
daemon/Makefile.am | 4 +-
daemon/control/Makefile.am | 1 +
daemon/control/gkd-control.c | 267 +++++++++++++++++++--
daemon/control/gkd-control.h | 4 +-
daemon/dbus/gkd-dbus-environment.c | 5 +-
daemon/dbus/gkd-dbus-service.c | 5 +-
daemon/dbus/gkd-dbus-session.c | 7 +-
daemon/{gkr-daemon.c => gkd-main.c} | 457 +++++++++++++++--------------------
daemon/gkd-main.h | 31 +++
daemon/gkd-util.c | 209 ++++++++++++++++
daemon/gkd-util.h | 46 ++++
daemon/gkr-daemon-io.c | 14 +-
daemon/gkr-daemon-ops.c | 7 +-
daemon/gkr-daemon.h | 4 -
daemon/pkcs11/gkr-pkcs11-daemon.c | 8 +-
daemon/util/gkr-daemon-util.c | 105 --------
daemon/util/gkr-daemon-util.h | 8 -
pam/gkr-pam-client.c | 51 ++--
pam/gkr-pam-module.c | 58 +++---
pam/tests/unit-test-pam.c | 6 +-
pkcs11/rpc-layer/gck-rpc-dispatch.c | 2 +-
pkcs11/rpc-layer/gck-rpc-module.c | 6 +-
pkcs11/ssh-agent/gck-ssh-agent.c | 2 +-
23 files changed, 814 insertions(+), 493 deletions(-)
---
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 73d81ee..cc818f0 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -26,7 +26,8 @@ INCLUDES= \
$(GLIB_CFLAGS)
gnome_keyring_daemon_SOURCES = \
- gkr-daemon.c gkr-daemon.h \
+ gkd-main.c gkd-main.h \
+ gkd-util.c gkd-util.h \
gkr-daemon-io.c \
gkr-daemon-ops.c
@@ -35,6 +36,7 @@ gnome_keyring_daemon_LDADD = \
$(top_builddir)/daemon/dbus/libgkr-dbus.la \
$(top_builddir)/daemon/keyrings/libgkr-keyrings.la \
$(top_builddir)/daemon/ui/libgkr-ui.la \
+ $(top_builddir)/daemon/control/libgkd-control.la \
$(top_builddir)/daemon/prompt/libgkd-prompt.la \
$(top_builddir)/daemon/util/libgkr-daemon-util.la \
$(top_builddir)/library/libgnome-keyring-common.la \
diff --git a/daemon/control/Makefile.am b/daemon/control/Makefile.am
index 166505b..e189c5a 100644
--- a/daemon/control/Makefile.am
+++ b/daemon/control/Makefile.am
@@ -5,6 +5,7 @@ INCLUDES= \
-DLIBEXECDIR=\""$(libexecdir)"\" \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
-I$(top_srcdir) \
+ -I$(top_srcdir)/daemon \
-I$(top_builddir) \
$(GLIB_CFLAGS)
diff --git a/daemon/control/gkd-control.c b/daemon/control/gkd-control.c
index db22625..f01c483 100644
--- a/daemon/control/gkd-control.c
+++ b/daemon/control/gkd-control.c
@@ -22,6 +22,8 @@
#include "config.h"
#include "gkd-control.h"
+#include "gkd-main.h"
+#include "gkd-util.h"
#include "egg/egg-buffer.h"
#include "egg/egg-cleanup.h"
@@ -86,6 +88,10 @@ enum {
GNOME_KEYRING_RESULT_NO_MATCH
};
+/* -----------------------------------------------------------------------------------
+ * CONTROL SERVER
+ */
+
static ControlData*
control_data_new (void)
{
@@ -172,18 +178,37 @@ control_change_keyring_password (EggBuffer *buffer)
static guint32
control_prepare_environment (EggBuffer *buffer)
{
- gchar **environment;
- guint32 res;
+ 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;
- /* TODO: Prepare the environment */
- res = GNOME_KEYRING_RESULT_DENIED;
+ /* Accept environment from outside */
+ for (e = environment; *e; ++e) {
+ x = strchr (*e, '=');
+ if (x) {
+ *(x++) = 0;
+ /* We're only interested in these environment variables */
+ for (i = 0; GKD_UTIL_IN_ENVIRONMENT[i] != NULL; ++i) {
+ if (g_str_equal (*e, GKD_UTIL_IN_ENVIRONMENT[i])) {
+ g_setenv (*e, x, FALSE);
+ break;
+ }
+ }
+ }
+ }
g_strfreev (environment);
- return res;
+
+ /*
+ * 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;
}
static gboolean
@@ -230,21 +255,21 @@ control_process (EggBuffer *req, GIOChannel *channel)
case GNOME_KEYRING_OP_UNLOCK_KEYRING:
res = control_unlock_keyring (req);
cdata = control_data_new ();
- egg_buffer_add_uint32 (&cdata->buffer, 4);
+ 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);
cdata = control_data_new ();
- egg_buffer_add_uint32 (&cdata->buffer, 4);
+ 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);
cdata = control_data_new ();
- egg_buffer_add_uint32 (&cdata->buffer, 8);
- egg_buffer_add_uint32 (&cdata->buffer, res);
egg_buffer_add_uint32 (&cdata->buffer, 0);
+ egg_buffer_add_uint32 (&cdata->buffer, res);
+ egg_buffer_add_stringv (&cdata->buffer, gkd_util_get_environment ());
break;
default:
g_message ("received unsupported request operation on control socket: %d", (int)op);
@@ -252,6 +277,8 @@ control_process (EggBuffer *req, GIOChannel *channel)
}
if (cdata) {
+ g_return_if_fail (!egg_buffer_has_error (&cdata->buffer));
+ egg_buffer_set_uint32 (&cdata->buffer, 0, cdata->buffer.len);
g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, G_IO_OUT | G_IO_HUP,
control_output, cdata, control_data_free);
}
@@ -278,7 +305,7 @@ control_input (GIOChannel *channel, GIOCondition cond, gpointer user_data)
if (errno != EAGAIN || errno != EINTR)
finished = TRUE;
} else if (getuid () != uid) {
- g_warning ("uid mismatch: %u, should be %u\n", uid, getuid ());
+ g_message ("control request from bad uid: %u, should be %u\n", uid, getuid ());
finished = TRUE;
} else {
cdata->position = 1;
@@ -298,7 +325,7 @@ control_input (GIOChannel *channel, GIOCondition cond, gpointer user_data)
/* Time for reading the packet */
} else {
if (!egg_buffer_get_uint32 (buffer, 0, NULL, &packet_size) || packet_size < 4) {
- g_warning ("invalid packet size from client");
+ g_message ("invalid packet size in control request");
finished = TRUE;
} else {
g_assert (buffer->len < packet_size);
@@ -342,19 +369,19 @@ control_accept (GIOChannel *channel, GIOCondition cond, gpointer callback_data)
addrlen = sizeof (addr);
new_fd = accept (fd, (struct sockaddr *) &addr, &addrlen);
if (new_fd < 0) {
- g_warning ("couldn't accept new connection: %s", g_strerror (errno));
+ g_warning ("couldn't accept new control request: %s", g_strerror (errno));
return TRUE;
}
val = fcntl (new_fd, F_GETFL, 0);
if (val < 0) {
- g_warning ("can't get client fd flags: %s", g_strerror (errno));
+ g_warning ("can't get control request fd flags: %s", g_strerror (errno));
close (new_fd);
return TRUE;
}
if (fcntl (new_fd, F_SETFL, val | O_NONBLOCK) < 0) {
- g_warning ("can't set client to non-blocking io: %s", g_strerror (errno));
+ g_warning ("can't set control request to non-blocking io: %s", g_strerror (errno));
close (new_fd);
return TRUE;
}
@@ -378,20 +405,17 @@ control_cleanup_channel (gpointer user_data)
}
gboolean
-gkd_control_initialize (const gchar *directory)
+gkd_control_listen (void)
{
struct sockaddr_un addr;
GIOChannel *channel;
gchar *path;
int sock;
- path = g_strdup_printf ("%s/socket", directory);
+ path = g_strdup_printf ("%s/control", gkd_util_get_master_directory ());
egg_cleanup_register (control_cleanup_channel, path);
-#ifdef WITH_TESTS
- if (g_getenv ("GNOME_KEYRING_TEST_PATH"))
- unlink (path);
-#endif
+ unlink (path);
sock = socket (AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
@@ -403,18 +427,18 @@ gkd_control_initialize (const gchar *directory)
addr.sun_family = AF_UNIX;
g_strlcpy (addr.sun_path, path, sizeof (addr.sun_path));
if (bind (sock, (struct sockaddr*) &addr, sizeof (addr)) < 0) {
- g_warning ("couldn't bind to socket: %s: %s", path, g_strerror (errno));
+ g_warning ("couldn't bind to control socket: %s: %s", path, g_strerror (errno));
close (sock);
return FALSE;
}
if (listen (sock, 128) < 0) {
- g_warning ("couldn't listen on socket: %s: %s", path, g_strerror (errno));
+ g_warning ("couldn't listen on control socket: %s: %s", path, g_strerror (errno));
close (sock);
return FALSE;
}
- if (!egg_unix_credentials_setup (sock)) {
+ if (!egg_unix_credentials_setup (sock) < 0) {
close (sock);
return FALSE;
}
@@ -426,3 +450,200 @@ gkd_control_initialize (const gchar *directory)
return TRUE;
}
+
+/* -----------------------------------------------------------------------------------
+ * CONTROL CLIENT
+ */
+
+static int
+control_connect (const gchar *path)
+{
+ struct sockaddr_un addr;
+ struct stat st;
+ int sock;
+
+ /* First a bunch of checks to make sure nothing funny is going on */
+ if (lstat (path, &st) < 0) {
+ g_message ("couldn't access conrol socket: %s: %s", path, g_strerror (errno));
+ return -1;
+
+ } else if (st.st_uid != geteuid ()) {
+ g_message("The control socket is not owned with the same "
+ "credentials as the user login: %s", path);
+ return -1;
+
+ } else if (S_ISLNK (st.st_mode) || !S_ISSOCK (st.st_mode)) {
+ g_message ("The control socket is not a valid simple non-linked socket");
+ return -1;
+ }
+
+ addr.sun_family = AF_UNIX;
+ g_strlcpy (addr.sun_path, path, sizeof (addr.sun_path));
+
+ /* Now we connect */
+ sock = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ g_warning ("couldn't create control socket: %s", g_strerror (errno));
+ return -1;
+ }
+
+ /* Close on exec */
+ fcntl (sock, F_SETFD, 1);
+
+ if (connect (sock, (struct sockaddr*) &addr, sizeof (addr)) < 0) {
+ g_message ("couldn't connect to control socket at: %s: %s",
+ addr.sun_path, g_strerror (errno));
+ close (sock);
+ return -1;
+ }
+
+ /* This lets the server verify us */
+ for (;;) {
+ if (egg_unix_credentials_write (sock) < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ g_message ("couldn't send credentials to control socket: %s",
+ g_strerror (errno));
+ close (sock);
+ return -1;
+ }
+
+ return sock;
+ }
+}
+
+static gboolean
+control_write (int fd, EggBuffer *buf)
+{
+ gsize bytes = 0;
+ gssize res;
+
+ while (bytes < buf->len) {
+ res = write (fd, buf->buf + bytes, buf->len - bytes);
+ if (res < 0) {
+ if (errno != EINTR && errno != EAGAIN) {
+ g_warning ("couldn't write all bytes to control socket: %s",
+ g_strerror (errno));
+ return FALSE;
+ }
+ } else {
+ bytes += res;
+ }
+ }
+
+ return TRUE;
+}
+
+static gsize
+control_read_raw (int fd, guchar *buf, size_t len)
+{
+ gsize bytes;
+ gssize res;
+
+ bytes = 0;
+ while (bytes < len) {
+ res = read (fd, buf + bytes, len - bytes);
+ if (res <= 0) {
+ if (res == 0)
+ res = -1;
+ else if (errno == EAGAIN)
+ continue;
+ else
+ g_warning ("couldn't read %u bytes from control socket: %s",
+ (unsigned int)len, g_strerror (errno));
+ return res;
+ }
+ bytes += res;
+ }
+ return bytes;
+}
+
+
+static gboolean
+control_read (int fd, EggBuffer *buffer)
+{
+ guint32 packet_size;
+
+ egg_buffer_resize (buffer, 4);
+ if (control_read_raw (fd, buffer->buf, 4) != 4)
+ return FALSE;
+
+ if (!egg_buffer_get_uint32 (buffer, 0, NULL, &packet_size) ||
+ packet_size < 4)
+ return FALSE;
+
+ egg_buffer_resize (buffer, packet_size);
+ if (control_read_raw (fd, buffer->buf + 4, packet_size - 4) != packet_size - 4)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+control_chat (int sock)
+{
+ gchar **envp, **e;
+ EggBuffer buffer;
+ gsize offset;
+ gboolean ret;
+ guint32 res;
+
+ envp = gkd_util_build_environment (GKD_UTIL_IN_ENVIRONMENT);
+
+ 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_stringv (&buffer, (const char**)envp);
+ egg_buffer_set_uint32 (&buffer, 0, buffer.len);
+
+ g_strfreev (envp);
+
+ g_return_val_if_fail (!egg_buffer_has_error (&buffer), FALSE);
+
+ envp = NULL;
+
+ ret = control_write (sock, &buffer) &&
+ control_read (sock, &buffer);
+
+ offset = 4;
+ if (ret)
+ ret = egg_buffer_get_uint32 (&buffer, offset, &offset, &res);
+ if (ret && res == GNOME_KEYRING_RESULT_OK)
+ egg_buffer_get_stringv (&buffer, offset, &offset, &envp, g_realloc);
+
+ egg_buffer_uninit (&buffer);
+
+ if (!ret || res != GNOME_KEYRING_RESULT_OK) {
+ g_message ("couldn't initialize running daemon");
+ return FALSE;
+ }
+
+ g_return_val_if_fail (envp, FALSE);
+ for (e = envp; *e; ++e)
+ gkd_util_push_environment_full (*e);
+ g_strfreev (envp);
+
+ return TRUE;
+}
+
+gboolean
+gkd_control_initialize (const gchar *directory)
+{
+ gboolean ret;
+ gchar *path;
+ int sock;
+
+ g_return_val_if_fail (directory, FALSE);
+
+ path = g_strdup_printf ("%s/control", directory);
+ sock = control_connect (path);
+ g_free (path);
+
+ if (sock < 0)
+ return FALSE;
+
+ ret = control_chat (sock);
+
+ close (sock);
+ return ret;
+}
diff --git a/daemon/control/gkd-control.h b/daemon/control/gkd-control.h
index 09c1aa4..84249db 100644
--- a/daemon/control/gkd-control.h
+++ b/daemon/control/gkd-control.h
@@ -24,6 +24,8 @@
#include <glib.h>
-gboolean gkd_control_initialize (const gchar *directory);
+gboolean gkd_control_listen (void);
+
+gboolean gkd_control_initialize (const gchar *directory);
#endif /* __GKD_CONTROL_H__ */
diff --git a/daemon/dbus/gkd-dbus-environment.c b/daemon/dbus/gkd-dbus-environment.c
index bac3d37..3513e31 100644
--- a/daemon/dbus/gkd-dbus-environment.c
+++ b/daemon/dbus/gkd-dbus-environment.c
@@ -24,8 +24,7 @@
#include "config.h"
#include "gkd-dbus-private.h"
-
-#include "util/gkr-daemon-util.h"
+#include "gkd-util.h"
#include <dbus/dbus.h>
@@ -73,7 +72,7 @@ gkd_dbus_environment_init (DBusConnection *conn)
* The list of all environment variables registered by
* various components in the daemon.
*/
- envp = gkr_daemon_util_get_environment ();
+ envp = gkd_util_get_environment ();
for (; *envp; ++envp) {
diff --git a/daemon/dbus/gkd-dbus-service.c b/daemon/dbus/gkd-dbus-service.c
index 601dfda..c076152 100644
--- a/daemon/dbus/gkd-dbus-service.c
+++ b/daemon/dbus/gkd-dbus-service.c
@@ -24,9 +24,8 @@
#include "config.h"
#include "gkd-dbus-private.h"
-
+#include "gkd-util.h"
#include "gkr-daemon.h"
-#include "util/gkr-daemon-util.h"
#include <dbus/dbus.h>
@@ -71,7 +70,7 @@ message_handler_cb (DBusConnection *conn, DBusMessage *message, void *user_data)
DBusMessageIter items, entry;
gchar **parts;
- env = gkr_daemon_util_get_environment ();
+ env = gkd_util_get_environment ();
g_return_val_if_fail (env, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
/* Setup the result */
diff --git a/daemon/dbus/gkd-dbus-session.c b/daemon/dbus/gkd-dbus-session.c
index 2370999..b904486 100644
--- a/daemon/dbus/gkd-dbus-session.c
+++ b/daemon/dbus/gkd-dbus-session.c
@@ -24,8 +24,7 @@
#include "config.h"
#include "gkd-dbus-private.h"
-
-#include "gkr-daemon.h"
+#include "gkd-main.h"
#include <dbus/dbus.h>
@@ -121,7 +120,7 @@ signal_filter (DBusConnection *conn, DBusMessage *msg, void *user_data)
/* Quit the daemon when the session is over */
if (dbus_message_is_signal (msg, IFACE_SESSION_PRIVATE, "Stop")) {
unregister_daemon_in_session (conn);
- gkr_daemon_quit ();
+ gkd_main_quit ();
return DBUS_HANDLER_RESULT_HANDLED;
} else if (dbus_message_is_signal (msg, IFACE_SESSION_PRIVATE, "QueryEndSession")) {
send_end_session_response (conn);
@@ -129,7 +128,7 @@ signal_filter (DBusConnection *conn, DBusMessage *msg, void *user_data)
} else if (dbus_message_is_signal (msg, IFACE_SESSION_PRIVATE, "EndSession")) {
send_end_session_response (conn);
unregister_daemon_in_session (conn);
- gkr_daemon_quit ();
+ gkd_main_quit ();
return DBUS_HANDLER_RESULT_HANDLED;
}
diff --git a/daemon/gkr-daemon.c b/daemon/gkd-main.c
similarity index 73%
rename from daemon/gkr-daemon.c
rename to daemon/gkd-main.c
index affac8a..1d17458 100644
--- a/daemon/gkr-daemon.c
+++ b/daemon/gkd-main.c
@@ -7,23 +7,28 @@
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
-
+
Gnome keyring 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
General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Author: Alexander Larsson <alexl redhat com>
+ Author: Stef Walter <stef memberwebs com>
*/
#include "config.h"
+#include "gkd-main.h"
+#include "gkd-util.h"
#include "gkr-daemon.h"
+#include "control/gkd-control.h"
+
#include "dbus/gkd-dbus.h"
#include "egg/egg-cleanup.h"
@@ -40,11 +45,9 @@
#include "ui/gkr-ask-daemon.h"
#include "util/gkr-daemon-async.h"
-#include "util/gkr-daemon-util.h"
-#include <unistd.h>
-#include <fcntl.h>
#include <errno.h>
+#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
@@ -52,6 +55,8 @@
#include <signal.h>
#include <locale.h>
#include <syslog.h>
+#include <unistd.h>
+
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -92,21 +97,24 @@ 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;
static gboolean sig_thread_valid = FALSE;
static pthread_t sig_thread;
static GOptionEntry option_entries[] = {
- { "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,
+ { "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 for a user login. Read login password from stdin", NULL },
{ "start", 's', 0, G_OPTION_ARG_NONE, &run_for_start,
"Start a dameon or initialize an already running daemon." },
{ "components", 'c', 0, G_OPTION_ARG_STRING, &run_components,
"The optional components to run", DEFAULT_COMPONENTS },
+ { "control-directory", 'l', 0, G_OPTION_ARG_FILENAME, &control_directory,
+ "The directory for sockets and control data", NULL },
{ NULL }
};
@@ -115,28 +123,27 @@ parse_arguments (int *argc, char** argv[])
{
GError *err = NULL;
GOptionContext *context;
-
+
context = g_option_context_new ("- The Gnome Keyring Daemon");
g_option_context_add_main_entries (context, option_entries, GETTEXT_PACKAGE);
-
+
if (!g_option_context_parse (context, argc, argv, &err)) {
g_printerr ("gnome-keyring-daemon: %s", err && err->message ? err->message : "");
g_clear_error (&err);
}
-
+
/* Take ownership of the string */
if (run_components) {
run_components = g_strdup (run_components);
egg_cleanup_register (g_free, run_components);
}
-
+
/* Check the arguments */
if (run_for_login && run_for_start) {
g_printerr ("gnome-keyring-daemon: The --start option is incompatible with --login");
run_for_login = FALSE;
}
-
-
+
g_option_context_free (context);
}
@@ -146,37 +153,37 @@ check_conf_component (const gchar* component, gboolean *enabled)
GConfClient *client;
GConfValue *value;
GError *err = NULL;
- gchar *key;
+ 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",
+ 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;
-
+ 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;
+ 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;
@@ -190,16 +197,16 @@ check_run_component (const char* component)
if (run == NULL) {
- /* Use gconf to determine whether the component should be enabled */
+ /* 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
+
+ /*
+ * Note that this assumes that no components are substrings of
* one another. Which makes things quick, and simple.
*/
return strstr (run, component) ? TRUE : FALSE;
@@ -211,16 +218,16 @@ check_run_component (const char* component)
static gboolean do_warning = TRUE;
#define WARNING "couldn't allocate secure memory to keep passwords " \
- "and or keys from being written to the disk"
-
+ "and or keys from being written to the disk"
+
#define ABORTMSG "The GNOME_KEYRING_PARANOID environment variable was set. " \
"Exiting..."
-/*
+/*
* These are called from gkr-secure-memory.c to provide appropriate
* locking for memory between threads
- */
+ */
void
egg_memory_lock (void)
@@ -228,7 +235,7 @@ egg_memory_lock (void)
/* The daemon uses cooperative threading, and doesn't need locking */
}
-void
+void
egg_memory_unlock (void)
{
/* The daemon uses cooperative threading, and doesn't need locking */
@@ -238,35 +245,35 @@ void*
egg_memory_fallback (void *p, size_t sz)
{
const gchar *env;
-
+
/* We were asked to free memory */
if (!sz) {
g_free (p);
return NULL;
}
-
+
/* We were asked to allocate */
if (!p) {
if (do_warning) {
g_message (WARNING);
do_warning = FALSE;
}
-
+
env = g_getenv ("GNOME_KEYRING_PARANOID");
- if (env && *env)
+ if (env && *env)
g_error (ABORTMSG);
-
+
return g_malloc0 (sz);
}
-
- /*
- * Reallocation is a bit of a gray area, as we can be asked
- * by external libraries (like libgcrypt) to reallocate a
- * non-secure block into secure memory. We cannot satisfy
- * this request (as we don't know the size of the original
+
+ /*
+ * Reallocation is a bit of a gray area, as we can be asked
+ * by external libraries (like libgcrypt) to reallocate a
+ * non-secure block into secure memory. We cannot satisfy
+ * this request (as we don't know the size of the original
* block) so we just try our best here.
*/
-
+
return g_realloc (p, sz);
}
@@ -275,45 +282,45 @@ egg_memory_fallback (void *p, size_t sz)
*/
static void
-log_handler (const gchar *log_domain, GLogLevelFlags log_level,
+log_handler (const gchar *log_domain, GLogLevelFlags log_level,
const gchar *message, gpointer user_data)
{
- int level;
-
- /* Note that crit and err are the other way around in syslog */
-
- switch (G_LOG_LEVEL_MASK & log_level) {
- case G_LOG_LEVEL_ERROR:
- level = LOG_CRIT;
- break;
- case G_LOG_LEVEL_CRITICAL:
- level = LOG_ERR;
- break;
- case G_LOG_LEVEL_WARNING:
- level = LOG_WARNING;
- break;
- case G_LOG_LEVEL_MESSAGE:
- level = LOG_NOTICE;
- break;
- case G_LOG_LEVEL_INFO:
- level = LOG_INFO;
- break;
- case G_LOG_LEVEL_DEBUG:
- level = LOG_DEBUG;
- break;
- default:
- level = LOG_ERR;
- break;
- }
-
- /* Log to syslog first */
- if (log_domain)
- syslog (level, "%s: %s", log_domain, message);
- else
- syslog (level, "%s", message);
-
- /* And then to default handler for aborting and stuff like that */
- g_log_default_handler (log_domain, log_level, message, user_data);
+ int level;
+
+ /* Note that crit and err are the other way around in syslog */
+
+ switch (G_LOG_LEVEL_MASK & log_level) {
+ case G_LOG_LEVEL_ERROR:
+ level = LOG_CRIT;
+ break;
+ case G_LOG_LEVEL_CRITICAL:
+ level = LOG_ERR;
+ break;
+ case G_LOG_LEVEL_WARNING:
+ level = LOG_WARNING;
+ break;
+ case G_LOG_LEVEL_MESSAGE:
+ level = LOG_NOTICE;
+ break;
+ case G_LOG_LEVEL_INFO:
+ level = LOG_INFO;
+ break;
+ case G_LOG_LEVEL_DEBUG:
+ level = LOG_DEBUG;
+ break;
+ default:
+ level = LOG_ERR;
+ break;
+ }
+
+ /* Log to syslog first */
+ if (log_domain)
+ syslog (level, "%s: %s", log_domain, message);
+ else
+ syslog (level, "%s", message);
+
+ /* And then to default handler for aborting and stuff like that */
+ g_log_default_handler (log_domain, log_level, message, user_data);
}
static void
@@ -327,18 +334,18 @@ printerr_handler (const gchar *string)
static void
prepare_logging ()
{
- GLogLevelFlags flags = G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR |
- G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
- G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO;
-
- openlog ("gnome-keyring-daemon", LOG_PID, LOG_AUTH);
-
- g_log_set_handler (NULL, flags, log_handler, NULL);
- g_log_set_handler ("Glib", flags, log_handler, NULL);
- g_log_set_handler ("Gtk", flags, log_handler, NULL);
- g_log_set_handler ("Gnome", flags, log_handler, NULL);
- g_log_set_default_handler (log_handler, NULL);
- g_set_printerr_handler (printerr_handler);
+ GLogLevelFlags flags = G_LOG_FLAG_FATAL | G_LOG_LEVEL_ERROR |
+ G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING |
+ G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO;
+
+ openlog ("gnome-keyring-daemon", LOG_PID, LOG_AUTH);
+
+ g_log_set_handler (NULL, flags, log_handler, NULL);
+ g_log_set_handler ("Glib", flags, log_handler, NULL);
+ g_log_set_handler ("Gtk", flags, log_handler, NULL);
+ g_log_set_handler ("Gnome", flags, log_handler, NULL);
+ g_log_set_default_handler (log_handler, NULL);
+ g_set_printerr_handler (printerr_handler);
}
/* -----------------------------------------------------------------------------
@@ -409,7 +416,7 @@ setup_signal_handling (GMainLoop *loop)
}
void
-gkr_daemon_quit (void)
+gkd_main_quit (void)
{
/*
* Send a signal to terminate our signal thread,
@@ -444,7 +451,7 @@ sane_dup2 (int fd1, int fd2)
ret = dup2 (fd1, fd2);
if (ret < 0 && errno == EINTR)
goto retry;
-
+
return ret;
}
@@ -455,16 +462,16 @@ read_login_password (int fd)
#define MAX_LENGTH 8192
#define MAX_BLOCK 256
- /*
- * When --login is specified then the login password is passed
- * in on stdin. All data (including newlines) are part of the
+ /*
+ * When --login is specified then the login password is passed
+ * in on stdin. All data (including newlines) are part of the
* password.
*/
-
+
gchar *buf = egg_secure_alloc (MAX_BLOCK);
gchar *ret = NULL;
int r, len = 0;
-
+
for (;;) {
r = read (fd, buf, sizeof (buf));
if (r < 0) {
@@ -473,20 +480,20 @@ read_login_password (int fd)
egg_secure_free (ret);
egg_secure_free (buf);
return NULL;
-
- } else {
+
+ } else {
char *n = egg_secure_realloc (ret, len + r + 1);
- memset(n + len, 0, r + 1);
+ memset(n + len, 0, r + 1);
ret = n;
len = len + r;
-
+
strncat (ret, buf, r);
}
-
+
if (r == 0 || len > MAX_LENGTH)
break;
}
-
+
egg_secure_free (buf);
return ret;
}
@@ -506,131 +513,39 @@ clear_login_password (void)
login_password = NULL;
}
-static gboolean
-lifetime_slave_pipe_io (GIOChannel *channel,
- GIOCondition cond,
- gpointer callback_data)
-{
- egg_cleanup_perform ();
- _exit (2);
- return FALSE;
-}
-
-static void
-slave_lifetime_to_fd (void)
-{
- const char *env;
- GIOChannel *channel;
- int fd;
-
- env = getenv ("GNOME_KEYRING_LIFETIME_FD");
- if (env && env[0]) {
- fd = atoi (env);
- if (fd != 0) {
- channel = g_io_channel_unix_new (fd);
- g_io_add_watch (channel,
- G_IO_IN | G_IO_HUP,
- lifetime_slave_pipe_io, NULL);
- g_io_channel_unref (channel);
- }
- }
-}
-
static void
print_environment (pid_t pid)
{
const gchar **env;
- for (env = gkr_daemon_util_get_environment (); *env; ++env)
+ for (env = gkd_util_get_environment (); *env; ++env)
printf ("%s\n", *env);
if (pid)
printf ("GNOME_KEYRING_PID=%d\n", (gint)pid);
}
-static gboolean
-initialize_other_running_daemon (int sock)
-{
- GnomeKeyringResult res;
- gchar **envp, **e;
- EggBuffer buf;
- gboolean ret;
-
- if (egg_unix_credentials_write (sock) < 0)
- return FALSE;
-
- egg_buffer_init_full (&buf, 128, g_realloc);
-
- envp = gnome_keyring_build_environment (GNOME_KEYRING_IN_ENVIRONMENT);
- ret = gkr_proto_encode_prepare_environment (&buf, (const gchar**)envp);
- g_strfreev (envp);
-
- if (!ret) {
- egg_buffer_uninit (&buf);
- g_return_val_if_reached (FALSE);
- }
-
- envp = NULL;
-
- ret = gnome_keyring_socket_write_buffer (sock, &buf) &&
- gnome_keyring_socket_read_buffer (sock, &buf) &&
- gkr_proto_decode_prepare_environment_reply (&buf, &res, &envp);
-
-
- egg_buffer_uninit (&buf);
-
- if(!ret) {
- g_warning ("couldn't initialize running daemon");
- return FALSE;
- }
-
- if (res == GNOME_KEYRING_RESULT_OK) {
- g_return_val_if_fail (envp, FALSE);
- for (e = envp; *e; ++e)
- gkr_daemon_util_push_environment_full (*e);
- ret = TRUE;
- } else {
- g_warning ("couldn't initialize running daemon: %s", gnome_keyring_result_to_message (res));
- ret = FALSE;
- }
-
- g_strfreev (envp);
-
- return ret;
-}
static gboolean
-start_or_initialize_daemon (void)
+start_or_initialize_daemon (const gchar *directory)
{
- gboolean ret;
- int sock;
-
- /*
- * Is a daemon already running? If not we need to run
- * a daemon process, just return and let things go
- * their normal way.
- */
- sock = gnome_keyring_socket_connect_daemon (FALSE, TRUE);
- if (sock == -1)
+ if (!directory)
return FALSE;
-
- ret = initialize_other_running_daemon (sock);
- close (sock);
-
+
/* Initialization failed, start this process up as a daemon */
- if (!ret)
+ if (!gkd_control_initialize (directory))
return FALSE;
-
- /*
- * Now we've initialized the daemon, we need to print out
+
+ /*
+ * Now we've initialized the daemon, we need to print out
* the daemon's environment for any callers, and possibly
* block if we've been asked to remain in the foreground.
*/
print_environment (0);
-
+
/* TODO: Better way to sleep forever? */
if (run_foreground) {
while (sleep(0x08000000) == 0);
}
-
+
return TRUE;
}
@@ -645,15 +560,15 @@ fork_and_print_environment (void)
print_environment (getpid ());
return;
}
-
+
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);
@@ -661,7 +576,7 @@ fork_and_print_environment (void)
waitpid (pid, &status, 0);
if (WEXITSTATUS (status) != 0)
exit (WEXITSTATUS (status));
-
+
} else {
/* Not double forking, we know the PID */
print_environment (pid);
@@ -670,30 +585,30 @@ fork_and_print_environment (void)
/* The initial process exits successfully */
exit (0);
}
-
- if (run_daemonized) {
-
+
+ if (run_daemonized) {
+
/* 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
+
+ /*
+ * 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. Now we know the PID */
print_environment (pid);
-
+
/* The intermediate child exits */
exit (0);
}
-
+
}
/* Here we are in the resulting daemon or background process. */
@@ -708,8 +623,16 @@ fork_and_print_environment (void)
static gboolean
gkr_daemon_startup_steps (void)
{
+ /*
+ * Always initialize the keyring subsystem. This is a necessary
+ * component that everything else depends on in one way or
+ * another.
+ */
+ if (!gkr_daemon_io_create_master_socket ())
+ return FALSE;
+
/* Startup the appropriate components, creates sockets etc.. */
-#ifdef WITH_SSH
+#ifdef WITH_SSH
if (check_run_component ("ssh")) {
if (!gkr_pkcs11_daemon_startup_ssh ())
return FALSE;
@@ -732,15 +655,25 @@ gkr_daemon_initialize_steps (void)
if (!gkr_pkcs11_daemon_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 (!gkr_keyring_login_unlock (login_password))
+ g_message ("Failed to unlock login on startup");
+ egg_secure_strclear (login_password);
+ }
+
gkd_dbus_setup ();
return TRUE;
}
void
-gkr_daemon_complete_initialization (void)
+gkd_main_complete_initialization (void)
{
/*
- * Sometimes we don't initialize the full daemon right on
+ * Sometimes we don't initialize the full daemon right on
* startup. When run with --login is one such case.
*/
@@ -761,24 +694,24 @@ main (int argc, char *argv[])
GMainContext *ctx;
GMainLoop *loop;
- /*
- * 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
+ /*
+ * 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.
- *
+ *
* 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
+ *
+ * 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.
+ *
+ * Without either of these options, we follow a more boring and
+ * predictable startup.
*/
#ifdef WITH_TESTS
@@ -789,7 +722,7 @@ main (int argc, char *argv[])
g_type_init ();
g_thread_init (NULL);
-
+
#ifdef HAVE_LOCALE_H
/* internationalisation */
setlocale (LC_ALL, "");
@@ -802,30 +735,31 @@ main (int argc, char *argv[])
#endif
egg_libgcrypt_initialize ();
-
+
/* Send all warning or error messages to syslog */
prepare_logging ();
-
+
parse_arguments (&argc, &argv);
-
+
/* The --start option */
if (run_for_start) {
- if (start_or_initialize_daemon ())
+ if (!control_directory)
+ control_directory = g_getenv (GKD_UTIL_ENV_CONTROL);
+ if (start_or_initialize_daemon (control_directory))
cleanup_and_exit (0);
- }
+ }
+
+ /* 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);
ctx = g_main_loop_get_context (loop);
gkr_daemon_async_workers_init (loop);
-
- /*
- * Always initialize the keyring subsystem. This is a necessary
- * component that everything else depends on in one way or
- * another.
- */
- if (!gkr_daemon_io_create_master_socket ())
- cleanup_and_exit (1);
+
+ /* Initialize our control socket */
+ if (!gkd_control_listen ())
+ return FALSE;
/* The --login option. Delayed initialization */
if (run_for_login) {
@@ -853,27 +787,24 @@ main (int argc, char *argv[])
gkr_daemon_initialize_steps ();
}
- /* TODO: Do we still need this? XFCE still seems to use it. */
- slave_lifetime_to_fd ();
-
/*
* Unlock the login keyring if we were given a password on STDIN.
- * If it does not exist. We create it.
+ * If it does not exist. We create it.
*/
if (login_password) {
if (!gkr_keyring_login_unlock (login_password))
g_message ("Failed to unlock login on startup");
egg_secure_strclear (login_password);
}
-
+
g_main_loop_run (loop);
/* Make sure no other threads are running */
gkr_daemon_async_workers_stop_all ();
-
+
/* This wraps everything up in order */
egg_cleanup_perform ();
-
+
/* Final shutdown of anything workers running about */
gkr_daemon_async_workers_uninit ();
diff --git a/daemon/gkd-main.h b/daemon/gkd-main.h
new file mode 100644
index 0000000..4b14f4d
--- /dev/null
+++ b/daemon/gkd-main.h
@@ -0,0 +1,31 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2009 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef GKD_MAIN_H_
+#define GKD_MAIN_H_
+
+#include <glib.h>
+
+void gkd_main_quit (void);
+
+void gkd_main_complete_initialization (void);
+
+#endif /* GKD_MAIN_H_ */
diff --git a/daemon/gkd-util.c b/daemon/gkd-util.c
new file mode 100644
index 0000000..06e4dbf
--- /dev/null
+++ b/daemon/gkd-util.c
@@ -0,0 +1,209 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gkr-daemon-util.c - Helper utilities for the daemon
+
+ Copyright (C) 2007, Stefan Walter
+
+ 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,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef memberwebs com>
+*/
+
+#include "config.h"
+
+#include "gkd-util.h"
+
+#include "egg/egg-cleanup.h"
+#include "egg/egg-mkdtemp.h"
+#include "egg/egg-unix-credentials.h"
+
+#include <glib.h>
+
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * A list of all the environment variables the daemon can
+ * possibly send out when it starts.
+ */
+const gchar *GKD_UTIL_OUT_ENVIRONMENT[] = {
+ "SSH_AUTH_SOCK",
+ "GNOME_KEYRING_SOCKET",
+ "GNOME_KEYRING_CONTROL",
+ "GNOME_KEYRING_PID",
+ "SSH_AGENT_PID",
+ NULL
+};
+
+/*
+ * A list of all the environment variables the daemon
+ * is interested in from clients if it was started
+ * early before these environment variables were set.
+ */
+const gchar *GKD_UTIL_IN_ENVIRONMENT[] = {
+ "DISPLAY",
+ "DBUS_SESSION_BUS_ADDRESS",
+ "DESKTOP_AUTOSTART_ID",
+ "ICEAUTHORITY",
+ "LANG",
+ "XAUTHORITY",
+ "XAUTHLOCALHOSTNAME",
+ "XDG_SESSION_COOKIE",
+ "LOGNAME",
+ "USERNAME",
+ NULL
+};
+
+static gchar* master_directory = NULL;
+static GArray* published_environ = NULL;
+
+static void
+uninit_master_directory (gpointer data)
+{
+ g_assert (master_directory);
+ rmdir (master_directory);
+ g_free (master_directory);
+ master_directory = NULL;
+}
+
+void
+gkd_util_init_master_directory (const gchar *replace)
+{
+ gboolean exists = FALSE;
+ gboolean valid = FALSE;
+ struct stat st;
+
+ if (replace) {
+ exists = TRUE;
+ if (lstat (replace, &st) < 0) {
+ if (errno != ENOTDIR && errno != ENOENT)
+ exists = FALSE;
+ } else if (st.st_uid != geteuid ()) {
+ g_message ("The gnome-keyring control directory is not owned with the same "
+ "credentials as the user login: %s", replace);
+ } else if (st.st_mode != (S_IRUSR | S_IWUSR | S_IXUSR)) {
+ g_message ("The gnome-keyring control directory has invalid permissions. It "
+ "must be only be accessible by its owner (ie: 0600): %s", replace);
+ } else {
+ valid = TRUE;
+ }
+ }
+
+ /* Generate a new directory */
+ if (!valid) {
+ master_directory = g_build_filename (g_get_tmp_dir (), "keyring-XXXXXX", NULL);
+ if (egg_mkdtemp (master_directory) == NULL)
+ g_warning ("couldn't create socket directory: %s", g_strerror (errno));
+
+ /* A directory was supplied, but doesn't exist yet */
+ } else if (!exists) {
+ g_assert (replace);
+ master_directory = g_strdup (replace);
+ if (g_mkdir_with_parents (master_directory, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
+ g_warning ("couldn't create socket directory: %s", g_strerror (errno));
+
+ /* A valid existing directory was supplied */
+ } else {
+ g_assert (replace);
+ master_directory = g_strdup (replace);
+ }
+
+ gkd_util_push_environment (GKD_UTIL_ENV_CONTROL, master_directory);
+ egg_cleanup_register (uninit_master_directory, NULL);
+}
+
+const gchar*
+gkd_util_get_master_directory (void)
+{
+ g_return_val_if_fail (master_directory, NULL);
+ return master_directory;
+}
+
+static void
+uninit_environment (gpointer data)
+{
+ guint i;
+
+ if (published_environ) {
+ for (i = 0; i < published_environ->len; ++i)
+ g_free (g_array_index (published_environ, gchar*, i));
+ g_array_free (published_environ, TRUE);
+ }
+
+ published_environ = NULL;
+}
+
+static void
+init_environment ()
+{
+ if (published_environ)
+ return;
+ published_environ = g_array_new (TRUE, TRUE, sizeof (gchar*));
+ egg_cleanup_register (uninit_environment, NULL);
+}
+
+void
+gkd_util_push_environment (const gchar *name, const gchar *value)
+{
+ gchar *env;
+
+ init_environment ();
+
+ env = g_strdup_printf ("%s=%s", name, value);
+ g_array_append_val (published_environ, env);
+}
+
+void
+gkd_util_push_environment_full (const gchar *var)
+{
+ gchar *env;
+
+ g_return_if_fail (strchr (var, '=') != NULL);
+ init_environment ();
+
+ env = g_strdup (var);
+ g_array_append_val (published_environ, env);
+}
+
+const gchar**
+gkd_util_get_environment (void)
+{
+ init_environment ();
+ return (const gchar**)published_environ->data;
+}
+
+gchar**
+gkd_util_build_environment (const gchar **names)
+{
+ GArray *array = g_array_sized_new (TRUE, TRUE, sizeof (gchar*), 8);
+ const gchar *value;
+ const gchar **name;
+ gchar *env;
+
+ /* Transform them into NAME=VALUE pairs */
+ for (name = names; *name; ++name) {
+ value = g_getenv (*name);
+ if (value) {
+ env = g_strdup_printf ("%s=%s", *name, value);
+ g_array_append_val (array, env);
+ }
+ }
+
+ return (gchar**)g_array_free (array, FALSE);
+}
diff --git a/daemon/gkd-util.h b/daemon/gkd-util.h
new file mode 100644
index 0000000..d17bd2b
--- /dev/null
+++ b/daemon/gkd-util.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gkd-util.h - Helper utilities for the daemon
+
+ Copyright (C) 2008, Stefan Walter
+
+ 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,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef memberwebs com>
+*/
+
+#ifndef GKD_UTIL_H_
+#define GKD_UTIL_H_
+
+#include <glib.h>
+
+#define GKD_UTIL_ENV_CONTROL "GNOME_KEYRING_CONTROL"
+
+extern const gchar *GKD_UTIL_OUT_ENVIRONMENT[];
+extern const gchar *GKD_UTIL_IN_ENVIRONMENT[];
+
+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_full (const gchar *env);
+
+const gchar** gkd_util_get_environment (void);
+
+gchar** gkd_util_build_environment (const gchar **names);
+
+#endif /*GKD_UTIL_H_*/
diff --git a/daemon/gkr-daemon-io.c b/daemon/gkr-daemon-io.c
index e499c65..af12634 100644
--- a/daemon/gkr-daemon-io.c
+++ b/daemon/gkr-daemon-io.c
@@ -32,6 +32,7 @@
#include <sys/socket.h>
#include <sys/un.h>
+#include "gkd-util.h"
#include "gkr-daemon.h"
#include "egg/egg-buffer.h"
@@ -399,15 +400,12 @@ gkr_daemon_io_create_master_socket (void)
struct sockaddr_un addr;
GIOChannel *channel;
- tmp_dir = gkr_daemon_util_get_master_directory ();
+ tmp_dir = gkd_util_get_master_directory ();
g_return_val_if_fail (tmp_dir, FALSE);
snprintf (socket_path, sizeof (socket_path), "%s/socket", tmp_dir);
-
-#ifdef WITH_TESTS
- if (g_getenv ("GNOME_KEYRING_TEST_PATH"))
- unlink (socket_path);
-#endif
+
+ unlink (socket_path);
egg_cleanup_register (cleanup_socket_dir, NULL);
@@ -437,7 +435,7 @@ gkr_daemon_io_create_master_socket (void)
channel = g_io_channel_unix_new (sock);
g_io_add_watch (channel, G_IO_IN | G_IO_HUP, accept_client, NULL);
g_io_channel_unref (channel);
-
- gkr_daemon_util_push_environment ("GNOME_KEYRING_SOCKET", socket_path);
+
+ gkd_util_push_environment ("GNOME_KEYRING_SOCKET", socket_path);
return TRUE;
}
diff --git a/daemon/gkr-daemon-ops.c b/daemon/gkr-daemon-ops.c
index 04c004a..b12967f 100644
--- a/daemon/gkr-daemon-ops.c
+++ b/daemon/gkr-daemon-ops.c
@@ -22,6 +22,8 @@
#include "config.h"
+#include "gkd-main.h"
+#include "gkd-util.h"
#include "gkr-daemon.h"
#include "egg/egg-buffer.h"
@@ -39,7 +41,6 @@
#include "ui/gkr-ask-request.h"
#include "ui/gkr-ask-daemon.h"
-#include "util/gkr-daemon-util.h"
#include "util/gkr-location.h"
#include <unistd.h>
@@ -1738,12 +1739,12 @@ op_prepare_daemon_environment (EggBuffer *packet, EggBuffer *result, GkrKeyringR
* We've now definitely received everything we need to run. Ask
* the daemon to complete the initialization.
*/
- gkr_daemon_complete_initialization();
+ gkd_main_complete_initialization();
egg_buffer_add_uint32 (result, GNOME_KEYRING_RESULT_OK);
/* These are the environment variables that the daemon setup */
- daemonenv = gkr_daemon_util_get_environment ();
+ daemonenv = gkd_util_get_environment ();
g_return_val_if_fail (daemonenv, FALSE);
egg_buffer_add_stringv (result, daemonenv);
diff --git a/daemon/gkr-daemon.h b/daemon/gkr-daemon.h
index 80e3491..b843f24 100644
--- a/daemon/gkr-daemon.h
+++ b/daemon/gkr-daemon.h
@@ -45,10 +45,6 @@ typedef gboolean (*GkrDaemonOperation) (EggBuffer *packet, EggBuffer *result,
extern GkrDaemonOperation keyring_ops[];
-void gkr_daemon_quit (void);
-
-void gkr_daemon_complete_initialization (void);
-
gboolean gkr_daemon_io_create_master_socket (void);
const gchar* gkr_daemon_io_get_socket_path (void);
diff --git a/daemon/pkcs11/gkr-pkcs11-daemon.c b/daemon/pkcs11/gkr-pkcs11-daemon.c
index e05d76d..9fcaefc 100644
--- a/daemon/pkcs11/gkr-pkcs11-daemon.c
+++ b/daemon/pkcs11/gkr-pkcs11-daemon.c
@@ -21,6 +21,7 @@
#include "config.h"
+#include "gkd-util.h"
#include "gkr-pkcs11-auth.h"
#include "gkr-pkcs11-daemon.h"
@@ -33,7 +34,6 @@
#include "pkcs11/user-store/gck-user-store.h"
#include "daemon/util/gkr-daemon-async.h"
-#include "daemon/util/gkr-daemon-util.h"
#include "egg/egg-cleanup.h"
@@ -165,7 +165,7 @@ gkr_pkcs11_daemon_startup_pkcs11 (void)
const gchar *base_dir;
int sock;
- base_dir = gkr_daemon_util_get_master_directory ();
+ base_dir = gkd_util_get_master_directory ();
g_return_val_if_fail (base_dir, FALSE);
gkr_daemon_async_begin_concurrent ();
@@ -216,7 +216,7 @@ gkr_pkcs11_daemon_startup_ssh (void)
const gchar *base_dir;
int sock;
- base_dir = gkr_daemon_util_get_master_directory ();
+ base_dir = gkd_util_get_master_directory ();
g_return_val_if_fail (base_dir, FALSE);
gkr_daemon_async_begin_concurrent ();
@@ -233,7 +233,7 @@ gkr_pkcs11_daemon_startup_ssh (void)
g_io_channel_unref (channel);
/* gck-ssh-agent sets the environment variable */
- gkr_daemon_util_push_environment ("SSH_AUTH_SOCK", g_getenv ("SSH_AUTH_SOCK"));
+ gkd_util_push_environment ("SSH_AUTH_SOCK", g_getenv ("SSH_AUTH_SOCK"));
egg_cleanup_register (pkcs11_ssh_cleanup, NULL);
diff --git a/daemon/util/gkr-daemon-util.c b/daemon/util/gkr-daemon-util.c
index 8391902..fd3490a 100644
--- a/daemon/util/gkr-daemon-util.c
+++ b/daemon/util/gkr-daemon-util.c
@@ -228,108 +228,3 @@ gkr_daemon_client_get_app_path (GkrDaemonClient* client)
return client->app_path;
}
-/* -------------------------------------------------------------------------------------- */
-
-static gchar* master_directory = NULL;
-static GArray* published_environ = NULL;
-
-static void
-uninit_master_directory (gpointer data)
-{
- g_assert (master_directory);
- rmdir (master_directory);
- g_free (master_directory);
- master_directory = NULL;
-}
-
-static void
-init_master_directory (void)
-{
- gboolean have_path = FALSE;
-
- /*
- * When run under control of unit tests, we let the parent process
- * pass in the socket path that we're going to create our main socket on.
- */
-
-#ifdef WITH_TESTS
- const gchar* env = g_getenv ("GNOME_KEYRING_TEST_PATH");
- if (env && *env) {
- master_directory = g_strdup (env);
- if (g_mkdir_with_parents (master_directory, S_IRUSR | S_IWUSR | S_IXUSR) < 0)
- g_warning ("couldn't create socket directory: %s", g_strerror (errno));
- have_path = TRUE;
- }
-#endif /* WITH_TESTS */
-
- /* Create private directory for agent socket */
- if (!have_path) {
- master_directory = g_build_filename (g_get_tmp_dir (), "keyring-XXXXXX", NULL);
- if (egg_mkdtemp (master_directory) == NULL)
- g_warning ("couldn't create socket directory: %s", g_strerror (errno));
- }
-
- egg_cleanup_register (uninit_master_directory, NULL);
-}
-
-const gchar*
-gkr_daemon_util_get_master_directory (void)
-{
- if (!master_directory)
- init_master_directory ();
-
- return master_directory;
-}
-
-static void
-uninit_environment (gpointer data)
-{
- guint i;
-
- if (published_environ) {
- for (i = 0; i < published_environ->len; ++i)
- g_free (g_array_index (published_environ, gchar*, i));
- g_array_free (published_environ, TRUE);
- }
-
- published_environ = NULL;
-}
-
-static void
-init_environment ()
-{
- if (published_environ)
- return;
- published_environ = g_array_new (TRUE, TRUE, sizeof (gchar*));
- egg_cleanup_register (uninit_environment, NULL);
-}
-
-void
-gkr_daemon_util_push_environment (const gchar *name, const gchar *value)
-{
- gchar *env;
-
- init_environment ();
-
- env = g_strdup_printf ("%s=%s", name, value);
- g_array_append_val (published_environ, env);
-}
-
-void
-gkr_daemon_util_push_environment_full (const gchar *var)
-{
- gchar *env;
-
- g_return_if_fail (strchr (var, '=') != NULL);
- init_environment ();
-
- env = g_strdup (var);
- g_array_append_val (published_environ, env);
-}
-
-const gchar**
-gkr_daemon_util_get_environment (void)
-{
- init_environment ();
- return (const gchar**)published_environ->data;
-}
diff --git a/daemon/util/gkr-daemon-util.h b/daemon/util/gkr-daemon-util.h
index 0a6f06e..69ce6b2 100644
--- a/daemon/util/gkr-daemon-util.h
+++ b/daemon/util/gkr-daemon-util.h
@@ -31,14 +31,6 @@ G_BEGIN_DECLS
#include <sys/types.h>
-const gchar* gkr_daemon_util_get_master_directory (void);
-
-void gkr_daemon_util_push_environment (const gchar *name, const gchar *value);
-
-void gkr_daemon_util_push_environment_full (const gchar *env);
-
-const gchar** gkr_daemon_util_get_environment (void);
-
#define GKR_TYPE_DAEMON_CLIENT (gkr_daemon_client_get_type ())
#define GKR_DAEMON_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKR_TYPE_DAEMON_CLIENT, GkrDaemonClient))
#define GKR_DAEMON_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKR_TYPE_DAEMON_CLIENT, GkrDaemonClientClass))
diff --git a/pam/gkr-pam-client.c b/pam/gkr-pam-client.c
index 8ff890b..88a2382 100644
--- a/pam/gkr-pam-client.c
+++ b/pam/gkr-pam-client.c
@@ -29,6 +29,7 @@
#include "egg/egg-unix-credentials.h"
#include <sys/types.h>
+#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
@@ -54,9 +55,6 @@
#include <sys/ucred.h>
#endif
-#define PAM_APP_NAME "Auto Login (PAM)"
-#define PAM_APP_NAME_LEN (sizeof (PAM_APP_NAME) - 1)
-
static int
check_peer_same_uid (int sock)
{
@@ -143,16 +141,24 @@ write_credentials_byte (int sock)
}
static int
-connect_to_daemon (const char *path)
+connect_to_daemon (const char *control)
{
+ char path[MAXPATHLEN];
struct sockaddr_un addr;
struct stat st;
int sock;
-
- /* First a bunch of checks to make sure nothing funny is going on */
-
+
+ /* Build up the directory name */
+ if (strlen (control) + strlen ("/control") + 1 >= MAXPATHLEN) {
+ syslog (GKR_LOG_ERR, "The gnome keyring socket directory is too long");
+ return -1;
+ }
+ strcpy (path, control);
+ strcat (path, "/control");
+
+ /* A bunch of checks to make sure nothing funny is going on */
if (lstat (path, &st) < 0) {
- syslog (GKR_LOG_ERR, "Couldn't access gnome keyring socket: %s: %s",
+ syslog (GKR_LOG_ERR, "Couldn't access gnome keyring socket: %s: %s",
path, strerror (errno));
return -1;
}
@@ -176,7 +182,7 @@ connect_to_daemon (const char *path)
sock = socket (AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
- syslog (GKR_LOG_ERR, "couldn't create socket: %s", strerror (errno));
+ syslog (GKR_LOG_ERR, "couldn't create control socket: %s", strerror (errno));
return -1;
}
@@ -184,7 +190,7 @@ connect_to_daemon (const char *path)
fcntl (sock, F_SETFD, 1);
if (connect (sock, (struct sockaddr*) &addr, sizeof (addr)) < 0) {
- syslog (GKR_LOG_ERR, "couldn't connect to daemon at: %s: %s",
+ syslog (GKR_LOG_ERR, "couldn't connect to gnome-keyring-daemon socket at: %s: %s",
path, strerror (errno));
close (sock);
return -1;
@@ -262,16 +268,16 @@ read_part (int fd, unsigned char *data, int len)
}
static GnomeKeyringResult
-keyring_daemon_op (const char *socket, GnomeKeyringOpCode op, int argc,
+keyring_daemon_op (const char *control, GnomeKeyringOpCode op, int argc,
const char* argv[])
{
GnomeKeyringResult ret = GNOME_KEYRING_RESULT_OK;
unsigned char buf[4];
int i, sock = -1;
uint oplen, l;
-
- assert (socket);
-
+
+ assert (control);
+
/*
* We only support operations with zero or more strings
* and an empty (only result code) return.
@@ -281,19 +287,12 @@ keyring_daemon_op (const char *socket, GnomeKeyringOpCode op, int argc,
op == GNOME_KEYRING_OP_CREATE_KEYRING ||
op == GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD);
- sock = connect_to_daemon (socket);
+ sock = connect_to_daemon (control);
if (sock < 0) {
ret = -1;
goto done;
}
-
- /* Send the application packet / name */
- egg_buffer_encode_uint32 (buf, PAM_APP_NAME_LEN + 8);
- write_part (sock, buf, 4, &ret);
- egg_buffer_encode_uint32 (buf, PAM_APP_NAME_LEN);
- write_part (sock, buf, 4, &ret);
- write_part (sock, (unsigned char*)PAM_APP_NAME, PAM_APP_NAME_LEN, &ret);
-
+
/* Calculate the packet length */
oplen = 8; /* The packet size, and op code */
for (i = 0; i < argc; ++i)
@@ -348,7 +347,7 @@ done:
}
GnomeKeyringResult
-gkr_pam_client_run_operation (struct passwd *pwd, const char *socket,
+gkr_pam_client_run_operation (struct passwd *pwd, const char *control,
GnomeKeyringOpCode op, int argc, const char* argv[])
{
struct sigaction ignpipe, oldpipe, defchld, oldchld;
@@ -371,7 +370,7 @@ gkr_pam_client_run_operation (struct passwd *pwd, const char *socket,
pwd->pw_uid == geteuid () && pwd->pw_gid == getegid ()) {
/* Already running as the right user, simple */
- res = keyring_daemon_op (socket, op, argc, argv);
+ res = keyring_daemon_op (control, op, argc, argv);
} else {
@@ -392,7 +391,7 @@ gkr_pam_client_run_operation (struct passwd *pwd, const char *socket,
exit (GNOME_KEYRING_RESULT_IO_ERROR);
}
- res = keyring_daemon_op (socket, op, argc, argv);
+ res = keyring_daemon_op (control, op, argc, argv);
exit (res);
return 0; /* Never reached */
diff --git a/pam/gkr-pam-module.c b/pam/gkr-pam-module.c
index 530bf42..98e4ea7 100644
--- a/pam/gkr-pam-module.c
+++ b/pam/gkr-pam-module.c
@@ -67,10 +67,10 @@ enum {
ARG_USE_AUTHTOK = 1 << 2
};
-#define LOGIN_KEYRING "login"
+#define LOGIN_KEYRING "login"
-#define ENV_SOCKET "GNOME_KEYRING_SOCKET"
-#define ENV_PID "GNOME_KEYRING_PID"
+#define ENV_CONTROL "GNOME_KEYRING_CONTROL"
+#define ENV_PID "GNOME_KEYRING_PID"
/* read & write ends of a pipe */
#define READ_END 0
@@ -578,15 +578,15 @@ static int
start_daemon_if_necessary (pam_handle_t *ph, struct passwd *pwd,
const char *password, int* started)
{
- const char *socket;
+ const char *control;
int ret;
-
+
*started = 0;
-
+
/* See if it's already running, and transfer env variables */
- socket = get_any_env (ph, ENV_SOCKET);
- if (socket) {
- ret = setup_pam_env (ph, ENV_SOCKET, socket);
+ control = get_any_env (ph, ENV_CONTROL);
+ if (control) {
+ ret = setup_pam_env (ph, ENV_CONTROL, control);
if (ret != PAM_SUCCESS) {
syslog (GKR_LOG_ERR, "gkr-pam: couldn't set environment variables: %s",
pam_strerror (ph, ret));
@@ -647,15 +647,15 @@ done:
static int
create_keyring (pam_handle_t *ph, struct passwd *pwd, const char *password)
{
- const char *socket;
+ const char *control;
GnomeKeyringResult res;
const char *argv[2];
assert (pwd);
assert (password);
-
- socket = get_any_env (ph, ENV_SOCKET);
- if (!socket) {
+
+ 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;
@@ -664,7 +664,7 @@ create_keyring (pam_handle_t *ph, struct passwd *pwd, const char *password)
argv[0] = LOGIN_KEYRING;
argv[1] = password;
- res = gkr_pam_client_run_operation (pwd, socket, GNOME_KEYRING_OP_CREATE_KEYRING, 2, argv);
+ 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;
@@ -678,15 +678,15 @@ create_keyring (pam_handle_t *ph, struct passwd *pwd, const char *password)
static int
unlock_keyring (pam_handle_t *ph, struct passwd *pwd, const char *password)
{
- const char *socket;
+ const char *control;
GnomeKeyringResult res;
const char *argv[2];
assert (pwd);
assert (password);
-
- socket = get_any_env (ph, ENV_SOCKET);
- if (!socket) {
+
+ 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");
return PAM_SERVICE_ERR;
@@ -695,7 +695,7 @@ unlock_keyring (pam_handle_t *ph, struct passwd *pwd, const char *password)
argv[0] = LOGIN_KEYRING;
argv[1] = password;
- res = gkr_pam_client_run_operation (pwd, socket, GNOME_KEYRING_OP_UNLOCK_KEYRING, 2, argv);
+ res = gkr_pam_client_run_operation (pwd, control, GNOME_KEYRING_OP_UNLOCK_KEYRING, 2, argv);
/* 'login' keyring doesn't exist, create it */
if (res == GNOME_KEYRING_RESULT_NO_SUCH_KEYRING) {
@@ -715,16 +715,16 @@ static int
change_keyring_password (pam_handle_t *ph, struct passwd *pwd,
const char *password, const char *original)
{
- const char *socket;
+ const char *control;
GnomeKeyringResult res;
const char *argv[3];
assert (pwd);
assert (password);
assert (original);
-
- socket = get_any_env (ph, ENV_SOCKET);
- if (!socket) {
+
+ 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");
return PAM_SERVICE_ERR;
@@ -734,7 +734,7 @@ change_keyring_password (pam_handle_t *ph, struct passwd *pwd,
argv[1] = original;
argv[2] = password;
- res = gkr_pam_client_run_operation (pwd, socket, GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD, 3, argv);
+ res = gkr_pam_client_run_operation (pwd, control, GNOME_KEYRING_OP_CHANGE_KEYRING_PASSWORD, 3, argv);
/* No keyring, not an error. Will be created at initial authenticate. */
if (res == GNOME_KEYRING_RESULT_NO_SUCH_KEYRING) {
@@ -841,7 +841,7 @@ pam_sm_authenticate (pam_handle_t *ph, int unused, int argc, const char **argv)
{
struct passwd *pwd;
const char *user, *password;
- const char *socket;
+ const char *control;
int started_daemon;
uint args;
int ret;
@@ -884,11 +884,11 @@ pam_sm_authenticate (pam_handle_t *ph, int unused, int argc, const char **argv)
if (ret != PAM_SUCCESS)
return ret;
}
-
- socket = get_any_env (ph, ENV_SOCKET);
+
+ control = get_any_env (ph, ENV_CONTROL);
/* If gnome keyring is running, then unlock now */
- if (socket) {
+ if (control) {
/* If we started the daemon, its already unlocked, since we passed the password */
if (!started_daemon) {
ret = unlock_keyring (ph, pwd, password);
@@ -958,7 +958,7 @@ pam_sm_open_session (pam_handle_t *ph, int flags, int argc, const char **argv)
}
/* If gnome keyring is running, but we didn't start it here, then unlock now */
- if (get_any_env (ph, ENV_SOCKET) != NULL) {
+ if (get_any_env (ph, ENV_CONTROL) != NULL) {
if (!started_daemon && password != NULL) {
if (unlock_keyring (ph, pwd, password) != PAM_SUCCESS)
return PAM_SERVICE_ERR;
diff --git a/pam/tests/unit-test-pam.c b/pam/tests/unit-test-pam.c
index 3e2679d..2881661 100644
--- a/pam/tests/unit-test-pam.c
+++ b/pam/tests/unit-test-pam.c
@@ -37,7 +37,7 @@ DEFINE_TEST(pam_open)
char** pam_env;
/* Clear out this environment variable so we force a new daemon */
- putenv("GNOME_KEYRING_SOCKET=");
+ putenv("GNOME_KEYRING_CONTROL=");
int ret = pam_authenticate (test_pamh, 0);
if (ret != PAM_SUCCESS)
@@ -56,13 +56,13 @@ DEFINE_TEST(pam_env)
{
const char *socket;
- socket = g_getenv ("GNOME_KEYRING_SOCKET");
+ socket = g_getenv ("GNOME_KEYRING_CONTROL");
/* "socket should have been setup" */
g_assert (socket && socket[0]);
/* "socket should have been created" */
g_assert (g_file_test (socket, G_FILE_TEST_EXISTS));
- g_printerr ("GNOME_KEYRING_SOCKET is: %s\n", g_getenv ("GNOME_KEYRING_SOCKET"));
+ g_printerr ("GNOME_KEYRING_CONTROL is: %s\n", g_getenv ("GNOME_KEYRING_CONTROL"));
sleep (3);
}
diff --git a/pkcs11/rpc-layer/gck-rpc-dispatch.c b/pkcs11/rpc-layer/gck-rpc-dispatch.c
index 58e0533..13e1909 100644
--- a/pkcs11/rpc-layer/gck-rpc-dispatch.c
+++ b/pkcs11/rpc-layer/gck-rpc-dispatch.c
@@ -2296,7 +2296,7 @@ gck_rpc_layer_startup (const char *prefix)
assert (pkcs11_dispatchers == NULL);
snprintf (pkcs11_socket_path, sizeof (pkcs11_socket_path),
- "%s/socket.pkcs11", prefix);
+ "%s/pkcs11", prefix);
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
diff --git a/pkcs11/rpc-layer/gck-rpc-module.c b/pkcs11/rpc-layer/gck-rpc-module.c
index 8094d57..837abe3 100644
--- a/pkcs11/rpc-layer/gck-rpc-module.c
+++ b/pkcs11/rpc-layer/gck-rpc-module.c
@@ -1176,12 +1176,12 @@ rpc_C_Initialize (CK_VOID_PTR init_args)
}
}
- /* Lookup the socket path, append '.pkcs11' */
+ /* Lookup the socket path, append '/pkcs11' */
if (pkcs11_socket_path[0] == 0) {
pkcs11_socket_path[0] = 0;
- path = getenv ("GNOME_KEYRING_SOCKET");
+ path = getenv ("GNOME_KEYRING_CONTROL");
if (path && path[0]) {
- snprintf (pkcs11_socket_path, sizeof (pkcs11_socket_path), "%s.pkcs11", path);
+ snprintf (pkcs11_socket_path, sizeof (pkcs11_socket_path), "%s/pkcs11", path);
pkcs11_socket_path[sizeof (pkcs11_socket_path) - 1] = 0;
}
}
diff --git a/pkcs11/ssh-agent/gck-ssh-agent.c b/pkcs11/ssh-agent/gck-ssh-agent.c
index 7b4d0ac..322f5c8 100644
--- a/pkcs11/ssh-agent/gck-ssh-agent.c
+++ b/pkcs11/ssh-agent/gck-ssh-agent.c
@@ -411,7 +411,7 @@ gck_ssh_agent_startup (const gchar *prefix)
g_return_val_if_fail (prefix, -1);
- snprintf (socket_path, sizeof (socket_path), "%s/socket.ssh", prefix);
+ snprintf (socket_path, sizeof (socket_path), "%s/ssh", prefix);
unlink (socket_path);
sock = socket (AF_UNIX, SOCK_STREAM, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]