GNode * _gcr_subject_public_key_load_finish (GAsyncResult *result, GError **error) { GckAttributes *attributes; GSimpleAsyncResult *res; LoadClosure *closure; GNode *asn; g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, _gcr_subject_public_key_load_async), NULL); res = G_SIMPLE_ASYNC_RESULT (result); if (g_simple_async_result_propagate_error (res, error)) return NULL; closure = g_simple_async_result_get_op_res_gpointer (res); attributes = gck_attributes_ref_sink (gck_builder_end (&closure->builder)); asn = _gcr_subject_public_key_for_attributes (attributes); if (asn == NULL) { g_set_error_literal (error, GCK_ERROR, CKR_TEMPLATE_INCONSISTENT, _("Couldn't build public key")); } gck_attributes_unref (attributes); return asn; }
static gboolean service_method_create_with_master_password (GkdExportedInternal *skeleton, GDBusMethodInvocation *invocation, GVariant *attributes, GVariant *master, GkdSecretService *self) { GckBuilder builder = GCK_BUILDER_INIT; GkdSecretSecret *secret = NULL; GckAttributes *attrs = NULL; GError *error = NULL; gchar *path; const gchar *caller; if (!gkd_secret_property_parse_all (attributes, SECRET_COLLECTION_INTERFACE, &builder)) { gck_builder_clear (&builder); g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid properties argument"); return TRUE; } caller = g_dbus_method_invocation_get_sender (invocation); secret = gkd_secret_secret_parse (self, caller, master, &error); if (secret == NULL) { gck_builder_clear (&builder); g_dbus_method_invocation_take_error (invocation, error); return TRUE; } gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE); attrs = gck_attributes_ref_sink (gck_builder_end (&builder)); path = gkd_secret_create_with_secret (attrs, secret, &error); gck_attributes_unref (attrs); gkd_secret_secret_free (secret); if (path == NULL) { gkd_secret_propagate_error (invocation, "Couldn't create collection", error); return TRUE; } /* Notify the callers that a collection was created */ g_message ("emit collection_Created"); gkd_secret_service_emit_collection_created (self, path); gkd_exported_internal_complete_create_with_master_password (skeleton, invocation, path); g_free (path); return TRUE; }
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 gboolean service_method_create_collection (GkdExportedService *skeleton, GDBusMethodInvocation *invocation, GVariant *properties, gchar *alias, GkdSecretService *self) { GckBuilder builder = GCK_BUILDER_INIT; GckAttributes *attrs; GkdSecretCreate *create; const gchar *path; const char *caller; if (!gkd_secret_property_parse_all (properties, SECRET_COLLECTION_INTERFACE, &builder)) { gck_builder_clear (&builder); g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid properties"); return TRUE; } /* Empty alias is no alias */ if (alias) { if (!alias[0]) { alias = NULL; } else if (!g_str_equal (alias, "default")) { gck_builder_clear (&builder); g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "Only the 'default' alias is supported"); return TRUE; } } gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE); attrs = gck_attributes_ref_sink (gck_builder_end (&builder)); /* Create the prompt object, for the password */ caller = g_dbus_method_invocation_get_sender (invocation); create = gkd_secret_create_new (self, caller, attrs, alias); gck_attributes_unref (attrs); path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (create)); gkd_secret_service_publish_dispatch (self, caller, GKD_SECRET_DISPATCH (create)); gkd_exported_service_complete_create_collection (skeleton, invocation, "/", path); return TRUE; }
/** * gcr_importer_register: * @importer_type: the GType of the importer being registered * @attrs: the attributes that this importer is compatible with * * Register an importer to handle parsed items that match the given attributes. * * If @attrs are a floating reference, then it is consumed. */ void gcr_importer_register (GType importer_type, GckAttributes *attrs) { GcrRegistered registered; if (!registered_importers) registered_importers = g_array_new (FALSE, FALSE, sizeof (GcrRegistered)); registered.importer_type = importer_type; registered.attrs = gck_attributes_ref_sink (attrs); g_array_append_val (registered_importers, registered); registered_sorted = FALSE; }
static DBusMessage* service_method_create_with_master_password (GkdSecretService *self, DBusMessage *message) { GckBuilder builder = GCK_BUILDER_INIT; DBusError derr = DBUS_ERROR_INIT; DBusMessageIter iter, array; DBusMessage *reply = NULL; GkdSecretSecret *secret = NULL; GckAttributes *attrs = NULL; GError *error = NULL; gchar *path; /* Parse the incoming message */ if (!dbus_message_has_signature (message, "a{sv}(oayays)")) return NULL; if (!dbus_message_iter_init (message, &iter)) g_return_val_if_reached (NULL); dbus_message_iter_recurse (&iter, &array); if (!gkd_secret_property_parse_all (&array, SECRET_COLLECTION_INTERFACE, &builder)) { gck_builder_clear (&builder); return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS, "Invalid properties argument"); } dbus_message_iter_next (&iter); secret = gkd_secret_secret_parse (self, message, &iter, &derr); if (secret == NULL) { gck_builder_clear (&builder); return gkd_secret_error_to_reply (message, &derr); } gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE); attrs = gck_attributes_ref_sink (gck_builder_end (&builder)); path = gkd_secret_create_with_secret (attrs, secret, &error); gck_attributes_unref (attrs); gkd_secret_secret_free (secret); if (path == NULL) return gkd_secret_propagate_error (message, "Couldn't create collection", error); /* Notify the callers that a collection was created */ gkd_secret_service_emit_collection_created (self, path); reply = dbus_message_new_method_return (message); dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); g_free (path); return reply; }
static gboolean collection_method_create_item (GkdExportedCollection *skeleton, GDBusMethodInvocation *invocation, GVariant *properties, GVariant *secret_variant, gboolean replace, GkdSecretObjects *self) { GckBuilder builder = GCK_BUILDER_INIT; GckSession *pkcs11_session = NULL; GkdSecretSecret *secret = NULL; GckAttributes *attrs = NULL; const GckAttribute *fields; GckObject *item = NULL; const gchar *base; GError *error = NULL; gchar *path = NULL; gchar *identifier; gboolean created = FALSE; GckObject *object; object = secret_objects_lookup_gck_object_for_invocation (self, invocation); if (!object) { return TRUE; } if (!gkd_secret_property_parse_all (properties, SECRET_ITEM_INTERFACE, &builder)) { g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid properties argument"); goto cleanup; } base = g_dbus_method_invocation_get_object_path (invocation); secret = gkd_secret_secret_parse (self->service, g_dbus_method_invocation_get_sender (invocation), secret_variant, &error); if (secret == NULL) { g_dbus_method_invocation_take_error (invocation, error); error = NULL; goto cleanup; } if (!gkd_secret_util_parse_path (base, &identifier, NULL)) g_return_val_if_reached (FALSE); g_return_val_if_fail (identifier, FALSE); pkcs11_session = gck_object_get_session (object); g_return_val_if_fail (pkcs11_session, FALSE); attrs = gck_attributes_ref_sink (gck_builder_end (&builder)); if (replace) { fields = gck_attributes_find (attrs, CKA_G_FIELDS); if (fields) item = collection_find_matching_item (self, pkcs11_session, identifier, fields); } /* Replace the item */ if (item) { if (!gck_object_set (item, attrs, NULL, &error)) goto cleanup; /* Create a new item */ } else { gck_builder_add_all (&builder, attrs); gck_builder_add_string (&builder, CKA_G_COLLECTION, identifier); gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY); item = gck_session_create_object (pkcs11_session, gck_builder_end (&builder), NULL, &error); if (item == NULL) goto cleanup; created = TRUE; } /* Set the secret */ if (!gkd_secret_session_set_item_secret (secret->session, item, secret, &error)) { if (created) /* If we created, then try to destroy on failure */ gck_object_destroy (item, NULL, NULL); goto cleanup; } path = object_path_for_item (base, item); gkd_secret_objects_emit_item_created (self, object, path); gkd_exported_collection_complete_create_item (skeleton, invocation, path, "/"); cleanup: if (error) { if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN)) g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR, GKD_SECRET_ERROR_IS_LOCKED, "Cannot create an item in a locked collection"); else g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Couldn't create item: %s", egg_error_message (error)); g_clear_error (&error); } gkd_secret_secret_free (secret); gck_attributes_unref (attrs); if (item) g_object_unref (item); if (pkcs11_session) g_object_unref (pkcs11_session); g_free (path); g_object_unref (object); return TRUE; }
static DBusMessage* service_method_create_collection (GkdSecretService *self, DBusMessage *message) { GckBuilder builder = GCK_BUILDER_INIT; DBusMessageIter iter, array; GckAttributes *attrs; GkdSecretCreate *create; DBusMessage *reply; const gchar *path; const gchar *alias; const char *caller; const gchar *coll; /* Parse the incoming message */ if (!dbus_message_has_signature (message, "a{sv}s")) return NULL; if (!dbus_message_iter_init (message, &iter)) g_return_val_if_reached (NULL); dbus_message_iter_recurse (&iter, &array); if (!gkd_secret_property_parse_all (&array, SECRET_COLLECTION_INTERFACE, &builder)) { gck_builder_clear (&builder); return dbus_message_new_error_printf (message, DBUS_ERROR_INVALID_ARGS, "Invalid properties"); } if (!dbus_message_iter_next (&iter)) g_return_val_if_reached (NULL); dbus_message_iter_get_basic (&iter, &alias); /* Empty alias is no alias */ if (alias) { if (!alias[0]) { alias = NULL; } else if (!g_str_equal (alias, "default")) { gck_builder_clear (&builder); return dbus_message_new_error (message, DBUS_ERROR_NOT_SUPPORTED, "Only the 'default' alias is supported"); } } gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE); attrs = gck_attributes_ref_sink (gck_builder_end (&builder)); /* Create the prompt object, for the password */ caller = dbus_message_get_sender (message); create = gkd_secret_create_new (self, caller, attrs, alias); gck_attributes_unref (attrs); path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (create)); gkd_secret_service_publish_dispatch (self, caller, GKD_SECRET_DISPATCH (create)); coll = "/"; reply = dbus_message_new_method_return (message); dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &coll, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); g_object_unref (create); return reply; }