gnome-keyring r1625 - in trunk: . pkcs11 pkcs11/gck pkcs11/user-store



Author: nnielsen
Date: Fri Feb 27 02:52:51 2009
New Revision: 1625
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1625&view=rev

Log:
Add support for basic SO logins.

Modified:
   trunk/ChangeLog
   trunk/pkcs11/gck/gck-module.c
   trunk/pkcs11/gck/gck-module.h
   trunk/pkcs11/gck/gck-session.c
   trunk/pkcs11/gck/gck-session.h
   trunk/pkcs11/pkcs11i.h
   trunk/pkcs11/user-store/gck-user-module.c

Modified: trunk/pkcs11/gck/gck-module.c
==============================================================================
--- trunk/pkcs11/gck/gck-module.c	(original)
+++ trunk/pkcs11/gck/gck-module.c	Fri Feb 27 02:52:51 2009
@@ -56,7 +56,7 @@
 	CK_SLOT_ID slot_id;
 	GckManager *session_manager;
 	GList *sessions;
-	gboolean logged_in;
+	CK_USER_TYPE logged_in;
 } VirtualSlot;
 
 /* Our slot identifier is 1 */
@@ -195,7 +195,7 @@
 
 	slot = g_slice_new0 (VirtualSlot);
 	slot->session_manager = g_object_new (GCK_TYPE_MANAGER, "for-token", FALSE, NULL);
-	slot->logged_in = FALSE;
+	slot->logged_in = CKU_NONE;
 	slot->sessions = NULL;
 	slot->slot_id = slot_id;
 	
@@ -231,6 +231,20 @@
 }
 
 static void
+mark_login_virtual_slot (GckModule *self, VirtualSlot *slot, CK_USER_TYPE user)
+{
+	GList *l;
+
+	g_assert (slot);
+	g_assert (GCK_IS_MODULE (self));
+	
+	/* Mark all sessions in the partition as logged in */
+	for (l = slot->sessions; l; l = g_list_next (l)) 
+		gck_session_set_logged_in (l->data, user);
+	slot->logged_in = user;
+}
+
+static void
 parse_argument (GckModule *self, char *arg)
 {
 	gchar *value;
@@ -374,35 +388,36 @@
 gck_module_real_login_user (GckModule *self, CK_SLOT_ID slot_id, CK_UTF8CHAR_PTR pin, CK_ULONG n_pin)
 {
 	VirtualSlot *slot;
-	GList *l;
 	
 	slot = lookup_virtual_slot (self, slot_id);
 	g_return_val_if_fail (slot, CKR_GENERAL_ERROR);
 
-	/* Mark all sessions in the partition as logged in */
-	for (l = slot->sessions; l; l = g_list_next (l)) 
-		gck_session_set_logged_in (l->data, TRUE);
-	slot->logged_in = TRUE;
+	mark_login_virtual_slot (self, slot, CKU_USER);
+	return CKR_OK;
+}
+
+static CK_RV
+gck_module_real_login_so (GckModule *self, CK_SLOT_ID slot_id, CK_UTF8CHAR_PTR pin, CK_ULONG n_pin)
+{
+	VirtualSlot *slot;
 	
+	slot = lookup_virtual_slot (self, slot_id);
+	g_return_val_if_fail (slot, CKR_GENERAL_ERROR);
+
+	mark_login_virtual_slot (self, slot, CKU_SO);
 	return CKR_OK;
 }
 
 static CK_RV
-gck_module_real_logout_user (GckModule *self, CK_SLOT_ID slot_id)
+gck_module_real_logout_any (GckModule *self, CK_SLOT_ID slot_id)
 {
 	VirtualSlot *slot;
-	GList *l;
 
 	/* Calculate the partition identifier */
 	slot = lookup_virtual_slot (self, slot_id);
 	g_return_val_if_fail (slot, CKR_GENERAL_ERROR);
 
-	/* Mark all sessions in the partition as logged out */
-	for (l = slot->sessions; l; l = g_list_next (l)) 
-		gck_session_set_logged_in (l->data, FALSE);
-	slot->logged_in = FALSE;
-	
-	/* Derived classes should override if they want actual login */
+	mark_login_virtual_slot (self, slot, CKU_NONE);
 	return CKR_OK;
 }
 
@@ -534,7 +549,8 @@
 	klass->remove_token_object = gck_module_real_remove_token_object;
 	klass->login_change = gck_module_real_login_change;
 	klass->login_user = gck_module_real_login_user;
-	klass->logout_user = gck_module_real_logout_user;
+	klass->login_so = gck_module_real_login_so;
+	klass->logout_any = gck_module_real_logout_any;
 	
 	g_object_class_install_property (gobject_class, PROP_MANAGER,
 	           g_param_spec_object ("manager", "Manager", "Token object manager", 
@@ -608,11 +624,19 @@
 }
 
 CK_RV
-gck_module_logout_user (GckModule *self, CK_SLOT_ID slot_id)
+gck_module_login_so (GckModule *self, CK_SLOT_ID slot_id, CK_UTF8CHAR_PTR pin, CK_ULONG n_pin)
 {
 	g_return_val_if_fail (GCK_IS_MODULE (self), CKR_GENERAL_ERROR);
-	g_assert (GCK_MODULE_GET_CLASS (self)->logout_user);
-	return GCK_MODULE_GET_CLASS (self)->logout_user (self, slot_id);	
+	g_assert (GCK_MODULE_GET_CLASS (self)->login_so);
+	return GCK_MODULE_GET_CLASS (self)->login_so (self, slot_id, pin, n_pin);
+}
+
+CK_RV
+gck_module_logout_any (GckModule *self, CK_SLOT_ID slot_id)
+{
+	g_return_val_if_fail (GCK_IS_MODULE (self), CKR_GENERAL_ERROR);
+	g_assert (GCK_MODULE_GET_CLASS (self)->logout_any);
+	return GCK_MODULE_GET_CLASS (self)->logout_any (self, slot_id);	
 }
 
 CK_ULONG
@@ -907,6 +931,10 @@
 		slot = virtual_slot_new (GCK_MODULE_GET_CLASS (self), id);
 		register_virtual_slot (self, slot);
 	}
+	
+	/* Can't open read only session if SO login */
+	if (slot->logged_in == CKU_SO && !(flags & CKF_RW_SESSION))
+		return CKR_SESSION_READ_WRITE_SO_EXISTS; 
 
 	/* Make and register a new session */
 	handle = gck_module_next_handle (self);
@@ -1021,6 +1049,7 @@
 	CK_SLOT_ID slot_id;
 	GckSession *session;
 	VirtualSlot *slot;
+	GList *l;
 	
 	g_return_val_if_fail (GCK_IS_MODULE (self), CKR_CRYPTOKI_NOT_INITIALIZED);
 	
@@ -1032,12 +1061,8 @@
 	if (user_type == CKU_CONTEXT_SPECIFIC)
 		return gck_session_login_context_specific (session, pin, pin_len);
 
-	/* We don't have support for SO logins */
-	if (user_type == CKU_SO) 
-		return CKR_USER_TYPE_INVALID;
-	
 	/* Some random crap... */
-	if (user_type != CKU_USER)
+	if (user_type != CKU_USER && user_type != CKU_SO)
 		return CKR_USER_TYPE_INVALID;
 
 	/* Calculate the virtual slot */
@@ -1045,10 +1070,25 @@
 	slot = lookup_virtual_slot (self, slot_id);
 	g_return_val_if_fail (slot, CKR_GENERAL_ERROR);
 
-	if (slot->logged_in)
+	if (slot->logged_in != CKU_NONE)
 		return CKR_USER_ALREADY_LOGGED_IN;
-	
-	return gck_module_login_user (self, slot_id, pin, pin_len);
+
+	if (user_type == CKU_SO) {
+		
+		/* Can't login as SO if read-only sessions exist */
+		for (l = slot->sessions; l; l = g_list_next (l)) {
+			if (gck_session_get_read_only (l->data))
+				return CKR_SESSION_READ_ONLY_EXISTS;
+		}
+		
+		return gck_module_login_so (self, slot_id, pin, pin_len);
+				
+	} else if (user_type == CKU_USER) {
+		return gck_module_login_user (self, slot_id, pin, pin_len);
+		
+	} else {
+		return CKR_USER_TYPE_INVALID;
+	}
 }
 
 CK_RV
@@ -1068,8 +1108,8 @@
 	slot = lookup_virtual_slot (self, slot_id);
 	g_return_val_if_fail (slot, CKR_GENERAL_ERROR);
 
-	if (!slot->logged_in)
+	if (slot->logged_in == CKU_NONE)
 		return CKR_USER_NOT_LOGGED_IN;
 
-	return gck_module_logout_user (self, slot_id);
+	return gck_module_logout_any (self, slot_id);
 }

Modified: trunk/pkcs11/gck/gck-module.h
==============================================================================
--- trunk/pkcs11/gck/gck-module.h	(original)
+++ trunk/pkcs11/gck/gck-module.h	Fri Feb 27 02:52:51 2009
@@ -68,8 +68,11 @@
 
 	CK_RV (*login_user) (GckModule *self, CK_SLOT_ID slot_id, 
 	                     CK_UTF8CHAR_PTR pin, CK_ULONG n_pin);
+
+	CK_RV (*login_so) (GckModule *self, CK_SLOT_ID slot_id, 
+	                   CK_UTF8CHAR_PTR pin, CK_ULONG n_pin);
 	
-	CK_RV (*logout_user) (GckModule *self, CK_SLOT_ID slot_id);
+	CK_RV (*logout_any) (GckModule *self, CK_SLOT_ID slot_id);
 };
 
 /* 
@@ -116,7 +119,12 @@
                                                                    CK_UTF8CHAR_PTR pin,
                                                                    CK_ULONG n_pin);
 
-CK_RV                  gck_module_logout_user                     (GckModule *self,
+CK_RV                  gck_module_login_so                        (GckModule *self,
+                                                                   CK_SLOT_ID slot_id,
+                                                                   CK_UTF8CHAR_PTR pin,
+                                                                   CK_ULONG n_pin);
+
+CK_RV                  gck_module_logout_any                      (GckModule *self,
                                                                    CK_SLOT_ID slot_id);
 
 CK_RV                  gck_module_refresh_token                   (GckModule *self);

Modified: trunk/pkcs11/gck/gck-session.c
==============================================================================
--- trunk/pkcs11/gck/gck-session.c	(original)
+++ trunk/pkcs11/gck/gck-session.c	Fri Feb 27 02:52:51 2009
@@ -22,6 +22,7 @@
 #include "config.h"
 
 #include "pkcs11/pkcs11.h"
+#include "pkcs11/pkcs11i.h"
 
 #include "gck-attributes.h"
 #include "gck-crypto.h"
@@ -52,7 +53,7 @@
 	GckManager *manager;
 	GckStore *store;
 
-	gboolean logged_in;
+	CK_USER_TYPE logged_in;
 	gboolean read_only;
 
 	CK_NOTIFY notify_callback;
@@ -255,7 +256,7 @@
 	 * Check that we're not accessing private objects on a 
 	 * non-logged in session 
 	 */
-	if (!self->pv->logged_in) {
+	if (self->pv->logged_in != CKU_USER) {
 		if (!gck_object_get_attribute_boolean (object, CKA_PRIVATE, &is_private))
 			is_private = FALSE;
 		if (is_private)
@@ -475,7 +476,7 @@
 		self->pv->read_only = g_value_get_boolean (value);
 		break;
 	case PROP_LOGGED_IN:
-		gck_session_set_logged_in (self, g_value_get_boolean (value));
+		gck_session_set_logged_in (self, g_value_get_ulong (value));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -506,7 +507,7 @@
 		g_value_set_boolean (value, gck_session_get_read_only (self));
 		break;
 	case PROP_LOGGED_IN:
-		g_value_set_boolean (value, gck_session_get_logged_in (self));
+		g_value_set_ulong (value, gck_session_get_logged_in (self));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -549,8 +550,8 @@
 	                               TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 	
 	g_object_class_install_property (gobject_class, PROP_LOGGED_IN,
-	         g_param_spec_boolean ("logged-in", "Logged in", "Whether this session is logged in or not", 
-	                               FALSE, G_PARAM_READWRITE));
+	         g_param_spec_ulong ("logged-in", "Logged in", "Whether this session is logged in or not", 
+	                             0, G_MAXULONG, CKU_NONE, G_PARAM_READWRITE));
 }
 
 /* -----------------------------------------------------------------------------
@@ -587,7 +588,7 @@
 	return self->pv->manager;	
 }
 
-gboolean
+gulong
 gck_session_get_logged_in (GckSession *self)
 {
 	g_return_val_if_fail (GCK_IS_SESSION (self), FALSE);
@@ -595,7 +596,7 @@
 }
 
 void
-gck_session_set_logged_in (GckSession *self, gboolean logged_in)
+gck_session_set_logged_in (GckSession *self, gulong logged_in)
 {
 	g_return_if_fail (GCK_IS_SESSION (self));
 	self->pv->logged_in = logged_in;
@@ -679,8 +680,10 @@
 		return CKR_ARGUMENTS_BAD;
 	
 	info->slotID = self->pv->slot_id;
-	if (self->pv->logged_in)
+	if (self->pv->logged_in == CKU_USER)
 		info->state = self->pv->read_only ? CKS_RO_USER_FUNCTIONS : CKS_RW_USER_FUNCTIONS;
+	else if (self->pv->logged_in == CKU_SO)
+		info->state = CKS_RW_SO_FUNCTIONS;
 	else
 		info->state = self->pv->read_only ? CKS_RO_PUBLIC_SESSION : CKS_RW_PUBLIC_SESSION;
 	info->flags = CKF_SERIAL_SESSION;
@@ -762,7 +765,7 @@
 		g_return_val_if_fail (object, CKR_GENERAL_ERROR);
 
 		/* Can only create public objects unless logged in */
-		if (!gck_session_get_logged_in (self) &&
+		if (gck_session_get_logged_in (self) != CKU_USER &&
 		    gck_object_get_attribute_boolean (object, CKA_PRIVATE, &is_private) && 
 		    is_private == TRUE) {
 			gck_transaction_fail (transaction, CKR_USER_NOT_LOGGED_IN);
@@ -928,7 +931,7 @@
 	found = g_array_new (FALSE, TRUE, sizeof (CK_OBJECT_HANDLE));
 
 	/* If not logged in, then skip private objects */
-	also_private = gck_session_get_logged_in (self); 
+	also_private = gck_session_get_logged_in (self) == CKU_USER; 
 
 	if (all || token) {
 		rv = gck_module_refresh_token (self->pv->module);

Modified: trunk/pkcs11/gck/gck-session.h
==============================================================================
--- trunk/pkcs11/gck/gck-session.h	(original)
+++ trunk/pkcs11/gck/gck-session.h	Fri Feb 27 02:52:51 2009
@@ -69,10 +69,10 @@
 
 gboolean                 gck_session_get_read_only                      (GckSession *self);
 
-gboolean                 gck_session_get_logged_in                      (GckSession *self);
+gulong                   gck_session_get_logged_in                      (GckSession *self);
 
 void                     gck_session_set_logged_in                      (GckSession *self,
-                                                                         gboolean logged_in);
+                                                                         gulong logged_in);
 
 CK_RV                    gck_session_lookup_readable_object             (GckSession *self, 
                                                                          CK_OBJECT_HANDLE handle, 

Modified: trunk/pkcs11/pkcs11i.h
==============================================================================
--- trunk/pkcs11/pkcs11i.h	(original)
+++ trunk/pkcs11/pkcs11i.h	Fri Feb 27 02:52:51 2009
@@ -27,6 +27,9 @@
 #include "pkcs11.h"
 #include "pkcs11g.h"
 
+/* Signifies that nobody is logged in */
+#define CKU_NONE G_MAXULONG
+
 /* ----------------------------------------------------------------------
  * APARTMENT SLOTS
  * 
@@ -72,4 +75,5 @@
 
 #define CK_GNOME_INTERNAL_SHA1                      (CKA_GNOME + 1000)
 
+
 #endif /* PKCS11I_H */

Modified: trunk/pkcs11/user-store/gck-user-module.c
==============================================================================
--- trunk/pkcs11/user-store/gck-user-module.c	(original)
+++ trunk/pkcs11/user-store/gck-user-module.c	Fri Feb 27 02:52:51 2009
@@ -40,7 +40,7 @@
 	GckModule parent;
 	GckUserStorage *storage;
 	gchar *directory;
-	GHashTable *logged_in_apps;
+	GHashTable *unlocked_apps;
 	CK_TOKEN_INFO token_info;
 };
 
@@ -181,13 +181,13 @@
 	CK_RV rv;
 
 	/* See if this application has logged in */
-	if (g_hash_table_lookup (self->logged_in_apps, &slot_id))
+	if (g_hash_table_lookup (self->unlocked_apps, &slot_id))
 		return CKR_USER_ALREADY_LOGGED_IN;
 
 	login = gck_user_storage_get_login (self->storage);
 	
 	/* No application is logged in */
-	if (g_hash_table_size (self->logged_in_apps) == 0) {
+	if (g_hash_table_size (self->unlocked_apps) == 0) {
 
 		g_return_val_if_fail (login == NULL, CKR_GENERAL_ERROR);
 
@@ -210,7 +210,7 @@
 
 	/* Note that this application logged in */
 	if (rv == CKR_OK) {
-		g_hash_table_insert (self->logged_in_apps, gck_util_ulong_alloc (slot_id), UNUSED_VALUE);
+		g_hash_table_insert (self->unlocked_apps, gck_util_ulong_alloc (slot_id), UNUSED_VALUE);
 		rv = GCK_MODULE_CLASS (gck_user_module_parent_class)->login_user (base, slot_id, pin, n_pin);
 	}
 	
@@ -218,20 +218,36 @@
 }
 
 static CK_RV 
-gck_user_module_real_logout_user (GckModule *base, CK_SLOT_ID slot_id)
+gck_user_module_real_login_so (GckModule *base, CK_SLOT_ID slot_id, CK_UTF8CHAR_PTR pin, CK_ULONG n_pin)
+{
+	GckUserModule *self = GCK_USER_MODULE (base);
+	
+	/* See if this application has unlocked, in which case we can't login */
+	if (g_hash_table_lookup (self->unlocked_apps, &slot_id))
+		return CKR_USER_ALREADY_LOGGED_IN;
+	
+	/* Note that for an SO login, we don't actually unlock, and pin is always blank */
+	if (n_pin != 0)
+		return CKR_PIN_INCORRECT;
+
+	return GCK_MODULE_CLASS (gck_user_module_parent_class)->login_so (base, slot_id, pin, n_pin);
+}
+
+static CK_RV 
+gck_user_module_real_logout_any (GckModule *base, CK_SLOT_ID slot_id)
 {
 	GckUserModule *self = GCK_USER_MODULE (base);
 	CK_RV rv;
 	
-	if (!g_hash_table_remove (self->logged_in_apps, &slot_id))
+	if (!g_hash_table_remove (self->unlocked_apps, &slot_id))
 		return CKR_USER_NOT_LOGGED_IN;
 	
-	if (g_hash_table_size (self->logged_in_apps) > 0)
+	if (g_hash_table_size (self->unlocked_apps) > 0)
 		return CKR_OK;
 	
 	rv = gck_user_storage_lock (self->storage);
 	if (rv == CKR_OK)
-		rv = GCK_MODULE_CLASS (gck_user_module_parent_class)->logout_user (base, slot_id);
+		rv = GCK_MODULE_CLASS (gck_user_module_parent_class)->logout_any (base, slot_id);
 	
 	return rv;
 }
@@ -252,7 +268,7 @@
 static void
 gck_user_module_init (GckUserModule *self)
 {
-	self->logged_in_apps = g_hash_table_new_full (gck_util_ulong_hash, gck_util_ulong_equal, gck_util_ulong_free, NULL);
+	self->unlocked_apps = g_hash_table_new_full (gck_util_ulong_hash, gck_util_ulong_equal, gck_util_ulong_free, NULL);
 	
 	/* Our default token info, updated as module runs */
 	memcpy (&self->token_info, &user_module_token_info, sizeof (CK_TOKEN_INFO));
@@ -271,7 +287,7 @@
 		g_object_unref (self->storage);
 	self->storage = NULL;
 	
-	g_hash_table_remove_all (self->logged_in_apps);
+	g_hash_table_remove_all (self->unlocked_apps);
     
 	G_OBJECT_CLASS (gck_user_module_parent_class)->dispose (obj);
 }
@@ -283,9 +299,9 @@
 	
 	g_assert (self->storage == NULL);
 	
-	g_assert (self->logged_in_apps);
-	g_hash_table_destroy (self->logged_in_apps);
-	self->logged_in_apps = NULL;
+	g_assert (self->unlocked_apps);
+	g_hash_table_destroy (self->unlocked_apps);
+	self->unlocked_apps = NULL;
 	
 	g_free (self->directory);
 	self->directory = NULL;
@@ -310,7 +326,8 @@
 	module_class->store_token_object = gck_user_module_real_store_token_object;
 	module_class->remove_token_object = gck_user_module_real_remove_token_object;
 	module_class->login_user = gck_user_module_real_login_user;
-	module_class->logout_user = gck_user_module_real_logout_user;
+	module_class->login_so = gck_user_module_real_login_so;
+	module_class->logout_any = gck_user_module_real_logout_any;
 	module_class->login_change = gck_user_module_real_login_change;
 }
 



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