gnome-keyring r1411 - in trunk: . gp11 gp11/tests
- From: nnielsen svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-keyring r1411 - in trunk: . gp11 gp11/tests
- Date: Sat, 27 Dec 2008 18:29:23 +0000 (UTC)
Author: nnielsen
Date: Sat Dec 27 18:29:23 2008
New Revision: 1411
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1411&view=rev
Log:
* gp11/gp11.h:
* gp11/gp11-call.c:
* gp11/gp11-marshal.list:
* gp11/gp11-misc.c:
* gp11/gp11-module.c:
* gp11/gp11-object.c:
* gp11/gp11-session.c:
* gp11/gp11-slot.c:
* gp11/tests/unit-test-gp11-module.c:
* gp11/tests/unit-test-gp11-object.c:
* gp11/tests/unit-test-gp11-session.c: Add basic thread-safety.
Modified:
trunk/ChangeLog
trunk/gp11/gp11-call.c
trunk/gp11/gp11-marshal.list
trunk/gp11/gp11-misc.c
trunk/gp11/gp11-module.c
trunk/gp11/gp11-object.c
trunk/gp11/gp11-session.c
trunk/gp11/gp11-slot.c
trunk/gp11/gp11.h
trunk/gp11/tests/unit-test-gp11-module.c
trunk/gp11/tests/unit-test-gp11-object.c
trunk/gp11/tests/unit-test-gp11-session.c
Modified: trunk/gp11/gp11-call.c
==============================================================================
--- trunk/gp11/gp11-call.c (original)
+++ trunk/gp11/gp11-call.c Sat Dec 27 18:29:23 2008
@@ -33,6 +33,7 @@
struct _GP11Call {
GObject parent;
+ GP11Module *module;
/* For making the call */
GP11CallFunc func;
@@ -131,6 +132,8 @@
static void
process_result (GP11Call *call, gpointer unused)
{
+ GP11Slot *slot;
+
/* Double check a few things */
g_assert (GP11_IS_CALL (call));
@@ -147,8 +150,10 @@
if (call->rv == CKR_USER_NOT_LOGGED_IN && GP11_IS_SESSION (call->object)) {
g_free (call->password);
call->password = NULL;
- call->do_login = _gp11_slot_token_authentication (GP11_SESSION (call->object)->slot,
- &call->password);
+ slot = gp11_session_get_slot (GP11_SESSION (call->object));
+ g_assert (GP11_IS_SLOT (slot));
+ call->do_login = _gp11_slot_token_authentication (slot, &call->password);
+ g_object_unref (slot);
}
/* If we're supposed to do a login, then queue this call again */
@@ -238,6 +243,10 @@
_gp11_call_finalize (GObject *obj)
{
GP11Call *call = GP11_CALL (obj);
+
+ if (call->module)
+ g_object_unref (call->module);
+ call->module = NULL;
if (call->object)
g_object_unref (call->object);
@@ -395,6 +404,7 @@
GP11Arguments *args = (GP11Arguments*)data;
gchar *password = NULL;
GP11Module *module = NULL;
+ GP11Slot *slot;
CK_ULONG pin_len;
CK_RV rv;
@@ -404,9 +414,10 @@
g_object_get (object, "module", &module, "handle", &args->handle, NULL);
g_assert (GP11_IS_MODULE (module));
-
- args->pkcs11 = module->funcs;
- g_object_unref (module);
+
+ /* We now hold a reference to module until below */
+ args->pkcs11 = gp11_module_get_function_list (module);
+ g_assert (args->pkcs11);
rv = perform_call ((GP11CallFunc)func, cancellable, args);
@@ -417,20 +428,23 @@
if (rv == CKR_USER_NOT_LOGGED_IN && GP11_IS_SESSION (object)) {
do {
- if (!_gp11_slot_token_authentication (GP11_SESSION (object)->slot,
- &password)) {
+ slot = gp11_session_get_slot (GP11_SESSION (object));
+ if (!_gp11_slot_token_authentication (slot, &password)) {
rv = CKR_USER_NOT_LOGGED_IN;
} else {
pin_len = password ? strlen (password) : 0;
rv = (args->pkcs11->C_Login) (args->handle, CKU_USER,
(CK_UTF8CHAR_PTR)password, pin_len);
}
+ g_object_unref (slot);
} while (rv == CKR_PIN_INCORRECT);
/* If we logged in successfully then try again */
if (rv == CKR_OK)
rv = perform_call ((GP11CallFunc)func, cancellable, args);
}
+
+ g_object_unref (module);
if (rv == CKR_OK)
return TRUE;
@@ -477,15 +491,18 @@
void
_gp11_call_async_object (GP11Call *call, gpointer object)
{
- GP11Module *module;
-
g_assert (GP11_IS_CALL (call));
g_assert (call->args);
- g_object_get (object, "module", &module, "handle", &call->args->handle, NULL);
- g_assert (GP11_IS_MODULE (module));
- call->args->pkcs11 = module->funcs;
- g_object_unref (module);
+ if (call->module)
+ g_object_unref (call->module);
+ call->module = NULL;
+
+ g_object_get (object, "module", &call->module, "handle", &call->args->handle, NULL);
+ g_assert (GP11_IS_MODULE (call->module));
+ call->args->pkcs11 = gp11_module_get_function_list (call->module);
+
+ /* We now hold a reference on module until finalize */
}
GP11Call*
Modified: trunk/gp11/gp11-marshal.list
==============================================================================
--- trunk/gp11/gp11-marshal.list (original)
+++ trunk/gp11/gp11-marshal.list Sat Dec 27 18:29:23 2008
@@ -1,2 +1,3 @@
BOOLEAN:POINTER
BOOLEAN:OBJECT,POINTER
+BOOLEAN:ULONG
Modified: trunk/gp11/gp11-misc.c
==============================================================================
--- trunk/gp11/gp11-misc.c (original)
+++ trunk/gp11/gp11-misc.c Sat Dec 27 18:29:23 2008
@@ -38,8 +38,13 @@
gp11_get_error_quark (void)
{
static GQuark domain = 0;
- if (domain == 0)
+ static volatile gsize quark_inited = 0;
+
+ if (g_once_init_enter (&quark_inited)) {
domain = g_quark_from_static_string ("gp11-error");
+ g_once_init_leave (&quark_inited, 1);
+ }
+
return domain;
}
Modified: trunk/gp11/gp11-module.c
==============================================================================
--- trunk/gp11/gp11-module.c (original)
+++ trunk/gp11/gp11-module.c Sat Dec 27 18:29:23 2008
@@ -27,18 +27,35 @@
#include <string.h>
+/*
+ * MT safe
+ *
+ * The only thing that can change after object initialization in
+ * a GP11Module is the finalized flag, which can be set
+ * to 1 in dispose.
+ */
+
enum {
PROP_0,
- PROP_MODULE_PATH
+ PROP_PATH,
+ PROP_FUNCTION_LIST
};
-typedef struct _GP11ModulePrivate {
+typedef struct _GP11ModuleData {
GModule *module;
+ gchar *path;
+ gint finalized;
+ CK_FUNCTION_LIST_PTR funcs;
CK_C_INITIALIZE_ARGS init_args;
+} GP11ModuleData;
+
+typedef struct _GP11ModulePrivate {
+ GP11ModuleData data;
+ /* Add future mutex and non-MT-safe data here */
} GP11ModulePrivate;
-#define GP11_MODULE_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE((o), GP11_TYPE_MODULE, GP11ModulePrivate))
+#define GP11_MODULE_GET_DATA(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), GP11_TYPE_MODULE, GP11ModuleData))
G_DEFINE_TYPE (GP11Module, gp11_module, G_TYPE_OBJECT);
@@ -94,7 +111,7 @@
*/
static void
-gp11_module_init (GP11Module *module)
+gp11_module_init (GP11Module *self)
{
}
@@ -103,11 +120,14 @@
gp11_module_get_property (GObject *obj, guint prop_id, GValue *value,
GParamSpec *pspec)
{
- GP11Module *module = GP11_MODULE (obj);
+ GP11Module *self = GP11_MODULE (obj);
switch (prop_id) {
- case PROP_MODULE_PATH:
- g_value_set_string (value, module->path);
+ case PROP_PATH:
+ g_value_set_string (value, gp11_module_get_path (self));
+ break;
+ case PROP_FUNCTION_LIST:
+ g_value_set_pointer (value, gp11_module_get_function_list (self));
break;
}
}
@@ -116,14 +136,14 @@
gp11_module_set_property (GObject *obj, guint prop_id, const GValue *value,
GParamSpec *pspec)
{
- GP11ModulePrivate *pv = GP11_MODULE_GET_PRIVATE (obj);
- GP11Module *module = GP11_MODULE (obj);
+ GP11ModuleData *data = GP11_MODULE_GET_DATA (obj);
+ /* Only allowed during initialization */
switch (prop_id) {
- case PROP_MODULE_PATH:
- g_return_if_fail (!pv->module);
- module->path = g_value_dup_string (value);
- g_return_if_fail (module->path);
+ case PROP_PATH:
+ g_return_if_fail (!data->path);
+ data->path = g_value_dup_string (value);
+ g_return_if_fail (data->path);
break;
}
}
@@ -131,36 +151,39 @@
static void
gp11_module_dispose (GObject *obj)
{
- GP11Module *module = GP11_MODULE (obj);
+ GP11ModuleData *data = GP11_MODULE_GET_DATA (obj);
+ gint finalized = g_atomic_int_get (&data->finalized);
CK_RV rv;
-
- if (module->funcs) {
- rv = (module->funcs->C_Finalize) (NULL);
+
+ /* Must be careful when accessing funcs */
+ if (data->funcs && !finalized &&
+ g_atomic_int_compare_and_exchange (&data->finalized, finalized, 1)) {
+ rv = (data->funcs->C_Finalize) (NULL);
if (rv != CKR_OK) {
g_warning ("C_Finalize on module '%s' failed: %s",
- module->path, gp11_message_from_rv (rv));
+ data->path, gp11_message_from_rv (rv));
}
- module->funcs = NULL;
}
+
+ G_OBJECT_CLASS (gp11_module_parent_class)->dispose (obj);
}
static void
gp11_module_finalize (GObject *obj)
{
- GP11ModulePrivate *pv = GP11_MODULE_GET_PRIVATE (obj);
- GP11Module *module = GP11_MODULE (obj);
+ GP11ModuleData *data = GP11_MODULE_GET_DATA (obj);
- g_assert (module->funcs == NULL);
+ data->funcs = NULL;
- if (pv->module) {
- if (!g_module_close (pv->module))
+ if (data->module) {
+ if (!g_module_close (data->module))
g_warning ("failed to close the pkcs11 module: %s",
g_module_error ());
- pv->module = NULL;
+ data->module = NULL;
}
- g_free (module->path);
- module->path = NULL;
+ g_free (data->path);
+ data->path = NULL;
G_OBJECT_CLASS (gp11_module_parent_class)->finalize (obj);
}
@@ -177,10 +200,14 @@
gobject_class->dispose = gp11_module_dispose;
gobject_class->finalize = gp11_module_finalize;
- g_object_class_install_property (gobject_class, PROP_MODULE_PATH,
- g_param_spec_string ("module-path", "Module Path", "Path to the PKCS11 Module",
+ g_object_class_install_property (gobject_class, PROP_PATH,
+ g_param_spec_string ("path", "Module Path", "Path to the PKCS11 Module",
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (gobject_class, PROP_FUNCTION_LIST,
+ g_param_spec_pointer ("function-list", "Function List", "PKCS11 Function List",
+ G_PARAM_READABLE));
+
g_type_class_add_private (gobject_class, sizeof (GP11ModulePrivate));
}
@@ -218,19 +245,19 @@
gp11_module_initialize (const gchar *path, gpointer reserved, GError **err)
{
CK_C_GetFunctionList get_function_list;
- GP11ModulePrivate *pv;
+ GP11ModuleData *data;
GP11Module *mod;
CK_RV rv;
g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (!err || !*err, NULL);
- mod = g_object_new (GP11_TYPE_MODULE, "module-path", path, NULL);
- pv = GP11_MODULE_GET_PRIVATE (mod);
+ mod = g_object_new (GP11_TYPE_MODULE, "path", path, NULL);
+ data = GP11_MODULE_GET_DATA (mod);
/* Load the actual module */
- pv->module = g_module_open (path, 0);
- if (!pv->module) {
+ data->module = g_module_open (path, 0);
+ if (!data->module) {
g_set_error (err, GP11_ERROR, (int)CKR_GP11_MODULE_PROBLEM,
"Error loading pkcs11 module: %s", g_module_error ());
g_object_unref (mod);
@@ -238,7 +265,7 @@
}
/* Get the entry point */
- if (!g_module_symbol (pv->module, "C_GetFunctionList", (void**)&get_function_list)) {
+ if (!g_module_symbol (data->module, "C_GetFunctionList", (void**)&get_function_list)) {
g_set_error (err, GP11_ERROR, (int)CKR_GP11_MODULE_PROBLEM,
"Invalid pkcs11 module: %s", g_module_error ());
g_object_unref (mod);
@@ -246,7 +273,7 @@
}
/* Get the function list */
- rv = (get_function_list) (&mod->funcs);
+ rv = (get_function_list) (&data->funcs);
if (rv != CKR_OK) {
g_set_error (err, GP11_ERROR, rv, "Couldn't get pkcs11 function list: %s",
gp11_message_from_rv (rv));
@@ -254,26 +281,16 @@
return NULL;
}
- /* Make sure we have a compatible version */
- if (mod->funcs->version.major != CRYPTOKI_VERSION_MAJOR) {
- g_set_error (err, GP11_ERROR, (int)CKR_GP11_MODULE_PROBLEM,
- "Incompatible version of pkcs11 module: %d.%d",
- (int)mod->funcs->version.major,
- (int)mod->funcs->version.minor);
- g_object_unref (mod);
- return NULL;
- }
-
- memset (&pv->init_args, 0, sizeof (pv->init_args));
- pv->init_args.flags = CKF_OS_LOCKING_OK;
- pv->init_args.CreateMutex = create_mutex;
- pv->init_args.DestroyMutex = destroy_mutex;
- pv->init_args.LockMutex = lock_mutex;
- pv->init_args.UnlockMutex = unlock_mutex;
- pv->init_args.pReserved = reserved;
+ memset (&data->init_args, 0, sizeof (data->init_args));
+ data->init_args.flags = CKF_OS_LOCKING_OK;
+ data->init_args.CreateMutex = create_mutex;
+ data->init_args.DestroyMutex = destroy_mutex;
+ data->init_args.LockMutex = lock_mutex;
+ data->init_args.UnlockMutex = unlock_mutex;
+ data->init_args.pReserved = reserved;
/* Now initialize the module */
- rv = (mod->funcs->C_Initialize) (&pv->init_args);
+ rv = (data->funcs->C_Initialize) (&data->init_args);
if (rv != CKR_OK) {
g_set_error (err, GP11_ERROR, rv, "Couldn't initialize module: %s",
gp11_message_from_rv (rv));
@@ -286,24 +303,25 @@
/**
* gp11_module_get_info:
- * @module: The module to get info for.
+ * @self: The module to get info for.
*
* Get the info about a PKCS#11 module.
*
* Return value: The module info. Release this with gp11_module_info_free().
**/
GP11ModuleInfo*
-gp11_module_get_info (GP11Module *module)
+gp11_module_get_info (GP11Module *self)
{
+ GP11ModuleData *data = GP11_MODULE_GET_DATA (self);
GP11ModuleInfo *modinfo;
CK_INFO info;
CK_RV rv;
- g_return_val_if_fail (GP11_IS_MODULE (module), NULL);
- g_return_val_if_fail (module->funcs, NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (self), NULL);
+ g_return_val_if_fail (data->funcs, NULL);
memset (&info, 0, sizeof (info));
- rv = (module->funcs->C_GetInfo (&info));
+ rv = (data->funcs->C_GetInfo (&info));
if (rv != CKR_OK) {
g_warning ("couldn't get module info: %s", gp11_message_from_rv (rv));
return NULL;
@@ -325,7 +343,7 @@
/**
* gp11_module_get_slots:
- * @module: The module for which to get the slots.
+ * @self: The module for which to get the slots.
* @token_present: Whether to limit only to slots with a token present.
*
* Get the GP11Slot objects for a given module.
@@ -333,17 +351,18 @@
* Return value: The possibly empty list of slots. Release this with gp11_list_unref_free().
*/
GList*
-gp11_module_get_slots (GP11Module *module, gboolean token_present)
+gp11_module_get_slots (GP11Module *self, gboolean token_present)
{
+ GP11ModuleData *data = GP11_MODULE_GET_DATA (self);
CK_SLOT_ID_PTR slot_list;
CK_ULONG count, i;
GList *result;
CK_RV rv;
- g_return_val_if_fail (GP11_IS_MODULE (module), NULL);
- g_return_val_if_fail (module->funcs, NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (self), NULL);
+ g_return_val_if_fail (data->funcs, NULL);
- rv = (module->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, NULL, &count);
+ rv = (data->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, NULL, &count);
if (rv != CKR_OK) {
g_warning ("couldn't get slot count: %s", gp11_message_from_rv (rv));
return NULL;
@@ -353,7 +372,7 @@
return NULL;
slot_list = g_new (CK_SLOT_ID, count);
- rv = (module->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, slot_list, &count);
+ rv = (data->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, slot_list, &count);
if (rv != CKR_OK) {
g_warning ("couldn't get slot list: %s", gp11_message_from_rv (rv));
g_free (slot_list);
@@ -362,13 +381,44 @@
result = NULL;
for (i = 0; i < count; ++i) {
- /* TODO: Should we be looking these up somewhere? */
result = g_list_prepend (result, g_object_new (GP11_TYPE_SLOT,
"handle", slot_list[i],
- "module", module, NULL));
+ "module", self, NULL));
}
g_free (slot_list);
return g_list_reverse (result);
}
+/**
+ * gp11_module_get_path:
+ * @self: The module for which to get the path.
+ *
+ * Get the file path of this module. This may not be an absolute path, and
+ * usually reflects the path passed to gp11_module_initialize().
+ *
+ * Return value: The path, do not modify or free this value.
+ **/
+const gchar*
+gp11_module_get_path (GP11Module *self)
+{
+ GP11ModuleData *data = GP11_MODULE_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_MODULE (self), NULL);
+ return data->path;
+}
+
+/**
+ * gp11_module_get_function_list:
+ * @self: The module for which to get the function list.
+ *
+ * Get the PKCS#11 function list for the module.
+ *
+ * Return value: The function list, do not modify this structure.
+ **/
+CK_FUNCTION_LIST_PTR
+gp11_module_get_function_list (GP11Module *self)
+{
+ GP11ModuleData *data = GP11_MODULE_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_MODULE (self), NULL);
+ return data->funcs;
+}
Modified: trunk/gp11/gp11-object.c
==============================================================================
--- trunk/gp11/gp11-object.c (original)
+++ trunk/gp11/gp11-object.c Sat Dec 27 18:29:23 2008
@@ -28,6 +28,12 @@
#include <string.h>
+/*
+ * MT safe -- Nothing in GP11ObjectData changes between
+ * init and finalize. All GP11ObjectPrivate access between init
+ * and finalize is locked.
+ */
+
enum {
PROP_0,
PROP_MODULE,
@@ -36,6 +42,21 @@
PROP_SESSION
};
+typedef struct _GP11ObjectData {
+ GP11Module *module;
+ GP11Slot *slot;
+ CK_OBJECT_HANDLE handle;
+} GP11ObjectData;
+
+typedef struct _GP11ObjectPrivate {
+ GP11ObjectData data;
+ GStaticMutex mutex;
+ GP11Session *session;
+} GP11ObjectPrivate;
+
+#define GP11_OBJECT_GET_DATA(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), GP11_TYPE_OBJECT, GP11ObjectData))
+
G_DEFINE_TYPE (GP11Object, gp11_object, G_TYPE_OBJECT);
/* ----------------------------------------------------------------------------
@@ -80,26 +101,37 @@
}
static void
-require_session_async (GP11Object *object, GP11Call *call,
+require_session_async (GP11Object *self, GP11Call *call,
gulong flags, GCancellable *cancellable)
{
- g_assert (GP11_IS_OBJECT (object));
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+ GP11Session *session;
+
+ g_assert (GP11_IS_OBJECT (self));
+
+ session = gp11_object_get_session (self);
+ if (session) {
+ run_call_with_session (call, session);
+ g_object_unref (session);
+ } else {
+ gp11_slot_open_session_async (data->slot, flags, cancellable, opened_session, call);
+ }
- if (object->session)
- run_call_with_session (call, object->session);
- else
- gp11_slot_open_session_async (object->slot, flags, cancellable, opened_session, call);
}
static GP11Session*
-require_session_sync (GP11Object *object, gulong flags, GError **err)
+require_session_sync (GP11Object *self, gulong flags, GError **err)
{
- g_assert (GP11_IS_OBJECT (object));
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+ GP11Session *session;
+
+ g_assert (GP11_IS_OBJECT (self));
- if (object->session)
- return g_object_ref (object->session);
+ session = gp11_object_get_session (self);
+ if (session)
+ return session;
- return gp11_slot_open_session (object->slot, flags, err);
+ return gp11_slot_open_session (data->slot, flags, err);
}
/* ----------------------------------------------------------------------------
@@ -107,29 +139,30 @@
*/
static void
-gp11_object_init (GP11Object *object)
+gp11_object_init (GP11Object *self)
{
-
+ GP11ObjectPrivate *pv = (G_TYPE_INSTANCE_GET_PRIVATE(self, GP11_TYPE_OBJECT, GP11ObjectPrivate));
+ g_static_mutex_init (&pv->mutex);
}
static void
gp11_object_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
+ GParamSpec *pspec)
{
- GP11Object *object = GP11_OBJECT (obj);
+ GP11Object *self = GP11_OBJECT (obj);
switch (prop_id) {
case PROP_MODULE:
- g_value_set_object (value, object->module);
+ g_value_take_object (value, gp11_object_get_module (self));
break;
case PROP_SLOT:
- g_value_set_object (value, object->slot);
+ g_value_take_object (value, gp11_object_get_slot (self));
break;
case PROP_SESSION:
- g_value_set_object (value, object->session);
+ g_value_take_object (value, gp11_object_get_session (self));
break;
case PROP_HANDLE:
- g_value_set_uint (value, object->handle);
+ g_value_set_ulong (value, gp11_object_get_handle (self));
break;
}
}
@@ -138,61 +171,55 @@
gp11_object_set_property (GObject *obj, guint prop_id, const GValue *value,
GParamSpec *pspec)
{
- GP11Object *object = GP11_OBJECT (obj);
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (obj);
+ GP11Object *self = GP11_OBJECT (obj);
+
+ /* The sets to data below are only allowed during construction */
switch (prop_id) {
case PROP_MODULE:
- g_return_if_fail (!object->module);
- object->module = g_value_get_object (value);
- g_return_if_fail (object->module);
- g_object_ref (object->module);
+ g_return_if_fail (!data->module);
+ data->module = g_value_get_object (value);
+ g_return_if_fail (data->module);
+ g_object_ref (data->module);
break;
case PROP_SLOT:
- g_return_if_fail (!object->slot);
- object->slot = g_value_get_object (value);
- g_return_if_fail (object->slot);
- g_object_ref (object->slot);
+ g_return_if_fail (!data->slot);
+ data->slot = g_value_get_object (value);
+ g_return_if_fail (data->slot);
+ g_object_ref (data->slot);
break;
case PROP_SESSION:
- gp11_object_set_session (object, g_value_get_object (value));
+ gp11_object_set_session (self, g_value_get_object (value));
break;
case PROP_HANDLE:
- g_return_if_fail (!object->handle);
- object->handle = g_value_get_uint (value);
+ g_return_if_fail (!data->handle);
+ data->handle = g_value_get_ulong (value);
break;
}
}
static void
-gp11_object_dispose (GObject *obj)
+gp11_object_finalize (GObject *obj)
{
- GP11Object *object = GP11_OBJECT (obj);
+ GP11ObjectPrivate *pv = (G_TYPE_INSTANCE_GET_PRIVATE(obj, GP11_TYPE_OBJECT, GP11ObjectPrivate));
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (obj);
+
+ if (data->slot)
+ g_object_unref (data->slot);
+ data->slot = NULL;
- if (object->slot)
- g_object_unref (object->slot);
- object->slot = NULL;
+ if (data->module)
+ g_object_unref (data->module);
+ data->module = NULL;
- if (object->module)
- g_object_unref (object->module);
- object->module = NULL;
+ if (pv->session)
+ g_object_unref (pv->session);
+ pv->session = NULL;
- if (object->session)
- g_object_unref (object->session);
- object->session = NULL;
-
- G_OBJECT_CLASS (gp11_object_parent_class)->dispose (obj);
-}
-
-static void
-gp11_object_finalize (GObject *obj)
-{
- GP11Object *object = GP11_OBJECT (obj);
-
- g_assert (object->slot == NULL);
- g_assert (object->module == NULL);
- g_assert (object->session == NULL);
+ data->handle = 0;
- object->handle = 0;
+ g_static_mutex_free (&pv->mutex);
G_OBJECT_CLASS (gp11_object_parent_class)->finalize (obj);
}
@@ -206,7 +233,6 @@
gobject_class->get_property = gp11_object_get_property;
gobject_class->set_property = gp11_object_set_property;
- gobject_class->dispose = gp11_object_dispose;
gobject_class->finalize = gp11_object_finalize;
g_object_class_install_property (gobject_class, PROP_MODULE,
@@ -218,12 +244,14 @@
GP11_TYPE_SLOT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_HANDLE,
- g_param_spec_uint ("handle", "Object Handle", "PKCS11 Object Handle",
- 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_param_spec_ulong ("handle", "Object Handle", "PKCS11 Object Handle",
+ 0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_SESSION,
g_param_spec_object ("session", "session", "PKCS11 Session to make calls on",
GP11_TYPE_SESSION, G_PARAM_READWRITE));
+
+ g_type_class_add_private (klass, sizeof (GP11ObjectPrivate));
}
/* ----------------------------------------------------------------------------
@@ -243,8 +271,16 @@
GP11Object*
gp11_object_from_handle (GP11Slot *slot, CK_OBJECT_HANDLE handle)
{
+ GP11Module *module = NULL;
+ GP11Object *object;
+
g_return_val_if_fail (GP11_IS_SLOT (slot), NULL);
- return g_object_new (GP11_TYPE_OBJECT, "module", slot->module, "handle", handle, "slot", slot, NULL);
+
+ module = gp11_slot_get_module (slot);
+ object = g_object_new (GP11_TYPE_OBJECT, "module", module, "handle", handle, "slot", slot, NULL);
+ g_object_unref (module);
+
+ return object;
}
/**
@@ -277,22 +313,57 @@
/**
* gp11_object_get_handle:
- * @object: The object.
+ * @self: The object.
*
* Get the raw PKCS#11 handle of a GP11Object.
*
* Return value: The raw object handle.
**/
CK_OBJECT_HANDLE
-gp11_object_get_handle (GP11Object *object)
+gp11_object_get_handle (GP11Object *self)
+{
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_OBJECT (self), (CK_OBJECT_HANDLE)-1);
+ return data->handle;
+}
+
+/**
+ * gp11_object_get_module:
+ * @self: The object.
+ *
+ * Get the PKCS#11 module to which this object belongs.
+ *
+ * Return value: The module, which should be unreffed after use.
+ **/
+GP11Module*
+gp11_object_get_module (GP11Object *self)
+{
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (data->module), NULL);
+ return g_object_ref (data->module);
+}
+
+/**
+ * gp11_object_get_slot:
+ * @self: The object.
+ *
+ * Get the PKCS#11 slot to which this object belongs.
+ *
+ * Return value: The slot, which should be unreffed after use.
+ **/
+GP11Slot*
+gp11_object_get_slot (GP11Object *self)
{
- g_return_val_if_fail (GP11_IS_OBJECT (object), (CK_OBJECT_HANDLE)-1);
- return object->handle;
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+ g_return_val_if_fail (GP11_IS_SLOT (data->slot), NULL);
+ return g_object_ref (data->slot);
}
/**
* gp11_object_get_session:
- * @object: The object
+ * @self: The object
*
* Get the PKCS#11 session assigned to make calls on when operating
* on this object.
@@ -301,18 +372,30 @@
* object. By default an object will open and close sessions
* appropriate for its calls.
*
- * Return value: The assigned session.
+ * Return value: The assigned session, which must be unreffed after use.
**/
GP11Session*
-gp11_object_get_session (GP11Object *object)
+gp11_object_get_session (GP11Object *self)
{
- g_return_val_if_fail (GP11_IS_OBJECT (object), NULL);
- return object->session;
+ GP11ObjectPrivate *pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GP11_TYPE_OBJECT, GP11ObjectPrivate));
+ GP11Session *session;
+
+ g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+
+ g_static_mutex_lock (&pv->mutex);
+
+ {
+ session = pv->session ? g_object_ref (pv->session) : NULL;
+ }
+
+ g_static_mutex_unlock (&pv->mutex);
+
+ return session;
}
/**
- * gp11_object_get_session:
- * @object: The object
+ * gp11_object_set_session:
+ * @self: The object
* @session: The assigned session
*
* Set the PKCS#11 session assigned to make calls on when operating
@@ -326,14 +409,23 @@
* that modify the state of the object will probably fail.
**/
void
-gp11_object_set_session (GP11Object *object, GP11Session *session)
+gp11_object_set_session (GP11Object *self, GP11Session *session)
{
- g_return_if_fail (GP11_IS_OBJECT (object));
- if (session)
- g_object_ref (session);
- if (object->session)
- g_object_unref (object->session);
- object->session = session;
+ GP11ObjectPrivate *pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GP11_TYPE_OBJECT, GP11ObjectPrivate));
+
+ g_return_if_fail (GP11_IS_OBJECT (self));
+
+ g_static_mutex_lock (&pv->mutex);
+
+ {
+ if (session)
+ g_object_ref (session);
+ if (pv->session)
+ g_object_unref (pv->session);
+ pv->session = session;
+ }
+
+ g_static_mutex_unlock (&pv->mutex);
}
/* DESTROY */
@@ -351,7 +443,7 @@
/**
* gp11_object_destroy:
- * @object: The object to destroy.
+ * @self: The object to destroy.
* @err: A location to return an error.
*
* Destroy a PKCS#11 object, deleting it from storage or the session.
@@ -360,14 +452,14 @@
* Return value: Whether the call was successful or not.
**/
gboolean
-gp11_object_destroy (GP11Object *object, GError **err)
+gp11_object_destroy (GP11Object *self, GError **err)
{
- return gp11_object_destroy_full (object, NULL, err);
+ return gp11_object_destroy_full (self, NULL, err);
}
/**
* gp11_object_destroy_full:
- * @object: The object to destroy.
+ * @self: The object to destroy.
* @cancellable: Optional cancellable object, or NULL to ignore.
* @err: A location to return an error.
*
@@ -377,18 +469,19 @@
* Return value: Whether the call was successful or not.
**/
gboolean
-gp11_object_destroy_full (GP11Object *object, GCancellable *cancellable, GError **err)
+gp11_object_destroy_full (GP11Object *self, GCancellable *cancellable, GError **err)
{
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
Destroy args = { GP11_ARGUMENTS_INIT, 0 };
GP11Session *session;
gboolean ret = FALSE;
- g_return_val_if_fail (GP11_IS_OBJECT (object), FALSE);
- g_return_val_if_fail (GP11_IS_SLOT (object->slot), FALSE);
+ g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+ g_return_val_if_fail (GP11_IS_SLOT (data->slot), FALSE);
- args.object = object->handle;
+ args.object = data->handle;
- session = require_session_sync (object, CKF_RW_SESSION, err);
+ session = require_session_sync (self, CKF_RW_SESSION, err);
if (session)
ret = _gp11_call_sync (session, perform_destroy, &args, cancellable, err);
g_object_unref (session);
@@ -397,7 +490,7 @@
/**
* gp11_object_destroy_async:
- * @object: The object to destroy.
+ * @self: The object to destroy.
* @cancellable: Optional cancellable object, or NULL to ignore.
* @callback: Callback which is called when operation completes.
* @user_data: Data to pass to the callback.
@@ -406,25 +499,26 @@
* This call will return immediately and complete asynchronously.
**/
void
-gp11_object_destroy_async (GP11Object *object, GCancellable *cancellable,
+gp11_object_destroy_async (GP11Object *self, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
Destroy* args;
GP11Call *call;
- g_return_if_fail (GP11_IS_OBJECT (object));
- g_return_if_fail (GP11_IS_SLOT (object->slot));
+ g_return_if_fail (GP11_IS_OBJECT (self));
+ g_return_if_fail (GP11_IS_SLOT (data->slot));
- args = _gp11_call_async_prep (NULL, object, perform_destroy, sizeof (*args), NULL);
- args->object = object->handle;
+ args = _gp11_call_async_prep (data->slot, self, perform_destroy, sizeof (*args), NULL);
+ args->object = data->handle;
call = _gp11_call_async_ready (args, cancellable, callback, user_data);
- require_session_async (object, call, CKF_RW_SESSION, cancellable);
+ require_session_async (self, call, CKF_RW_SESSION, cancellable);
}
/**
* gp11_object_destroy_finish:
- * @object: The object being destroyed.
+ * @self: The object being destroyed.
* @result: The result of the destory operation passed to the callback.
* @err: A location to store an error.
*
@@ -434,7 +528,7 @@
* Return value: Whether the object was destroyed successfully or not.
*/
gboolean
-gp11_object_destroy_finish (GP11Object *object, GAsyncResult *result, GError **err)
+gp11_object_destroy_finish (GP11Object *self, GAsyncResult *result, GError **err)
{
return _gp11_call_basic_finish (result, err);
}
@@ -462,7 +556,7 @@
/**
* gp11_object_set:
- * @object: The object to set attributes on.
+ * @self: The object to set attributes on.
* @err: A location to return an error.
* ...: The attributes to set.
*
@@ -493,7 +587,7 @@
* Return value: Whether the call was successful or not.
**/
gboolean
-gp11_object_set (GP11Object *object, GError **err, ...)
+gp11_object_set (GP11Object *self, GError **err, ...)
{
GP11Attributes *attrs;
va_list va;
@@ -503,7 +597,7 @@
attrs = gp11_attributes_new_valist (va);
va_end (va);
- rv = gp11_object_set_full (object, attrs, NULL, err);
+ rv = gp11_object_set_full (self, attrs, NULL, err);
gp11_attributes_unref (attrs);
return rv;
@@ -511,7 +605,7 @@
/**
* gp11_object_set_full:
- * @object: The object to set attributes on.
+ * @self: The object to set attributes on.
* @attrs: The attributes to set on the object.
* @cancellable: Optional cancellable object, or NULL to ignore.
* @err: A location to return an error.
@@ -521,20 +615,21 @@
* Return value: Whether the call was successful or not.
**/
gboolean
-gp11_object_set_full (GP11Object *object, GP11Attributes *attrs,
+gp11_object_set_full (GP11Object *self, GP11Attributes *attrs,
GCancellable *cancellable, GError **err)
{
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
SetAttributes args;
GP11Session *session;
gboolean ret = FALSE;
- g_return_val_if_fail (GP11_IS_OBJECT (object), FALSE);
+ g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
memset (&args, 0, sizeof (args));
args.attrs = attrs;
- args.object = object->handle;
+ args.object = data->handle;
- session = require_session_sync (object, CKF_RW_SESSION, err);
+ session = require_session_sync (self, CKF_RW_SESSION, err);
if (session)
ret = _gp11_call_sync (session, perform_set_attributes, &args, cancellable, err);
g_object_unref (session);
@@ -543,7 +638,7 @@
/**
* gp11_object_set_async:
- * @object: The object to set attributes on.
+ * @self: The object to set attributes on.
* @attrs: The attributes to set on the object.
* @cancellable: Optional cancellable object, or NULL to ignore.
* @callback: Callback which is called when operation completes.
@@ -553,27 +648,28 @@
* immediately and completes asynchronously.
**/
void
-gp11_object_set_async (GP11Object *object, GP11Attributes *attrs, GCancellable *cancellable,
+gp11_object_set_async (GP11Object *self, GP11Attributes *attrs, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
SetAttributes *args;
GP11Call *call;
- g_return_if_fail (GP11_IS_OBJECT (object));
+ g_return_if_fail (GP11_IS_OBJECT (self));
- args = _gp11_call_async_prep (object->slot, object, perform_set_attributes,
+ args = _gp11_call_async_prep (data->slot, self, perform_set_attributes,
sizeof (*args), free_set_attributes);
args->attrs = attrs;
gp11_attributes_ref (attrs);
- args->object = object->handle;
+ args->object = data->handle;
call = _gp11_call_async_ready (args, cancellable, callback, user_data);
- require_session_async (object, call, CKF_RW_SESSION, cancellable);
+ require_session_async (self, call, CKF_RW_SESSION, cancellable);
}
/**
* gp11_object_set_finish:
- * @object: The object to set attributes on.
+ * @self: The object to set attributes on.
* @result: The result of the destory operation passed to the callback.
* @err: A location to store an error.
*
@@ -583,7 +679,7 @@
* Return value: Whether the attributes were successfully set on the object or not.
*/
gboolean
-gp11_object_set_finish (GP11Object *object, GAsyncResult *result, GError **err)
+gp11_object_set_finish (GP11Object *self, GAsyncResult *result, GError **err)
{
return _gp11_call_basic_finish (result, err);
}
@@ -682,7 +778,7 @@
/**
* gp11_object_get:
- * @object: The object to get attributes from.
+ * @self: The object to get attributes from.
* @err: A location to store an error.
* ...: The attribute types to get.
*
@@ -695,7 +791,7 @@
* Return value: The resulting PKCS#11 attributes, or NULL if an error occurred.
**/
GP11Attributes*
-gp11_object_get (GP11Object *object, GError **err, ...)
+gp11_object_get (GP11Object *self, GError **err, ...)
{
GP11Attributes *result;
GArray *array;
@@ -712,14 +808,14 @@
}
va_end (va);
- result = gp11_object_get_full (object, (gulong*)array->data, array->len, NULL, err);
+ result = gp11_object_get_full (self, (gulong*)array->data, array->len, NULL, err);
g_array_free (array, TRUE);
return result;
}
/**
* gp11_object_get:
- * @object: The object to get attributes from.
+ * @self: The object to get attributes from.
* @attr_types: The attributes to get.
* @n_attr_types: The number of attributes to get.
* @cancellable: Optional cancellation object, or NULL.
@@ -734,22 +830,23 @@
* Return value: The resulting PKCS#11 attributes, or NULL if an error occurred.
**/
GP11Attributes*
-gp11_object_get_full (GP11Object *object, const gulong *attr_types, gsize n_attr_types,
+gp11_object_get_full (GP11Object *self, const gulong *attr_types, gsize n_attr_types,
GCancellable *cancellable, GError **err)
{
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
GetAttributes args;
GP11Session *session;
- g_return_val_if_fail (GP11_IS_OBJECT (object), FALSE);
+ g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
- session = require_session_sync (object, 0, err);
+ session = require_session_sync (self, 0, err);
if (!session)
return NULL;
memset (&args, 0, sizeof (args));
args.attr_types = (gulong*)attr_types;
args.n_attr_types = n_attr_types;
- args.object = object->handle;
+ args.object = data->handle;
if (!_gp11_call_sync (session, perform_get_attributes, &args, cancellable, err)) {
gp11_attributes_unref (args.results);
@@ -763,7 +860,7 @@
/**
* gp11_object_get_async:
- * @object: The object to get attributes from.
+ * @self: The object to get attributes from.
* @attr_types: The attributes to get.
* @n_attr_types: The number of attributes to get.
* @cancellable: Optional cancellation object, or NULL.
@@ -774,28 +871,29 @@
* immediately and completes asynchronously.
**/
void
-gp11_object_get_async (GP11Object *object, const gulong *attr_types, gsize n_attr_types,
+gp11_object_get_async (GP11Object *self, const gulong *attr_types, gsize n_attr_types,
GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
{
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
GetAttributes *args;
GP11Call *call;
- g_return_if_fail (GP11_IS_OBJECT (object));
+ g_return_if_fail (GP11_IS_OBJECT (self));
- args = _gp11_call_async_prep (object->session, object, perform_get_attributes,
+ args = _gp11_call_async_prep (data->slot, self, perform_get_attributes,
sizeof (*args), free_get_attributes);
args->n_attr_types = n_attr_types;
if (n_attr_types)
args->attr_types = g_memdup (attr_types, sizeof (gulong) * n_attr_types);
- args->object = object->handle;
+ args->object = data->handle;
call = _gp11_call_async_ready (args, cancellable, callback, user_data);
- require_session_async (object, call, 0, cancellable);
+ require_session_async (self, call, 0, cancellable);
}
/**
* gp11_object_get_finish:
- * @object: The object to get attributes from.
+ * @self: The object to get attributes from.
* @result: The result passed to the callback.
* @err: A location to store an error.
*
@@ -808,7 +906,7 @@
* Return value: The resulting PKCS#11 attributes, or NULL if an error occurred.
**/
GP11Attributes*
-gp11_object_get_finish (GP11Object *object, GAsyncResult *result, GError **err)
+gp11_object_get_finish (GP11Object *self, GAsyncResult *result, GError **err)
{
GP11Attributes *results;
GetAttributes *args;
@@ -826,7 +924,7 @@
/**
* gp11_object_get_one:
- * @object: The object to get an attribute from.
+ * @self: The object to get an attribute from.
* @attr_type: The attribute to get.
* @err: A location to store an error.
*
@@ -836,14 +934,14 @@
* Return value: The resulting PKCS#11 attribute, or NULL if an error occurred.
**/
GP11Attribute*
-gp11_object_get_one (GP11Object *object, gulong attr_type, GError **err)
+gp11_object_get_one (GP11Object *self, gulong attr_type, GError **err)
{
- return gp11_object_get_one_full (object, attr_type, NULL, err);
+ return gp11_object_get_one_full (self, attr_type, NULL, err);
}
/**
* gp11_object_get_one_full:
- * @object: The object to get an attribute from.
+ * @self: The object to get an attribute from.
* @attr_type: The attribute to get.
* @cancellable: Optional cancellation object, or NULL.
* @err: A location to store an error.
@@ -854,13 +952,13 @@
* Return value: The resulting PKCS#11 attribute, or NULL if an error occurred.
**/
GP11Attribute*
-gp11_object_get_one_full (GP11Object *object, gulong attr_type,
+gp11_object_get_one_full (GP11Object *self, gulong attr_type,
GCancellable *cancellable, GError **err)
{
GP11Attributes *attrs;
GP11Attribute *attr;
- attrs = gp11_object_get_full (object, &attr_type, 1, cancellable, err);
+ attrs = gp11_object_get_full (self, &attr_type, 1, cancellable, err);
if (!attrs || !gp11_attributes_count (attrs))
return NULL;
@@ -873,7 +971,7 @@
/**
* gp11_object_get_one_async:
- * @object: The object to get an attribute from.
+ * @self: The object to get an attribute from.
* @attr_type: The attribute to get.
* @cancellable: Optional cancellation object, or NULL.
* @callback: Called when the operation completes.
@@ -883,15 +981,15 @@
* return immediately and complete asynchronously.
**/
void
-gp11_object_get_one_async (GP11Object *object, gulong attr_type, GCancellable *cancellable,
+gp11_object_get_one_async (GP11Object *self, gulong attr_type, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
- gp11_object_get_async (object, &attr_type, 1, cancellable, callback, user_data);
+ gp11_object_get_async (self, &attr_type, 1, cancellable, callback, user_data);
}
/**
* gp11_object_get_one_finish:
- * @object: The object to get an attribute from.
+ * @self: The object to get an attribute from.
* @result: The result passed to the callback.
* @err: A location to store an error.
*
@@ -902,12 +1000,12 @@
**/
GP11Attribute*
-gp11_object_get_one_finish (GP11Object *object, GAsyncResult *result, GError **err)
+gp11_object_get_one_finish (GP11Object *self, GAsyncResult *result, GError **err)
{
GP11Attributes *attrs;
GP11Attribute *attr;
- attrs = gp11_object_get_finish (object, result, err);
+ attrs = gp11_object_get_finish (self, result, err);
if (!attrs)
return NULL;
Modified: trunk/gp11/gp11-session.c
==============================================================================
--- trunk/gp11/gp11-session.c (original)
+++ trunk/gp11/gp11-session.c Sat Dec 27 18:29:23 2008
@@ -24,6 +24,7 @@
#include "config.h"
#include "gp11.h"
+#include "gp11-marshal.h"
#include "gp11-private.h"
#include <string.h>
@@ -40,6 +41,21 @@
PROP_SLOT
};
+typedef struct _GP11SessionData {
+ GP11Slot *slot;
+ GP11Module *module;
+ CK_SESSION_HANDLE handle;
+ gint discarded;
+} GP11SessionData;
+
+typedef struct _GP11SessionPrivate {
+ GP11SessionData data;
+ /* Add mutex and future MT-unsafe members here */
+} GP11SessionPrivate;
+
+#define GP11_SESSION_GET_DATA(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), GP11_TYPE_SESSION, GP11SessionData))
+
G_DEFINE_TYPE (GP11Session, gp11_session, G_TYPE_OBJECT);
static guint signals[LAST_SIGNAL] = { 0 };
@@ -48,51 +64,78 @@
* OBJECT
*/
-static void
-gp11_session_init (GP11Session *session)
+static gboolean
+gp11_session_real_discard_handle (GP11Session *self, CK_OBJECT_HANDLE handle)
{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ CK_FUNCTION_LIST_PTR funcs;
+ CK_RV rv;
+
+ /* The default functionality, close the handle */
+
+ g_return_val_if_fail (data->module, FALSE);
+ g_object_ref (data->module);
+
+ funcs = gp11_module_get_function_list (data->module);
+ g_return_val_if_fail (funcs, FALSE);
+ rv = (funcs->C_CloseSession) (handle);
+ if (rv != CKR_OK) {
+ g_warning ("couldn't close session properly: %s",
+ gp11_message_from_rv (rv));
+ }
+
+ g_object_unref (data->module);
+ return TRUE;
+}
+
+static void
+gp11_session_init (GP11Session *self)
+{
+
}
static void
gp11_session_get_property (GObject *obj, guint prop_id, GValue *value,
GParamSpec *pspec)
{
- GP11Session *session = GP11_SESSION (obj);
+ GP11Session *self = GP11_SESSION (obj);
switch (prop_id) {
case PROP_MODULE:
- g_value_set_object (value, session->module);
+ g_value_take_object (value, gp11_session_get_module (self));
break;
case PROP_HANDLE:
- g_value_set_uint (value, session->handle);
+ g_value_set_ulong (value, gp11_session_get_handle (self));
break;
case PROP_SLOT:
- g_value_set_object(value, session->slot);
+ g_value_take_object (value, gp11_session_get_slot (self));
break;
}
}
static void
gp11_session_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
+ GParamSpec *pspec)
{
- GP11Session *session = GP11_SESSION (obj);
+ GP11SessionData *data = GP11_SESSION_GET_DATA (obj);
+
+ /* Only valid calls are from constructor */
switch (prop_id) {
case PROP_MODULE:
- g_return_if_fail (!session->module);
- session->module = g_value_dup_object (value);
- g_return_if_fail (session->module);
+ g_return_if_fail (!data->module);
+ data->module = g_value_dup_object (value);
+ g_return_if_fail (data->module);
break;
case PROP_HANDLE:
- g_return_if_fail (!session->handle);
- session->handle = g_value_get_uint (value);
+ g_return_if_fail (!data->handle);
+ data->handle = g_value_get_ulong (value);
break;
case PROP_SLOT:
- g_return_if_fail (!session->slot);
- session->slot = g_value_dup_object (value);
- g_return_if_fail (session->slot);
+ g_return_if_fail (!data->slot);
+ data->slot = g_value_dup_object (value);
+ g_return_if_fail (data->slot);
break;
}
}
@@ -100,51 +143,47 @@
static void
gp11_session_dispose (GObject *obj)
{
- GP11Session *session = GP11_SESSION (obj);
- CK_RV rv;
+ GP11SessionData *data = GP11_SESSION_GET_DATA (obj);
+ GP11Session *self = GP11_SESSION (obj);
+ gboolean handled;
+ gint discarded;
- g_return_if_fail (GP11_IS_SESSION (session));
-
- /*
- * Let the world know that we're discarding the session
- * handle. This allows session reuse to work.
- */
- if (session->handle)
- g_signal_emit_by_name (session, "discard-handle");
-
- if (session->handle) {
- g_return_if_fail (session->module && session->module->funcs);
- rv = (session->module->funcs->C_CloseSession) (session->handle);
- if (rv != CKR_OK) {
- g_warning ("couldn't close session properly: %s",
- gp11_message_from_rv (rv));
- }
- session->handle = 0;
- }
+ g_return_if_fail (GP11_IS_SESSION (self));
- if (session->slot)
- g_object_unref (session->slot);
- session->slot = NULL;
-
- if (session->module)
- g_object_unref (session->module);
- session->module = NULL;
+ discarded = g_atomic_int_get (&data->discarded);
+ if (!discarded && g_atomic_int_compare_and_exchange (&data->discarded, discarded, 1)) {
+ /*
+ * Let the world know that we're discarding the session
+ * handle. This allows session reuse to work.
+ */
+
+ g_signal_emit_by_name (self, "discard-handle", data->handle, &handled);
+ g_return_if_fail (handled);
+
+ }
+
G_OBJECT_CLASS (gp11_session_parent_class)->dispose (obj);
}
static void
gp11_session_finalize (GObject *obj)
{
- GP11Session *session = GP11_SESSION (obj);
+ GP11SessionData *data = GP11_SESSION_GET_DATA (obj);
- g_assert (session->module == NULL);
- g_assert (session->handle == 0);
+ g_assert (data->discarded != 0);
+
+ if (data->slot)
+ g_object_unref (data->slot);
+ data->slot = NULL;
+
+ if (data->module)
+ g_object_unref (data->module);
+ data->module = NULL;
G_OBJECT_CLASS (gp11_session_parent_class)->finalize (obj);
}
-
static void
gp11_session_class_init (GP11SessionClass *klass)
{
@@ -156,22 +195,26 @@
gobject_class->dispose = gp11_session_dispose;
gobject_class->finalize = gp11_session_finalize;
+ klass->discard_handle = gp11_session_real_discard_handle;
+
g_object_class_install_property (gobject_class, PROP_MODULE,
g_param_spec_object ("module", "Module", "PKCS11 Module",
GP11_TYPE_MODULE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_HANDLE,
- g_param_spec_uint ("handle", "Session Handle", "PKCS11 Session Handle",
- 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_param_spec_ulong ("handle", "Session Handle", "PKCS11 Session Handle",
+ 0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_SLOT,
g_param_spec_object ("slot", "Slot that this session uses", "PKCS11 Slot",
GP11_TYPE_SLOT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
signals[DISCARD_HANDLE] = g_signal_new ("discard-handle", GP11_TYPE_SESSION,
- G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GP11SessionClass, discard_handle),
- NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GP11SessionClass, discard_handle),
+ g_signal_accumulator_true_handled, NULL,
+ _gp11_marshal_BOOLEAN__ULONG, G_TYPE_BOOLEAN, 1, G_TYPE_ULONG);
+
+ g_type_class_add_private (klass, sizeof (GP11SessionPrivate));
}
/* ----------------------------------------------------------------------------
@@ -206,29 +249,72 @@
GP11Session*
gp11_session_from_handle (GP11Slot *slot, CK_SESSION_HANDLE handle)
{
+ GP11Module *module;
+ GP11Session *session;
+
g_return_val_if_fail (GP11_IS_SLOT (slot), NULL);
- return g_object_new (GP11_TYPE_SESSION, "module", slot->module,
- "handle", handle, "slot", slot, NULL);
+
+ module = gp11_slot_get_module (slot);
+ session = g_object_new (GP11_TYPE_SESSION, "module", module,
+ "handle", handle, "slot", slot, NULL);
+ g_object_unref (module);
+
+ return session;
}
/**
* gp11_session_get_handle:
- * @session: The session object.
+ * @self: The session object.
*
* Get the raw PKCS#11 session handle from a GP11Session object.
*
* Return value: The raw session handle.
**/
CK_SESSION_HANDLE
-gp11_session_get_handle (GP11Session *session)
+gp11_session_get_handle (GP11Session *self)
{
- g_return_val_if_fail (GP11_IS_SESSION (session), (CK_SESSION_HANDLE)-1);
- return session->handle;
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_SESSION (self), (CK_SESSION_HANDLE)-1);
+ return data->handle;
+}
+
+/**
+ * gp11_session_get_module:
+ * @self: The session object.
+ *
+ * Get the PKCS#11 module to which this session belongs.
+ *
+ * Return value: The module, which should be unreffed after use.
+ **/
+GP11Module*
+gp11_session_get_module (GP11Session *self)
+{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_SESSION (self), NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (data->module), NULL);
+ return g_object_ref (data->module);
+}
+
+/**
+ * gp11_session_get_slot:
+ * @self: The session object.
+ *
+ * Get the PKCS#11 slot to which this session belongs.
+ *
+ * Return value: The slot, which should be unreffed after use.
+ **/
+GP11Slot*
+gp11_session_get_slot (GP11Session *self)
+{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_SESSION (self), NULL);
+ g_return_val_if_fail (GP11_IS_SLOT (data->slot), NULL);
+ return g_object_ref (data->slot);
}
/**
* gp11_session_get_info:
- * @session: The session object.
+ * @self: The session object.
*
* Get information about the session.
*
@@ -236,18 +322,27 @@
* when done.
**/
GP11SessionInfo*
-gp11_session_get_info (GP11Session *session)
+gp11_session_get_info (GP11Session *self)
{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
GP11SessionInfo *sessioninfo;
+ CK_FUNCTION_LIST_PTR funcs;
CK_SESSION_INFO info;
CK_RV rv;
- g_return_val_if_fail (GP11_IS_SESSION (session), NULL);
- g_return_val_if_fail (GP11_IS_MODULE (session->module), NULL);
- g_return_val_if_fail (session->module->funcs, NULL);
+ g_return_val_if_fail (GP11_IS_SESSION (self), NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (data->module), NULL);
+
+ g_object_ref (data->module);
+
+ funcs = gp11_module_get_function_list (data->module);
+ g_return_val_if_fail (funcs, NULL);
memset (&info, 0, sizeof (info));
- rv = (session->module->funcs->C_GetSessionInfo) (session->handle, &info);
+ rv = (funcs->C_GetSessionInfo) (data->handle, &info);
+
+ g_object_unref (data->module);
+
if (rv != CKR_OK) {
g_warning ("couldn't get session info: %s", gp11_message_from_rv (rv));
return NULL;
@@ -289,7 +384,7 @@
/**
* gp11_session_login:
- * @session: Log into this session.
+ * @self: Log into this session.
* @user_type: The type of login user.
* @pin: The user's PIN, or NULL for protected authentication path.
* @n_pin: The length of the PIN.
@@ -301,15 +396,15 @@
* Return value: Whether successful or not.
**/
gboolean
-gp11_session_login (GP11Session *session, gulong user_type, const guchar *pin,
+gp11_session_login (GP11Session *self, gulong user_type, const guchar *pin,
gsize n_pin, GError **err)
{
- return gp11_session_login_full (session, user_type, pin, n_pin, NULL, err);
+ return gp11_session_login_full (self, user_type, pin, n_pin, NULL, err);
}
/**
* gp11_session_login_full:
- * @session: Log into this session.
+ * @self: Log into this session.
* @user_type: The type of login user.
* @pin: The user's PIN, or NULL for protected authentication path.
* @n_pin: The length of the PIN.
@@ -322,17 +417,17 @@
* Return value: Whether successful or not.
**/
gboolean
-gp11_session_login_full (GP11Session *session, gulong user_type, const guchar *pin,
+gp11_session_login_full (GP11Session *self, gulong user_type, const guchar *pin,
gsize n_pin, GCancellable *cancellable, GError **err)
{
Login args = { GP11_ARGUMENTS_INIT, user_type, (guchar*)pin, n_pin };
- return _gp11_call_sync (session, perform_login, &args, cancellable, err);
+ return _gp11_call_sync (self, perform_login, &args, cancellable, err);
}
/**
* gp11_session_login_async:
- * @session: Log into this session.
+ * @self: Log into this session.
* @user_type: The type of login user.
* @pin: The user's PIN, or NULL for protected authentication path.
* @n_pin: The length of the PIN.
@@ -344,11 +439,11 @@
* immediately and completes asynchronously.
**/
void
-gp11_session_login_async (GP11Session *session, gulong user_type, const guchar *pin,
+gp11_session_login_async (GP11Session *self, gulong user_type, const guchar *pin,
gsize n_pin, GCancellable *cancellable, GAsyncReadyCallback callback,
gpointer user_data)
{
- Login* args = _gp11_call_async_prep (session, session, perform_login, sizeof (*args), free_login);
+ Login* args = _gp11_call_async_prep (self, self, perform_login, sizeof (*args), free_login);
args->user_type = user_type;
args->pin = pin && n_pin ? g_memdup (pin, n_pin) : NULL;
@@ -360,7 +455,7 @@
/**
* gp11_session_login_finish:
- * @session: The session logged into.
+ * @self: The session logged into.
* @result: The result passed to the callback.
* @err: A location to return an error.
*
@@ -369,7 +464,7 @@
* Return value: Whether the operation was successful or not.
**/
gboolean
-gp11_session_login_finish (GP11Session *session, GAsyncResult *result, GError **err)
+gp11_session_login_finish (GP11Session *self, GAsyncResult *result, GError **err)
{
return _gp11_call_basic_finish (result, err);
}
@@ -387,7 +482,7 @@
/**
* gp11_session_logout:
- * @session: Logout of this session.
+ * @self: Logout of this session.
* @err: A location to return an error.
*
* Log out of the session. This call may block for an indefinite period.
@@ -395,14 +490,14 @@
* Return value: Whether the logout was successful or not.
**/
gboolean
-gp11_session_logout (GP11Session *session, GError **err)
+gp11_session_logout (GP11Session *self, GError **err)
{
- return gp11_session_logout_full (session, NULL, err);
+ return gp11_session_logout_full (self, NULL, err);
}
/**
* gp11_session_logout_full:
- * @session: Logout of this session.
+ * @self: Logout of this session.
* @cancellable: Optional cancellation object, or NULL.
* @err: A location to return an error.
*
@@ -411,15 +506,15 @@
* Return value: Whether the logout was successful or not.
**/
gboolean
-gp11_session_logout_full (GP11Session *session, GCancellable *cancellable, GError **err)
+gp11_session_logout_full (GP11Session *self, GCancellable *cancellable, GError **err)
{
GP11Arguments args = GP11_ARGUMENTS_INIT;
- return _gp11_call_sync (session, perform_logout, &args, cancellable, err);
+ return _gp11_call_sync (self, perform_logout, &args, cancellable, err);
}
/**
* gp11_session_logout_async:
- * @session: Logout of this session.
+ * @self: Logout of this session.
* @cancellable: Optional cancellation object, or NULL.
* @callback: Called when the operation completes.
* @user_data: Data to pass to the callback.
@@ -428,16 +523,16 @@
* asynchronously.
**/
void
-gp11_session_logout_async (GP11Session *session, GCancellable *cancellable,
+gp11_session_logout_async (GP11Session *self, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
- GP11Arguments *args = _gp11_call_async_prep (session, session, perform_logout, 0, NULL);
+ GP11Arguments *args = _gp11_call_async_prep (self, self, perform_logout, 0, NULL);
_gp11_call_async_ready_go (args, cancellable, callback, user_data);
}
/**
* gp11_session_logout_finish:
- * @session: Logout of this session.
+ * @self: Logout of this session.
* @result: The result passed to the callback.
* @err: A location to return an error.
*
@@ -446,7 +541,7 @@
* Return value: Whether the logout was successful or not.
**/
gboolean
-gp11_session_logout_finish (GP11Session *session, GAsyncResult *result, GError **err)
+gp11_session_logout_finish (GP11Session *self, GAsyncResult *result, GError **err)
{
return _gp11_call_basic_finish (result, err);
}
@@ -480,7 +575,7 @@
/**
* gp11_session_create_object:
- * @session: The session to create the object on.
+ * @self: The session to create the object on.
* @err: A location to store an error.
* ...: The attributes to create the new object with.
*
@@ -512,7 +607,7 @@
* Return value: The newly created object, or NULL if an error occurred.
**/
GP11Object*
-gp11_session_create_object (GP11Session *session, GError **err, ...)
+gp11_session_create_object (GP11Session *self, GError **err, ...)
{
GP11Attributes *attrs;
GP11Object *object;
@@ -522,14 +617,14 @@
attrs = gp11_attributes_new_valist (va);
va_end (va);
- object = gp11_session_create_object_full (session, attrs, NULL, err);
+ object = gp11_session_create_object_full (self, attrs, NULL, err);
gp11_attributes_unref (attrs);
return object;
}
/**
* gp11_session_create_object_full:
- * @session: The session to create the object on.
+ * @self: The session to create the object on.
* @attrs: The attributes to create the object with.
* @cancellable: Optional cancellation object, or NULL.
* @err: A location to return an error, or NULL.
@@ -540,18 +635,19 @@
* Return value: The newly created object or NULL if an error occurred.
**/
GP11Object*
-gp11_session_create_object_full (GP11Session *session, GP11Attributes *attrs,
+gp11_session_create_object_full (GP11Session *self, GP11Attributes *attrs,
GCancellable *cancellable, GError **err)
{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
CreateObject args = { GP11_ARGUMENTS_INIT, attrs, 0 };
- if (!_gp11_call_sync (session, perform_create_object, &args, cancellable, err))
+ if (!_gp11_call_sync (self, perform_create_object, &args, cancellable, err))
return NULL;
- return gp11_object_from_handle (session->slot, args.object);
+ return gp11_object_from_handle (data->slot, args.object);
}
/**
* gp11_session_create_object_async:
- * @session: The session to create the object on.
+ * @self: The session to create the object on.
* @attrs: The attributes to create the object with.
* @cancellable: Optional cancellation object or NULL.
* @callback: Called when the operation completes.
@@ -561,11 +657,11 @@
* and complete asynchronously.
**/
void
-gp11_session_create_object_async (GP11Session *session, GP11Attributes *attrs,
+gp11_session_create_object_async (GP11Session *self, GP11Attributes *attrs,
GCancellable *cancellable, GAsyncReadyCallback callback,
gpointer user_data)
{
- CreateObject *args = _gp11_call_async_prep (session, session, perform_create_object,
+ CreateObject *args = _gp11_call_async_prep (self, self, perform_create_object,
sizeof (*args), free_create_object);
args->attrs = attrs;
gp11_attributes_ref (attrs);
@@ -574,7 +670,7 @@
/**
* gp11_session_create_object_finish:
- * @session: The session to create the object on.
+ * @self: The session to create the object on.
* @result: The result passed to the callback.
* @err: A location to return an error, or NULL.
*
@@ -583,14 +679,15 @@
* Return value: The newly created object or NULL if an error occurred.
**/
GP11Object*
-gp11_session_create_object_finish (GP11Session *session, GAsyncResult *result, GError **err)
+gp11_session_create_object_finish (GP11Session *self, GAsyncResult *result, GError **err)
{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
CreateObject *args;
if (!_gp11_call_basic_finish (result, err))
return NULL;
args = _gp11_call_arguments (result, CreateObject);
- return gp11_object_from_handle (session->slot, args->object);
+ return gp11_object_from_handle (data->slot, args->object);
}
@@ -666,14 +763,15 @@
}
static GList*
-objlist_from_handles (GP11Session *session, CK_OBJECT_HANDLE_PTR objects,
+objlist_from_handles (GP11Session *self, CK_OBJECT_HANDLE_PTR objects,
CK_ULONG n_objects)
{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
GList *results = NULL;
while (n_objects > 0) {
results = g_list_prepend (results,
- gp11_object_from_handle (session->slot, objects[--n_objects]));
+ gp11_object_from_handle (data->slot, objects[--n_objects]));
}
return g_list_reverse (results);
@@ -681,7 +779,7 @@
/**
* gp11_session_find_objects:
- * @session: The session to find objects on.
+ * @self: The session to find objects on.
* @err: A location to return an error or NULL.
* ...: The attributes to match.
*
@@ -712,7 +810,7 @@
* Return value: A list of the matching objects, which may be empty.
**/
GList*
-gp11_session_find_objects (GP11Session *session, GError **err, ...)
+gp11_session_find_objects (GP11Session *self, GError **err, ...)
{
GP11Attributes *attrs;
GList *results;
@@ -722,14 +820,14 @@
attrs = gp11_attributes_new_valist (va);
va_end (va);
- results = gp11_session_find_objects_full (session, attrs, NULL, err);
+ results = gp11_session_find_objects_full (self, attrs, NULL, err);
gp11_attributes_unref (attrs);
return results;
}
/**
* gp11_session_find_objects_full:
- * @session: The session to find objects on.
+ * @self: The session to find objects on.
* @attrs: The attributes to match.
* @cancellable: Optional cancellation object or NULL.
* @err: A location to return an error or NULL.
@@ -740,21 +838,21 @@
* Return value: A list of the matching objects, which may be empty.
**/
GList*
-gp11_session_find_objects_full (GP11Session *session, GP11Attributes *attrs,
+gp11_session_find_objects_full (GP11Session *self, GP11Attributes *attrs,
GCancellable *cancellable, GError **err)
{
FindObjects args = { GP11_ARGUMENTS_INIT, attrs, NULL, 0 };
GList *results = NULL;
- if (_gp11_call_sync (session, perform_find_objects, &args, cancellable, err))
- results = objlist_from_handles (session, args.objects, args.n_objects);
+ if (_gp11_call_sync (self, perform_find_objects, &args, cancellable, err))
+ results = objlist_from_handles (self, args.objects, args.n_objects);
g_free (args.objects);
return results;
}
/**
* gp11_session_find_objects_async:
- * @session: The session to find objects on.
+ * @self: The session to find objects on.
* @attrs: The attributes to match.
* @cancellable: Optional cancellation object or NULL.
* @callback: Called when the operation completes.
@@ -764,11 +862,11 @@
* return immediately and complete asynchronously.
**/
void
-gp11_session_find_objects_async (GP11Session *session, GP11Attributes *attrs,
+gp11_session_find_objects_async (GP11Session *self, GP11Attributes *attrs,
GCancellable *cancellable, GAsyncReadyCallback callback,
gpointer user_data)
{
- FindObjects *args = _gp11_call_async_prep (session, session, perform_find_objects,
+ FindObjects *args = _gp11_call_async_prep (self, self, perform_find_objects,
sizeof (*args), free_find_objects);
args->attrs = attrs;
gp11_attributes_ref (attrs);
@@ -777,7 +875,7 @@
/**
* gp11_session_find_objects_finish:
- * @session: The session to find objects on.
+ * @self: The session to find objects on.
* @result: The attributes to match.
* @err: A location to return an error.
*
@@ -786,14 +884,14 @@
* Return value: A list of the matching objects, which may be empty.
**/
GList*
-gp11_session_find_objects_finish (GP11Session *session, GAsyncResult *result, GError **err)
+gp11_session_find_objects_finish (GP11Session *self, GAsyncResult *result, GError **err)
{
FindObjects *args;
if (!_gp11_call_basic_finish (result, err))
return NULL;
args = _gp11_call_arguments (result, FindObjects);
- return objlist_from_handles (session, args->objects, args->n_objects);
+ return objlist_from_handles (self, args->objects, args->n_objects);
}
@@ -855,7 +953,7 @@
}
static guchar*
-crypt_sync (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args, const guchar *input,
+crypt_sync (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args, const guchar *input,
gsize n_input, gsize *n_result, GCancellable *cancellable, GError **err,
CK_C_EncryptInit init_func, CK_C_Encrypt complete_func)
{
@@ -881,7 +979,7 @@
args.init_func = init_func;
args.complete_func = complete_func;
- if (!_gp11_call_sync (session, perform_crypt, &args, cancellable, err)) {
+ if (!_gp11_call_sync (self, perform_crypt, &args, cancellable, err)) {
g_free (args.result);
return NULL;
}
@@ -890,11 +988,11 @@
}
static void
-crypt_async (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args, const guchar *input,
+crypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args, const guchar *input,
gsize n_input, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data,
CK_C_EncryptInit init_func, CK_C_Encrypt complete_func)
{
- Crypt *args = _gp11_call_async_prep (session, session, perform_crypt, sizeof (*args), free_crypt);
+ Crypt *args = _gp11_call_async_prep (self, self, perform_crypt, sizeof (*args), free_crypt);
g_return_if_fail (GP11_IS_OBJECT (key));
g_return_if_fail (mech_args);
@@ -919,12 +1017,12 @@
}
static guchar*
-crypt_finish (GP11Session *session, GAsyncResult *result, gsize *n_result, GError **err)
+crypt_finish (GP11Session *self, GAsyncResult *result, gsize *n_result, GError **err)
{
Crypt *args;
guchar *res;
- if (!_gp11_call_basic_finish (session, result, err))
+ if (!_gp11_call_basic_finish (self, result, err))
return NULL;
args = _gp11_call_arguments (result, Crypt);
@@ -938,25 +1036,25 @@
}
guchar*
-gp11_session_encrypt (GP11Session *session, GP11Object *key, gulong mech, const guchar *input,
+gp11_session_encrypt (GP11Session *self, GP11Object *key, gulong mech, const guchar *input,
gsize n_input, gsize *n_result, GError **err)
{
GP11Mechanism mech_args = { mech, NULL, 0 };
- return gp11_session_encrypt_full (session, key, &mech_args, input, n_input, n_result, NULL, err);
+ return gp11_session_encrypt_full (self, key, &mech_args, input, n_input, n_result, NULL, err);
}
guchar*
-gp11_session_encrypt_full (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_encrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
const guchar *input, gsize n_input, gsize *n_result,
GCancellable *cancellable, GError **err)
{
GP11Module *module = NULL;
guchar *ret;
- g_object_get (session, "module", &module, NULL);
+ g_object_get (self, "module", &module, NULL);
g_return_val_if_fail (module != NULL, NULL);
- ret = crypt_sync (session, key, mech_args, input, n_input, n_result, cancellable, err,
+ ret = crypt_sync (self, key, mech_args, input, n_input, n_result, cancellable, err,
module->funcs->C_EncryptInit, module->funcs->C_Encrypt);
g_object_unref (module);
@@ -964,117 +1062,117 @@
}
void
-gp11_session_encrypt_async (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_encrypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
const guchar *input, gsize n_input, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
GP11Module *module = NULL;
- g_object_get (session, "module", &module, NULL);
+ g_object_get (self, "module", &module, NULL);
g_return_if_fail (module != NULL);
- crypt_async (session, key, mech_args, input, n_input, cancellable, callback, user_data,
+ crypt_async (self, key, mech_args, input, n_input, cancellable, callback, user_data,
module->funcs->C_EncryptInit, module->funcs->C_Encrypt);
g_object_unref (module);
}
guchar*
-gp11_session_encrypt_finish (GP11Session *session, GAsyncResult *result, gsize *n_result,
+gp11_session_encrypt_finish (GP11Session *self, GAsyncResult *result, gsize *n_result,
GError **err)
{
- return crypt_finish (session, result, n_result, err);
+ return crypt_finish (self, result, n_result, err);
}
guchar*
-gp11_session_decrypt (GP11Session *session, GP11Object *key, gulong mech_type, const guchar *input,
+gp11_session_decrypt (GP11Session *self, GP11Object *key, gulong mech_type, const guchar *input,
gsize n_input, gsize *n_result, GError **err)
{
GP11Mechanism mech_args = { mech_type, NULL, 0 };
- return gp11_session_decrypt_full (session, key, &mech_args, input, n_input, n_result, NULL, err);
+ return gp11_session_decrypt_full (self, key, &mech_args, input, n_input, n_result, NULL, err);
}
guchar*
-gp11_session_decrypt_full (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_decrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
const guchar *input, gsize n_input, gsize *n_result,
GCancellable *cancellable, GError **err)
{
GP11Module *module = NULL;
guchar *ret;
- g_object_get (session, "module", &module, NULL);
+ g_object_get (self, "module", &module, NULL);
g_return_val_if_fail (module != NULL, NULL);
- ret = crypt_sync (session, key, mech_args, input, n_input, n_result, cancellable, err,
+ ret = crypt_sync (self, key, mech_args, input, n_input, n_result, cancellable, err,
module->funcs->C_DecryptInit, module->funcs->C_Decrypt);
g_object_unref (module);
return ret;
}
void
-gp11_session_decrypt_async (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_decrypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
const guchar *input, gsize n_input, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
GP11Module *module = NULL;
- g_object_get (session, "module", &module, NULL);
+ g_object_get (self, "module", &module, NULL);
g_return_if_fail (module != NULL);
- crypt_async (session, key, mech_args, input, n_input, cancellable, callback, user_data,
+ crypt_async (self, key, mech_args, input, n_input, cancellable, callback, user_data,
module->funcs->C_DecryptInit, module->funcs->C_Decrypt);
g_object_unref (module);
}
guchar*
-gp11_session_decrypt_finish (GP11Session *session, GAsyncResult *result,
+gp11_session_decrypt_finish (GP11Session *self, GAsyncResult *result,
gsize *n_result, GError **err)
{
- return crypt_finish (session, result, n_result, err);
+ return crypt_finish (self, result, n_result, err);
}
guchar*
-gp11_session_sign (GP11Session *session, GP11Object *key, gulong mech_type, const guchar *input,
+gp11_session_sign (GP11Session *self, GP11Object *key, gulong mech_type, const guchar *input,
gsize n_input, gsize *n_result, GError **err)
{
GP11Mechanism mech_args = { mech_type, NULL, 0 };
- return gp11_session_sign_full (session, key, &mech_args, input, n_input, n_result, NULL, err);
+ return gp11_session_sign_full (self, key, &mech_args, input, n_input, n_result, NULL, err);
}
guchar*
-gp11_session_sign_full (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_sign_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
const guchar *input, gsize n_input, gsize *n_result,
GCancellable *cancellable, GError **err)
{
GP11Module *module = NULL;
guchar *ret;
- g_object_get (session, "module", &module, NULL);
+ g_object_get (self, "module", &module, NULL);
g_return_val_if_fail (module != NULL, NULL);
- return crypt_sync (session, key, mech_args, input, n_input, n_result, cancellable, err,
+ return crypt_sync (self, key, mech_args, input, n_input, n_result, cancellable, err,
module->funcs->C_SignInit, module->funcs->C_Sign);
g_object_unref (module);
return ret;
}
void
-gp11_session_sign_async (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_sign_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
const guchar *input, gsize n_input, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
GP11Module *module = NULL;
- g_object_get (session, "module", &module, NULL);
+ g_object_get (self, "module", &module, NULL);
g_return_if_fail (module != NULL);
- crypt_async (session, key, mech_args, input, n_input, cancellable, callback, user_data,
+ crypt_async (self, key, mech_args, input, n_input, cancellable, callback, user_data,
module->funcs->C_SignInit, module->funcs->C_Sign);
g_object_unref (module);
}
guchar*
-gp11_session_sign_finish (GP11Session *session, GAsyncResult *result,
+gp11_session_sign_finish (GP11Session *self, GAsyncResult *result,
gsize *n_result, GError **err)
{
- return crypt_finish (session, result, n_result, err);
+ return crypt_finish (self, result, n_result, err);
}
@@ -1115,16 +1213,16 @@
}
gboolean
-gp11_session_verify (GP11Session *session, GP11Object *key, gulong mech_type, const guchar *input,
+gp11_session_verify (GP11Session *self, GP11Object *key, gulong mech_type, const guchar *input,
gsize n_input, const guchar *signature, gsize n_signature, GError **err)
{
GP11Mechanism mech_args = { mech_type, NULL, 0 };
- return gp11_session_verify_full (session, key, &mech_args, input, n_input,
+ return gp11_session_verify_full (self, key, &mech_args, input, n_input,
signature, n_signature, NULL, err);
}
gboolean
-gp11_session_verify_full (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_verify_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
const guchar *input, gsize n_input, const guchar *signature,
gsize n_signature, GCancellable *cancellable, GError **err)
{
@@ -1147,16 +1245,16 @@
args.signature = (guchar*)signature;
args.n_signature = n_signature;
- return _gp11_call_sync (session, perform_verify, &args, cancellable, err);
+ return _gp11_call_sync (self, perform_verify, &args, cancellable, err);
}
void
-gp11_session_verify_async (GP11Session *session, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_verify_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
const guchar *input, gsize n_input, const guchar *signature,
gsize n_signature, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
- Verify *args = _gp11_call_async_prep (session, session, perform_verify, sizeof (*args), free_verify);
+ Verify *args = _gp11_call_async_prep (self, self, perform_verify, sizeof (*args), free_verify);
g_return_if_fail (GP11_IS_OBJECT (key));
g_return_if_fail (mech_args);
@@ -1178,9 +1276,9 @@
}
gboolean
-gp11_session_verify_finish (GP11Session *session, GAsyncResult *result, GError **err)
+gp11_session_verify_finish (GP11Session *self, GAsyncResult *result, GError **err)
{
- return _gp11_call_basic_finish (session, result, err);
+ return _gp11_call_basic_finish (self, result, err);
}
#endif /* UNTESTED */
Modified: trunk/gp11/gp11-slot.c
==============================================================================
--- trunk/gp11/gp11-slot.c (original)
+++ trunk/gp11/gp11-slot.c Sat Dec 27 18:29:23 2008
@@ -46,7 +46,14 @@
LAST_SIGNAL
};
+typedef struct _GP11SlotData {
+ GP11Module *module;
+ CK_SLOT_ID handle;
+} GP11SlotData;
+
typedef struct _GP11SlotPrivate {
+ GP11SlotData data;
+ GStaticMutex mutex;
gboolean auto_login;
GHashTable *open_sessions;
GP11TokenInfo *token_info;
@@ -54,8 +61,8 @@
G_DEFINE_TYPE (GP11Slot, gp11_slot, G_TYPE_OBJECT);
-#define GP11_SLOT_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE((o), GP11_TYPE_SLOT, GP11SlotPrivate))
+#define GP11_SLOT_GET_DATA(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), GP11_TYPE_SLOT, GP11SlotData))
typedef struct _SessionPool {
gulong flags;
@@ -102,242 +109,246 @@
* HELPERS
*/
+static guint
+ulong_hash (gconstpointer v)
+{
+ const signed char *p = v;
+ guint32 i, h = *p;
+
+ for(i = 0; i < sizeof (gulong); ++i)
+ h = (h << 5) - h + *(p++);
+
+ return h;
+}
+
+static gboolean
+ulong_equal (gconstpointer v1, gconstpointer v2)
+{
+ return *((const gulong*)v1) == *((const gulong*)v2);
+}
+
static void
close_session (GP11Module *module, CK_SESSION_HANDLE handle)
{
+ CK_FUNCTION_LIST_PTR funcs;
CK_RV rv;
g_return_if_fail (GP11_IS_MODULE (module));
- g_return_if_fail (module->funcs);
- rv = (module->funcs->C_CloseSession) (handle);
+
+ g_object_ref (module);
+
+ funcs = gp11_module_get_function_list (module);
+ g_return_if_fail (funcs);
+
+ rv = (funcs->C_CloseSession) (handle);
if (rv != CKR_OK) {
g_warning ("couldn't close session properly: %s",
gp11_message_from_rv (rv));
}
+
+ g_object_unref (module);
}
-static void
-free_session_pool (gpointer p)
+static GP11SlotPrivate*
+lock_private (gpointer obj)
{
- SessionPool *pool = p;
- guint i;
+ GP11SlotPrivate *pv;
+ GP11Slot *self;
- for(i = 0; i < pool->sessions->len; ++i)
- close_session (pool->module, g_array_index(pool->sessions, CK_SESSION_HANDLE, i));
- g_array_free(pool->sessions, TRUE);
- g_free (pool);
+ g_assert (GP11_IS_SLOT (obj));
+ self = GP11_SLOT (obj);
+
+ g_object_ref (self);
+
+ pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GP11_TYPE_SLOT, GP11SlotPrivate);
+ g_static_mutex_lock (&pv->mutex);
+
+ return pv;
}
-#ifdef UNUSED
-
static void
-foreach_count_sessions (gpointer key, gpointer value, gpointer user_data)
+unlock_private (gpointer obj, GP11SlotPrivate *pv)
{
- SessionPool *pool = value;
- guint *result = user_data;
- *result += pool->sessions->len;
-}
+ GP11Slot *self;
-static guint
-count_session_table (GP11Slot *slot, guint flags)
-{
- GP11SlotPrivate *pv = GP11_SLOT_GET_PRIVATE (slot);
- guint result = 0;
+ g_assert (pv);
+ g_assert (GP11_IS_SLOT (obj));
- if (!pv->open_sessions)
- return 0;
+ self = GP11_SLOT (obj);
- g_hash_table_foreach (pv->open_sessions, foreach_count_sessions, &result);
- return result;
+ g_assert (G_TYPE_INSTANCE_GET_PRIVATE (self, GP11_TYPE_SLOT, GP11SlotPrivate) == pv);
+
+ g_static_mutex_unlock (&pv->mutex);
+ g_object_unref (self);
}
-#endif /* UNUSED */
-
static void
-push_session_table (GP11Slot *slot, gulong flags, CK_SESSION_HANDLE handle)
+free_session_pool (gpointer p)
{
- GP11SlotPrivate *pv = GP11_SLOT_GET_PRIVATE (slot);
- SessionPool *pool;
-
- if (!pv->open_sessions) {
- close_session (slot->module, handle);
- return;
- }
+ SessionPool *pool = p;
+ guint i;
+ for(i = 0; i < pool->sessions->len; ++i)
+ close_session (pool->module, g_array_index(pool->sessions, CK_SESSION_HANDLE, i));
+ g_array_free(pool->sessions, TRUE);
+ g_free (pool);
+}
+
+static gboolean
+push_session_table (GP11SlotPrivate *pv, gulong flags, CK_SESSION_HANDLE handle)
+{
+ SessionPool *pool;
+
g_assert (handle);
- g_assert (GP11_IS_MODULE (slot->module));
-
+ g_assert (GP11_IS_MODULE (pv->data.module));
+
+ if (pv->open_sessions == NULL)
+ return FALSE;
+
pool = g_hash_table_lookup (pv->open_sessions, &flags);
if (!pool) {
pool = g_new0 (SessionPool, 1);
pool->flags = flags;
- pool->module = slot->module; /* weak ref */
+ pool->module = pv->data.module; /* weak ref */
pool->sessions = g_array_new (FALSE, TRUE, sizeof (CK_SESSION_HANDLE));
g_hash_table_insert (pv->open_sessions, g_memdup (&flags, sizeof (flags)), pool);
}
g_assert (pool->flags == flags);
g_array_append_val (pool->sessions, handle);
+ return TRUE;
}
static CK_SESSION_HANDLE
-pop_session_table (GP11Slot *slot, gulong flags)
+pop_session_table (GP11SlotPrivate *pv, gulong flags)
{
- GP11SlotPrivate *pv = GP11_SLOT_GET_PRIVATE (slot);
- CK_SESSION_HANDLE result;
+ CK_SESSION_HANDLE result = 0;
SessionPool *pool;
-
- if (!pv->open_sessions)
- return 0;
-
- g_assert (GP11_IS_MODULE (slot->module));
-
- pool = g_hash_table_lookup (pv->open_sessions, &flags);
- if (!pool)
- return 0;
-
- g_assert (pool->sessions->len > 0);
- result = g_array_index (pool->sessions, CK_SESSION_HANDLE, pool->sessions->len - 1);
- g_assert (result != 0);
- g_array_remove_index_fast (pool->sessions, pool->sessions->len - 1);
- if (!pool->sessions->len)
- g_hash_table_remove(pv->open_sessions, &flags);
+
+ g_return_val_if_fail (pv, 0);
+
+
+ g_assert (GP11_IS_MODULE (pv->data.module));
+
+ if (pv->open_sessions) {
+ pool = g_hash_table_lookup (pv->open_sessions, &flags);
+ if (pool) {
+ g_assert (pool->sessions->len > 0);
+ result = g_array_index (pool->sessions, CK_SESSION_HANDLE, pool->sessions->len - 1);
+ g_assert (result != 0);
+ g_array_remove_index_fast (pool->sessions, pool->sessions->len - 1);
+ if (!pool->sessions->len)
+ g_hash_table_remove(pv->open_sessions, &flags);
+ }
+ }
return result;
}
static void
-destroy_session_table (GP11Slot *slot)
+destroy_session_table (GP11SlotPrivate *pv)
{
- GP11SlotPrivate *pv = GP11_SLOT_GET_PRIVATE (slot);
if (pv->open_sessions)
g_hash_table_unref (pv->open_sessions);
pv->open_sessions = NULL;
}
-static guint
-ulong_hash (gconstpointer v)
-{
- // TODO: I'm sure there's a better gulong hash
- const signed char *p = v;
- guint32 i, h = *p;
-
- for(i = 0; i < sizeof (gulong); ++i)
- h = (h << 5) - h + *(p++);
-
- return h;
-}
-
-static gboolean
-ulong_equal (gconstpointer v1, gconstpointer v2)
-{
- return *((const gulong*)v1) == *((const gulong*)v2);
-}
-
static void
-create_session_table (GP11Slot *slot)
+create_session_table (GP11SlotPrivate *pv)
{
- GP11SlotPrivate *pv = GP11_SLOT_GET_PRIVATE (slot);
if (!pv->open_sessions)
pv->open_sessions = g_hash_table_new_full (ulong_hash, ulong_equal, g_free, free_session_pool);
}
-static void
-reuse_session_handle (GP11Session *session, GP11Slot *slot)
+static gboolean
+reuse_session_handle (GP11Session *session, CK_SESSION_HANDLE handle, GP11Slot *self)
{
+ GP11SlotData *data = GP11_SLOT_GET_DATA (self);
+ GP11SlotPrivate *pv;
+ CK_FUNCTION_LIST_PTR funcs;
CK_SESSION_INFO info;
- gulong *flags;
+ gboolean handled = FALSE;
CK_RV rv;
- g_return_if_fail (GP11_IS_SESSION (session));
- g_return_if_fail (GP11_IS_SLOT (slot));
- g_return_if_fail (GP11_IS_MODULE (slot->module));
- g_return_if_fail (session->handle != 0);
+ g_return_val_if_fail (GP11_IS_SESSION (session), FALSE);
+ g_return_val_if_fail (GP11_IS_SLOT (self), FALSE);
+ funcs = gp11_module_get_function_list (data->module);
+ g_return_val_if_fail (funcs, FALSE);
+
/* Get the session info so we know where to categorize this */
- rv = (slot->module->funcs->C_GetSessionInfo) (session->handle, &info);
-
- /* An already closed session, we don't want to bother with */
- if (rv == CKR_SESSION_CLOSED || rv == CKR_SESSION_HANDLE_INVALID) {
- session->handle = 0;
- return;
- }
+ rv = (funcs->C_GetSessionInfo) (handle, &info);
+
+ if (rv == CKR_OK) {
- /* A strange session, let it go to be closed somewhere else */
- if (rv != CKR_OK)
- return;
+ /* Keep this one around for later use */
+ pv = lock_private (self);
+
+ {
+ handled = push_session_table (pv, info.flags, handle);
+ }
+
+ unlock_private (self, pv);
- /*
- * Get the flags that this session was opened with originally, and
- * check them against the session's current flags. If they're no
- * longer present, then don't reuse this session.
- */
- flags = g_object_get_data (G_OBJECT (session), "gp11-open-session-flags");
- g_return_if_fail (flags);
- if ((*flags & info.flags) != *flags)
- return;
+ } else {
- /* Keep this one around for later use */
- push_session_table (slot, *flags, session->handle);
- session->handle = 0;
+ /* An already closed session, we don't want to bother with */
+ if (rv == CKR_SESSION_CLOSED || rv == CKR_SESSION_HANDLE_INVALID)
+ handled = TRUE;
+ }
+
+ return handled;
}
static GP11Session*
-make_session_object (GP11Slot *slot, gulong flags, CK_SESSION_HANDLE handle)
+make_session_object (GP11Slot *self, gulong flags, CK_SESSION_HANDLE handle)
{
GP11Session *session;
-
+
g_return_val_if_fail (handle != 0, NULL);
- session = gp11_session_from_handle (slot, handle);
- g_return_val_if_fail (session != NULL, NULL);
-
- /* Session keeps a reference to us, so this is safe */
- g_signal_connect (session, "discard-handle", G_CALLBACK (reuse_session_handle), slot);
- /* Mark the flags on the session for later looking up */
- g_object_set_data_full (G_OBJECT (session), "gp11-open-session-flags",
- g_memdup (&flags, sizeof (flags)), g_free);
+ g_object_ref (self);
+
+ session = gp11_session_from_handle (self, handle);
+ g_return_val_if_fail (session != NULL, NULL);
+
+ /* Session keeps a reference to us, so this is safe */
+ g_signal_connect (session, "discard-handle", G_CALLBACK (reuse_session_handle), self);
+
+ g_object_unref (self);
return session;
}
-static void
-ensure_token_info (GP11Slot *slot)
-{
- GP11SlotPrivate *pv = GP11_SLOT_GET_PRIVATE (slot);
- if (!pv->token_info)
- pv->token_info = gp11_slot_get_token_info (slot);
-}
-
/* ----------------------------------------------------------------------------
* OBJECT
*/
static void
-gp11_slot_init (GP11Slot *slot)
+gp11_slot_init (GP11Slot *self)
{
-
+ GP11SlotPrivate *pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GP11_TYPE_SLOT, GP11SlotPrivate);
+ g_static_mutex_init (&pv->mutex);
}
static void
gp11_slot_get_property (GObject *obj, guint prop_id, GValue *value,
GParamSpec *pspec)
{
- GP11SlotPrivate *pv = GP11_SLOT_GET_PRIVATE (obj);
- GP11Slot *slot = GP11_SLOT (obj);
-
+ GP11Slot *self = GP11_SLOT (obj);
+
switch (prop_id) {
case PROP_MODULE:
- g_value_set_object (value, slot->module);
+ g_value_take_object (value, gp11_slot_get_module (self));
break;
case PROP_HANDLE:
- g_value_set_uint (value, slot->handle);
+ g_value_set_ulong (value, gp11_slot_get_handle (self));
break;
case PROP_AUTO_LOGIN:
- g_value_set_boolean (value, pv->auto_login);
+ g_value_set_boolean (value, gp11_slot_get_auto_login (self));
break;
case PROP_REUSE_SESSIONS:
- g_value_set_boolean (value, pv->open_sessions != NULL);
+ g_value_set_boolean (value, gp11_slot_get_reuse_sessions (self));
break;
}
}
@@ -346,28 +357,27 @@
gp11_slot_set_property (GObject *obj, guint prop_id, const GValue *value,
GParamSpec *pspec)
{
- GP11SlotPrivate *pv = GP11_SLOT_GET_PRIVATE (obj);
- GP11Slot *slot = GP11_SLOT (obj);
+ GP11SlotData *data = GP11_SLOT_GET_DATA (obj);
+ GP11Slot *self = GP11_SLOT (obj);
+
+ /* All writes to data members below, happen only during construct phase */
switch (prop_id) {
case PROP_MODULE:
- g_return_if_fail (!slot->module);
- slot->module = g_value_get_object (value);
- g_return_if_fail (slot->module);
- g_object_ref (slot->module);
+ g_assert (!data->module);
+ data->module = g_value_get_object (value);
+ g_assert (data->module);
+ g_object_ref (data->module);
break;
case PROP_HANDLE:
- g_return_if_fail (!slot->handle);
- slot->handle = g_value_get_uint (value);
+ g_assert (!data->handle);
+ data->handle = g_value_get_ulong (value);
break;
case PROP_AUTO_LOGIN:
- pv->auto_login = g_value_get_boolean (value);
+ gp11_slot_set_auto_login (self, g_value_get_boolean (value));
break;
case PROP_REUSE_SESSIONS:
- if (g_value_get_boolean (value))
- create_session_table (slot);
- else
- destroy_session_table (slot);
+ gp11_slot_set_reuse_sessions (self, g_value_get_boolean (value));
break;
}
}
@@ -375,14 +385,14 @@
static void
gp11_slot_dispose (GObject *obj)
{
- GP11Slot *slot = GP11_SLOT (obj);
-
- /* Need to do this before the module goes away */
- destroy_session_table (slot);
+ GP11SlotPrivate *pv = lock_private (obj);
+
+ {
+ /* Need to do this before the module goes away */
+ destroy_session_table (pv);
+ }
- if (slot->module)
- g_object_unref (slot->module);
- slot->module = NULL;
+ unlock_private (obj, pv);
G_OBJECT_CLASS (gp11_slot_parent_class)->dispose (obj);
}
@@ -390,10 +400,22 @@
static void
gp11_slot_finalize (GObject *obj)
{
- GP11Slot *slot = GP11_SLOT (obj);
+ GP11SlotPrivate *pv = G_TYPE_INSTANCE_GET_PRIVATE (obj, GP11_TYPE_SLOT, GP11SlotPrivate);
+ GP11SlotData *data = GP11_SLOT_GET_DATA (obj);
+
+ data->handle = 0;
+
+ g_assert (!pv->open_sessions);
+
+ if (data->module)
+ g_object_unref (data->module);
+ data->module = NULL;
+
+ if (pv->token_info)
+ gp11_token_info_free (pv->token_info);
+ pv->token_info = NULL;
- g_assert (slot->module == NULL);
- slot->handle = 0;
+ g_static_mutex_free (&pv->mutex);
G_OBJECT_CLASS (gp11_slot_parent_class)->finalize (obj);
}
@@ -415,8 +437,8 @@
GP11_TYPE_MODULE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_HANDLE,
- g_param_spec_uint ("handle", "Handle", "PKCS11 Slot ID",
- 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_param_spec_ulong ("handle", "Handle", "PKCS11 Slot ID",
+ 0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class, PROP_AUTO_LOGIN,
g_param_spec_boolean ("auto-login", "Auto Login", "Auto Login to Token when necessary",
@@ -439,29 +461,41 @@
*/
gboolean
-_gp11_slot_token_authentication (GP11Slot *slot, gchar **password)
+_gp11_slot_token_authentication (GP11Slot *self, gchar **password)
{
- GP11SlotPrivate *pv = GP11_SLOT_GET_PRIVATE (slot);
+ GP11SlotPrivate *pv = lock_private (self);
+ gboolean emit_signal = FALSE;
gboolean ret = FALSE;
-
- g_return_val_if_fail (GP11_IS_SLOT (slot), FALSE);
+
+ g_return_val_if_fail (GP11_IS_SLOT (self), FALSE);
g_return_val_if_fail (password, FALSE);
-
- if (!pv->auto_login)
- return FALSE;
- /*
- * If it's a protected authentication path style token, then
- * we don't prompt here, the hardware/software is expected
- * to prompt the user in some other way.
- */
- ensure_token_info (slot);
- if (pv->token_info && (pv->token_info->flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
- *password = NULL;
- return TRUE;
+ {
+ if (pv->auto_login) {
+
+ /*
+ * If it's a protected authentication path style token, then
+ * we don't prompt here, the hardware/software is expected
+ * to prompt the user in some other way.
+ */
+
+ if (!pv->token_info)
+ pv->token_info = gp11_slot_get_token_info (self);
+
+ if (pv->token_info && (pv->token_info->flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
+ *password = NULL;
+ ret = TRUE;
+ } else {
+ emit_signal = TRUE;
+ }
+ }
}
-
- g_signal_emit (slot, signals[AUTHENTICATE_TOKEN], 0, password, &ret);
+
+ unlock_private (self, pv);
+
+ if (emit_signal)
+ g_signal_emit (self, signals[AUTHENTICATE_TOKEN], 0, password, &ret);
+
return ret;
}
@@ -519,22 +553,40 @@
/**
* gp11_slot_get_handle:
- * @slot: The slot to get the handle of.
+ * @self: The slot to get the handle of.
*
* Get the raw PKCS#11 handle of a slot.
*
* Return value: The raw handle.
**/
CK_SLOT_ID
-gp11_slot_get_handle (GP11Slot *slot)
+gp11_slot_get_handle (GP11Slot *self)
+{
+ GP11SlotData *data = GP11_SLOT_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_SLOT (self), (CK_SLOT_ID)-1);
+ return data->handle;
+}
+
+/**
+ * gp11_slot_get_module:
+ * @self: The slot to get the module for.
+ *
+ * Get the module that this slot is on.
+ *
+ * Return value: The module, you must unreference this after you're done with it.
+ */
+GP11Module*
+gp11_slot_get_module (GP11Slot *self)
{
- g_return_val_if_fail (GP11_IS_SLOT (slot), (CK_SLOT_ID)-1);
- return slot->handle;
+ GP11SlotData *data = GP11_SLOT_GET_DATA (self);
+ g_return_val_if_fail (GP11_IS_SLOT (self), NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (data->module), NULL);
+ return g_object_ref (data->module);
}
/**
* gp11_slot_get_reuse_sessions:
- * @slot: The slot to get setting from.
+ * @self: The slot to get setting from.
*
* Get the reuse sessions setting. When this is set, sessions
* will be pooled and reused if their flags match when
@@ -543,30 +595,51 @@
* Return value: Whether reusing sessions or not.
**/
gboolean
-gp11_slot_get_reuse_sessions (GP11Slot *slot)
+gp11_slot_get_reuse_sessions (GP11Slot *self)
{
- gboolean reuse = FALSE;
- g_object_get (slot, "reuse-sessions", &reuse, NULL);
- return reuse;
+ GP11SlotPrivate *pv = lock_private (self);
+ gboolean ret;
+
+ g_return_val_if_fail (pv, FALSE);
+
+ {
+ ret = pv->open_sessions != NULL;
+ }
+
+ unlock_private (self, pv);
+
+ return ret;
}
/**
* gp11_slot_set_reuse_sessions:
- * @slot: The slot to set the setting on.
+ * @self: The slot to set the setting on.
* @reuse: Whether to reuse sessions or not.
*
* When this is set, sessions will be pooled and reused
* if their flags match when gp11_slot_open_session() is called.
**/
void
-gp11_slot_set_reuse_sessions (GP11Slot *slot, gboolean reuse)
+gp11_slot_set_reuse_sessions (GP11Slot *self, gboolean reuse)
{
- g_object_set (slot, "reuse-sessions", reuse, NULL);
+ GP11SlotPrivate *pv = lock_private (self);
+
+ g_return_if_fail (pv);
+
+ {
+ if (reuse)
+ create_session_table (pv);
+ else
+ destroy_session_table (pv);
+ }
+
+ unlock_private (self, pv);
+ g_object_notify (G_OBJECT (self), "reuse-sessions");
}
/**
* gp11_slot_get_auto_login:
- * @slot: The slot to get setting from.
+ * @self: The slot to get setting from.
*
* Get the auto login setting. When this is set, this slot
* will emit the 'authenticate-token' signal when a session
@@ -575,16 +648,25 @@
* Return value: Whether auto login or not.
**/
gboolean
-gp11_slot_get_auto_login (GP11Slot *slot)
+gp11_slot_get_auto_login (GP11Slot *self)
{
- gboolean auto_login = FALSE;
- g_object_get (slot, "auto-login", &auto_login, NULL);
- return auto_login;
+ GP11SlotPrivate *pv = lock_private (self);
+ gboolean ret;
+
+ g_return_val_if_fail (pv, FALSE);
+
+ {
+ ret = pv->auto_login;
+ }
+
+ unlock_private (self, pv);
+
+ return ret;
}
/**
* gp11_slot_set_auto_login:
- * @slot: The slot to set the setting on.
+ * @self: The slot to set the setting on.
* @auto_login: Whether auto login or not.
*
* When this is set, this slot
@@ -592,14 +674,23 @@
* requires authentication.
**/
void
-gp11_slot_set_auto_login (GP11Slot *slot, gboolean auto_login)
+gp11_slot_set_auto_login (GP11Slot *self, gboolean auto_login)
{
- g_object_set (slot, "auto-login", auto_login, NULL);
+ GP11SlotPrivate *pv = lock_private (self);
+
+ g_return_if_fail (pv);
+
+ {
+ pv->auto_login = auto_login;
+ }
+
+ unlock_private (self, pv);
+ g_object_notify (G_OBJECT (self), "auto-login");
}
/**
* gp11_slot_get_info:
- * @slot: The slot to get info for.
+ * @self: The slot to get info for.
*
* Get the information for this slot.
*
@@ -607,18 +698,28 @@
* to release it.
**/
GP11SlotInfo*
-gp11_slot_get_info (GP11Slot *slot)
+gp11_slot_get_info (GP11Slot *self)
{
+ CK_SLOT_ID handle = (CK_SLOT_ID)-1;
+ GP11Module *module = NULL;
+ CK_FUNCTION_LIST_PTR funcs;
GP11SlotInfo *slotinfo;
CK_SLOT_INFO info;
CK_RV rv;
- g_return_val_if_fail (GP11_IS_SLOT (slot), NULL);
- g_return_val_if_fail (GP11_IS_MODULE (slot->module), NULL);
- g_return_val_if_fail (slot->module->funcs, NULL);
+ g_return_val_if_fail (GP11_IS_SLOT (self), NULL);
+
+ g_object_get (self, "module", &module, "handle", &handle, NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (module), NULL);
+
+ funcs = gp11_module_get_function_list (module);
+ g_return_val_if_fail (funcs, NULL);
memset (&info, 0, sizeof (info));
- rv = (slot->module->funcs->C_GetSlotInfo) (slot->handle, &info);
+ rv = (funcs->C_GetSlotInfo) (handle, &info);
+
+ g_object_unref (module);
+
if (rv != CKR_OK) {
g_warning ("couldn't get slot info: %s", gp11_message_from_rv (rv));
return NULL;
@@ -640,7 +741,7 @@
/**
* gp11_slot_get_token_info:
- * @slot: The slot to get info for.
+ * @self: The slot to get info for.
*
* Get the token information for this slot.
*
@@ -648,20 +749,30 @@
* to release it.
**/
GP11TokenInfo*
-gp11_slot_get_token_info (GP11Slot *slot)
+gp11_slot_get_token_info (GP11Slot *self)
{
+ CK_SLOT_ID handle = (CK_SLOT_ID)-1;
+ CK_FUNCTION_LIST_PTR funcs;
+ GP11Module *module = NULL;
GP11TokenInfo *tokeninfo;
CK_TOKEN_INFO info;
gchar *string;
struct tm tm;
CK_RV rv;
- g_return_val_if_fail (GP11_IS_SLOT (slot), NULL);
- g_return_val_if_fail (GP11_IS_MODULE (slot->module), NULL);
- g_return_val_if_fail (slot->module->funcs, NULL);
+ g_return_val_if_fail (GP11_IS_SLOT (self), NULL);
+
+ g_object_get (self, "module", &module, "handle", &handle, NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (module), NULL);
+
+ funcs = gp11_module_get_function_list (module);
+ g_return_val_if_fail (funcs, NULL);
memset (&info, 0, sizeof (info));
- rv = (slot->module->funcs->C_GetTokenInfo) (slot->handle, &info);
+ rv = (funcs->C_GetTokenInfo) (handle, &info);
+
+ g_object_unref (module);
+
if (rv != CKR_OK) {
g_warning ("couldn't get slot info: %s", gp11_message_from_rv (rv));
return NULL;
@@ -706,7 +817,7 @@
/**
* gp11_slot_get_mechanisms:
- * @slot: The slot to get mechanisms for.
+ * @self: The slot to get mechanisms for.
*
* Get the available mechanisms for this slot.
*
@@ -714,33 +825,42 @@
* gp11_mechanisms_free() when done with this.
**/
GP11Mechanisms*
-gp11_slot_get_mechanisms (GP11Slot *slot)
+gp11_slot_get_mechanisms (GP11Slot *self)
{
+ CK_SLOT_ID handle = (CK_SLOT_ID)-1;
+ CK_FUNCTION_LIST_PTR funcs;
+ GP11Module *module = NULL;
CK_MECHANISM_TYPE_PTR mech_list;
CK_ULONG count, i;
GP11Mechanisms *result;
CK_RV rv;
- g_return_val_if_fail (GP11_IS_SLOT (slot), NULL);
- g_return_val_if_fail (GP11_IS_MODULE (slot->module), NULL);
- g_return_val_if_fail (slot->module->funcs, NULL);
+ g_return_val_if_fail (GP11_IS_SLOT (self), NULL);
- rv = (slot->module->funcs->C_GetMechanismList) (slot->handle, NULL, &count);
+ g_object_get (self, "module", &module, "handle", &handle, NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (module), NULL);
+
+ funcs = gp11_module_get_function_list (module);
+ g_return_val_if_fail (funcs, NULL);
+
+ rv = (funcs->C_GetMechanismList) (handle, NULL, &count);
if (rv != CKR_OK) {
g_warning ("couldn't get mechanism count: %s", gp11_message_from_rv (rv));
- return NULL;
+ count = 0;
+ } else {
+ mech_list = g_new (CK_MECHANISM_TYPE, count);
+ rv = (funcs->C_GetMechanismList) (handle, mech_list, &count);
+ if (rv != CKR_OK) {
+ g_warning ("couldn't get mechanism list: %s", gp11_message_from_rv (rv));
+ g_free (mech_list);
+ count = 0;
+ }
}
- if (!count)
- return NULL;
+ g_object_unref (module);
- mech_list = g_new (CK_MECHANISM_TYPE, count);
- rv = (slot->module->funcs->C_GetMechanismList) (slot->handle, mech_list, &count);
- if (rv != CKR_OK) {
- g_warning ("couldn't get mechanism list: %s", gp11_message_from_rv (rv));
- g_free (mech_list);
+ if (!count)
return NULL;
- }
result = g_array_new (FALSE, TRUE, sizeof (CK_MECHANISM_TYPE));
for (i = 0; i < count; ++i)
@@ -753,7 +873,7 @@
/**
* gp11_slot_get_mechanism_info:
- * @slot: The slot to get mechanism info from.
+ * @self: The slot to get mechanism info from.
* @mech_type: The mechanisms type to get info for.
*
* Get information for the specified mechanism.
@@ -762,19 +882,29 @@
* gp11_mechanism_info_free() when done with it.
**/
GP11MechanismInfo*
-gp11_slot_get_mechanism_info (GP11Slot *slot, gulong mech_type)
+gp11_slot_get_mechanism_info (GP11Slot *self, gulong mech_type)
{
+ CK_SLOT_ID handle = (CK_SLOT_ID)-1;
+ CK_FUNCTION_LIST_PTR funcs;
GP11MechanismInfo *mechinfo;
+ GP11Module *module = NULL;
CK_MECHANISM_INFO info;
struct tm;
CK_RV rv;
- g_return_val_if_fail (GP11_IS_SLOT (slot), NULL);
- g_return_val_if_fail (GP11_IS_MODULE (slot->module), NULL);
- g_return_val_if_fail (slot->module->funcs, NULL);
+ g_return_val_if_fail (GP11_IS_SLOT (self), NULL);
+
+ g_object_get (self, "module", &module, "handle", &handle, NULL);
+ g_return_val_if_fail (GP11_IS_MODULE (module), NULL);
+ funcs = gp11_module_get_function_list (module);
+ g_return_val_if_fail (funcs, NULL);
+
memset (&info, 0, sizeof (info));
- rv = (slot->module->funcs->C_GetMechanismInfo) (slot->handle, mech_type, &info);
+ rv = (funcs->C_GetMechanismInfo) (handle, mech_type, &info);
+
+ g_object_unref (module);
+
if (rv != CKR_OK) {
g_warning ("couldn't get mechanism info: %s", gp11_message_from_rv (rv));
return NULL;
@@ -806,20 +936,20 @@
}
gboolean
-gp11_slot_init_token (GP11Slot *slot, const guchar *pin, gsize length,
+gp11_slot_init_token (GP11Slot *self, const guchar *pin, gsize length,
const gchar *label, GCancellable *cancellable,
GError **err)
{
InitToken args = { GP11_ARGUMENTS_INIT, pin, length, label };
- return _gp11_call_sync (slot, perform_init_token, &args, err);
+ return _gp11_call_sync (self, perform_init_token, &args, err);
}
void
-gp11_slot_init_token_async (GP11Slot *slot, const guchar *pin, gsize length,
+gp11_slot_init_token_async (GP11Slot *self, const guchar *pin, gsize length,
const gchar *label, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
- InitToken* args = _gp11_call_async_prep (slot, slot, perform_init_token,
+ InitToken* args = _gp11_call_async_prep (self, self, perform_init_token,
sizeof (*args));
args->pin = pin;
@@ -830,9 +960,9 @@
}
gboolean
-gp11_slot_init_token_finish (GP11Slot *slot, GAsyncResult *result, GError **err)
+gp11_slot_init_token_finish (GP11Slot *self, GAsyncResult *result, GError **err)
{
- return _gp11_call_basic_finish (slot, result, err);
+ return _gp11_call_basic_finish (self, result, err);
}
#endif /* UNIMPLEMENTED */
@@ -853,7 +983,7 @@
/**
* gp11_slot_open_session:
- * @slot: The slot ot open a session on.
+ * @self: The slot ot open a session on.
* @flags: The flags to open a session with.
* @err: A location to return an error, or NULL.
*
@@ -865,14 +995,14 @@
* Return value: A new session or NULL if an error occurs.
**/
GP11Session*
-gp11_slot_open_session (GP11Slot *slot, gulong flags, GError **err)
+gp11_slot_open_session (GP11Slot *self, gulong flags, GError **err)
{
- return gp11_slot_open_session_full (slot, flags, NULL, err);
+ return gp11_slot_open_session_full (self, flags, NULL, err);
}
/**
* gp11_slot_open_session_full:
- * @slot: The slot to open a session on.
+ * @self: The slot to open a session on.
* @flags: The flags to open a session with.
* @cancellable: Optional cancellation object, or NULL.
* @err: A location to return an error, or NULL.
@@ -885,26 +1015,42 @@
* Return value: A new session or NULL if an error occurs.
**/
GP11Session*
-gp11_slot_open_session_full (GP11Slot *slot, gulong flags, GCancellable *cancellable, GError **err)
+gp11_slot_open_session_full (GP11Slot *self, gulong flags, GCancellable *cancellable, GError **err)
{
- OpenSession args = { GP11_ARGUMENTS_INIT, flags, 0 };
+ GP11SlotPrivate *pv;
+ GP11Session *session = NULL;
CK_SESSION_HANDLE handle;
+
+ flags |= CKF_SERIAL_SESSION;
+
+ g_object_ref (self);
- /* Try to use a cached session */
- handle = pop_session_table (slot, flags);
- if (handle != 0)
- return make_session_object (slot, flags, handle);
+ pv = lock_private (self);
+ {
+ /* Try to use a cached session */
+ handle = pop_session_table (pv, flags);
+ if (handle != 0)
+ session = make_session_object (self, flags, handle);
+ }
+
+ unlock_private (self, pv);
+
/* Open a new session */
- if (!_gp11_call_sync (slot, perform_open_session, &args, cancellable, err))
- return FALSE;
+ if (session == NULL) {
+ OpenSession args = { GP11_ARGUMENTS_INIT, flags, 0 };
+ if (_gp11_call_sync (self, perform_open_session, &args, cancellable, err))
+ session = make_session_object (self, flags, args.session);
+ }
+
+ g_object_unref (self);
- return make_session_object (slot, flags, args.session);
+ return session;
}
/**
* gp11_slot_open_session_async:
- * @slot: The slot to open a session on.
+ * @self: The slot to open a session on.
* @flags: The flags to open a session with.
* @cancellable: Optional cancellation object, or NULL.
* @callback: Called when the operation completes.
@@ -916,27 +1062,41 @@
* This call will return immediately and complete asynchronously.
**/
void
-gp11_slot_open_session_async (GP11Slot *slot, gulong flags, GCancellable *cancellable,
+gp11_slot_open_session_async (GP11Slot *self, gulong flags, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
+ GP11SlotPrivate *pv;
GP11Call *call;
- OpenSession *args = _gp11_call_async_prep (slot, slot, perform_open_session,
- sizeof (*args), NULL);
+ OpenSession *args;
+
+ flags |= CKF_SERIAL_SESSION;
+
+ g_object_ref (self);
- /* Try to use a cached session */
- args->session = pop_session_table (slot, flags);
- args->flags = flags;
+ args = _gp11_call_async_prep (self, self, perform_open_session, sizeof (*args), NULL);
+
+ pv = lock_private (self);
+
+ {
+ /* Try to use a cached session */
+ args->session = pop_session_table (pv, flags);
+ args->flags = flags;
+ }
+
+ unlock_private (self, pv);
call = _gp11_call_async_ready (args, cancellable, callback, user_data);
if (args->session)
_gp11_call_async_short (call, CKR_OK);
else
_gp11_call_async_go (call);
+
+ g_object_unref (self);
}
/**
* gp11_slot_open_session_finish:
- * @slot: The slot to open a session on.
+ * @self: The slot to open a session on.
* @result: The result passed to the callback.
* @err: A location to return an error or NULL.
*
@@ -946,13 +1106,22 @@
* Return value: The new session or NULL if an error occurs.
*/
GP11Session*
-gp11_slot_open_session_finish (GP11Slot *slot, GAsyncResult *result, GError **err)
+gp11_slot_open_session_finish (GP11Slot *self, GAsyncResult *result, GError **err)
{
- OpenSession *args;
+ GP11Session *session = NULL;
+
+ g_object_ref (self);
- if (!_gp11_call_basic_finish (result, err))
- return NULL;
+ {
+ OpenSession *args;
+
+ if (_gp11_call_basic_finish (result, err)) {
+ args = _gp11_call_arguments (result, OpenSession);
+ session = make_session_object (self, args->flags, args->session);
+ }
+ }
+
+ g_object_unref (self);
- args = _gp11_call_arguments (result, OpenSession);
- return make_session_object (slot, args->flags, args->session);
+ return session;
}
Modified: trunk/gp11/gp11.h
==============================================================================
--- trunk/gp11/gp11.h (original)
+++ trunk/gp11/gp11.h Sat Dec 27 18:29:23 2008
@@ -243,25 +243,28 @@
struct _GP11Module {
GObject parent;
-
- gchar *path;
- CK_FUNCTION_LIST_PTR funcs;
+ gpointer reserved[4];
};
struct _GP11ModuleClass {
GObjectClass parent;
+ gpointer reserved[8];
};
-GType gp11_module_get_type (void) G_GNUC_CONST;
+GType gp11_module_get_type (void) G_GNUC_CONST;
-GP11Module* gp11_module_initialize (const gchar *path,
- gpointer reserved,
- GError **err);
+GP11Module* gp11_module_initialize (const gchar *path,
+ gpointer reserved,
+ GError **err);
+
+const gchar* gp11_module_get_path (GP11Module *module);
+
+CK_FUNCTION_LIST_PTR gp11_module_get_function_list (GP11Module *module);
-GP11ModuleInfo* gp11_module_get_info (GP11Module *module);
+GP11ModuleInfo* gp11_module_get_info (GP11Module *module);
-GList* gp11_module_get_slots (GP11Module *module,
- gboolean token_present);
+GList* gp11_module_get_slots (GP11Module *module,
+ gboolean token_present);
enum {
GP11_IS_STRING = -1,
@@ -338,16 +341,14 @@
struct _GP11Slot {
GObject parent;
-
- GP11Module *module;
- CK_SLOT_ID handle;
+ gpointer reserved[4];
};
struct _GP11SlotClass {
GObjectClass parent;
gboolean (*authenticate_token) (GP11Slot *slot, gchar **password);
-
+
#ifdef UNIMPLEMENTED
gboolean (*authenticate_key) (GP11Slot *slot, GP11Object *object,
gchar **password);
@@ -355,10 +356,13 @@
void (*slot_event) (GP11Slot *slot);
#endif
+ gpointer reserved[10];
};
GType gp11_slot_get_type (void) G_GNUC_CONST;
+GP11Module* gp11_slot_get_module (GP11Slot *slot);
+
CK_SLOT_ID gp11_slot_get_handle (GP11Slot *slot);
gboolean gp11_slot_get_reuse_sessions (GP11Slot *slot);
@@ -447,24 +451,26 @@
struct _GP11Session {
GObject parent;
-
- GP11Slot *slot;
- GP11Module *module;
- CK_SESSION_HANDLE handle;
};
struct _GP11SessionClass {
GObjectClass parent;
- void (*discard_handle) (GP11Session *session);
+ gboolean (*discard_handle) (GP11Session *session, CK_SESSION_HANDLE handle);
};
GType gp11_session_get_type (void) G_GNUC_CONST;
GP11Session* gp11_session_from_handle (GP11Slot *slot, CK_SESSION_HANDLE handle);
+GP11Module* gp11_session_get_module (GP11Session *self);
+
+GP11Slot* gp11_session_get_slot (GP11Session *self);
+
CK_SESSION_HANDLE gp11_session_get_handle (GP11Session *session);
+CK_SESSION_HANDLE gp11_session_steal_handle (GP11Session *session);
+
GP11SessionInfo* gp11_session_get_info (GP11Session *session);
#if UNIMPLEMENTED
@@ -1195,11 +1201,6 @@
struct _GP11Object {
GObject parent;
-
- GP11Module *module;
- GP11Slot *slot;
- GP11Session *session;
- CK_OBJECT_HANDLE handle;
};
struct _GP11ObjectClass {
@@ -1214,6 +1215,10 @@
GList* gp11_objects_from_handle_array (GP11Slot *slot,
const GP11Attribute *attr);
+GP11Module* gp11_object_get_module (GP11Object *self);
+
+GP11Slot* gp11_object_get_slot (GP11Object *object);
+
CK_OBJECT_HANDLE gp11_object_get_handle (GP11Object *object);
GP11Session* gp11_object_get_session (GP11Object *object);
Modified: trunk/gp11/tests/unit-test-gp11-module.c
==============================================================================
--- trunk/gp11/tests/unit-test-gp11-module.c (original)
+++ trunk/gp11/tests/unit-test-gp11-module.c Sat Dec 27 18:29:23 2008
@@ -40,7 +40,7 @@
{
gchar *path;
- g_object_get (module, "module-path", &path, NULL);
+ g_object_get (module, "path", &path, NULL);
g_assert (path != NULL && "no module-path");
g_assert (strcmp (".libs/libgp11-test-module.so", path) == 0 && "module path wrong");
g_free (path);
Modified: trunk/gp11/tests/unit-test-gp11-object.c
==============================================================================
--- trunk/gp11/tests/unit-test-gp11-object.c (original)
+++ trunk/gp11/tests/unit-test-gp11-object.c Sat Dec 27 18:29:23 2008
@@ -33,7 +33,7 @@
SUCCESS_RES(session, err);
/* Our module always exports a token object with this */
- object = gp11_object_from_handle (session->slot, 2);
+ object = gp11_object_from_handle (slot, 2);
g_assert (object != NULL);
}
@@ -47,12 +47,12 @@
DEFINE_TEST(object_props)
{
- GP11Slot *slot;
+ GP11Slot *sl;
GP11Module *mod;
CK_OBJECT_HANDLE handle;
- g_object_get (object, "slot", &slot, "module", &mod, "handle", &handle, NULL);
- g_assert (slot == session->slot);
- g_object_unref (slot);
+ g_object_get (object, "slot", &sl, "module", &mod, "handle", &handle, NULL);
+ g_assert (slot == sl);
+ g_object_unref (sl);
g_assert (module == mod);
g_object_unref (mod);
g_assert (handle == 2);
@@ -84,7 +84,7 @@
g_assert (GP11_IS_OBJECT (object));
if (object) {
- last_handle = object->handle;
+ last_handle = gp11_object_get_handle (object);
g_object_unref (object);
}
@@ -100,8 +100,8 @@
SUCCESS_RES (object, err);
if (object) {
- g_assert (last_handle != object->handle);
- last_handle = object->handle;
+ g_assert (last_handle != gp11_object_get_handle (object));
+ last_handle = gp11_object_get_handle (object);
g_object_unref (object);
}
@@ -380,11 +380,13 @@
/* Set an explicit session */
gp11_object_set_session (object, session);
- g_assert (gp11_object_get_session (object) == session);
+ sess = gp11_object_get_session (object);
+ g_assert (sess == session);
+ g_object_unref (sess);
g_object_get (object, "session", &sess, NULL);
g_assert (sess == session);
g_object_unref (sess);
-
+
/* Simple */
attrs = gp11_object_get (object, &err, CKA_CLASS, CKA_LABEL, -1);
SUCCESS_RES (attrs, err);
@@ -415,4 +417,11 @@
g_assert (gp11_object_get_session (object) == NULL);
g_object_get (object, "session", &sess, NULL);
g_assert (sess == NULL);
+
+ /* Test property settor */
+ g_object_set (object, "session", session, NULL);
+ sess = gp11_object_get_session (object);
+ g_assert (sess == session);
+ gp11_object_set_session (object, NULL);
+ g_object_unref (sess);
}
Modified: trunk/gp11/tests/unit-test-gp11-session.c
==============================================================================
--- trunk/gp11/tests/unit-test-gp11-session.c (original)
+++ trunk/gp11/tests/unit-test-gp11-session.c Sat Dec 27 18:29:23 2008
@@ -42,14 +42,17 @@
DEFINE_TEST(session_props)
{
GP11Module *mod;
+ GP11Slot *sl;
guint handle;
- g_object_get (session, "module", &mod, "handle", &handle, NULL);
+ g_object_get (session, "module", &mod, "handle", &handle, "slot", &sl, NULL);
g_assert (mod == module);
+ g_assert (sl == slot);
g_object_unref (mod);
+ g_object_unref (sl);
g_assert (handle != 0);
- g_assert (session->handle == handle);
+ g_assert (gp11_session_get_handle (session) == handle);
}
DEFINE_TEST(session_info)
@@ -59,7 +62,7 @@
info = gp11_session_get_info (session);
g_assert (info != NULL && "no session info");
- g_assert (info->slot_id == slot->handle);
+ g_assert (info->slot_id == gp11_slot_get_handle (slot));
g_assert ((info->flags & CKF_SERIAL_SESSION) == CKF_SERIAL_SESSION);
g_assert (info->device_error == 1414);
gp11_session_info_free (info);
@@ -103,24 +106,27 @@
GP11Session *sess, *sess2;
GAsyncResult *result = NULL;
GError *err = NULL;
+ gboolean value;
g_assert (gp11_slot_get_reuse_sessions (slot) == FALSE);
gp11_slot_set_reuse_sessions (slot, TRUE);
g_assert (gp11_slot_get_reuse_sessions (slot) == TRUE);
+ g_object_get (slot, "reuse-sessions", &value, NULL);
+ g_assert (value == TRUE);
sess = gp11_slot_open_session (slot, 0, &err);
SUCCESS_RES (sess, err);
if (!sess) return;
/* Make note of the handle we saw */
- handle = sess->handle;
+ handle = gp11_session_get_handle (sess);
g_object_unref (sess);
/* Open again, and see if the same handle */
sess = gp11_slot_open_session (slot, 0, &err);
SUCCESS_RES (sess, err);
if (!sess) return;
- g_assert (handle == sess->handle);
+ g_assert (handle == gp11_session_get_handle (sess));
g_object_unref (sess);
/* Test opening async */
@@ -130,7 +136,7 @@
sess = gp11_slot_open_session_finish (slot, result, &err);
SUCCESS_RES (sess, err);
if (!sess) return;
- g_assert (handle == sess->handle);
+ g_assert (handle == gp11_session_get_handle (sess));
g_object_unref (result);
g_object_unref (sess);
@@ -138,14 +144,17 @@
sess = gp11_slot_open_session (slot, CKF_RW_SESSION, &err);
SUCCESS_RES (sess, err);
if (!sess) return;
- g_assert (handle != sess->handle);
+ g_assert (handle != gp11_session_get_handle (sess));
/* Now open a second session, with same flags, shouldn't return the same */
sess2 = gp11_slot_open_session (slot, CKF_RW_SESSION, &err);
SUCCESS_RES (sess2, err);
if (!sess2) return;
- g_assert (sess->handle != sess2->handle);
+ g_assert (gp11_session_get_handle (sess) != gp11_session_get_handle (sess2));
+ g_object_set (slot, "reuse-sessions", FALSE, NULL);
+ g_assert (gp11_slot_get_reuse_sessions (slot) == FALSE);
+
g_object_unref (sess);
g_object_unref (sess2);
}
@@ -214,6 +223,7 @@
GError *err = NULL;
GP11Attributes *attrs;
gboolean ret;
+ gboolean value;
attrs = gp11_attributes_newv (CKA_CLASS, GP11_ULONG, CKO_DATA,
CKA_LABEL, GP11_STRING, "TEST OBJECT",
@@ -230,6 +240,8 @@
g_assert (gp11_slot_get_auto_login (slot) == FALSE);
gp11_slot_set_auto_login (slot, TRUE);
g_assert (gp11_slot_get_auto_login (slot) == TRUE);
+ g_object_get (slot, "auto-login", &value, NULL);
+ g_assert (value == TRUE);
g_signal_connect (slot, "authenticate-token", G_CALLBACK (authenticate_token), GUINT_TO_POINTER (35));
@@ -254,4 +266,7 @@
/* We should now be logged in, try to log out */
ret = gp11_session_logout (session, &err);
SUCCESS_RES (ret, err);
+
+ g_object_set (slot, "auto-login", FALSE, NULL);
+ g_assert (gp11_slot_get_auto_login (slot) == FALSE);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]