gnome-keyring r1040 - in trunk: . common daemon library pam pkcs11



Author: nnielsen
Date: Thu Feb  7 19:34:55 2008
New Revision: 1040
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1040&view=rev

Log:
	* common/Makefile.am:
	* common/gkr-daemon-util.h:
	* common/gkr-unix-credentials.c: (added)
	* common/gkr-unix-credentials.h: (added)
	* daemon/gkr-daemon-io.c:
	* library/gnome-keyring.c:
	* pam/gkr-pam-client.c:
	* pam/gkr-pkcs11-daemon-session.c:
	* pam/gkr-pkcs11-daemon.c:
	* pam/gkr-pkcs11-module.c: Add checking that PKCS#11 socket 
	connections come from the appropriate uid.


Added:
   trunk/common/gkr-unix-credentials.c
   trunk/common/gkr-unix-credentials.h
Modified:
   trunk/ChangeLog
   trunk/common/Makefile.am
   trunk/daemon/gkr-daemon-io.c
   trunk/library/gnome-keyring.c
   trunk/pam/gkr-pam-client.c
   trunk/pkcs11/gkr-pkcs11-daemon-session.c
   trunk/pkcs11/gkr-pkcs11-daemon.c
   trunk/pkcs11/gkr-pkcs11-module.c

Modified: trunk/common/Makefile.am
==============================================================================
--- trunk/common/Makefile.am	(original)
+++ trunk/common/Makefile.am	Thu Feb  7 19:34:55 2008
@@ -30,6 +30,7 @@
 	gkr-location-watch.c gkr-location-watch.h \
 	gkr-secure-memory.c gkr-secure-memory.h \
 	gkr-unique.c gkr-unique.h \
+	gkr-unix-credentials.c gkr-unix-credentials.h \
 	gkr-unix-signal.c gkr-unix-signal.h \
 	gkr-wakeup.c gkr-wakeup.h 
 
@@ -41,11 +42,9 @@
 # COMMON STUFF COMPILED INTO LOADABLE MODULES
 
 libgkr_module_common_la_SOURCES = \
-	gkr-buffer.c \
-	gkr-buffer.h \
-	gkr-secure-memory.c \
-	gkr-secure-memory.h
-
+	gkr-buffer.c gkr-buffer.h \
+	gkr-secure-memory.c gkr-secure-memory.h \
+	gkr-unix-credentials.c gkr-unix-credentials.h
 
 if WITH_TESTS
 TESTS_DIR = tests

Added: trunk/common/gkr-unix-credentials.c
==============================================================================
--- (empty file)
+++ trunk/common/gkr-unix-credentials.c	Thu Feb  7 19:34:55 2008
@@ -0,0 +1,196 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gkr-unix-credentials.c - write and read unix credentials on socket
+
+   Copyright (C) 2003 Red Hat, Inc
+
+   Gnome keyring is free software; you can redistribute it and/or
+   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 "gkr-unix-credentials.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#if defined(HAVE_GETPEERUCRED)
+#include <ucred.h>
+#endif
+
+int
+gkr_unix_credentials_read (int sock, pid_t *pid, uid_t *uid)
+{
+	struct msghdr msg;
+	struct iovec iov;
+	char buf;
+	int ret;
+	
+#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
+	/* Prefer CMSGCRED over LOCAL_CREDS because the former provides the
+	 * remote PID. */
+#if defined(HAVE_CMSGCRED)
+	struct cmsgcred *cred;
+	const size_t cmsglen = CMSG_LEN (sizeof (struct cmsgcred));
+	const size_t cmsgspace = CMSG_SPACE (sizeof (struct cmsgcred));
+#else /* defined(LOCAL_CREDS) */
+	struct sockcred *cred;
+	const size_t cmsglen = CMSG_LEN (sizeof (struct sockcred));
+	const size_t cmsgspace = CMSG_SPACE (sizeof (struct sockcred));
+#endif
+	union {
+		struct cmsghdr hdr;
+		char cred[cmsgspace];
+	} cmsg;
+#endif
+	
+	*pid = 0;
+	*uid = 0;
+	
+	/* If LOCAL_CREDS are used in this platform, they have already been
+	 * initialized by init_connection prior to sending of the credentials
+	 * byte we receive below. */
+	
+	iov.iov_base = &buf;
+	iov.iov_len = 1;
+	
+	memset (&msg, 0, sizeof (msg));
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+	
+#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
+	memset (&cmsg, 0, sizeof (cmsg));
+	msg.msg_control = (caddr_t) &cmsg;
+	msg.msg_controllen = cmsgspace;
+#endif
+
+ again:
+	ret = recvmsg (sock, &msg, 0);
+
+ 	if (ret < 0) {
+		if (errno == EINTR)
+			goto again;
+		return -1;
+	}
+	
+	if (buf != '\0') {
+		fprintf (stderr, "credentials byte was not nul\n");
+		return -1;
+	}
+
+#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
+	if (cmsg.hdr.cmsg_len < cmsglen || cmsg.hdr.cmsg_type != SCM_CREDS) {
+		fprintf (stderr, "message from recvmsg() was not SCM_CREDS\n");
+		return -1;
+	}
+#endif
+
+	{
+#ifdef SO_PEERCRED
+		struct ucred cr;   
+		socklen_t cr_len = sizeof (cr);
+		
+		if (getsockopt (sock, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
+		    cr_len == sizeof (cr)) {
+			*pid = cr.pid;
+			*uid = cr.uid;
+		} else {
+			fprintf (stderr, "failed to getsockopt() credentials, returned len %d/%d\n",
+				     cr_len, (int) sizeof (cr));
+			return -1;
+		}
+#elif defined(HAVE_CMSGCRED)
+		cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
+		*pid = cred->cmcred_pid;
+		*uid = cred->cmcred_euid;
+#elif defined(LOCAL_CREDS)
+		cred = (struct sockcred *) CMSG_DATA (&cmsg.hdr);
+		*pid = 0;
+		*uid = cred->sc_euid;
+		set_local_creds(fd, FALSE);
+#elif defined(HAVE_GETPEERUCRED)
+		ucred_t *uc = NULL;
+
+		if (getpeerucred (fd, &uc) == 0) {
+			*pid = ucred_getpid (uc);
+			*uid = ucred_geteuid (uc);
+			ucred_free (uc);
+		} else {
+			fprintf (stderr, "getpeerucred() failed: %s\n", strerror (errno));
+			return -1;
+		}
+#else /* !SO_PEERCRED && !HAVE_CMSGCRED */
+		fprintf (stderr, "socket credentials not supported on this OS\n");
+		return -1;
+#endif
+	}
+
+	return 0;
+}
+
+int
+gkr_unix_credentials_write (int socket)
+{
+	char buf;
+	int bytes_written;
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+	union {
+		struct cmsghdr hdr;
+		char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
+	} cmsg;
+	struct iovec iov;
+	struct msghdr msg;
+#endif
+
+	buf = 0;
+
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+	iov.iov_base = &buf;
+	iov.iov_len = 1;
+
+	memset (&msg, 0, sizeof (msg));
+	msg.msg_iov = &iov;
+	msg.msg_iovlen = 1;
+
+	msg.msg_control = (caddr_t) &cmsg;
+	msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
+	memset (&cmsg, 0, sizeof (cmsg));
+	cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
+	cmsg.hdr.cmsg_level = SOL_SOCKET;
+	cmsg.hdr.cmsg_type = SCM_CREDS;
+#endif
+
+again:
+
+#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
+	bytes_written = sendmsg (socket, &msg, 0);
+#else
+	bytes_written = write (socket, &buf, 1);
+#endif
+
+	if (bytes_written < 0 && errno == EINTR)
+		goto again;
+
+	if (bytes_written <= 0)
+		return -1;
+		
+	return 0;
+}

Added: trunk/common/gkr-unix-credentials.h
==============================================================================
--- (empty file)
+++ trunk/common/gkr-unix-credentials.h	Thu Feb  7 19:34:55 2008
@@ -0,0 +1,32 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gkr-unix-credentials.h - write and read unix credentials on socket
+
+   Copyright (C) 2008 Stefan Walter
+
+   Gnome keyring is free software; you can redistribute it and/or
+   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: Stef Walter <stef memberwebs com>
+*/
+
+#ifndef GKRUNIXCREDENTIALS_H_
+#define GKRUNIXCREDENTIALS_H_
+
+#include <unistd.h>
+
+int gkr_unix_credentials_read (int sock, pid_t *pid, uid_t *uid);
+
+int gkr_unix_credentials_write (int sock);
+ 
+#endif /*GKRUNIXCREDENTIALS_H_*/

Modified: trunk/daemon/gkr-daemon-io.c
==============================================================================
--- trunk/daemon/gkr-daemon-io.c	(original)
+++ trunk/daemon/gkr-daemon-io.c	Thu Feb  7 19:34:55 2008
@@ -31,10 +31,6 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
-#include <sys/uio.h>
-#if defined(HAVE_GETPEERUCRED)
-#include <ucred.h>
-#endif
 
 #include "gkr-daemon.h"
 
@@ -43,6 +39,7 @@
 #include "common/gkr-cleanup.h"
 #include "common/gkr-daemon-util.h"
 #include "common/gkr-secure-memory.h"
+#include "common/gkr-unix-credentials.h"
 
 #include "keyrings/gkr-keyrings.h"
 
@@ -137,125 +134,6 @@
 }
 
 static gboolean
-read_unix_socket_credentials (int fd,
-			      pid_t *pid,
-			      uid_t *uid)
-{
-	struct msghdr msg;
-	struct iovec iov;
-	char buf;
-	int ret;
-	
-#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
-	/* Prefer CMSGCRED over LOCAL_CREDS because the former provides the
-	 * remote PID. */
-#if defined(HAVE_CMSGCRED)
-	struct cmsgcred *cred;
-	const size_t cmsglen = CMSG_LEN (sizeof (struct cmsgcred));
-	const size_t cmsgspace = CMSG_SPACE (sizeof (struct cmsgcred));
-#else /* defined(LOCAL_CREDS) */
-	struct sockcred *cred;
-	const size_t cmsglen = CMSG_LEN (sizeof (struct sockcred));
-	const size_t cmsgspace = CMSG_SPACE (sizeof (struct sockcred));
-#endif
-	union {
-		struct cmsghdr hdr;
-		char cred[cmsgspace];
-	} cmsg;
-#endif
-	
-	*pid = 0;
-	*uid = 0;
-	
-	/* If LOCAL_CREDS are used in this platform, they have already been
-	 * initialized by init_connection prior to sending of the credentials
-	 * byte we receive below. */
-	
-	iov.iov_base = &buf;
-	iov.iov_len = 1;
-	
-	memset (&msg, 0, sizeof (msg));
-	msg.msg_iov = &iov;
-	msg.msg_iovlen = 1;
-	
-#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
-	memset (&cmsg, 0, sizeof (cmsg));
-	msg.msg_control = (caddr_t) &cmsg;
-	msg.msg_controllen = cmsgspace;
-#endif
-
- again:
- 	gkr_async_begin_concurrent ();
- 	
- 		ret = recvmsg (fd, &msg, 0);
- 	
- 	gkr_async_end_concurrent ();
- 	
- 	if (ret < 0) {
-		if (errno == EINTR) {
-			goto again;
-		}
-		
-		g_warning ("Failed to read credentials byte");
-		return FALSE;
-	}
-	
-	if (buf != '\0') {
-		g_warning ("Credentials byte was not nul");
-		return FALSE;
-	}
-
-#if defined(HAVE_CMSGCRED) || defined(LOCAL_CREDS)
-	if (cmsg.hdr.cmsg_len < cmsglen || cmsg.hdr.cmsg_type != SCM_CREDS) {
-		g_warning ("Message from recvmsg() was not SCM_CREDS\n");
-		return FALSE;
-	}
-#endif
-
-	{
-#ifdef SO_PEERCRED
-		struct ucred cr;   
-		socklen_t cr_len = sizeof (cr);
-		
-		if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 &&
-		    cr_len == sizeof (cr)) {
-			*pid = cr.pid;
-			*uid = cr.uid;
-		} else {
-			g_warning ("Failed to getsockopt() credentials, returned len %d/%d\n",
-				   cr_len, (int) sizeof (cr));
-			return FALSE;
-		}
-#elif defined(HAVE_CMSGCRED)
-		cred = (struct cmsgcred *) CMSG_DATA (&cmsg.hdr);
-		*pid = cred->cmcred_pid;
-		*uid = cred->cmcred_euid;
-#elif defined(LOCAL_CREDS)
-		cred = (struct sockcred *) CMSG_DATA (&cmsg.hdr);
-		*pid = 0;
-		*uid = cred->sc_euid;
-		set_local_creds(fd, FALSE);
-#elif defined(HAVE_GETPEERUCRED)
-		ucred_t *uc = NULL;
-
-		if (getpeerucred (fd, &uc) == 0) {
-			*pid = ucred_getpid (uc);
-			*uid = ucred_geteuid (uc);
-			ucred_free (uc);
-		} else {
-			g_warning ("getpeerucred() failed: %s", strerror (errno));
-			return FALSE;
-		}
-#else /* !SO_PEERCRED && !HAVE_CMSGCRED */
-		g_warning ("Socket credentials not supported on this OS\n");
-		return FALSE;
-#endif
-	}
-
-	return TRUE;
-}
-
-static gboolean
 yield_and_read_all (int fd, guchar *buf, int len)
 {
 	int all = len;
@@ -350,6 +228,20 @@
 	return TRUE;
 }
 
+static gboolean
+yield_and_read_credentials (int sock, pid_t *pid, uid_t *uid)
+{
+	gboolean ret;
+	
+	gkr_async_begin_concurrent ();
+	
+		ret = gkr_unix_credentials_read (sock, pid, uid) >= 0;
+		
+	gkr_async_end_concurrent ();
+	
+	return ret;
+}
+
 static void
 close_fd (gpointer data)
 {
@@ -375,7 +267,7 @@
 	
 	/* 1. First we read and verify the client's user credentials */	
 	debug_print (("GNOME_CLIENT_STATE_CREDENTIALS %p\n", client));
-	if (!read_unix_socket_credentials (client->sock, &pid, &uid))
+	if (!yield_and_read_credentials (client->sock, &pid, &uid))
 		return NULL;
 	if (getuid() != uid) {
 		g_warning ("uid mismatch: %u, should be %u\n", (guint)uid, (guint)getuid());

Modified: trunk/library/gnome-keyring.c
==============================================================================
--- trunk/library/gnome-keyring.c	(original)
+++ trunk/library/gnome-keyring.c	Thu Feb  7 19:34:55 2008
@@ -31,6 +31,7 @@
 #include "gnome-keyring-proto.h"
 
 #include "common/gkr-buffer.h"
+#include "common/gkr-unix-credentials.h"
 
 #include <time.h>
 #include <unistd.h>
@@ -362,109 +363,24 @@
 static GnomeKeyringResult
 write_credentials_byte_sync (int socket)
 {
-  char buf;
-  int bytes_written;
-#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
-  union {
-	  struct cmsghdr hdr;
-	  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
-  } cmsg;
-  struct iovec iov;
-  struct msghdr msg;
-#endif
-
-  buf = 0;
-#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
-  iov.iov_base = &buf;
-  iov.iov_len = 1;
-
-  memset (&msg, 0, sizeof (msg));
-  msg.msg_iov = &iov;
-  msg.msg_iovlen = 1;
-
-  msg.msg_control = (caddr_t) &cmsg;
-  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
-  memset (&cmsg, 0, sizeof (cmsg));
-  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
-  cmsg.hdr.cmsg_level = SOL_SOCKET;
-  cmsg.hdr.cmsg_type = SCM_CREDS;
-#endif
-
- again:
-
-#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
-  bytes_written = sendmsg (socket, &msg, 0);
-#else
-  bytes_written = write (socket, &buf, 1);
-#endif
-
-  if (bytes_written < 0 && errno == EINTR)
-    goto again;
-
-  if (bytes_written <= 0) {
-	  return GNOME_KEYRING_RESULT_IO_ERROR;
-  } else {
-	  return GNOME_KEYRING_RESULT_OK;
-  }
+	if (gkr_unix_credentials_write (socket) < 0)
+		return GNOME_KEYRING_RESULT_IO_ERROR;
+	return GNOME_KEYRING_RESULT_OK;
 }
-  
 
 static void
 write_credentials_byte (GnomeKeyringOperation *op)
 {
-  char buf;
-  int bytes_written;
-#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
-  union {
-	  struct cmsghdr hdr;
-	  char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
-  } cmsg;
-  struct iovec iov;
-  struct msghdr msg;
-#endif
-
-  buf = 0;
-#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
-  iov.iov_base = &buf;
-  iov.iov_len = 1;
-
-  memset (&msg, 0, sizeof (msg));
-  msg.msg_iov = &iov;
-  msg.msg_iovlen = 1;
-
-  msg.msg_control = (caddr_t) &cmsg;
-  msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
-  memset (&cmsg, 0, sizeof (cmsg));
-  cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
-  cmsg.hdr.cmsg_level = SOL_SOCKET;
-  cmsg.hdr.cmsg_type = SCM_CREDS;
-#endif
-
- again:
-
-#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
-  bytes_written = sendmsg (op->socket, &msg, 0);
-#else
-  bytes_written = write (op->socket, &buf, 1);
-#endif
-
-  if (bytes_written < 0 && errno == EINTR)
-    goto again;
-
-  if (bytes_written <= 0) {
-	  if (errno == EAGAIN) {
-		  return;
-	  }
-	  schedule_op_failed (op, GNOME_KEYRING_RESULT_IO_ERROR);
-	  return;
-  } else {
-	  op->state = STATE_WRITING_PACKET;
-	  return;
-  }
+	if (gkr_unix_credentials_write (op->socket) < 0) {
+		if (errno == EAGAIN)
+			return;
+		schedule_op_failed (op, GNOME_KEYRING_RESULT_IO_ERROR);
+		return;
+	}
+	
+	op->state = STATE_WRITING_PACKET;
 }
 
-
-
 static gboolean
 operation_io (GIOChannel  *io_channel,
 	      GIOCondition cond,

Modified: trunk/pam/gkr-pam-client.c
==============================================================================
--- trunk/pam/gkr-pam-client.c	(original)
+++ trunk/pam/gkr-pam-client.c	Thu Feb  7 19:34:55 2008
@@ -26,6 +26,7 @@
 #include "gkr-pam.h"
 
 #include "common/gkr-buffer.h"
+#include "common/gkr-unix-credentials.h"
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -126,54 +127,16 @@
 static int
 write_credentials_byte (int sock)
 {
-#if defined(HAVE_CMSGCRED) && (!defined(LOCAL_CREDS) || defined(__FreeBSD__))
-	union {
-		struct cmsghdr hdr;
-		char cred[CMSG_SPACE (sizeof (struct cmsgcred))];
-	} cmsg;
-	struct iovec iov;
-	struct msghdr msg;
-#endif
-
-	int bytes_written;
-  	char buf = 0;
-
-	/*
-	 * All this fuss is for certain OS's, as a byte needs to have 
-	 * gone through the socket before they know who is on the 
-	 * other side. :( 
-	 */
-
-#if !defined(HAVE_GETPEEREID) && defined(HAVE_CMSGCRED)
-	iov.iov_base = &buf;
-	iov.iov_len = 1;
-
-	memset (&msg, 0, sizeof (msg));
-	msg.msg_iov = &iov;
-	msg.msg_iovlen = 1;
-
-	msg.msg_control = (caddr_t) &cmsg;
-	msg.msg_controllen = CMSG_SPACE (sizeof (struct cmsgcred));
-	memset (&cmsg, 0, sizeof (cmsg));
-	cmsg.hdr.cmsg_len = CMSG_LEN (sizeof (struct cmsgcred));
-	cmsg.hdr.cmsg_level = SOL_SOCKET;
-	cmsg.hdr.cmsg_type = SCM_CREDS;
-#endif
-
-again:
-
-#if !defined(HAVE_GETPEEREID) && defined(HAVE_CMSGCRED)
-	bytes_written = sendmsg (sock, &msg, 0);
-#else
-	bytes_written = write (sock, &buf, 1);
-#endif
-
-	if (bytes_written < 0) {
-		if (errno == EINTR || errno == EAGAIN)
-			goto again;
-		syslog (GKR_LOG_ERR, "couldn't send credentials to daemon: %s", 
-		        strerror (errno));
-		return -1;
+	for (;;) {
+		if (gkr_unix_credentials_write (sock) < 0) {
+			if (errno == EINTR || errno == EAGAIN)
+				continue;
+			syslog (GKR_LOG_ERR, "couldn't send credentials to daemon: %s", 
+			        strerror (errno));
+			return -1;
+		}
+		
+		break;
 	}
 	
 	return 0;

Modified: trunk/pkcs11/gkr-pkcs11-daemon-session.c
==============================================================================
--- trunk/pkcs11/gkr-pkcs11-daemon-session.c	(original)
+++ trunk/pkcs11/gkr-pkcs11-daemon-session.c	Thu Feb  7 19:34:55 2008
@@ -32,6 +32,7 @@
 
 #include "common/gkr-async.h"
 #include "common/gkr-buffer.h"
+#include "common/gkr-unix-credentials.h"
 
 #include "keyrings/gkr-keyring-login.h"
 
@@ -1592,6 +1593,20 @@
 	return TRUE;
 }
 
+static gboolean
+session_read_credentials (int sock, pid_t *pid, uid_t *uid)
+{
+	gboolean ret;
+	
+	gkr_async_begin_concurrent ();
+	
+		ret = gkr_unix_credentials_read (sock, pid, uid) >= 0;
+		
+	gkr_async_end_concurrent ();
+	
+	return ret;
+}
+
 gpointer
 gkr_pkcs11_daemon_session_thread (gpointer user_data)
 {
@@ -1601,11 +1616,21 @@
 	CK_RV ret;
 	uint32_t len;
 	int sock;
+	uid_t uid;
+	pid_t pid;
 	
 	/* The argument to the worker thread is the socket */
 	sock = GPOINTER_TO_INT (user_data);
 	g_assert (sock >= 0);
 	
+	/* Make sure the credentials are appropriate */
+	if (!session_read_credentials (sock, &pid, &uid))
+		return NULL;
+	if (getuid() != uid) {
+		g_warning ("uid mismatch: %u, should be %u\n", (guint)uid, (guint)getuid());
+		return NULL;
+	}
+	
 	/* Setup our buffers */
 	/* TODO: Do these need to be secure buffers? */
 	req = gkr_pkcs11_message_new ((GkrBufferAllocator)g_realloc);

Modified: trunk/pkcs11/gkr-pkcs11-daemon.c
==============================================================================
--- trunk/pkcs11/gkr-pkcs11-daemon.c	(original)
+++ trunk/pkcs11/gkr-pkcs11-daemon.c	Thu Feb  7 19:34:55 2008
@@ -208,8 +208,6 @@
 		return FALSE;
 	}
 	
-	/* TODO: Socket credentials */
-
 	pkcs11_socket_channel = g_io_channel_unix_new (sock);
 	g_io_add_watch (pkcs11_socket_channel, G_IO_IN | G_IO_HUP, 
 	                handle_new_connection, NULL);

Modified: trunk/pkcs11/gkr-pkcs11-module.c
==============================================================================
--- trunk/pkcs11/gkr-pkcs11-module.c	(original)
+++ trunk/pkcs11/gkr-pkcs11-module.c	Thu Feb  7 19:34:55 2008
@@ -30,6 +30,7 @@
 
 #include "common/gkr-buffer.h"
 #include "common/gkr-secure-memory.h"
+#include "common/gkr-unix-credentials.h"
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -125,7 +126,7 @@
 	va_end (va);
 }
 
-#ifdef _xDEBUG 
+#ifdef _DEBUG 
 
 static void 
 gkr_pkcs11_debug (const char* msg, ...)
@@ -327,10 +328,17 @@
 		return CKR_DEVICE_ERROR;
 	}
 
+	if (gkr_unix_credentials_write (sock) < 0) {
+		close (sock);
+		WARN (("S%d: couldn't send socket credentials: %s", 
+		       cs->id, strerror (errno)));
+		return CKR_DEVICE_ERROR;
+	}
+
 	cs->socket = sock;
 	cs->call_state = CALL_READY;
-	
 	DBG (("S%d: connected", cs->id));
+	
 	return CKR_OK;
 }
 



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