gnome-keyring r1625 - in trunk: . pkcs11 pkcs11/gck pkcs11/user-store
- From: nnielsen svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-keyring r1625 - in trunk: . pkcs11 pkcs11/gck pkcs11/user-store
- Date: Fri, 27 Feb 2009 02:52:51 +0000 (UTC)
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]