[gnome-keyring/wip/dueno/ssh-agent: 12/24] WIP ssh-agent interaction



commit be89768b5b313432889ca2e405576726e95edfa7
Author: Stef Walter <stefw gnome org>
Date:   Sun Nov 23 22:43:42 2014 +0100

    WIP ssh-agent interaction

 daemon/ssh-agent/Makefile.am                       |    7 +-
 daemon/ssh-agent/gkd-ssh-agent-ops.c               |   22 +---
 daemon/ssh-agent/gkd-ssh-agent-preload.c           |   17 +++
 daemon/ssh-agent/gkd-ssh-interaction.c             |  127 +++++++++++++++-----
 daemon/ssh-agent/gkd-ssh-interaction.h             |   42 +++++++
 .../{gkm-ssh-openssh.c => gkd-ssh-openssh.c}       |    8 +-
 po/POTFILES.in                                     |    2 +
 7 files changed, 169 insertions(+), 56 deletions(-)
---
diff --git a/daemon/ssh-agent/Makefile.am b/daemon/ssh-agent/Makefile.am
index 687db32..9f5f1db 100644
--- a/daemon/ssh-agent/Makefile.am
+++ b/daemon/ssh-agent/Makefile.am
@@ -13,6 +13,11 @@ libgkd_ssh_agent_la_SOURCES = \
        daemon/ssh-agent/gkd-ssh-agent-preload.h \
        daemon/ssh-agent/gkd-ssh-agent-preload.c \
        daemon/ssh-agent/gkd-ssh-agent-private.h \
-       daemon/ssh-agent/gkd-ssh-agent-ops.c
+       daemon/ssh-agent/gkd-ssh-agent-ops.c \
+       daemon/ssh-agent/gkd-ssh-interaction.h \
+       daemon/ssh-agent/gkd-ssh-interaction.c \
+       daemon/ssh-agent/gkd-ssh-openssh.h \
+       daemon/ssh-agent/gkd-ssh-openssh.c \
+       $(NULL)
 libgkd_ssh_agent_la_CFLAGS = \
        $(DAEMON_CFLAGS)
diff --git a/daemon/ssh-agent/gkd-ssh-agent-ops.c b/daemon/ssh-agent/gkd-ssh-agent-ops.c
index 5278fe1..f528a41 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-ops.c
+++ b/daemon/ssh-agent/gkd-ssh-agent-ops.c
@@ -26,6 +26,7 @@
 #include "gkd-ssh-agent-client.h"
 #include "gkd-ssh-agent-preload.h"
 #include "gkd-ssh-agent-private.h"
+#include "gkd-ssh-interaction.h"
 
 #include "egg/egg-error.h"
 #include "egg/egg-secure-memory.h"
@@ -158,24 +159,10 @@ op_request_identities (GkdSshAgentCall *call)
 }
 
 static void
-on_ssh_add_prompting (GcrSystemInteraction *interaction,
-                      GcrPrompt *prompt,
-                      gint prompt_type,
-                      gpointer user_data)
-{
-       if (prompt_type == 1) {
-               choice = NULL;
-               if (gkd_login_available ())
-                       choice = _("Automatically unlock this key, whenever I'm logged in");
-               gcr_prompt_set_choice_label (prompt, choice);
-       }
-}
-
-static void
 preload_key_if_necessary (gint ssh_agent,
                           GBytes *key)
 {
-       GcrPrompt *prompt;
+       GTlsInteraction *interaction;
        GcrSshAskpass *askpass;
        GError *error = NULL;
        gchar *filename;
@@ -191,13 +178,12 @@ preload_key_if_necessary (gint ssh_agent,
        if (!filename)
                return;
 
-       interaction = gcr_system_interaction_new (_("Secure Shell Key"));
-       g_signal_connect (intercation, "prompting", G_CALLBACK (on_ssh_add_prompting), NULL);
+       interaction = gkd_ssh_interaction_new (key);
        askpass = gcr_ssh_askpass_new (interaction);
        g_object_unref (interaction);
 
        if (!g_spawn_sync (NULL, argv, NULL, G_SPAWN_DEFAULT,
-                          gcr_ssh_askpass_setup, askpass,
+                          gcr_ssh_askpass_child_setup, askpass,
                           NULL, NULL, &status, &error)) {
                g_warning ("cannot run %s: %s", argv[0], error->message);
 
diff --git a/daemon/ssh-agent/gkd-ssh-agent-preload.c b/daemon/ssh-agent/gkd-ssh-agent-preload.c
index 8da2f52..5595e43 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-preload.c
+++ b/daemon/ssh-agent/gkd-ssh-agent-preload.c
@@ -204,6 +204,23 @@ gkd_ssh_agent_preload_comment (GBytes *key)
        return comment;
 }
 
+gchar *
+gkd_ssh_agent_preload_path (GBytes *key)
+{
+       gchar *path = NULL;
+       Preload *preload;
+
+       preload_lock_and_update ();
+
+       preload = g_hash_table_lookup (preloads_by_key, key);
+       if (preload)
+               path = g_strdup (preload->filename);
+
+       preload_unlock ();
+
+       return path;
+}
+
 void
 gkd_ssh_agent_preload_clear (GBytes *key)
 {
diff --git a/daemon/ssh-agent/gkd-ssh-interaction.c b/daemon/ssh-agent/gkd-ssh-interaction.c
index c52333c..f9d7470 100644
--- a/daemon/ssh-agent/gkd-ssh-interaction.c
+++ b/daemon/ssh-agent/gkd-ssh-interaction.c
@@ -24,80 +24,143 @@
 
 #include "gkd-ssh-interaction.h"
 
-#define MOCK_INTERACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), MOCK_TYPE_INTERACTION, 
MockInteraction))
-#define MOCK_IS_INTERACTION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), MOCK_TYPE_INTERACTION))
-#define MOCK_INTERACTION_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), MOCK_TYPE_INTERACTION, 
MockInteractionClass))
+#include "daemon/login/gkd-login.h"
 
-typedef struct _MockInteractionClass MockInteractionClass;
+#include <gcr/gcr-base.h>
 
-struct _MockInteraction {
+#include <glib/gi18n-lib.h>
+
+#define GKD_SSH_INTERACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GKD_SSH_TYPE_INTERACTION, 
GkdSshInteraction))
+#define GKD_SSH_IS_INTERACTION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GKD_SSH_TYPE_INTERACTION))
+#define GKD_SSH_INTERACTION_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GKD_SSH_TYPE_INTERACTION, 
GkdSshInteractionClass))
+
+typedef struct _GkdSshInteractionClass GkdSshInteractionClass;
+
+struct _GkdSshInteraction {
        GTlsInteraction interaction;
+       GBytes *key;
+       gchar *label;
 };
 
-struct _MockInteractionClass {
+struct _GkdSshInteractionClass {
        GTlsInteractionClass parent;
 };
 
-G_DEFINE_TYPE (MockInteraction, mock_interaction, G_TYPE_TLS_INTERACTION);
+G_DEFINE_TYPE (GkdSshInteraction, gkd_ssh_interaction, G_TYPE_TLS_INTERACTION);
 
 static void
-mock_interaction_init (MockInteraction *self)
+gkd_ssh_interaction_init (GkdSshInteraction *self)
 {
+       self->label = g_strdup ("XXXXX");
+}
 
+static void
+gkd_ssh_interaction_finalize (GObject *obj)
+{
+       GkdSshInteraction *self = GKD_SSH_INTERACTION (obj);
+
+       g_free (self->label);
+
+       G_OBJECT_CLASS (gkd_ssh_interaction_parent_class)->finalize (obj);
 }
 
 static void
-mock_interaction_finalize (GObject *obj)
+on_prompt_open (GObject *source_object,
+                GAsyncResult *result,
+                gpointer user_data)
 {
-       MockInteraction *self = MOCK_INTERACTION (obj);
+       GTask *task = G_TASK (user_data);
+       GTlsPassword *password = g_task_get_task_data (task);
+       GkdSshInteraction *self = GKD_SSH_INTERACTION (g_task_get_source_object (task));
+       GError *error = NULL;
+       GcrPrompt *prompt;
+       const gchar *choice;
+       gchar *text;
+
+       prompt = gcr_system_prompt_open_finish (result, &error);
+       if (error != NULL) {
+               g_task_return_error (task, error);
+
+       } else {
+               gcr_prompt_set_title (prompt, _("Unlock private key"));
+               gcr_prompt_set_message (prompt, _("Enter password to unlock the private key"));
+
+               /* TRANSLATORS: The private key is locked */
+               text = g_strdup_printf (_("An application wants access to the private key '%s', but it is 
locked"),
+                                       self->label);
+               gcr_prompt_set_description (prompt, text);
+               g_free (text);
+
+               choice = NULL;
+               if (gkd_login_available (NULL))
+                       choice = _("Automatically unlock this key whenever I'm logged in");
+               gcr_prompt_set_choice_label (prompt, choice);
+               gcr_prompt_set_continue_label (prompt, _("Unlock"));
+       }
 
-       g_free (self->password);
+       if (g_tls_password_get_flags (password) & G_TLS_PASSWORD_RETRY)
+               gcr_prompt_set_warning (prompt, _("The unlock password was incorrect"));
 
-       G_OBJECT_CLASS (mock_interaction_parent_class)->dispose (obj);
+       g_object_unref (task);
 }
 
-static GTlsInteractionResult
-mock_interaction_ask_password_async (GTlsInteraction *interaction,
-                                     GTlsPassword *password,
-                                     GCancellable *cancellable,
-                                     GError **error)
+static void
+gkd_ssh_interaction_ask_password_async (GTlsInteraction *interaction,
+                                        GTlsPassword *password,
+                                        GCancellable *cancellable,
+                                        GAsyncReadyCallback callback,
+                                        gpointer user_data)
 {
-       g_task_new ();
+       GTask *task;
+
+       task = g_task_new (interaction, cancellable, callback, user_data);
+       g_task_set_task_data (task, g_object_ref (password), g_object_unref);
 
+#if 0
+       {'unique': 'ssh-store:/data/.ssh/id_rsa', 'xdg:schema': 'org.freedesktop.Secret.Generic'}
        if (gkd_login_available() && self->keyid) {
                xxxx = gkd_login_lookup (self->keyid);
                g_tls_password_set_value (password, xxxx);
 
        }
+#endif
 
-       MockInteraction *self = MOCK_INTERACTION (interaction);
 
-       if (self->password) {
-               g_tls_password_set_value (password, (const guchar *)self->password, -1);
-               return G_TLS_INTERACTION_HANDLED;
-       } else {
-               return G_TLS_INTERACTION_UNHANDLED;
-       }
+       gcr_system_prompt_open_async (60, cancellable, on_prompt_open,
+                                     g_object_ref (task));
+
+       g_object_unref (task);
+}
+
+static GTlsInteractionResult
+gkd_ssh_interaction_ask_password_finish (GTlsInteraction *interaction,
+                                         GAsyncResult *result,
+                                         GError **error)
+{
+       GTask *task = G_TASK (result);
+       if (!g_task_propagate_boolean (task, error))
+               return G_TLS_INTERACTION_FAILED;
+       return G_TLS_INTERACTION_HANDLED;
 }
 
 static void
-mock_interaction_class_init (MockInteractionClass *klass)
+gkd_ssh_interaction_class_init (GkdSshInteractionClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
        GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (klass);
 
-       object_class->finalize = mock_interaction_finalize;
+       object_class->finalize = gkd_ssh_interaction_finalize;
 
-       interaction_class->ask_password = mock_interaction_ask_password;
+       interaction_class->ask_password_async = gkd_ssh_interaction_ask_password_async;
+       interaction_class->ask_password_finish = gkd_ssh_interaction_ask_password_finish;
 }
 
 GTlsInteraction *
-mock_interaction_new (const gchar *password)
+gkd_ssh_interaction_new (GBytes *key)
 {
-       MockInteraction *result;
+       GkdSshInteraction *result;
 
-       result = g_object_new (MOCK_TYPE_INTERACTION, NULL);
-       result->password = g_strdup (password);
+       result = g_object_new (GKD_TYPE_SSH_INTERACTION, NULL);
 
        return G_TLS_INTERACTION (result);
 }
diff --git a/daemon/ssh-agent/gkd-ssh-interaction.h b/daemon/ssh-agent/gkd-ssh-interaction.h
new file mode 100644
index 0000000..3735290
--- /dev/null
+++ b/daemon/ssh-agent/gkd-ssh-interaction.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gkd-ssh-interaction.h
+
+   Copyright (C) 2014 Stefan Walter
+
+   The Gnome Keyring Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Keyring Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   see <http://www.gnu.org/licenses/>.
+
+   Author: Stef Walter <stefw redhat com>
+*/
+
+#ifndef GKD_SSH_INTERACTION_H
+#define GKD_SSH_INTERACTION_H
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GKD_TYPE_SSH_INTERACTION    (gkd_ssh_interaction_get_type ())
+#define GKD_SSH_INTERACTION(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKD_TYPE_SSH_INTERACTION, 
GkdSshInteraction))
+#define GKD_SSH_IS_INTERACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKD_TYPE_SSH_INTERACTION))
+
+typedef struct _GkdSshInteraction GkdSshInteraction;
+
+GType               gkd_ssh_interaction_get_type               (void) G_GNUC_CONST;
+
+GTlsInteraction *   gkd_ssh_interaction_new                    (GBytes *key);
+
+G_END_DECLS
+
+#endif /* GKD_SSH_INTERACTION_H */
diff --git a/daemon/ssh-agent/gkm-ssh-openssh.c b/daemon/ssh-agent/gkd-ssh-openssh.c
similarity index 98%
rename from daemon/ssh-agent/gkm-ssh-openssh.c
rename to daemon/ssh-agent/gkd-ssh-openssh.c
index c3a59a8..9894bf1 100644
--- a/daemon/ssh-agent/gkm-ssh-openssh.c
+++ b/daemon/ssh-agent/gkd-ssh-openssh.c
@@ -1,10 +1,7 @@
 
-#include "gkm-ssh-openssh.h"
-
-#include "gkm/gkm-data-asn1.h"
-#include "gkm/gkm-data-der.h"
-#include "gkm/gkm-data-types.h"
+#include "gkd-ssh-openssh.h"
 
+#if 0
 #include "egg/egg-armor.h"
 #include "egg/egg-asn1x.h"
 #include "egg/egg-buffer.h"
@@ -407,3 +404,4 @@ gkm_ssh_openssh_digest_private_key (GBytes *data)
        egg_armor_parse (data, digest_pem_block, &result);
        return result;
 }
+#endif
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3ed5e3d..3b2b359 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -7,6 +7,8 @@ daemon/gnome-keyring-pkcs11.desktop.in.in
 daemon/gnome-keyring-secrets.desktop.in.in
 daemon/gnome-keyring-ssh.desktop.in.in
 daemon/login/gkd-login.c
+daemon/ssh-agent/gkd-ssh-interaction.c
+daemon/org.gnome.keyring.service.in
 egg/dotlock.c
 egg/egg-oid.c
 pkcs11/gkm/gkm-certificate.c


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]