60
67
GckManager *manager;
63
71
GckObjectTransient *transient;
66
74
G_DEFINE_TYPE (GckObject, gck_object, G_TYPE_OBJECT);
76
/* Private friend functions from the manager */
77
void _gck_manager_register_object (GckManager *self, GckObject *object);
78
void _gck_manager_unregister_object (GckManager *self, GckObject *object);
68
80
/* -----------------------------------------------------------------------------
73
kaboom_callback (GckTimer *timer, gpointer user_data)
85
self_destruct (GckObject *self)
75
GckObject *self = user_data;
76
87
GckTransaction *transaction;
77
GckObjectTransient *transient;
80
g_return_if_fail (GCK_IS_OBJECT (self));
81
g_return_if_fail (self->pv->transient);
82
transient = self->pv->transient;
84
g_return_if_fail (timer == transient->timed_timer);
85
transient->timed_timer = NULL;
89
90
transaction = gck_transaction_new ();
92
92
gck_object_destroy (self, transaction);
94
94
gck_transaction_complete (transaction);
95
95
rv = gck_transaction_get_result (transaction);
96
96
g_object_unref (transaction);
99
98
g_warning ("Unexpected failure to auto destruct object (code: %lu)", (gulong)rv);
102
timer_callback (GckTimer *timer, gpointer user_data)
104
GckObject *self = user_data;
105
glong after, idle, offset;
106
GckObjectTransient *transient;
109
g_return_if_fail (GCK_IS_OBJECT (self));
113
g_return_if_fail (self->pv->transient);
114
transient = self->pv->transient;
115
g_return_if_fail (timer == transient->timer);
116
transient->timer = NULL;
118
g_get_current_time (&tv);
119
idle = after = G_MAXLONG;
121
/* Are we supposed to be destroyed after a certain time? */
122
if (transient->timed_after) {
123
g_return_if_fail (transient->stamp_created);
124
after = (transient->stamp_created + transient->timed_after) - tv.tv_sec;
127
/* Are we supposed to be destroyed after an idle time? */
128
if (transient->timed_idle) {
129
g_return_if_fail (transient->stamp_used);
130
idle = (transient->stamp_used + transient->timed_idle) - tv.tv_sec;
133
/* Okay, time to destroy? */
134
offset = MIN (after, idle);
136
self_destruct (self);
138
/* Setup the next timer */
140
transient->timer = gck_timer_start (self->pv->module, offset, timer_callback, self);
101
142
g_object_unref (self);
107
148
GckObject *self = GCK_OBJECT (obj);
108
149
GckObjectTransient *transient;
110
152
g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
111
153
g_return_val_if_fail (self->pv->transient, FALSE);
112
154
transient = self->pv->transient;
114
g_return_val_if_fail (!transient->timed_timer, FALSE);
115
transient->timed_timer = gck_timer_start (self->pv->module, transient->timed_when,
116
kaboom_callback, self);
155
g_return_val_if_fail (!transient->timer, FALSE);
157
g_get_current_time (&tv);
158
transient->stamp_created = tv.tv_sec;
159
transient->stamp_used = tv.tv_sec;
161
/* Start the timer going */
162
timer_callback (NULL, self);
184
complete_expose (GckTransaction *transaction, GObject *obj, gpointer user_data)
186
GckObject *self = GCK_OBJECT (obj);
187
gboolean expose = GPOINTER_TO_UINT (user_data);
189
if (gck_transaction_get_failed (transaction))
190
gck_object_expose (self, !expose);
196
find_credential (GckCredential *cred, GckObject *object, gpointer user_data)
198
CK_OBJECT_HANDLE *result = user_data;
199
g_return_val_if_fail (!*result, FALSE);
200
*result = gck_object_get_handle (GCK_OBJECT (cred));
137
204
/* -----------------------------------------------------------------------------
153
221
case CKA_PRIVATE:
154
222
return gck_attribute_set_bool (attr, FALSE);
156
if (!self->pv->manager)
157
return gck_attribute_set_bool (attr, FALSE);
158
return gck_attribute_set_bool (attr, gck_manager_get_for_token (self->pv->manager));
224
return gck_attribute_set_bool (attr, gck_object_is_token (self));
225
case CKA_G_CREDENTIAL:
226
gck_credential_for_each (session, GCK_OBJECT (self), find_credential, &handle);
227
return gck_attribute_set_ulong (attr, handle);
159
228
case CKA_GNOME_UNIQUE:
160
229
if (self->pv->unique)
161
230
return gck_attribute_set_string (attr, self->pv->unique);
162
231
return CKR_ATTRIBUTE_TYPE_INVALID;
163
232
case CKA_GNOME_TRANSIENT:
164
233
return gck_attribute_set_bool (attr, self->pv->transient ? TRUE : FALSE);
165
case CKA_GNOME_AUTO_DESTRUCT:
166
return gck_attribute_set_time (attr, self->pv->transient ?
167
self->pv->transient->timed_when : -1);
234
case CKA_G_DESTRUCT_AFTER:
235
return gck_attribute_set_ulong (attr, self->pv->transient ?
236
self->pv->transient->timed_after : 0);
237
case CKA_G_DESTRUCT_IDLE:
238
return gck_attribute_set_ulong (attr, self->pv->transient ?
239
self->pv->transient->timed_idle : 0);
240
case CKA_G_DESTRUCT_USES:
241
return gck_attribute_set_ulong (attr, self->pv->transient ?
242
self->pv->transient->uses_remaining : 0);
170
245
/* Give store a shot */
217
gck_transaction_fail (transaction, CKR_ATTRIBUTE_TYPE_INVALID);
295
/* Check if this attribute exists */
296
check.type = attr->type;
298
check.ulValueLen = 0;
299
rv = gck_object_get_attribute (self, session, &check);
300
if (rv == CKR_ATTRIBUTE_TYPE_INVALID)
301
gck_transaction_fail (transaction, CKR_ATTRIBUTE_TYPE_INVALID);
303
gck_transaction_fail (transaction, CKR_ATTRIBUTE_READ_ONLY);
222
308
GckTransaction *transaction, CK_ATTRIBUTE *attrs, CK_ULONG n_attrs)
224
310
CK_ATTRIBUTE_PTR transient_attr;
225
CK_ATTRIBUTE_PTR lifetime_attr;
226
311
gboolean transient = FALSE;
230
316
/* Parse the transient attribute */
231
317
transient_attr = gck_attributes_find (attrs, n_attrs, CKA_GNOME_TRANSIENT);
232
318
if (transient_attr) {
233
319
rv = gck_attribute_get_bool (transient_attr, &transient);
234
gck_attribute_consume (transient_attr);
235
320
if (rv != CKR_OK) {
236
321
gck_transaction_fail (transaction, rv);
241
326
/* Parse the auto destruct attribute */
242
lifetime_attr = gck_attributes_find (attrs, n_attrs, CKA_GNOME_AUTO_DESTRUCT);
244
rv = gck_attribute_get_time (lifetime_attr, &lifetime);
245
gck_attribute_consume (lifetime_attr);
247
gck_transaction_fail (transaction, rv);
251
/* Default for the transient attribute */
327
if (!gck_attributes_find_ulong (attrs, n_attrs, CKA_G_DESTRUCT_AFTER, &after))
329
if (!gck_attributes_find_ulong (attrs, n_attrs, CKA_G_DESTRUCT_IDLE, &idle))
331
/* Default for the transient attribute */
332
if (!transient_attr && (idle || after))
335
/* Used up these attributes */
336
gck_attributes_consume (attrs, n_attrs, CKA_G_DESTRUCT_AFTER,
337
CKA_G_DESTRUCT_IDLE, CKA_GNOME_TRANSIENT, G_MAXULONG);
257
340
self->pv->transient = g_slice_new0 (GckObjectTransient);
258
self->pv->transient->timed_when = lifetime;
341
self->pv->transient->timed_after = after;
342
self->pv->transient->timed_idle = idle;
262
346
if (!self->pv->transient) {
263
347
gck_transaction_fail (transaction, CKR_TEMPLATE_INCONSISTENT);
272
gck_object_real_unlock (GckObject *self, GckAuthenticator *auth)
356
gck_object_real_unlock (GckObject *self, GckCredential *cred)
274
358
/* A derived class should have overridden this */
275
359
return CKR_FUNCTION_FAILED;
363
gck_object_real_expose_object (GckObject *self, gboolean expose)
365
g_return_if_fail (expose != self->pv->exposed);
366
g_return_if_fail (self->pv->manager);
368
self->pv->exposed = expose;
370
_gck_manager_register_object (self->pv->manager, self);
372
_gck_manager_unregister_object (self->pv->manager, self);
279
376
gck_object_constructor (GType type, guint n_props, GObjectConstructParam *props)
299
396
GckObject *self = GCK_OBJECT (obj);
300
397
GckObjectTransient *transient;
302
if (self->pv->manager)
303
gck_manager_unregister_object (self->pv->manager, self);
304
g_assert (self->pv->manager == NULL);
399
if (self->pv->manager) {
400
if (self->pv->exposed)
401
gck_object_expose (self, FALSE);
402
g_return_if_fail (!self->pv->exposed);
403
g_object_remove_weak_pointer (G_OBJECT (self->pv->manager),
404
(gpointer*)&(self->pv->manager));
405
self->pv->manager = NULL;
306
408
g_object_set (self, "store", NULL, NULL);
307
409
g_assert (self->pv->store == NULL);
309
411
if (self->pv->transient) {
310
412
transient = self->pv->transient;
311
if (transient->timed_timer)
312
gck_timer_cancel (transient->timed_timer);
313
transient->timed_timer = NULL;
413
if (transient->timer)
414
gck_timer_cancel (transient->timer);
415
transient->timer = NULL;
315
g_slice_free (GckObjectTransient, transient);
316
self->pv->transient = NULL;
319
418
G_OBJECT_CLASS (gck_object_parent_class)->dispose (obj);
331
430
g_object_weak_unref (G_OBJECT (self->pv->module), module_went_away, self);
332
431
self->pv->module = NULL;
334
g_assert (self->pv->transient == NULL);
433
if (self->pv->transient) {
434
g_slice_free (GckObjectTransient, self->pv->transient);
435
self->pv->transient = NULL;
336
438
G_OBJECT_CLASS (gck_object_parent_class)->finalize (obj);
355
456
g_object_weak_ref (G_OBJECT (self->pv->module), module_went_away, self);
357
458
case PROP_MANAGER:
358
manager = g_value_get_object (value);
459
g_return_if_fail (!self->pv->manager);
460
self->pv->manager = g_value_get_object (value);
359
461
if (self->pv->manager) {
360
g_return_if_fail (!manager);
361
g_object_remove_weak_pointer (G_OBJECT (self->pv->manager),
362
(gpointer*)&(self->pv->manager));
364
self->pv->manager = manager;
365
if (self->pv->manager)
366
462
g_object_add_weak_pointer (G_OBJECT (self->pv->manager),
367
463
(gpointer*)&(self->pv->manager));
369
g_object_notify (G_OBJECT (self), "manager");
372
467
store = g_value_get_object (value);
440
535
klass->set_attribute = gck_object_real_set_attribute;
441
536
klass->create_attributes = gck_object_real_create_attributes;
538
klass->expose_object = gck_object_real_expose_object;
443
540
g_object_class_install_property (gobject_class, PROP_HANDLE,
444
541
g_param_spec_ulong ("handle", "Handle", "Object handle",
445
542
0, G_MAXULONG, 0, G_PARAM_READWRITE));
451
548
g_object_class_install_property (gobject_class, PROP_MANAGER,
452
549
g_param_spec_object ("manager", "Manager", "Object manager",
453
GCK_TYPE_MANAGER, G_PARAM_READWRITE));
550
GCK_TYPE_MANAGER, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
455
552
g_object_class_install_property (gobject_class, PROP_STORE,
456
553
g_param_spec_object ("store", "Store", "Object store",
460
557
g_param_spec_string ("unique", "Unique Identifer", "Machine unique identifier",
461
558
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
560
signals[EXPOSE_OBJECT] = g_signal_new ("expose-object", GCK_TYPE_OBJECT,
561
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GckObjectClass, expose_object),
562
NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
563
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
463
565
signals[NOTIFY_ATTRIBUTE] = g_signal_new ("notify-attribute", GCK_TYPE_OBJECT,
464
566
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GckObjectClass, notify_attribute),
465
567
NULL, NULL, g_cclosure_marshal_VOID__ULONG,
494
593
g_assert (GCK_OBJECT_GET_CLASS (self)->set_attribute);
496
/* Check if this attribute exists */
497
check.type = attr->type;
499
check.ulValueLen = 0;
500
rv = gck_object_get_attribute (self, session, &check);
501
if (rv != CKR_OK && rv != CKR_ATTRIBUTE_SENSITIVE) {
502
gck_transaction_fail (transaction, rv);
506
595
/* Check that the value will actually change */
507
if (rv == CKR_ATTRIBUTE_SENSITIVE || !gck_object_match (self, session, attr))
596
if (!gck_object_match (self, session, attr))
508
597
GCK_OBJECT_GET_CLASS (self)->set_attribute (self, session, transaction, attr);
618
gck_object_get_transient (GckObject *self)
707
gck_object_is_token (GckObject *self)
709
g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
710
if (!self->pv->manager)
712
return gck_manager_get_for_token (self->pv->manager);
716
gck_object_is_transient (GckObject *self)
620
718
g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
621
719
return self->pv->transient ? TRUE : FALSE;
723
gck_object_mark_used (GckObject *self)
725
GckObjectTransient *transient;
728
g_return_if_fail (GCK_IS_OBJECT (self));
729
transient = self->pv->transient;
732
if (transient->timed_idle) {
733
g_get_current_time (&tv);
734
transient->stamp_used = tv.tv_sec;
736
if (transient->uses_remaining) {
737
--(transient->uses_remaining);
738
if (transient->uses_remaining == 0)
739
self_destruct (self);
626
gck_object_unlock (GckObject *self, GckAuthenticator *auth)
745
gck_object_unlock (GckObject *self, GckCredential *cred)
628
747
g_return_val_if_fail (GCK_IS_OBJECT (self), CKR_GENERAL_ERROR);
629
748
g_return_val_if_fail (GCK_OBJECT_GET_CLASS (self)->unlock, CKR_GENERAL_ERROR);
630
return GCK_OBJECT_GET_CLASS (self)->unlock (self, auth);
749
return GCK_OBJECT_GET_CLASS (self)->unlock (self, cred);
703
822
return attr.pValue;
826
gck_object_has_attribute_ulong (GckObject *self, GckSession *session,
827
CK_ATTRIBUTE_TYPE type, gulong value)
832
g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
833
g_return_val_if_fail (GCK_IS_SESSION (session), FALSE);
835
data = gck_object_get_attribute_data (self, session, type, &n_data);
839
g_return_val_if_fail (n_data % sizeof (gulong) == 0, FALSE);
840
for (i = 0; i < n_data / sizeof (gulong); ++i) {
841
if (data[i] == value) {
852
gck_object_has_attribute_boolean (GckObject *self, GckSession *session,
853
CK_ATTRIBUTE_TYPE type, gboolean value)
857
g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
858
g_return_val_if_fail (GCK_IS_SESSION (session), FALSE);
860
if (!gck_object_get_attribute_boolean (self, session, type, &data))
862
return data == value;
707
866
gck_object_destroy (GckObject *self, GckTransaction *transaction)
733
892
g_object_unref (self);
896
gck_object_is_exposed (GckObject *self)
898
g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
899
return self->pv->exposed;
903
gck_object_expose (GckObject *self, gboolean expose)
905
if (!expose && !self)
908
g_return_if_fail (GCK_IS_OBJECT (self));
910
if (self->pv->exposed != expose)
911
g_signal_emit (self, signals[EXPOSE_OBJECT], 0, expose);
915
gck_object_expose_full (GckObject *self, GckTransaction *transaction, gboolean expose)
917
if (!expose && !self)
920
g_return_if_fail (GCK_IS_OBJECT (self));
921
g_return_if_fail (!transaction || !gck_transaction_get_failed (transaction));
923
if (self->pv->exposed != expose) {
925
gck_transaction_add (transaction, self, complete_expose, GUINT_TO_POINTER (expose));
926
gck_object_expose (self, expose);