gboolean gkm_object_has_attribute_boolean (GkmObject *self, GkmSession *session, CK_ATTRIBUTE_TYPE type, gboolean value) { gboolean data; g_return_val_if_fail (GKM_IS_OBJECT (self), FALSE); g_return_val_if_fail (GKM_IS_SESSION (session), FALSE); if (!gkm_object_get_attribute_boolean (self, session, type, &data)) return FALSE; return data == value; }
void gkm_mate2_storage_create (GkmMate2Storage *self, GkmTransaction *transaction, GkmObject *object) { gboolean is_private; GkmDataResult res; gchar *identifier; gpointer data; gsize n_data; gchar *path; g_return_if_fail (GKM_IS_MATE2_STORAGE (self)); g_return_if_fail (GKM_IS_TRANSACTION (transaction)); g_return_if_fail (!gkm_transaction_get_failed (transaction)); g_return_if_fail (GKM_IS_OBJECT (object)); /* Make sure we haven't already stored it */ identifier = g_hash_table_lookup (self->object_to_identifier, object); g_return_if_fail (identifier == NULL); /* Double check that the object is in fact serializable */ if (!GKM_IS_SERIALIZABLE (object)) { g_warning ("can't store object of type '%s' on token", G_OBJECT_TYPE_NAME (object)); gkm_transaction_fail (transaction, CKR_GENERAL_ERROR); g_return_if_reached (); } /* Figure out whether this is a private object */ if (!gkm_object_get_attribute_boolean (object, NULL, CKA_PRIVATE, &is_private)) is_private = FALSE; /* Can't serialize private if we're not unlocked */ if (is_private && !self->login) { gkm_transaction_fail (transaction, CKR_USER_NOT_LOGGED_IN); return; } /* Hook ourselves into the transaction */ if (!begin_modification_state (self, transaction)) return; /* Create an identifier guaranteed unique by this transaction */ identifier = identifier_for_object (object); if (gkm_mate2_file_unique_entry (self->file, &identifier) != GKM_DATA_SUCCESS) { gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED); g_return_if_reached (); } /* We don't want to get signals about this item being added */ g_signal_handlers_block_by_func (self->file, data_file_entry_added, self); g_signal_handlers_block_by_func (self->file, data_file_entry_changed, self); res = gkm_mate2_file_create_entry (self->file, identifier, is_private ? GKM_MATE2_FILE_SECTION_PRIVATE : GKM_MATE2_FILE_SECTION_PUBLIC); g_signal_handlers_unblock_by_func (self->file, data_file_entry_added, self); g_signal_handlers_unblock_by_func (self->file, data_file_entry_changed, self); switch(res) { case GKM_DATA_FAILURE: case GKM_DATA_UNRECOGNIZED: g_free (identifier); gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED); return; case GKM_DATA_LOCKED: g_free (identifier); gkm_transaction_fail (transaction, CKR_USER_NOT_LOGGED_IN); return; case GKM_DATA_SUCCESS: break; default: g_assert_not_reached (); } /* Serialize the object in question */ if (!gkm_serializable_save (GKM_SERIALIZABLE (object), is_private ? self->login : NULL, &data, &n_data)) { gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED); g_return_if_reached (); } path = g_build_filename (self->directory, identifier, NULL); gkm_transaction_write_file (transaction, path, data, n_data); /* Make sure we write in the object hash */ if (!gkm_transaction_get_failed (transaction)) store_object_hash (self, transaction, identifier, data, n_data); /* Now we decide to own the object */ if (!gkm_transaction_get_failed (transaction)) take_object_ownership (self, identifier, object); g_free (identifier); g_free (path); g_free (data); }