static gchar * object_path_for_item (const gchar *base, GckObject *item) { GError *error = NULL; gpointer identifier; gsize n_identifier; gchar *alloc = NULL; gchar *path = NULL; if (base == NULL) base = alloc = collection_path_for_item (item); identifier = gck_object_get_data (item, CKA_ID, NULL, &n_identifier, &error); if (identifier == NULL) { g_warning ("couldn't get item identifier: %s", egg_error_message (error)); g_clear_error (&error); path = NULL; } else { path = gkd_secret_util_build_path (base, identifier, n_identifier); g_free (identifier); } g_free (alloc); return path; }
static void item_cleanup_search_results (GckSession *session, GList *items, GList **locked, GList **unlocked) { GError *error = NULL; gpointer value; gsize n_value; GList *l; *locked = NULL; *unlocked = NULL; for (l = items; l; l = g_list_next (l)) { value = gck_object_get_data (l->data, CKA_G_LOCKED, NULL, &n_value, &error); if (value == NULL) { if (!g_error_matches (error, GCK_ERROR, CKR_OBJECT_HANDLE_INVALID)) g_warning ("couldn't check if item is locked: %s", egg_error_message (error)); g_clear_error (&error); /* Is not locked */ } if (n_value == 1 && *((CK_BBOOL*)value) == CK_FALSE) { *unlocked = g_list_prepend (*unlocked, l->data); /* Is locked */ } else { *locked = g_list_prepend (*locked, l->data); } g_free (value); } *locked = g_list_reverse (*locked); *unlocked = g_list_reverse (*unlocked); }
gchar* gkd_secret_create_with_secret (GckAttributes *attrs, GkdSecretSecret *master, DBusError *derr) { GckAttributes *atts; GckObject *cred; GckObject *collection; GckSession *session; GError *error = NULL; gpointer identifier; gsize n_identifier; gboolean token; gchar *path; if (!gck_attributes_find_boolean (attrs, CKA_TOKEN, &token)) token = FALSE; atts = gck_attributes_new (); gck_attributes_add_ulong (atts, CKA_CLASS, CKO_G_CREDENTIAL); gck_attributes_add_boolean (atts, CKA_MATE_TRANSIENT, TRUE); gck_attributes_add_boolean (atts, CKA_TOKEN, token); session = gkd_secret_session_get_pkcs11_session (master->session); g_return_val_if_fail (session, NULL); /* Create ourselves some credentials */ cred = gkd_secret_session_create_credential (master->session, session, atts, master, derr); gck_attributes_unref (atts); if (cred == NULL) return FALSE; collection = gkd_secret_create_with_credential (session, attrs, cred, &error); gck_attributes_unref (atts); g_object_unref (cred); if (collection == NULL) { g_warning ("couldn't create collection: %s", egg_error_message (error)); g_clear_error (&error); dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't create new collection"); return FALSE; } identifier = gck_object_get_data (collection, CKA_ID, NULL, &n_identifier, &error); g_object_unref (collection); if (!identifier) { g_warning ("couldn't lookup new collection identifier: %s", egg_error_message (error)); g_clear_error (&error); dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't find new collection just created"); return FALSE; } path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier); g_free (identifier); return path; }
void gkd_secret_objects_foreach_collection (GkdSecretObjects *self, const gchar *caller, GkdSecretObjectsForeach callback, gpointer user_data) { GckBuilder builder = GCK_BUILDER_INIT; GckSession *session; GError *error = NULL; GList *collections, *l; gpointer identifier; gsize n_identifier; gchar *path; g_return_if_fail (GKD_SECRET_IS_OBJECTS (self)); g_return_if_fail (callback); /* The session we're using to access the object */ if (caller == NULL) { session = gkd_secret_service_internal_pkcs11_session (self->service); } else { session = gkd_secret_service_get_pkcs11_session (self->service, caller); } gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_COLLECTION); collections = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error); if (error != NULL) { g_warning ("couldn't lookup collections: %s", egg_error_message (error)); g_clear_error (&error); return; } for (l = collections; l; l = g_list_next (l)) { identifier = gck_object_get_data (l->data, CKA_ID, NULL, &n_identifier, &error); if (identifier == NULL) { g_warning ("couldn't get collection identifier: %s", egg_error_message (error)); g_clear_error (&error); continue; } path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier); g_free (identifier); (callback) (self, path, l->data, user_data); g_free (path); } gck_list_unref_free (collections); }
gchar* gkd_secret_create_with_secret (GckAttributes *attrs, GkdSecretSecret *master, GError **error) { GckBuilder builder = GCK_BUILDER_INIT; GckAttributes *atts; GckObject *cred; GckObject *collection; GckSession *session; gpointer identifier; gsize n_identifier; gboolean token; gchar *path; if (!gck_attributes_find_boolean (attrs, CKA_TOKEN, &token)) token = FALSE; gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_CREDENTIAL); gck_builder_add_boolean (&builder, CKA_GNOME_TRANSIENT, TRUE); gck_builder_add_boolean (&builder, CKA_TOKEN, token); session = gkd_secret_session_get_pkcs11_session (master->session); g_return_val_if_fail (session, NULL); /* Create ourselves some credentials */ atts = gck_attributes_ref_sink (gck_builder_end (&builder)); cred = gkd_secret_session_create_credential (master->session, session, atts, master, error); gck_attributes_unref (atts); if (cred == NULL) return FALSE; collection = gkd_secret_create_with_credential (session, attrs, cred, error); g_object_unref (cred); if (collection == NULL) return FALSE; identifier = gck_object_get_data (collection, CKA_ID, NULL, &n_identifier, error); g_object_unref (collection); if (!identifier) return FALSE; path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier); g_free (identifier); return path; }
static gchar * collection_path_for_item (GckObject *item) { GError *error = NULL; gpointer identifier; gsize n_identifier; gchar *path = NULL; identifier = gck_object_get_data (item, CKA_G_COLLECTION, NULL, &n_identifier, &error); if (!identifier) { g_warning ("couldn't get item collection identifier: %s", egg_error_message (error)); g_clear_error (&error); return NULL; } path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier); g_free (identifier); return path; }
static gchar * object_path_for_collection (GckObject *collection) { GError *error = NULL; gpointer identifier; gsize n_identifier; gchar *path = NULL; identifier = gck_object_get_data (collection, CKA_ID, NULL, &n_identifier, &error); if (identifier == NULL) { g_warning ("couldn't get collection identifier: %s", egg_error_message (error)); g_clear_error (&error); path = NULL; } else { path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier); g_free (identifier); } return path; }
static GckObject* collection_find_matching_item (GkdSecretObjects *self, GckSession *session, const gchar *identifier, const GckAttribute *fields) { GckBuilder builder = GCK_BUILDER_INIT; GckObject *result = NULL; GError *error = NULL; GckObject *search; gpointer data; gsize n_data; /* Find items matching the collection and fields */ gck_builder_add_attribute (&builder, fields); gck_builder_add_string (&builder, CKA_G_COLLECTION, identifier); gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_SEARCH); gck_builder_add_boolean (&builder, CKA_TOKEN, FALSE); /* Create the search object */ search = gck_session_create_object (session, gck_builder_end (&builder), NULL, &error); if (error != NULL) { g_warning ("couldn't search for matching item: %s", egg_error_message (error)); g_clear_error (&error); return NULL; } /* Get the matched item handles, and delete the search object */ data = gck_object_get_data (search, CKA_G_MATCHED, NULL, &n_data, NULL); gck_object_destroy (search, NULL, NULL); g_object_unref (search); if (n_data >= sizeof (CK_OBJECT_HANDLE)) result = gck_object_from_handle (session, *((CK_OBJECT_HANDLE_PTR)data)); g_free (data); return result; }
static GVariant * object_property_get (GkdSecretObjects *objects, GckObject *object, const gchar *prop_name, GError **error_out) { GError *error = NULL; GckAttribute attr; gpointer value; gsize length; GVariant *res; if (!gkd_secret_property_get_type (prop_name, &attr.type)) { g_set_error (error_out, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_PROPERTY, "Object does not have the '%s' property", prop_name); return NULL; } /* Retrieve the actual attribute */ attr.value = value = gck_object_get_data (object, attr.type, NULL, &length, &error); if (error != NULL) { g_set_error (error_out, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Couldn't retrieve '%s' property: %s", prop_name, egg_error_message (error)); g_clear_error (&error); return NULL; } /* Marshall the data back out */ attr.length = length; res = gkd_secret_property_append_variant (&attr); g_free (value); return res; }
gboolean gkd_secret_objects_handle_search_items (GkdSecretObjects *self, GDBusMethodInvocation *invocation, GVariant *attributes, const gchar *base, gboolean separate_locked) { GckBuilder builder = GCK_BUILDER_INIT; GckObject *search; GckSession *session; GError *error = NULL; gchar *identifier; gpointer data; gsize n_data; GList *locked, *unlocked; GList *items; GVariantBuilder result; if (!gkd_secret_property_parse_fields (attributes, &builder)) { gck_builder_clear (&builder); g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Invalid data in attributes argument"); return TRUE; } if (base != NULL) { if (!gkd_secret_util_parse_path (base, &identifier, NULL)) g_return_val_if_reached (FALSE); gck_builder_add_string (&builder, CKA_G_COLLECTION, identifier); g_free (identifier); } gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_SEARCH); gck_builder_add_boolean (&builder, CKA_TOKEN, FALSE); /* The session we're using to access the object */ session = gkd_secret_service_get_pkcs11_session (self->service, g_dbus_method_invocation_get_sender (invocation)); g_return_val_if_fail (session, FALSE); /* Create the search object */ search = gck_session_create_object (session, gck_builder_end (&builder), NULL, &error); if (error != NULL) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Couldn't search for items: %s", egg_error_message (error)); g_clear_error (&error); return TRUE; } /* Get the matched item handles, and delete the search object */ data = gck_object_get_data (search, CKA_G_MATCHED, NULL, &n_data, &error); gck_object_destroy (search, NULL, NULL); g_object_unref (search); if (error != NULL) { g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Couldn't retrieve matched items: %s", egg_error_message (error)); g_clear_error (&error); return TRUE; } /* Build a list of object handles */ items = gck_objects_from_handle_array (session, data, n_data / sizeof (CK_OBJECT_HANDLE)); g_free (data); /* Filter out the locked items */ if (separate_locked) { GVariant *unlocked_variant, *locked_variant; item_cleanup_search_results (session, items, &locked, &unlocked); g_variant_builder_init (&result, G_VARIANT_TYPE ("ao")); objects_foreach_item (self, unlocked, NULL, on_object_path_append_to_builder, &result); unlocked_variant = g_variant_builder_end (&result); g_variant_builder_init (&result, G_VARIANT_TYPE ("ao")); objects_foreach_item (self, locked, NULL, on_object_path_append_to_builder, &result); locked_variant = g_variant_builder_end (&result); g_list_free (locked); g_list_free (unlocked); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@ao@ao)", unlocked_variant, locked_variant)); } else { g_variant_builder_init (&result, G_VARIANT_TYPE ("ao")); objects_foreach_item (self, items, NULL, on_object_path_append_to_builder, &result); g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@ao)", g_variant_builder_end (&result))); } gck_list_unref_free (items); return TRUE; }