static gboolean service_method_change_with_master_password (GkdExportedInternal *skeleton, GDBusMethodInvocation *invocation, gchar *path, GVariant *original_variant, GVariant *master_variant, GkdSecretService *self) { GkdSecretSecret *original, *master; GckObject *collection; GError *error = NULL; const gchar *sender; sender = g_dbus_method_invocation_get_sender (invocation); /* Parse the incoming message */ original = gkd_secret_secret_parse (self, sender, original_variant, &error); if (original == NULL) { g_dbus_method_invocation_take_error (invocation, error); return TRUE; } master = gkd_secret_secret_parse (self, sender, master_variant, &error); if (master == NULL) { g_dbus_method_invocation_take_error (invocation, error); return TRUE; } /* Make sure we have such a collection */ collection = gkd_secret_objects_lookup_collection (self->objects, sender, path); /* No such collection */ if (collection == NULL) { g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR, GKD_SECRET_ERROR_NO_SUCH_OBJECT, "The collection does not exist"); } /* Success */ else if (gkd_secret_change_with_secrets (collection, NULL, original, master, &error)) gkd_exported_internal_complete_change_with_master_password (skeleton, invocation); /* Failure */ else gkd_secret_propagate_error (invocation, "Couldn't change collection password", error); gkd_secret_secret_free (original); gkd_secret_secret_free (master); if (collection) g_object_unref (collection); return TRUE; }
static DBusMessage* service_method_change_with_master_password (GkdSecretService *self, DBusMessage *message) { DBusError derr = DBUS_ERROR_INIT; GkdSecretSecret *original, *master; GckObject *collection; DBusMessageIter iter; DBusMessage *reply; GError *error = NULL; const gchar *path; /* Parse the incoming message */ if (!dbus_message_has_signature (message, "o(oayays)(oayays)")) return NULL; if (!dbus_message_iter_init (message, &iter)) g_return_val_if_reached (NULL); dbus_message_iter_get_basic (&iter, &path); dbus_message_iter_next (&iter); original = gkd_secret_secret_parse (self, message, &iter, &derr); if (original == NULL) return gkd_secret_error_to_reply (message, &derr); dbus_message_iter_next (&iter); master = gkd_secret_secret_parse (self, message, &iter, &derr); if (master == NULL) { gkd_secret_secret_free (original); return gkd_secret_error_to_reply (message, &derr); } /* Make sure we have such a collection */ collection = gkd_secret_objects_lookup_collection (self->objects, dbus_message_get_sender (message), path); /* No such collection */ if (collection == NULL) reply = dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT, "The collection does not exist"); /* Success */ else if (gkd_secret_change_with_secrets (collection, NULL, original, master, &error)) reply = dbus_message_new_method_return (message); /* Failure */ else reply = gkd_secret_propagate_error (message, "Couldn't change collection password", error); gkd_secret_secret_free (original); gkd_secret_secret_free (master); if (collection) g_object_unref (collection); return reply; }
static void gkd_secret_create_prompt_ready (GkdSecretPrompt *prompt) { GkdSecretCreate *self = GKD_SECRET_CREATE (prompt); GkdSecretSecret *master; if (!gku_prompt_has_response (GKU_PROMPT (prompt))) { /* Does the alias exist? */ if (locate_alias_collection_if_exists (self)) unlock_or_complete_this_prompt (self); /* Otherwise we're going to prompt */ else prepare_create_prompt (self); return; } /* Already prompted, create collection */ g_return_if_fail (gku_prompt_get_response (GKU_PROMPT (prompt)) == GKU_RESPONSE_OK); master = gkd_secret_prompt_get_secret (prompt, "password"); if (master && create_collection_with_secret (self, master)) gkd_secret_prompt_complete (prompt); else gkd_secret_prompt_dismiss (prompt); gkd_secret_secret_free (master); }
gboolean gkd_secret_objects_handle_get_secrets (GkdSecretObjects *self, GDBusMethodInvocation *invocation, const gchar **paths, const gchar *session_path) { GkdSecretSession *session; GkdSecretSecret *secret; GckObject *item; const char *caller; int i; GVariantBuilder builder; GError *error = NULL; caller = g_dbus_method_invocation_get_sender (invocation); session = gkd_secret_service_lookup_session (self->service, session_path, caller); if (session == NULL) { g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR, GKD_SECRET_ERROR_NO_SESSION, "The session does not exist"); return TRUE; } g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{o(oayays)}")); for (i = 0; paths[i] != NULL; ++i) { /* Try to find the item, if it doesn't exist, just ignore */ item = gkd_secret_objects_lookup_item (self, caller, paths[i]); if (!item) continue; secret = gkd_secret_session_get_item_secret (session, item, &error); g_object_unref (item); if (secret == NULL) { /* We ignore is locked, and just leave out from response */ if (g_error_matches (error, GKD_SECRET_ERROR, GKD_SECRET_ERROR_IS_LOCKED)) { g_clear_error (&error); continue; /* All other errors stop the operation */ } else { g_dbus_method_invocation_take_error (invocation, error); return TRUE; } } g_variant_builder_add (&builder, "{o@(oayays)}", paths[i], gkd_secret_secret_append (secret)); gkd_secret_secret_free (secret); } g_dbus_method_invocation_return_value (invocation, g_variant_new ("(@a{o(oayays)})", g_variant_builder_end (&builder))); return TRUE; }
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; }
static void gkd_secret_create_finalize (GObject *obj) { GkdSecretCreate *self = GKD_SECRET_CREATE (obj); gkd_secret_secret_free (self->master); gck_attributes_unref (self->attributes); g_free (self->result_path); g_free (self->alias); G_OBJECT_CLASS (gkd_secret_create_parent_class)->finalize (obj); }
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 void gkd_secret_exchange_finalize (GObject *obj) { GkdSecretExchange *self = GKD_SECRET_EXCHANGE (obj); if (self->service) { g_object_remove_weak_pointer (G_OBJECT (self->service), (gpointer*)&(self->service)); self->service = NULL; } g_clear_object (&self->session); gkd_secret_secret_free (self->last_secret); g_free (self->caller); G_OBJECT_CLASS (gkd_secret_exchange_parent_class)->finalize (obj); }
static DBusMessage* service_method_create_with_master_password (GkdSecretService *self, DBusMessage *message) { DBusError derr = DBUS_ERROR_INIT; DBusMessageIter iter, array; DBusMessage *reply = NULL; GkdSecretSecret *secret = NULL; GckAttributes *attrs = 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); attrs = gck_attributes_new (); dbus_message_iter_recurse (&iter, &array); if (!gkd_secret_property_parse_all (&array, SECRET_COLLECTION_INTERFACE, attrs)) { gck_attributes_unref (attrs); 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_attributes_unref (attrs); return gkd_secret_error_to_reply (message, &derr); } gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE); path = gkd_secret_create_with_secret (attrs, secret, &derr); gck_attributes_unref (attrs); gkd_secret_secret_free (secret); if (path == NULL) return gkd_secret_error_to_reply (message, &derr); 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 gkd_secret_exchange_decrypt_transport_data (GcrSecretExchange *exchange, GckAllocator allocator, const guchar *cipher_text, gsize n_cipher_text, const guchar *parameter, gsize n_parameter, guchar **plain_text, gsize *n_plain_text) { GkdSecretExchange *self = GKD_SECRET_EXCHANGE (exchange); gkd_secret_secret_free (self->last_secret); self->last_secret = gkd_secret_secret_new (self->session, parameter, n_parameter, cipher_text, n_cipher_text); *plain_text = NULL; *n_plain_text = 0; return TRUE; }
static gboolean item_method_set_secret (GkdExportedItem *skeleton, GDBusMethodInvocation *invocation, GVariant *secret_variant, GkdSecretObjects *self) { GkdSecretSecret *secret; const char *caller; GckObject *item; GError *error = NULL; item = secret_objects_lookup_gck_object_for_invocation (self, invocation); if (!item) { return TRUE; } caller = g_dbus_method_invocation_get_sender (invocation); secret = gkd_secret_secret_parse (self->service, caller, secret_variant, &error); if (error != NULL) { goto cleanup; } gkd_secret_session_set_item_secret (secret->session, item, secret, &error); gkd_secret_secret_free (secret); if (error != NULL) { goto cleanup; } cleanup: if (error != NULL) { g_dbus_method_invocation_take_error (invocation, error); } else { gkd_exported_item_complete_set_secret (skeleton, invocation); } g_object_unref (item); return TRUE; }
static gboolean item_method_get_secret (GkdExportedItem *skeleton, GDBusMethodInvocation *invocation, gchar *path, GkdSecretObjects *self) { GkdSecretSession *session; GkdSecretSecret *secret; GckObject *item; GError *error = NULL; item = secret_objects_lookup_gck_object_for_invocation (self, invocation); if (!item) { return TRUE; } session = gkd_secret_service_lookup_session (self->service, path, g_dbus_method_invocation_get_sender (invocation)); if (session == NULL) { g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR, GKD_SECRET_ERROR_NO_SESSION, "The session does not exist"); goto cleanup; } secret = gkd_secret_session_get_item_secret (session, item, &error); if (secret == NULL) { g_dbus_method_invocation_take_error (invocation, error); goto cleanup; } gkd_exported_item_complete_get_secret (skeleton, invocation, gkd_secret_secret_append (secret)); gkd_secret_secret_free (secret); cleanup: g_object_unref (item); return TRUE; }
static void on_prompt_confirmation_complete (GObject *source, GAsyncResult *result, gpointer user_data) { GkdSecretCreate *self = GKD_SECRET_CREATE (source); GkdSecretPrompt *prompt = GKD_SECRET_PROMPT (source); GError *error = NULL; self->confirmed = gcr_prompt_confirm_finish (GCR_PROMPT (source), result, &error); if (error != NULL) { gkd_secret_prompt_dismiss_with_error (prompt, error); g_error_free (error); return; } /* If not confirmed, then prompt again */ if (!self->confirmed) { gkd_secret_secret_free (self->master); self->master = NULL; } perform_prompting (self); }
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; }