[seahorse/wip/nielsdg/gtask: 3/4] gpgme: Don't use gpgme_op_edit for password change
- From: Niels De Graef <nielsdg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse/wip/nielsdg/gtask: 3/4] gpgme: Don't use gpgme_op_edit for password change
- Date: Fri, 1 Feb 2019 13:03:59 +0000 (UTC)
commit cf12ffe92b0438e3683fc585b9efd1594aea0295
Author: Niels De Graef <nielsdegraef gmail com>
Date: Fri Feb 1 11:03:04 2019 +0100
gpgme: Don't use gpgme_op_edit for password change
GPGME provides the `gpgme_op_passwd_start()` function, which implements
this in a much nicer way for us. We can now also properly split this in
an `_async()` and appropriate `_finish()` function.
This also relates to #210
pgp/seahorse-gpgme-key-op.c | 175 ++++++++++++++------------------------
pgp/seahorse-gpgme-key-op.h | 9 +-
pgp/seahorse-pgp-key-properties.c | 34 ++++++--
3 files changed, 102 insertions(+), 116 deletions(-)
---
diff --git a/pgp/seahorse-gpgme-key-op.c b/pgp/seahorse-gpgme-key-op.c
index d00c6025..c7ec5312 100644
--- a/pgp/seahorse-gpgme-key-op.c
+++ b/pgp/seahorse-gpgme-key-op.c
@@ -174,7 +174,7 @@ seahorse_gpgme_key_op_generate_async (SeahorseGpgmeKeyring *keyring,
gctx = seahorse_gpgme_keyring_new_context (&gerr);
task = g_task_new (keyring, cancellable, callback, user_data);
- gpgme_set_progress_cb (gctx, on_key_op_generate_progress, task);
+ gpgme_set_progress_cb (gctx, on_key_op_progress, task);
g_task_set_task_data (task, gctx, (GDestroyNotify) gpgme_release);
seahorse_progress_prep_and_begin (cancellable, task, NULL);
@@ -634,125 +634,80 @@ seahorse_gpgme_key_op_sign (SeahorseGpgmeKey *pkey, SeahorseGpgmeKey *signer,
return sign_process (signed_key, signing_key, 0, check, options);
}
-typedef enum {
- PASS_START,
- PASS_COMMAND,
- PASS_PASSPHRASE,
- PASS_QUIT,
- PASS_SAVE,
- PASS_ERROR
-} PassState;
-
-/* action helper for changing passphrase */
-static gpgme_error_t
-edit_pass_action (guint state, gpointer data, int fd)
+static gboolean
+on_key_op_change_pass_complete (gpgme_error_t gerr,
+ gpointer user_data)
{
- switch (state) {
- case PASS_COMMAND:
- PRINT ((fd, "passwd"));
- break;
- case PASS_PASSPHRASE:
- /* Do nothing */
- return GPG_OK;
- case PASS_QUIT:
- PRINT ((fd, QUIT));
- break;
- case PASS_SAVE:
- PRINT ((fd, YES));
- break;
- default:
- return GPG_E (GPG_ERR_GENERAL);
+ GTask *task = G_TASK (user_data);
+ g_autoptr(GError) error = NULL;
+
+ if (seahorse_gpgme_propagate_error (gerr, &error)) {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return FALSE; /* don't call again */
}
-
- PRINT ((fd, "\n"));
- return GPG_OK;
+
+ seahorse_progress_end (g_task_get_cancellable (task), task);
+ g_task_return_boolean (task, TRUE);
+ return FALSE; /* don't call again */
}
-/* transition helper for changing passphrase */
-static guint
-edit_pass_transit (guint current_state, gpgme_status_code_t status,
- const gchar *args, gpointer data, gpgme_error_t *err)
+/**
+ * seahorse_gpgme_key_op_change_pass_async:
+ * @pkey: The key that you want to change the password of
+ * @cancellable: (nullable): A #GCancellable
+ * @callback: The callback that will be called when the operation finishes
+ * @user_data: (closure callback): User data passed on to @callback
+ *
+ * Changes the password of @pkey. The actual changing will be done by GPGME, so
+ * this function doesn't allow to specify the new password.
+ */
+void
+seahorse_gpgme_key_op_change_pass_async (SeahorseGpgmeKey *pkey,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- guint next_state;
-
- switch (current_state) {
- /* start state, go to command */
- case PASS_START:
- if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT))
- next_state = PASS_COMMAND;
- else {
- *err = GPG_E (GPG_ERR_GENERAL);
- g_return_val_if_reached (PASS_ERROR);
- }
- break;
+ g_autoptr(GTask) task = NULL;
+ gpgme_ctx_t gctx;
+ gpgme_error_t gerr;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GSource) gsource = NULL;
+ gpgme_key_t key;
- case PASS_COMMAND:
- /* did command, go to should be the passphrase now */
- if (status == GPGME_STATUS_NEED_PASSPHRASE_SYM)
- next_state = PASS_PASSPHRASE;
-
- /* If all tries for passphrase were wrong, we get here */
- else if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT)) {
- *err = GPG_E (GPG_ERR_BAD_PASSPHRASE);
- next_state = PASS_ERROR;
-
- /* No idea how we got here ... */
- } else {
- *err = GPG_E (GPG_ERR_GENERAL);
- g_return_val_if_reached (PASS_ERROR);
- }
- break;
- /* got passphrase now quit */
- case PASS_PASSPHRASE:
- if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT))
- next_state = PASS_QUIT;
- else {
- *err = GPG_E (GPG_ERR_GENERAL);
- g_return_val_if_reached (PASS_ERROR);
- }
- break;
-
- /* quit, go to save */
- case PASS_QUIT:
- if (status == GPGME_STATUS_GET_BOOL && g_str_equal (args, SAVE))
- next_state = PASS_SAVE;
- else {
- *err = GPG_E (GPG_ERR_GENERAL);
- g_return_val_if_reached (PASS_ERROR);
- }
- break;
-
- /* error, go to quit */
- case PASS_ERROR:
- if (status == GPGME_STATUS_GET_LINE && g_str_equal (args, PROMPT))
- next_state = PASS_QUIT;
- else
- next_state = PASS_ERROR;
- break;
-
- default:
- *err = GPG_E (GPG_ERR_GENERAL);
- g_return_val_if_reached (PASS_ERROR);
- break;
+ g_return_if_fail (SEAHORSE_IS_GPGME_KEY (pkey));
+ g_return_if_fail (seahorse_object_get_usage (SEAHORSE_OBJECT (pkey)) == SEAHORSE_USAGE_PRIVATE_KEY);
+
+ gctx = seahorse_gpgme_keyring_new_context (&gerr);
+
+ task = g_task_new (pkey, cancellable, callback, user_data);
+ gpgme_set_progress_cb (gctx, on_key_op_progress, task);
+ g_task_set_task_data (task, gctx, (GDestroyNotify) gpgme_release);
+
+ seahorse_progress_prep_and_begin (cancellable, task, NULL);
+ gsource = seahorse_gpgme_gsource_new (gctx, cancellable);
+ g_source_set_callback (gsource, (GSourceFunc)on_key_op_change_pass_complete,
+ g_object_ref (task), g_object_unref);
+
+ key = seahorse_gpgme_key_get_private (pkey);
+ if (gerr == 0)
+ gerr = gpgme_op_passwd_start (gctx, key, 0);
+
+ if (seahorse_gpgme_propagate_error (gerr, &error)) {
+ g_task_return_error (task, g_steal_pointer (&error));
+ return;
}
-
- return next_state;
+
+ g_source_attach (gsource, g_main_context_default ());
}
-gpgme_error_t
-seahorse_gpgme_key_op_change_pass (SeahorseGpgmeKey *pkey)
+gboolean
+seahorse_gpgme_key_op_change_pass_finish (SeahorseGpgmeKey *pkey,
+ GAsyncResult *result,
+ GError **error)
{
- SeahorseEditParm *parms;
- gpgme_error_t err;
-
- g_return_val_if_fail (SEAHORSE_IS_GPGME_KEY (pkey), GPG_E (GPG_ERR_WRONG_KEY_USAGE));
- g_return_val_if_fail (seahorse_object_get_usage (SEAHORSE_OBJECT (pkey)) ==
SEAHORSE_USAGE_PRIVATE_KEY, GPG_E (GPG_ERR_WRONG_KEY_USAGE));
-
- parms = seahorse_edit_parm_new (PASS_START, edit_pass_action, edit_pass_transit, NULL);
-
- err = edit_key (pkey, parms);
-
- return err;
+ g_return_val_if_fail (g_task_is_valid (result, pkey), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
}
typedef enum
diff --git a/pgp/seahorse-gpgme-key-op.h b/pgp/seahorse-gpgme-key-op.h
index 7eedadab..52b3507b 100644
--- a/pgp/seahorse-gpgme-key-op.h
+++ b/pgp/seahorse-gpgme-key-op.h
@@ -127,7 +127,14 @@ gpgme_error_t seahorse_gpgme_key_op_sign_uid (SeahorseGpgmeUid *
SeahorseSignCheck check,
SeahorseSignOptions options);
-gpgme_error_t seahorse_gpgme_key_op_change_pass (SeahorseGpgmeKey *pkey);
+void seahorse_gpgme_key_op_change_pass_async (SeahorseGpgmeKey *pkey,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean seahorse_gpgme_key_op_change_pass_finish (SeahorseGpgmeKey *pkey,
+ GAsyncResult *Result,
+ GError **error);
gpgme_error_t seahorse_gpgme_key_op_set_trust (SeahorseGpgmeKey *pkey,
SeahorseValidity validity);
diff --git a/pgp/seahorse-pgp-key-properties.c b/pgp/seahorse-pgp-key-properties.c
index a0d4cc2a..dc57bd47 100644
--- a/pgp/seahorse-pgp-key-properties.c
+++ b/pgp/seahorse-pgp-key-properties.c
@@ -823,15 +823,39 @@ static GType uid_columns[] = {
G_TYPE_STRING /* comment */
};
+static void
+on_gpgme_key_change_pass_done (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SeahorseWidget *swidget = SEAHORSE_WIDGET (user_data);
+ SeahorseGpgmeKey *pkey = SEAHORSE_GPGME_KEY (source);
+ g_autoptr(GError) error = NULL;
+
+ if (!seahorse_gpgme_key_op_change_pass_finish (pkey, res, &error)) {
+ GtkWidget *window;
+
+ window = GTK_WIDGET (seahorse_widget_get_toplevel (swidget));
+ seahorse_util_show_error (window, _("Error changing password"), error->message);
+ }
+
+ g_object_unref (swidget);
+}
+
G_MODULE_EXPORT void
on_pgp_owner_passphrase_button_clicked (GtkWidget *widget,
gpointer user_data)
{
- SeahorseWidget *swidget = SEAHORSE_WIDGET (user_data);
- SeahorseObject *object = SEAHORSE_OBJECT (SEAHORSE_OBJECT_WIDGET (swidget)->object);
- if (seahorse_object_get_usage (object) == SEAHORSE_USAGE_PRIVATE_KEY &&
- SEAHORSE_IS_GPGME_KEY (object))
- seahorse_gpgme_key_op_change_pass (SEAHORSE_GPGME_KEY (object));
+ SeahorseWidget *swidget = SEAHORSE_WIDGET (user_data);
+ SeahorseObject *object = SEAHORSE_OBJECT (SEAHORSE_OBJECT_WIDGET (swidget)->object);
+
+ g_return_if_fail (SEAHORSE_IS_GPGME_KEY (object));
+ g_return_if_fail (seahorse_object_get_usage (object) == SEAHORSE_USAGE_PRIVATE_KEY);
+
+ seahorse_gpgme_key_op_change_pass_async (SEAHORSE_GPGME_KEY (object),
+ NULL,
+ on_gpgme_key_change_pass_done,
+ g_object_ref (swidget));
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]