[seahorse] Rework password prompting, key generation and upload.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [seahorse] Rework password prompting, key generation and upload.
- Date: Thu, 15 Sep 2011 08:07:26 +0000 (UTC)
commit 8f165666aacb2403395f9fdc739a1b2ec294ddde
Author: Stef Walter <stefw collabora co uk>
Date: Thu Sep 15 10:04:43 2011 +0200
Rework password prompting, key generation and upload.
* openssh changed and we can no longer pass file descriptors to
our seahorse-ssh-askpass process.
* Rework how seahorse-ssh-askpass works, and have it pormpt for
the password directly.
* We can no longer ask for confirmation of passwords in the same
prompt, but at least things work.
* Fix issue with showing help when generating key.
* Close key generation and upload dialogs before we start ssh
operations.
ssh/seahorse-ssh-askpass.c | 170 ++++++++++----------
ssh/seahorse-ssh-generate.c | 16 +-
ssh/seahorse-ssh-generate.xml | 1 -
ssh/seahorse-ssh-operation.c | 363 +++++++----------------------------------
ssh/seahorse-ssh-source.c | 86 +++++++---
ssh/seahorse-ssh-upload.c | 5 +-
6 files changed, 211 insertions(+), 430 deletions(-)
---
diff --git a/ssh/seahorse-ssh-askpass.c b/ssh/seahorse-ssh-askpass.c
index aad85a3..7b380a1 100644
--- a/ssh/seahorse-ssh-askpass.c
+++ b/ssh/seahorse-ssh-askpass.c
@@ -2,6 +2,7 @@
* Seahorse
*
* Copyright (C) 2005 Stefan Walter
+ * Copyright (C) 2011 Collabora Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,102 +18,101 @@
* Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
*/
#include "config.h"
-#include <errno.h>
+#include "seahorse-passphrase.h"
+
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-static FILE* seahorse_link = NULL;
-
-static gchar*
-askpass_command (const gchar *cmd, const gchar *arg)
+int
+main (int argc, char* argv[])
{
- const gchar* env;
- gchar *t;
- int fd;
-
- /* Try an open the connection with seahorse */
- if (!seahorse_link) {
- env = g_getenv ("SEAHORSE_SSH_ASKPASS_FD");
- if (env == NULL)
- return NULL;
- g_unsetenv ("SEAHORSE_SSH_ASKPASS_FD");
-
- fd = strtol (env, &t, 10);
- if (*t) {
- g_warning ("fd received from seahorse was not valid: %s", env);
- return NULL;
- }
-
- seahorse_link = fdopen (fd, "r+b");
- if (!seahorse_link) {
- g_warning ("couldn't open fd %d: %s", fd, strerror (errno));
- return NULL;
- }
-
- setvbuf(seahorse_link, 0, _IONBF, 0);
- }
-
- /* Request a setting be sent */
- fprintf (seahorse_link, "%s %s\n", cmd, arg ? arg : "");
- fflush (seahorse_link);
-
- /* Read the setting */
- t = g_new0 (gchar, 512);
- fgets (t, 512, seahorse_link);
-
- /* Make sure it worked */
- if (ferror (seahorse_link)) {
- g_warning ("error reading from seahorse");
- fclose (seahorse_link);
- seahorse_link = NULL;
- g_free (t);
- return NULL;
- }
-
- return t;
-}
+ GtkDialog *dialog;
+ const gchar *title;
+ const gchar *argument;
+ gchar *message;
+ const gchar *flags;
+ gint result;
+ const gchar *pass;
+ gsize len;
-int main (int argc, char* argv[])
-{
- gchar *pass, *message, *p;
-
- bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-
- /* Non buffered stdout */
- setvbuf(stdout, 0, _IONBF, 0);
-
- if (argc > 1)
- message = g_strjoinv (" ", argv + 1);
- else
- message = g_strdup (_("Enter your Secure Shell passphrase:"));
-
- /* Check if we're being handed a password from seahorse */
- pass = askpass_command ("PASSWORD", message);
- g_free (message);
-
- if (pass == NULL)
- return 1;
-
- if (write (1, pass, strlen (pass)) != strlen (pass))
- g_warning ("couldn't write out password properly");
- for (p = pass; *p; p++)
- *p = 0;
- g_free (pass);
-
- if (seahorse_link)
- fclose (seahorse_link);
-
- return 0;
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ gtk_init (&argc, &argv);
+
+ /* Non buffered stdout */
+ setvbuf (stdout, 0, _IONBF, 0);
+
+ /* TODO: Change lousy default, rarely used, and string freeze right now */
+ title = g_getenv ("SEAHORSE_SSH_ASKPASS_TITLE");
+ if (!title || !title[0])
+ title = _("Enter your Secure Shell passphrase:");
+
+ message = (gchar *)g_getenv ("SEAHORSE_SSH_ASKPASS_MESSAGE");
+ if (message && message[0])
+ message = g_strdup (message);
+ else if (argc > 1)
+ message = g_strjoinv (" ", argv + 1);
+ else
+ message = g_strdup (_("Enter your Secure Shell passphrase:"));
+
+ argument = g_getenv ("SEAHORSE_SSH_ASKPASS_ARGUMENT");
+ if (!argument)
+ argument = "";
+
+ flags = g_getenv ("SEAHORSE_SSH_ASKPASS_FLAGS");
+ if (!flags)
+ flags = "";
+ if (strstr (flags, "multiple")) {
+ gchar *lower = g_ascii_strdown (message, -1);
+
+ /* Need the old passphrase */
+ if (strstr (lower, "old pass")) {
+ title = _("Old Key Passphrase");
+ message = g_strdup_printf (_("Enter the old passphrase for: %s"), argument);
+
+ /* Look for the new passphrase thingy */
+ } else if (strstr (lower, "new pass")) {
+ title = _("New Key Passphrase");
+ message = g_strdup_printf (_("Enter the new passphrase for: %s"), argument);
+
+ /* Confirm the new passphrase, just send it again */
+ } else if (strstr (lower, "again")) {
+ title = _("New Key Passphrase");
+ message = g_strdup_printf (_("Enter the new passphrase again: %s"), argument);
+ }
+
+ g_free (lower);
+ }
+
+ dialog = seahorse_passphrase_prompt_show (title, message, _("Password:"),
+ NULL, FALSE);
+
+ g_free (message);
+
+ result = 1;
+ if (gtk_dialog_run (dialog) == GTK_RESPONSE_ACCEPT) {
+ pass = seahorse_passphrase_prompt_get (dialog);
+ len = strlen (pass ? pass : "");
+ if (write (1, pass, len) != len) {
+ g_warning ("couldn't write out password properly");
+ result = 1;
+ } else {
+ result = 0;
+ }
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ return result;
}
diff --git a/ssh/seahorse-ssh-generate.c b/ssh/seahorse-ssh-generate.c
index 6cb6bf5..e6e2512 100644
--- a/ssh/seahorse-ssh-generate.c
+++ b/ssh/seahorse-ssh-generate.c
@@ -106,16 +106,13 @@ on_generate_complete (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- SeahorseWidget *swidget = SEAHORSE_WIDGET (user_data);
GError *error = NULL;
seahorse_ssh_op_generate_finish (SEAHORSE_SSH_SOURCE (source),
result, &error);
if (error != NULL)
- seahorse_util_handle_error (&error, swidget, _("Couldn't generate Secure Shell key"));
-
- g_object_unref (swidget);
+ seahorse_util_handle_error (&error, NULL, _("Couldn't generate Secure Shell key"));
}
static void
@@ -123,7 +120,6 @@ on_generate_complete_and_upload (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- SeahorseWidget *swidget = SEAHORSE_WIDGET (user_data);
GError *error = NULL;
SeahorseObject *object;
GList *keys;
@@ -132,15 +128,13 @@ on_generate_complete_and_upload (GObject *source,
result, &error);
if (error != NULL) {
- seahorse_util_handle_error (&error, swidget, _("Couldn't generate Secure Shell key"));
+ seahorse_util_handle_error (&error, NULL, _("Couldn't generate Secure Shell key"));
} else {
keys = g_list_append (NULL, object);
- seahorse_ssh_upload_prompt (keys, GTK_WINDOW (seahorse_widget_get_widget (swidget, swidget->name)));
+ seahorse_ssh_upload_prompt (keys, NULL);
g_list_free (keys);
}
-
- g_object_unref (swidget);
}
static void
@@ -199,9 +193,11 @@ on_response (GtkDialog *dialog, guint response, SeahorseWidget *swidget)
cancellable = g_cancellable_new ();
seahorse_ssh_op_generate_async (src, email, type, bits, cancellable,
upload ? on_generate_complete_and_upload : on_generate_complete,
- g_object_ref (swidget));
+ NULL);
seahorse_progress_show (cancellable, _("Creating Secure Shell Key"), FALSE);
g_object_unref (cancellable);
+
+ seahorse_widget_destroy (swidget);
}
void
diff --git a/ssh/seahorse-ssh-generate.xml b/ssh/seahorse-ssh-generate.xml
index 0e8b8cd..8b2fb9f 100644
--- a/ssh/seahorse-ssh-generate.xml
+++ b/ssh/seahorse-ssh-generate.xml
@@ -42,7 +42,6 @@
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
- <signal name="clicked" handler="on_widget_help" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
diff --git a/ssh/seahorse-ssh-operation.c b/ssh/seahorse-ssh-operation.c
index a065260..4ff4235 100644
--- a/ssh/seahorse-ssh-operation.c
+++ b/ssh/seahorse-ssh-operation.c
@@ -35,7 +35,6 @@
#include "seahorse-ssh-operation.h"
#include "seahorse-util.h"
-#include "seahorse-passphrase.h"
#define DEBUG_FLAG SEAHORSE_DEBUG_OPERATION
#include "seahorse-debug.h"
@@ -44,14 +43,11 @@
#define COMMAND_PASSWORD_LEN 9
typedef struct {
- SeahorseObject *key;
- GtkDialog *dialog;
- guint requests;
-} SeahorseSshSourcePrompt;
-
-typedef const gchar * (*SeahorseSshSourcePasswordCallback) (SeahorseSshSourcePrompt *prompt,
- const gchar* message,
- gpointer user_data);
+ const gchar *title;
+ const gchar *message;
+ const gchar *argument;
+ const gchar *flags;
+} SeahorseSshPromptInfo;
typedef struct {
GError *previous_error;
@@ -75,15 +71,6 @@ typedef struct {
GPid pid;
guint wpid;
- /* Callback for password prompting */
- SeahorseSshSourcePasswordCallback password_cb;
- SeahorseSshSourcePrompt *prompt;
-
- /* seahorse-ssh-askpass communication */
- GIOChannel *io_askpass;
- guint stag_askpass;
- int fds_askpass[2];
-
GCancellable *cancellable;
gulong cancelled_sig;
} ssh_operation_closure;
@@ -100,12 +87,6 @@ ssh_operation_free (gpointer data)
g_assert (closure->cancelled_sig == 0);
g_clear_object (&closure->cancellable);
- g_assert (closure->prompt);
- if (closure->prompt->dialog)
- gtk_widget_destroy (GTK_WIDGET (closure->prompt->dialog));
- g_clear_object (&closure->prompt->key);
- g_free (closure->prompt);
-
if (closure->win)
g_source_remove (closure->win);
if (closure->wout)
@@ -126,15 +107,8 @@ ssh_operation_free (gpointer data)
g_string_free (closure->sout, TRUE);
g_string_free (closure->serr, TRUE);
- /* Close the sockets */
- if (closure->fds_askpass[0] != -1)
- close (closure->fds_askpass[0]);
- if (closure->fds_askpass[1] != -1)
- close (closure->fds_askpass[1]);
-
/* watch_ssh_process always needs to have been called */
g_assert (closure->pid == 0 && closure->wpid == 0);
- g_assert (closure->io_askpass == NULL && closure->stag_askpass == 0);
g_free (closure);
}
@@ -185,40 +159,6 @@ escape_shell_arg (const gchar *arg)
return escaped;
}
-static const gchar*
-seahorse_ssh_source_prompt_passphrase (SeahorseSshSourcePrompt *prompt,
- const gchar* title,
- const gchar* message,
- const gchar* check,
- gboolean confirm)
-{
- const gchar *display;
- gchar *msg;
-
- if (prompt->dialog)
- gtk_widget_destroy (GTK_WIDGET (prompt->dialog));
-
- if (prompt->key)
- display = seahorse_object_get_label (prompt->key);
- else
- display = g_strdup (_("Secure Shell key"));
- msg = g_strdup_printf (message, display);
-
- prompt->dialog = seahorse_passphrase_prompt_show (title, msg, _("Password:"),
- check, confirm);
- g_free (msg);
-
- /* Run and check if cancelled? */
- if (gtk_dialog_run (prompt->dialog) != GTK_RESPONSE_ACCEPT) {
- gtk_widget_destroy (GTK_WIDGET (prompt->dialog));
- prompt->dialog = NULL;
- return NULL;
- }
-
- gtk_widget_hide (GTK_WIDGET (prompt->dialog));
- return seahorse_passphrase_prompt_get (prompt->dialog);
-}
-
static void
on_ssh_operation_cancelled (GCancellable *cancellable,
gpointer user_data)
@@ -238,14 +178,10 @@ on_watch_ssh_process (GPid pid,
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
ssh_operation_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ const gchar *message;
seahorse_debug ("SSHOP: SSH process done");
- /* Close off the askpass io channel etc... */
- if (closure->stag_askpass)
- g_source_remove (closure->stag_askpass);
- closure->stag_askpass = 0;
-
/* Already have an error? */
if (closure->previous_error) {
g_simple_async_result_take_error (res, closure->previous_error);
@@ -265,10 +201,13 @@ on_watch_ssh_process (GPid pid,
} else if (WEXITSTATUS (status) != 0) {
g_message ("SSH command failed: (%d)", WEXITSTATUS (status));
if (closure->serr->len)
- g_message ("SSH error output: %s", closure->serr->str);
- g_simple_async_result_set_error (res, SEAHORSE_ERROR, 0, "%s",
- closure->serr->len ? closure->serr->str : _("The SSH command failed."));
-
+ message = closure->serr->str;
+ else if (closure->sout->len)
+ message = closure->sout->str;
+ else
+ message = _("The SSH command failed.");
+ g_message ("SSH error: %s", message);
+ g_simple_async_result_set_error (res, SEAHORSE_ERROR, 0, "%s", message);
}
g_cancellable_disconnect (closure->cancellable,
@@ -279,9 +218,13 @@ on_watch_ssh_process (GPid pid,
closure->pid = 0;
closure->wpid = 0;
- if (closure->io_askpass)
- g_io_channel_unref (closure->io_askpass);
- closure->io_askpass = NULL;
+ if (closure->win)
+ g_source_remove (closure->win);
+ if (closure->wout)
+ g_source_remove (closure->wout);
+ if (closure->werr)
+ g_source_remove (closure->werr);
+ closure->win = closure->wout = closure->werr = 0;
g_simple_async_result_complete (res);
}
@@ -387,98 +330,10 @@ on_io_ssh_write (GIOChannel *source,
return ret;
}
-/* Communication with seahorse-ssh-askpass */
-static gboolean
-on_io_askpass_handler (GIOChannel *source,
- GIOCondition condition,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- ssh_operation_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
- gchar *string = NULL;
- gsize length;
- GError *error = NULL;
- gboolean ret = TRUE;
- const gchar *line;
- const gchar *result = NULL;
-
- if (condition & G_IO_IN) {
-
- /* Read 1 line from the io channel, including newline character */
- g_io_channel_read_line (source, &string, &length, NULL, &error);
-
- if (error != NULL) {
- g_critical ("couldn't read from seahorse-ssh-askpass: %s",
- error->message);
- g_clear_error (&error);
- ret = FALSE;
- }
-
- /* Process the line */
- if (string && ret) {
-
- string[length] = 0;
- seahorse_debug ("SSHOP: seahorse-ssh-askpass request: \"%s\"", string);
-
- if (g_ascii_strncasecmp (COMMAND_PASSWORD, string, COMMAND_PASSWORD_LEN) == 0) {
- line = g_strstrip (string + COMMAND_PASSWORD_LEN);
-
- /* Prompt for a password */
- if (closure->password_cb) {
- result = (closure->password_cb) (closure->prompt, line,
- g_async_result_get_user_data (G_ASYNC_RESULT (res)));
-
- /* Cancelled prompt, cancel operation */
- if (!result) {
- kill (closure->pid, SIGTERM);
- seahorse_debug ("SSHOP: password prompt cancelled");
- ret = FALSE;
- }
- }
-
- closure->prompt->requests++;
- }
-
- if (ret) {
- /* And write the result back out to seahorse-ssh-askpass */
- seahorse_debug ("SSHOP: seahorse-ssh-askpass response: %s", result ? result : "");
- if (result)
- g_io_channel_write_chars (closure->io_askpass, result,
- strlen (result), &length, &error);
- if (error == NULL)
- g_io_channel_write_chars (closure->io_askpass, "\n", 1, &length, &error);
- if (error == NULL)
- g_io_channel_flush (closure->io_askpass, &error);
- if (error != NULL) {
- g_critical ("couldn't read from seahorse-ssh-askpass: %s",
- error->message);
- g_clear_error (&error);
- ret = FALSE;
- }
- }
- }
- }
-
- if (condition & G_IO_HUP)
- ret = FALSE;
-
- if (!ret) {
- if (closure->io_askpass)
- g_io_channel_unref (closure->io_askpass);
- closure->io_askpass = NULL;
- closure->stag_askpass = 0;
- }
-
- g_free (string);
- return ret;
-}
-
-
static void
on_spawn_setup_child (gpointer user_data)
{
- ssh_operation_closure *closure = user_data;
- gchar buf[15];
+ SeahorseSshPromptInfo *prompt = user_data;
/* No terminal for this process */
setsid ();
@@ -490,15 +345,14 @@ on_spawn_setup_child (gpointer user_data)
g_setenv ("LC_ALL", "C", TRUE);
g_setenv ("LANG", "C", TRUE);
- /* Let child know which fd it is */
- if (closure->fds_askpass[1] != -1) {
- snprintf (buf, sizeof (buf), "%d", closure->fds_askpass[1]);
- g_setenv ("SEAHORSE_SSH_ASKPASS_FD", buf, TRUE);
+ if (prompt != NULL) {
+ if (prompt->title)
+ g_setenv ("SEAHORSE_SSH_ASKPASS_TITLE", prompt->title, TRUE);
+ if (prompt->message)
+ g_setenv ("SEAHORSE_SSH_ASKPASS_MESSAGE", prompt->message, TRUE);
+ if (prompt->flags)
+ g_setenv ("SEAHORSE_SSH_ASKPASS_FLAGS", prompt->flags, TRUE);
}
-
- /* Child doesn't need this stuff */
- if (closure->fds_askpass[0] != -1)
- close (closure->fds_askpass[0]);
}
static void
@@ -506,10 +360,9 @@ seahorse_ssh_operation_async (SeahorseSSHSource *source,
const gchar *command,
const gchar *input,
gssize length,
- SeahorseSSHKey *key,
GCancellable *cancellable,
GAsyncReadyCallback callback,
- SeahorseSshSourcePasswordCallback password,
+ SeahorseSshPromptInfo *prompt,
gpointer user_data)
{
GSimpleAsyncResult *res;
@@ -533,17 +386,6 @@ seahorse_ssh_operation_async (SeahorseSSHSource *source,
closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
closure->sout = g_string_new (NULL);
closure->serr = g_string_new (NULL);
- closure->password_cb = password;
- closure->prompt = g_new0 (SeahorseSshSourcePrompt, 1);
- closure->prompt->key = key ? g_object_ref (key) : NULL;
-
- /* The seahorse-ssh-askpass pipes */
- if (socketpair (AF_UNIX, SOCK_STREAM, 0, closure->fds_askpass) == -1) {
- g_warning ("couldn't create pipes to communicate with seahorse-ssh-askpass: %s",
- strerror(errno));
- closure->fds_askpass[0] = -1;
- closure->fds_askpass[1] = -1;
- }
g_simple_async_result_set_op_res_gpointer (res, closure, ssh_operation_free);
@@ -552,7 +394,7 @@ seahorse_ssh_operation_async (SeahorseSSHSource *source,
/* And off we go to run the program */
r = g_spawn_async_with_pipes (NULL, argv, NULL,
G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
- on_spawn_setup_child, closure, &closure->pid,
+ on_spawn_setup_child, prompt, &closure->pid,
input ? &fin : NULL, &fout, &ferr, &error);
g_strfreev (argv);
@@ -599,22 +441,6 @@ seahorse_ssh_operation_async (SeahorseSSHSource *source,
on_watch_ssh_process,
g_object_ref (res), g_object_unref);
- /* Setup askpass communication */
- if (closure->fds_askpass[0] != -1) {
- closure->io_askpass = g_io_channel_unix_new (closure->fds_askpass[0]);
- g_io_channel_set_close_on_unref (closure->io_askpass, TRUE);
- g_io_channel_set_encoding (closure->io_askpass, NULL, NULL);
- closure->stag_askpass = g_io_add_watch_full (closure->io_askpass, G_PRIORITY_DEFAULT,
- G_IO_IN | G_IO_HUP, on_io_askpass_handler,
- g_object_ref (res), g_object_unref);
- closure->fds_askpass[0] = -1; /* closed by io channel */
- }
-
- /* The other end of the pipe, close it */
- if (closure->fds_askpass[1] != -1)
- close (closure->fds_askpass[1]);
- closure->fds_askpass[1] = -1;
-
if (cancellable)
closure->cancelled_sig = g_cancellable_connect (closure->cancellable,
G_CALLBACK (on_ssh_operation_cancelled),
@@ -667,18 +493,6 @@ ssh_upload_free (gpointer data)
g_free (closure);
}
-static const gchar*
-on_upload_send_password (SeahorseSshSourcePrompt *prompt,
- const gchar* message,
- gpointer user_data)
-{
- seahorse_debug ("in upload_password_cb");
-
- /* Just prompt over and over again */
- return seahorse_ssh_source_prompt_passphrase (prompt, _("Remote Host Password"),
- message, NULL, FALSE);
-}
-
static void
on_upload_send_complete (GObject *source,
GAsyncResult *result,
@@ -701,6 +515,7 @@ on_upload_export_complete (GObject *source,
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
ssh_upload_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
+ SeahorseSshPromptInfo prompt = { _("Remote Host Password"), NULL, NULL, NULL };
GError *error = NULL;
gchar *data;
size_t length;
@@ -723,12 +538,14 @@ on_upload_export_complete (GObject *source,
closure->username, closure->hostname,
closure->port ? "-p" : "", closure->port ? closure->port : "");
+ if (g_output_stream_write_all (G_OUTPUT_STREAM (closure->output), "\n", 1, NULL, NULL, NULL) != 1)
+ g_return_if_reached ();
data = g_memory_output_stream_get_data (closure->output);
length = g_memory_output_stream_get_data_size (closure->output);
- seahorse_ssh_operation_async (SEAHORSE_SSH_SOURCE (source), cmd, data, length, NULL,
+ seahorse_ssh_operation_async (SEAHORSE_SSH_SOURCE (source), cmd, data, length,
closure->cancellable, on_upload_send_complete,
- on_upload_send_password, g_object_ref (res));
+ &prompt, g_object_ref (res));
g_free (cmd);
g_object_unref (res);
@@ -778,7 +595,7 @@ seahorse_ssh_op_upload_finish (SeahorseSSHSource *source,
GError **error)
{
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (source),
- seahorse_ssh_op_change_passphrase_async), FALSE);
+ seahorse_ssh_op_upload_async), FALSE);
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
return FALSE;
@@ -790,42 +607,6 @@ seahorse_ssh_op_upload_finish (SeahorseSSHSource *source,
* CHANGE PASSPHRASE
*/
-static const gchar *
-on_change_passphrase_password (SeahorseSshSourcePrompt *prompt,
- const gchar* message,
- gpointer user_data)
-{
- const gchar *ret = NULL;
- gchar *lcase;
-
- lcase = g_strdup (message ? message : "");
- seahorse_util_string_lower (lcase);
-
- seahorse_debug ("in change_password_cb");
-
- /* Need the old passphrase */
- if (strstr (lcase, "old pass"))
- ret = seahorse_ssh_source_prompt_passphrase (prompt, _("Old Key Passphrase"),
- _("Enter the old passphrase for: %s"), NULL, FALSE);
-
- /* Look for the new passphrase thingy */
- else if (strstr (lcase, "new pass"))
- ret = seahorse_ssh_source_prompt_passphrase (prompt, _("New Key Passphrase"),
- _("Enter the new passphrase for: %s"), NULL, TRUE);
-
- /* Confirm the new passphrase, just send it again */
- else if (strstr (lcase, "again") && prompt->dialog)
- ret = seahorse_passphrase_prompt_get (prompt->dialog);
-
- /* Something we don't understand */
- else
- ret = seahorse_ssh_source_prompt_passphrase (prompt, _("Enter Key Passphrase"),
- message, NULL, FALSE);
-
- g_free (lcase);
- return ret;
-}
-
static void
on_change_passphrase_complete (GObject *source,
GAsyncResult *result,
@@ -850,6 +631,7 @@ seahorse_ssh_op_change_passphrase_async (SeahorseSSHKey *key,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ SeahorseSshPromptInfo prompt = { _("Enter Key Passphrase"), NULL, NULL, NULL };
GSimpleAsyncResult *res;
SeahorseSource *source;
gchar *cmd;
@@ -860,14 +642,15 @@ seahorse_ssh_op_change_passphrase_async (SeahorseSSHKey *key,
source = seahorse_object_get_source (SEAHORSE_OBJECT (key));
g_return_if_fail (SEAHORSE_IS_SSH_SOURCE (source));
+ prompt.argument = seahorse_object_get_label (SEAHORSE_OBJECT (key));
+
res = g_simple_async_result_new (G_OBJECT (key), callback, user_data,
seahorse_ssh_op_change_passphrase_async);
g_simple_async_result_set_op_res_gpointer (res, g_object_ref (key), g_object_unref);
cmd = g_strdup_printf (SSH_KEYGEN_PATH " -p -f '%s'", key->keydata->privfile);
- seahorse_ssh_operation_async (SEAHORSE_SSH_SOURCE (source), cmd, NULL, 0, key, cancellable,
- on_change_passphrase_complete, on_change_passphrase_password,
- g_object_ref (res));
+ seahorse_ssh_operation_async (SEAHORSE_SSH_SOURCE (source), cmd, NULL, 0, cancellable,
+ on_change_passphrase_complete, &prompt, g_object_ref (res));
g_free (cmd);
g_object_unref (res);
@@ -929,24 +712,6 @@ on_generate_complete (GObject *source,
g_object_unref (res);
}
-static const gchar *
-on_generate_password (SeahorseSshSourcePrompt *prompt,
- const gchar* message,
- gpointer user_data)
-{
- seahorse_debug ("in generate_password_cb");
-
- /* If the first time then prompt */
- if (!prompt->dialog)
- return seahorse_ssh_source_prompt_passphrase (prompt,
- _("Passphrase for New Secure Shell Key"),
- _("Enter a passphrase for your new Secure Shell key."),
- NULL, TRUE);
-
- /* Otherwise return the entered passphrase */
- return seahorse_passphrase_prompt_get (prompt->dialog);
-}
-
void
seahorse_ssh_op_generate_async (SeahorseSSHSource *source,
const gchar *email,
@@ -956,6 +721,8 @@ seahorse_ssh_op_generate_async (SeahorseSSHSource *source,
GAsyncReadyCallback callback,
gpointer user_data)
{
+ SeahorseSshPromptInfo prompt = { _("Passphrase for New Secure Shell Key"),
+ NULL, NULL, NULL };
ssh_generate_closure *closure;
GSimpleAsyncResult *res;
const gchar *algo;
@@ -980,9 +747,8 @@ seahorse_ssh_op_generate_async (SeahorseSSHSource *source,
bits, algo, comment, closure->filename);
g_free (comment);
- seahorse_ssh_operation_async (source, cmd, NULL, 0, NULL, cancellable,
- on_generate_complete, on_generate_password,
- g_object_ref (res));
+ seahorse_ssh_operation_async (source, cmd, NULL, 0, cancellable,
+ on_generate_complete, &prompt, g_object_ref (res));
g_free (cmd);
g_object_unref (res);
@@ -1070,29 +836,6 @@ ssh_import_free (gpointer data)
g_free (closure);
}
-static const gchar *
-on_import_private_password (SeahorseSshSourcePrompt *prompt,
- const gchar* message,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- ssh_import_closure *closure = g_simple_async_result_get_op_res_gpointer (res);
- const gchar *ret;
- gchar* details;
-
- /* Add the comment to the output */
- if (closure->comment)
- details = g_strdup_printf (_("Importing key: %s"), closure->comment);
- else
- details = g_strdup (_("Importing key. Enter passphrase"));
-
- ret = seahorse_ssh_source_prompt_passphrase (prompt, _("Import Key"),
- details, NULL, FALSE);
- g_free (details);
-
- return ret;
-}
-
static void
on_import_private_complete (GObject *source,
GAsyncResult *result,
@@ -1145,9 +888,11 @@ seahorse_ssh_op_import_private_async (SeahorseSSHSource *source,
gpointer user_data)
{
GSimpleAsyncResult *res;
+ SeahorseSshPromptInfo prompt = { _("Import Key"), NULL, NULL, NULL };
gchar *cmd, *privfile = NULL;
GError *error = NULL;
ssh_import_closure *closure;
+ gchar *message;
g_return_if_fail (data && data->rawdata);
g_return_if_fail (SEAHORSE_IS_SSH_SOURCE (source));
@@ -1158,6 +903,13 @@ seahorse_ssh_op_import_private_async (SeahorseSSHSource *source,
g_return_if_fail (privfile);
}
+ /* Add the comment to the output */
+ if (data->comment)
+ message = g_strdup_printf (_("Importing key: %s"), data->comment);
+ else
+ message = g_strdup (_("Importing key. Enter passphrase"));
+ prompt.message = message;
+
res = g_simple_async_result_new (G_OBJECT (source), callback, user_data,
seahorse_ssh_op_import_private_async);
closure = g_new0 (ssh_import_closure, 1);
@@ -1176,10 +928,11 @@ seahorse_ssh_op_import_private_async (SeahorseSSHSource *source,
/* Start command to generate public key */
cmd = g_strdup_printf (SSH_KEYGEN_PATH " -y -f '%s'", privfile);
- seahorse_ssh_operation_async (source, cmd, NULL, 0, NULL, cancellable,
- on_import_private_complete,
- on_import_private_password,
+ seahorse_ssh_operation_async (source, cmd, NULL, 0, cancellable,
+ on_import_private_complete, &prompt,
g_object_ref (res));
+
+ g_free (message);
g_free (cmd);
g_object_unref (res);
diff --git a/ssh/seahorse-ssh-source.c b/ssh/seahorse-ssh-source.c
index 0f44520..8cf2b0f 100644
--- a/ssh/seahorse-ssh-source.c
+++ b/ssh/seahorse-ssh-source.c
@@ -322,6 +322,7 @@ typedef struct {
GHashTable *checks;
gchar *pubfile;
gchar *privfile;
+ SeahorseSSHKey *last_key;
} source_load_closure;
static void
@@ -329,8 +330,10 @@ source_load_free (gpointer data)
{
source_load_closure *closure = data;
g_object_unref (closure->source);
- g_hash_table_destroy (closure->loaded);
- g_hash_table_destroy (closure->checks);
+ if (closure->loaded)
+ g_hash_table_destroy (closure->loaded);
+ if (closure->checks)
+ g_hash_table_destroy (closure->checks);
g_free (closure->pubfile);
g_free (closure->privfile);
g_free (closure);
@@ -455,11 +458,57 @@ on_load_found_public_key (SeahorseSSHKeyData *data,
data->partial = FALSE;
/* Check and register thet key with the context, frees keydata */
- ssh_key_from_data (closure->source, closure, data);
+ closure->last_key = ssh_key_from_data (closure->source, closure, data);
return TRUE;
}
static void
+load_key_for_private_file (SeahorseSSHSource *self,
+ source_load_closure *closure,
+ const gchar *privfile)
+{
+ GError *error = NULL;
+
+ closure->privfile = g_strdup (privfile);
+ closure->pubfile = g_strconcat (closure->privfile, ".pub", NULL);
+
+ /* possibly an SSH key? */
+ if (g_file_test (closure->privfile, G_FILE_TEST_EXISTS) &&
+ g_file_test (closure->pubfile, G_FILE_TEST_EXISTS) &&
+ check_file_for_ssh_private (self, closure->privfile)) {
+ seahorse_ssh_key_data_parse_file (closure->pubfile, on_load_found_public_key,
+ NULL, closure, &error);
+ if (error != NULL) {
+ g_warning ("couldn't read SSH file: %s (%s)",
+ closure->pubfile, error->message);
+ g_clear_error (&error);
+ }
+ }
+
+ g_free (closure->privfile);
+ g_free (closure->pubfile);
+ closure->privfile = closure->pubfile = NULL;
+}
+
+static SeahorseSSHKey *
+seahorse_ssh_source_load_one_sync (SeahorseSSHSource *self,
+ const gchar *privfile)
+{
+ source_load_closure *closure;
+ SeahorseSSHKey *key;
+
+ closure = g_new0 (source_load_closure, 1);
+ closure->source = g_object_ref (self);
+
+ load_key_for_private_file (self, closure, privfile);
+
+ key = closure->last_key;
+ source_load_free (closure);
+
+ return key;
+}
+
+static void
seahorse_ssh_source_load_async (SeahorseSource *source,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -470,6 +519,7 @@ seahorse_ssh_source_load_async (SeahorseSource *source,
source_load_closure *closure;
GError *error = NULL;
const gchar *filename;
+ gchar *privfile;
GDir *dir;
res = g_simple_async_result_new (G_OBJECT (source), callback, user_data,
@@ -505,26 +555,9 @@ seahorse_ssh_source_load_async (SeahorseSource *source,
if (filename == NULL)
break;
- closure->privfile = g_build_filename (self->priv->ssh_homedir, filename, NULL);
- closure->pubfile = g_strconcat (closure->privfile, ".pub", NULL);
-
- /* possibly an SSH key? */
- if (g_file_test (closure->privfile, G_FILE_TEST_EXISTS) &&
- g_file_test (closure->pubfile, G_FILE_TEST_EXISTS) &&
- check_file_for_ssh_private (self, closure->privfile)) {
-
- seahorse_ssh_key_data_parse_file (closure->pubfile, on_load_found_public_key,
- NULL, closure, &error);
- if (error != NULL) {
- g_warning ("couldn't read SSH file: %s (%s)",
- closure->pubfile, error->message);
- g_clear_error (&error);
- }
- }
-
- g_free (closure->privfile);
- g_free (closure->pubfile);
- closure->privfile = closure->pubfile = NULL;
+ privfile = g_build_filename (self->priv->ssh_homedir, filename, NULL);
+ load_key_for_private_file (self, closure, privfile);
+ g_free (privfile);
}
g_dir_close (dir);
@@ -845,11 +878,14 @@ seahorse_ssh_source_key_for_filename (SeahorseSSHSource *ssrc,
g_return_val_if_fail (data, NULL);
/* If it's already loaded then just leave it at that */
- if (data->privfile && strcmp (privfile, data->privfile) == 0)
+ if (data->privfile && strcmp (privfile, data->privfile) == 0) {
+ g_list_free (keys);
return SEAHORSE_SSH_KEY (l->data);
+ }
}
+ g_list_free (keys);
- return NULL;
+ return seahorse_ssh_source_load_one_sync (ssrc, privfile);
}
gchar*
diff --git a/ssh/seahorse-ssh-upload.c b/ssh/seahorse-ssh-upload.c
index 8bc59fc..6a41a79 100644
--- a/ssh/seahorse-ssh-upload.c
+++ b/ssh/seahorse-ssh-upload.c
@@ -44,13 +44,10 @@ on_upload_complete (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
- SeahorseWidget *swidget = SEAHORSE_WIDGET (user_data);
GError *error = NULL;
if (!seahorse_ssh_op_upload_finish (SEAHORSE_SSH_SOURCE (source), result, &error))
- seahorse_util_handle_error (&error, swidget, _("Couldn't configure Secure Shell keys on remote computer."));
-
- g_object_unref (swidget);
+ seahorse_util_handle_error (&error, NULL, _("Couldn't configure Secure Shell keys on remote computer."));
}
G_MODULE_EXPORT void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]