~ubuntu-branches/ubuntu/natty/gnome-keyring/natty

« back to all changes in this revision

Viewing changes to pkcs11/gck/gck-object.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-02-16 19:00:06 UTC
  • mfrom: (1.1.58 upstream)
  • Revision ID: james.westby@ubuntu.com-20100216190006-cqpnic4zxlkmmi0o
Tags: 2.29.90git20100218-0ubuntu1
Updated to a git snapshot version

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#include "pkcs11/pkcs11.h"
25
25
#include "pkcs11/pkcs11g.h"
 
26
#include "pkcs11/pkcs11i.h"
26
27
 
27
28
#include "gck-attributes.h"
 
29
#include "gck-credential.h"
28
30
#include "gck-manager.h"
29
31
#include "gck-object.h"
30
32
#include "gck-transaction.h"
43
45
};
44
46
 
45
47
enum {
 
48
        EXPOSE_OBJECT,
46
49
        NOTIFY_ATTRIBUTE,
47
50
        LAST_SIGNAL
48
51
};
50
53
static guint signals[LAST_SIGNAL] = { 0 };
51
54
 
52
55
typedef struct _GckObjectTransient {
53
 
        GckTimer *timed_timer;
54
 
        glong timed_when;
 
56
        GckTimer *timer;
 
57
        gulong timed_after;
 
58
        gulong timed_idle;
 
59
        glong stamp_used;
 
60
        glong stamp_created;
 
61
        gulong uses_remaining;
55
62
} GckObjectTransient;
56
63
 
57
64
struct _GckObjectPrivate {
60
67
        GckManager *manager;
61
68
        GckStore *store;
62
69
        gchar *unique;
 
70
        gboolean exposed;
63
71
        GckObjectTransient *transient;
64
72
};
65
73
 
66
74
G_DEFINE_TYPE (GckObject, gck_object, G_TYPE_OBJECT);
67
75
 
 
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);
 
79
 
68
80
/* -----------------------------------------------------------------------------
69
81
 * INTERNAL 
70
82
 */
71
83
 
72
84
static void
73
 
kaboom_callback (GckTimer *timer, gpointer user_data)
 
85
self_destruct (GckObject *self)
74
86
{
75
 
        GckObject *self = user_data;
76
87
        GckTransaction *transaction;
77
 
        GckObjectTransient *transient;
78
88
        CK_RV rv;
79
89
 
80
 
        g_return_if_fail (GCK_IS_OBJECT (self));
81
 
        g_return_if_fail (self->pv->transient);
82
 
        transient = self->pv->transient;
83
 
 
84
 
        g_return_if_fail (timer == transient->timed_timer);
85
 
        transient->timed_timer = NULL;
86
 
 
87
 
        g_object_ref (self);
88
 
 
89
90
        transaction = gck_transaction_new ();
90
91
 
91
 
        /* Off we go */
92
92
        gck_object_destroy (self, transaction);
93
93
 
94
94
        gck_transaction_complete (transaction);
95
95
        rv = gck_transaction_get_result (transaction);
96
96
        g_object_unref (transaction);
97
 
 
98
97
        if (rv != CKR_OK)
99
98
                g_warning ("Unexpected failure to auto destruct object (code: %lu)", (gulong)rv);
 
99
}
 
100
 
 
101
static void
 
102
timer_callback (GckTimer *timer, gpointer user_data)
 
103
{
 
104
        GckObject *self = user_data;
 
105
        glong after, idle, offset;
 
106
        GckObjectTransient *transient;
 
107
        GTimeVal tv;
 
108
 
 
109
        g_return_if_fail (GCK_IS_OBJECT (self));
 
110
 
 
111
        g_object_ref (self);
 
112
 
 
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;
 
117
 
 
118
        g_get_current_time (&tv);
 
119
        idle = after = G_MAXLONG;
 
120
 
 
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;
 
125
        }
 
126
 
 
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;
 
131
        }
 
132
 
 
133
        /* Okay, time to destroy? */
 
134
        offset = MIN (after, idle);
 
135
        if (offset <= 0)
 
136
                self_destruct (self);
 
137
 
 
138
        /* Setup the next timer */
 
139
        else
 
140
                transient->timer = gck_timer_start (self->pv->module, offset, timer_callback, self);
100
141
 
101
142
        g_object_unref (self);
102
143
}
106
147
{
107
148
        GckObject *self = GCK_OBJECT (obj);
108
149
        GckObjectTransient *transient;
 
150
        GTimeVal tv;
109
151
 
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;
113
 
 
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);
117
 
 
 
155
        g_return_val_if_fail (!transient->timer, FALSE);
 
156
 
 
157
        g_get_current_time (&tv);
 
158
        transient->stamp_created = tv.tv_sec;
 
159
        transient->stamp_used = tv.tv_sec;
 
160
 
 
161
        /* Start the timer going */
 
162
        timer_callback (NULL, self);
118
163
        return TRUE;
119
164
}
120
165
 
123
168
{
124
169
        GckObject *self = GCK_OBJECT (data);
125
170
        g_return_if_fail (self->pv->module);
126
 
        g_warning ("module destroyed before object that module contained");
 
171
        g_warning ("module destroyed before %s that module contained",
 
172
                   G_OBJECT_TYPE_NAME (self));
127
173
        self->pv->module = NULL;
128
174
}
129
175
 
134
180
        return TRUE;
135
181
}
136
182
 
 
183
static gboolean
 
184
complete_expose (GckTransaction *transaction, GObject *obj, gpointer user_data)
 
185
{
 
186
        GckObject *self = GCK_OBJECT (obj);
 
187
        gboolean expose = GPOINTER_TO_UINT (user_data);
 
188
 
 
189
        if (gck_transaction_get_failed (transaction))
 
190
                gck_object_expose (self, !expose);
 
191
 
 
192
        return TRUE;
 
193
}
 
194
 
 
195
static gboolean
 
196
find_credential (GckCredential *cred, GckObject *object, gpointer user_data)
 
197
{
 
198
        CK_OBJECT_HANDLE *result = user_data;
 
199
        g_return_val_if_fail (!*result, FALSE);
 
200
        *result = gck_object_get_handle (GCK_OBJECT (cred));
 
201
        return TRUE;
 
202
}
 
203
 
137
204
/* -----------------------------------------------------------------------------
138
205
 * OBJECT 
139
206
 */
141
208
static CK_RV 
142
209
gck_object_real_get_attribute (GckObject *self, GckSession *session, CK_ATTRIBUTE* attr)
143
210
{
 
211
        CK_OBJECT_HANDLE handle = 0;
144
212
        CK_RV rv;
145
 
        
 
213
 
146
214
        switch (attr->type)
147
215
        {
148
216
        case CKA_CLASS:
153
221
        case CKA_PRIVATE:
154
222
                return gck_attribute_set_bool (attr, FALSE);
155
223
        case CKA_TOKEN:
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);
168
243
        };
169
244
 
170
245
        /* Give store a shot */
187
262
gck_object_real_set_attribute (GckObject *self, GckSession *session,
188
263
                               GckTransaction* transaction, CK_ATTRIBUTE* attr)
189
264
{
 
265
        CK_ATTRIBUTE check;
 
266
        CK_RV rv;
 
267
 
190
268
        switch (attr->type) {
191
269
        case CKA_TOKEN:
192
270
        case CKA_PRIVATE:
214
292
                return;
215
293
        }       
216
294
 
217
 
        gck_transaction_fail (transaction, CKR_ATTRIBUTE_TYPE_INVALID);
 
295
        /* Check if this attribute exists */
 
296
        check.type = attr->type;
 
297
        check.pValue = 0;
 
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);
 
302
        else
 
303
                gck_transaction_fail (transaction, CKR_ATTRIBUTE_READ_ONLY);
218
304
}
219
305
 
220
306
static void
222
308
                                   GckTransaction *transaction, CK_ATTRIBUTE *attrs, CK_ULONG n_attrs)
223
309
{
224
310
        CK_ATTRIBUTE_PTR transient_attr;
225
 
        CK_ATTRIBUTE_PTR lifetime_attr;
226
311
        gboolean transient = FALSE;
227
 
        glong lifetime = -1;
 
312
        gulong after = 0;
 
313
        gulong idle = 0;
228
314
        CK_RV rv;
229
315
 
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);
237
322
                        return;
239
324
        }
240
325
 
241
326
        /* Parse the auto destruct attribute */
242
 
        lifetime_attr = gck_attributes_find (attrs, n_attrs, CKA_GNOME_AUTO_DESTRUCT);
243
 
        if (lifetime_attr) {
244
 
                rv = gck_attribute_get_time (lifetime_attr, &lifetime);
245
 
                gck_attribute_consume (lifetime_attr);
246
 
                if (rv != CKR_OK) {
247
 
                        gck_transaction_fail (transaction, rv);
248
 
                        return;
249
 
                }
250
 
                
251
 
                /* Default for the transient attribute */
252
 
                if (!transient_attr)
253
 
                        transient = TRUE;
254
 
        }
 
327
        if (!gck_attributes_find_ulong (attrs, n_attrs, CKA_G_DESTRUCT_AFTER, &after))
 
328
                after = 0;
 
329
        if (!gck_attributes_find_ulong (attrs, n_attrs, CKA_G_DESTRUCT_IDLE, &idle))
 
330
                idle = 0;
 
331
        /* Default for the transient attribute */
 
332
        if (!transient_attr && (idle || after))
 
333
                transient = TRUE;
 
334
 
 
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);
255
338
 
256
339
        if (transient) {
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;
259
343
        }
260
344
 
261
 
        if (lifetime >= 0) {
 
345
        if (after || idle) {
262
346
                if (!self->pv->transient) {
263
347
                        gck_transaction_fail (transaction, CKR_TEMPLATE_INCONSISTENT);
264
348
                        return;
269
353
}
270
354
 
271
355
static CK_RV
272
 
gck_object_real_unlock (GckObject *self, GckAuthenticator *auth)
 
356
gck_object_real_unlock (GckObject *self, GckCredential *cred)
273
357
{
274
358
        /* A derived class should have overridden this */
275
359
        return CKR_FUNCTION_FAILED;
276
360
}
277
361
 
 
362
static void
 
363
gck_object_real_expose_object (GckObject *self, gboolean expose)
 
364
{
 
365
        g_return_if_fail (expose != self->pv->exposed);
 
366
        g_return_if_fail (self->pv->manager);
 
367
 
 
368
        self->pv->exposed = expose;
 
369
        if (expose)
 
370
                _gck_manager_register_object (self->pv->manager, self);
 
371
        else
 
372
                _gck_manager_unregister_object (self->pv->manager, self);
 
373
}
 
374
 
278
375
static GObject* 
279
376
gck_object_constructor (GType type, guint n_props, GObjectConstructParam *props) 
280
377
{
299
396
        GckObject *self = GCK_OBJECT (obj);
300
397
        GckObjectTransient *transient;
301
398
        
302
 
        if (self->pv->manager)
303
 
                gck_manager_unregister_object (self->pv->manager, self);
304
 
        g_assert (self->pv->manager == NULL);
305
 
        
 
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;
 
406
        }
 
407
 
306
408
        g_object_set (self, "store", NULL, NULL);
307
409
        g_assert (self->pv->store == NULL);
308
410
 
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;
 
416
        }
314
417
 
315
 
                g_slice_free (GckObjectTransient, transient);
316
 
                self->pv->transient = NULL;
317
 
        }
318
 
    
319
418
        G_OBJECT_CLASS (gck_object_parent_class)->dispose (obj);
320
419
}
321
420
 
331
430
        g_object_weak_unref (G_OBJECT (self->pv->module), module_went_away, self);
332
431
        self->pv->module = NULL;
333
432
 
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;
 
436
        }
335
437
 
336
438
        G_OBJECT_CLASS (gck_object_parent_class)->finalize (obj);
337
439
}
341
443
                           GParamSpec *pspec)
342
444
{
343
445
        GckObject *self = GCK_OBJECT (obj);
344
 
        GckManager *manager;
345
446
        GckStore *store;
346
447
        
347
448
        switch (prop_id) {
355
456
                g_object_weak_ref (G_OBJECT (self->pv->module), module_went_away, self);
356
457
                break;
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));
363
 
                }
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));
368
 
                
369
 
                g_object_notify (G_OBJECT (self), "manager");
 
464
                }
370
465
                break;
371
466
        case PROP_STORE:
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;
442
537
        
 
538
        klass->expose_object = gck_object_real_expose_object;
 
539
 
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));
450
547
        
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));
454
551
        
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));
462
559
        
 
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);
 
564
 
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, 
483
585
gck_object_set_attribute (GckObject *self, GckSession *session,
484
586
                          GckTransaction *transaction, CK_ATTRIBUTE_PTR attr)
485
587
{
486
 
        CK_ATTRIBUTE check;
487
 
        CK_RV rv;
488
 
        
489
588
        g_return_if_fail (GCK_IS_OBJECT (self));
490
589
        g_return_if_fail (GCK_IS_TRANSACTION (transaction));
491
590
        g_return_if_fail (!gck_transaction_get_failed (transaction));
493
592
 
494
593
        g_assert (GCK_OBJECT_GET_CLASS (self)->set_attribute);
495
594
 
496
 
        /* Check if this attribute exists */
497
 
        check.type = attr->type;
498
 
        check.pValue = 0;
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);
503
 
                return;
504
 
        }
505
 
        
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);
509
598
}
510
599
 
615
704
}
616
705
 
617
706
gboolean
618
 
gck_object_get_transient (GckObject *self)
 
707
gck_object_is_token (GckObject *self)
 
708
{
 
709
        g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
 
710
        if (!self->pv->manager)
 
711
                return FALSE;
 
712
        return gck_manager_get_for_token (self->pv->manager);
 
713
}
 
714
 
 
715
gboolean
 
716
gck_object_is_transient (GckObject *self)
619
717
{
620
718
        g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
621
719
        return self->pv->transient ? TRUE : FALSE;
622
720
}
623
721
 
 
722
void
 
723
gck_object_mark_used (GckObject *self)
 
724
{
 
725
        GckObjectTransient *transient;
 
726
        GTimeVal tv;
 
727
 
 
728
        g_return_if_fail (GCK_IS_OBJECT (self));
 
729
        transient = self->pv->transient;
 
730
 
 
731
        if (transient) {
 
732
                if (transient->timed_idle) {
 
733
                        g_get_current_time (&tv);
 
734
                        transient->stamp_used = tv.tv_sec;
 
735
                }
 
736
                if (transient->uses_remaining) {
 
737
                        --(transient->uses_remaining);
 
738
                        if (transient->uses_remaining == 0)
 
739
                                self_destruct (self);
 
740
                }
 
741
        }
 
742
}
624
743
 
625
744
CK_RV
626
 
gck_object_unlock (GckObject *self, GckAuthenticator *auth)
 
745
gck_object_unlock (GckObject *self, GckCredential *cred)
627
746
{
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);
631
750
}
632
751
 
633
752
 
703
822
        return attr.pValue;
704
823
}
705
824
 
 
825
gboolean
 
826
gck_object_has_attribute_ulong (GckObject *self, GckSession *session,
 
827
                                CK_ATTRIBUTE_TYPE type, gulong value)
 
828
{
 
829
        gulong *data;
 
830
        gsize n_data, i;
 
831
 
 
832
        g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
 
833
        g_return_val_if_fail (GCK_IS_SESSION (session), FALSE);
 
834
 
 
835
        data = gck_object_get_attribute_data (self, session, type, &n_data);
 
836
        if (data == NULL)
 
837
                return FALSE;
 
838
 
 
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) {
 
842
                        g_free (data);
 
843
                        return TRUE;
 
844
                }
 
845
        }
 
846
 
 
847
        g_free (data);
 
848
        return FALSE;
 
849
}
 
850
 
 
851
gboolean
 
852
gck_object_has_attribute_boolean (GckObject *self, GckSession *session,
 
853
                                  CK_ATTRIBUTE_TYPE type, gboolean value)
 
854
{
 
855
        gboolean data;
 
856
 
 
857
        g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
 
858
        g_return_val_if_fail (GCK_IS_SESSION (session), FALSE);
 
859
 
 
860
        if (!gck_object_get_attribute_boolean (self, session, type, &data))
 
861
                return FALSE;
 
862
        return data == value;
 
863
}
 
864
 
706
865
void
707
866
gck_object_destroy (GckObject *self, GckTransaction *transaction)
708
867
{
732
891
 
733
892
        g_object_unref (self);
734
893
}
 
894
 
 
895
gboolean
 
896
gck_object_is_exposed (GckObject *self)
 
897
{
 
898
        g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
 
899
        return self->pv->exposed;
 
900
}
 
901
 
 
902
void
 
903
gck_object_expose (GckObject *self, gboolean expose)
 
904
{
 
905
        if (!expose && !self)
 
906
                return;
 
907
 
 
908
        g_return_if_fail (GCK_IS_OBJECT (self));
 
909
 
 
910
        if (self->pv->exposed != expose)
 
911
                g_signal_emit (self, signals[EXPOSE_OBJECT], 0, expose);
 
912
}
 
913
 
 
914
void
 
915
gck_object_expose_full (GckObject *self, GckTransaction *transaction, gboolean expose)
 
916
{
 
917
        if (!expose && !self)
 
918
                return;
 
919
 
 
920
        g_return_if_fail (GCK_IS_OBJECT (self));
 
921
        g_return_if_fail (!transaction || !gck_transaction_get_failed (transaction));
 
922
 
 
923
        if (self->pv->exposed != expose) {
 
924
                if (transaction)
 
925
                        gck_transaction_add (transaction, self, complete_expose, GUINT_TO_POINTER (expose));
 
926
                gck_object_expose (self, expose);
 
927
        }
 
928
}