[gnome-keyring/wip/dueno/ssh-agent: 95/105] WIP ssh more



commit 1adc7693ca3a02186c023b7c6f2eafc96e9a32f6
Author: Stef Walter <stefw redhat com>
Date:   Fri Aug 29 15:30:18 2014 +0200

    WIP ssh more

 daemon/gkd-pkcs11.c                      |    6 +-
 daemon/ssh-agent/Makefile.am             |   46 -----------
 daemon/ssh-agent/gkd-ssh-agent-client.h  |   22 +++++-
 daemon/ssh-agent/gkd-ssh-agent-ops.c     |  120 ++++++++++++++++++-----------
 daemon/ssh-agent/gkd-ssh-agent-private.h |    4 +-
 daemon/ssh-agent/gkd-ssh-agent.c         |   24 +-----
 daemon/ssh-agent/gkd-ssh-agent.h         |    4 -
 7 files changed, 100 insertions(+), 126 deletions(-)
---
diff --git a/daemon/gkd-pkcs11.c b/daemon/gkd-pkcs11.c
index 5f407fa..8821d01 100644
--- a/daemon/gkd-pkcs11.c
+++ b/daemon/gkd-pkcs11.c
@@ -49,7 +49,6 @@ pkcs11_daemon_cleanup (gpointer unused)
 
        g_assert (pkcs11_roof);
 
-       gkd_ssh_agent_uninitialize ();
        gkm_rpc_layer_uninitialize ();
        rv = (pkcs11_roof->C_Finalize) (NULL);
 
@@ -113,10 +112,7 @@ gkd_pkcs11_initialize (void)
 
        egg_cleanup_register (pkcs11_daemon_cleanup, NULL);
 
-       ret = gkd_ssh_agent_initialize (pkcs11_roof) &&
-             gkm_rpc_layer_initialize (pkcs11_roof);
-
-       return ret;
+       return gkm_rpc_layer_initialize (pkcs11_roof);
 }
 
 static void
diff --git a/daemon/ssh-agent/Makefile.am b/daemon/ssh-agent/Makefile.am
index 0cc86c0..014c9c6 100644
--- a/daemon/ssh-agent/Makefile.am
+++ b/daemon/ssh-agent/Makefile.am
@@ -14,49 +14,3 @@ libgkd_ssh_agent_la_SOURCES = \
        daemon/ssh-agent/gkd-ssh-agent-proto.c
 libgkd_ssh_agent_la_CFLAGS = \
        $(DAEMON_CFLAGS)
-
-# ------------------------------------------------------------------------------
-# Standalone binary
-
-noinst_PROGRAMS += \
-       gkd-ssh-agent-standalone
-
-gkd_ssh_agent_standalone_SOURCES = \
-       daemon/ssh-agent/gkd-ssh-agent-standalone.c
-gkd_ssh_agent_standalone_CFLAGS = \
-       $(DAEMON_CFLAGS)
-gkd_ssh_agent_standalone_LDADD = \
-       libgkd-ssh-agent.la \
-       libegg-buffer.la \
-       libegg-secure.la \
-       libgkm.la \
-       $(DAEMON_LIBS)
-
-# ------------------------------------------------------------------------------
-# Tests
-
-ssh_agent_CFLAGS = \
-       $(GCK_CFLAGS)
-
-ssh_agent_LIBS = \
-       libgkd-ssh-agent.la \
-       libgkm.la \
-       libegg.la \
-       $(GLIB_LIBS) \
-       $(GCK_LIBS)
-       $(GTHREAD_LIBS)
-
-ssh_agent_TESTS = \
-       test-communication \
-       test-keytypes
-
-test_keytypes_SOURCES = daemon/ssh-agent/test-keytypes.c
-test_keytypes_CFLAGS = $(ssh_agent_CFLAGS)
-test_keytypes_LDADD = $(ssh_agent_LIBS)
-
-test_communication_SOURCES = daemon/ssh-agent/test-communication.c
-test_communication_CFLAGS = $(ssh_agent_CFLAGS)
-test_communication_LDADD = $(ssh_agent_LIBS)
-
-check_PROGRAMS += $(ssh_agent_TESTS)
-TESTS += $(ssh_agent_TESTS)
diff --git a/daemon/ssh-agent/gkd-ssh-agent-client.h b/daemon/ssh-agent/gkd-ssh-agent-client.h
index 9feacc0..c3cd135 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-client.h
+++ b/daemon/ssh-agent/gkd-ssh-agent-client.h
@@ -26,6 +26,8 @@
 
 #include <glib-object.h>
 
+#include "egg/egg-buffer.h"
+
 #define GKD_TYPE_SSH_AGENT_CLIENT               (gkm_ssh_agent_client_get_type ())
 #define GKD_SSH_AGENT_CLIENT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GKD_TYPE_SSH_AGENT_CLIENT, GkdSshAgentClient))
 #define GKD_SSH_AGENT_CLIENT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), 
GKD_TYPE_SSH_AGENT_CLIENT, GkdSshAgentClientClass))
@@ -38,9 +40,25 @@ typedef struct _GkdSshAgentClientClass GkdSshAgentClientClass;
 
 GType                gkd_ssh_agent_client_get_type            (void);
 
-GList *              gkd_ssh_agent_client_get_preload_keys    (GkdSshAgentClient *self);
+GkdSshAgentClient *  gkd_ssh_agent_client_connect             (void);
+
+gboolean             gkd_ssh_agent_client_call                (GkdSshAgentClient *self,
+                                                              EggBuffer *req,
+                                                              EggBuffer *resp);
+
+GList *              gkd_ssh_agent_client_preload_keys        (GkdSshAgentClient *self);
+
+gchar *              gkd_ssh_agent_client_preload_comment     (GkdSshAgentClient *self,
+                                                               GBytes *key);
+
+GBytes *             gkd_ssh_agent_client_preload_unlock      (GkdSshAgentClient *self,
+                                                              GBytes *key);
 
-void                 gkd_ssh_agent_client_clear_preload       (GkdSshAgentClient *self,
+void                 gkd_ssh_agent_client_preload_clear       (GkdSshAgentClient *self,
                                                                GBytes *key);
 
+void                 gkd_ssh_agent_client_preload_clear_all   (GkdSshAgentClient *self);
+
+void                 gkd_ssh_agent_client_cleanup             (void);
+
 #endif /* __GKD_SSH_AGENT_CLIENT_H__ */
diff --git a/daemon/ssh-agent/gkd-ssh-agent-ops.c b/daemon/ssh-agent/gkd-ssh-agent-ops.c
index 0912c3b..0f474e6 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-ops.c
+++ b/daemon/ssh-agent/gkd-ssh-agent-ops.c
@@ -45,8 +45,8 @@ op_add_identity (GkdSshAgentCall *call)
 {
        GList *keys;
        gsize offset;
-       gconstpointer data;
-       gsize size;
+       gconstpointer blob;
+       gsize length;
        GList *l;
 
        /*
@@ -59,19 +59,19 @@ op_add_identity (GkdSshAgentCall *call)
         * initial bytes as the public key we've loaded.
         */
 
-       keys = gkd_ssh_agent_client_get_preload_keys (call->agent);
+       keys = gkd_ssh_agent_client_preload_keys (call->agent);
 
        offset = 5;
        for (l = keys; l != NULL; l = g_list_next (l)) {
-               data = g_bytes_get_data (l->data, &size);
-               if (call->req->len >= size + offset &&
-                   memcmp (call->req->buf, data, size) == 0) {
-                       gkd_ssh_agent_client_clear_preload (call->agent, l->data);
+               blob = g_bytes_get_data (l->data, &length);
+               if (call->req->len >= length + offset &&
+                   memcmp (call->req->buf + offset, blob, length) == 0) {
+                       gkd_ssh_agent_client_preload_clear (call->agent, l->data);
                        break;
-               }:snp
+               }
        }
 
-       g_list_free_full (keys, g_bytes_unref);
+       g_list_free_full (keys, (GDestroyNotify)g_bytes_unref);
 
        return gkd_ssh_agent_relay (call);
 }
@@ -79,6 +79,10 @@ op_add_identity (GkdSshAgentCall *call)
 static GHashTable *
 parse_identities_answer (EggBuffer *resp)
 {
+       GHashTable *answer;
+       const guchar *blob;
+       gchar *comment;
+       gsize length;
        gsize offset = 4;
        guint32 count;
        guchar op;
@@ -91,19 +95,19 @@ parse_identities_answer (EggBuffer *resp)
                return NULL;
        }
 
-       keys = g_hash_table_new_full (g_bytes_hash, g_bytes_equal, g_bytes_unref, g_free);
+       answer = g_hash_table_new_full (g_bytes_hash, g_bytes_equal, (GDestroyNotify)g_bytes_unref, g_free);
 
        for (i = 0; i < count; i++) {
                if (!egg_buffer_get_byte_array (resp, offset, &offset, &blob, &length) ||
                    !egg_buffer_get_string (resp, offset, &offset, &comment, g_realloc)) {
                        g_warning ("got unparseable response back from ssh-agent when requesting identities");
-                       g_hash_table_unref (keys);
+                       g_hash_table_unref (answer);
                        return NULL;
                }
-               g_hash_table_insert (keys, g_bytes_new (blob, length), comment);
+               g_hash_table_insert (answer, g_bytes_new (blob, length), comment);
        }
 
-       return keys;
+       return answer;
 }
 
 
@@ -111,7 +115,12 @@ static gboolean
 op_request_identities (GkdSshAgentCall *call)
 {
        GHashTable *answer;
+       const guchar *blob;
+       gchar *comment;
+       gsize length;
        guint32 added;
+       GList *keys;
+       GList *l;
 
        if (!gkd_ssh_agent_relay (call))
                return FALSE;
@@ -124,72 +133,91 @@ op_request_identities (GkdSshAgentCall *call)
        added = 0;
 
        /* Add any preloaded keys not already in answer */
-       keys = gkd_ssh_agent_get_preload_keys (call->agent);
+       keys = gkd_ssh_agent_client_preload_keys (call->agent);
        for (l = keys; l != NULL; l = g_list_next (l)) {
                if (g_hash_table_lookup (answer, l->data))
                        continue;
                blob = g_bytes_get_data (l->data, &length);
                egg_buffer_add_byte_array (call->resp, blob, length);
-               comment = gkd_ssh_agent_get_preload_comment (l->data);
-               egg_buffer_add_string (comment ? comment : "");
+               comment = gkd_ssh_agent_client_preload_comment (call->agent, l->data);
+               egg_buffer_add_string (call->resp, comment ? comment : "");
+               g_free (comment);
                added++;
        }
 
-       g_list_free_full (keys, g_bytes_unref);
+       g_list_free_full (keys, (GDestroyNotify)g_bytes_unref);
 
        /* Set the correct amount of keys including the ones we added */
-       egg_buffer_set_uint32 (call->resp, 5, added + g_hash_table_get_size (answer));
+       egg_buffer_set_uint32 (call->resp, 5, added + g_hash_table_size (answer));
        g_hash_table_unref (answer);
 
        return TRUE;
 }
 
+static void
+preload_key_if_necessary (GkdSshAgentClient *agent,
+                          GBytes *key)
+{
+       EggBuffer buf;
+       const guchar *blob;
+       gchar *comment;
+       gsize length;
+       GBytes *priv;
+       guchar code;
+
+       priv = gkd_ssh_agent_client_preload_unlock (agent, key);
+       if (!priv)
+               return;
+
+       egg_buffer_init_full (&buf, 128, egg_secure_realloc);
+       egg_buffer_add_uint32 (&buf, 0); /* length */
+       egg_buffer_add_byte (&buf, GKD_SSH_OP_ADD_IDENTITY);
+       blob = g_bytes_get_data (priv, &length);
+       egg_buffer_add_byte_array (&buf, blob, length);
+
+       if (gkd_ssh_agent_client_call (agent, &buf, &buf)) {
+               if (!egg_buffer_get_byte (&buf, 4, NULL, &code) || code != GKD_SSH_RES_SUCCESS) {
+                       comment = gkd_ssh_agent_client_preload_comment (agent, key);
+                       g_warning ("couldn't add private key '%s' to ssh-agent", comment);
+                       g_free (comment);
+               }
+       }
+
+       gkd_ssh_agent_client_preload_clear (agent, key);
+}
+
 static gboolean
 op_sign_request (GkdSshAgentCall *call)
 {
-       EggBuffer buf;
+       const guchar *blob;
+       gsize length;
        gsize offset = 5;
        GBytes *key;
 
        /* If parsing the request fails, just pass through */
-       if (!egg_buffer_get_byte_array (call->resp, offset, &offset, &blob, &length)) {
+       if (egg_buffer_get_byte_array (call->resp, offset, &offset, &blob, &length)) {
+               key = g_bytes_new (blob, length);
+               preload_key_if_necessary (call->agent, key);
+               g_bytes_unref (key);
+       } else {
                g_warning ("got unparseable sign request for ssh-agent");
-               return gkd_ssh_agent_relay (call);
-       }
-
-       key = g_bytes_new (blob, length);
-       priv = gkd_ssh_agent_get_preload_private (call->agent, key);
-
-       if (priv) {
-               egg_buffer_init_full (&buf, xxxx);
-               egg_buffer_add_uint32 (&buf, 0); /* length */
-               egg_buffer_add_byte (&buf, GKR_ ADD_IDENTITY);
-               blob = g_bytes_get_data (&buf, priv, &length);
-               egg_buffer_add_byte_array (&buf, blob, length);
-
-               xxxx gkd_ssh_agent_call (call->agent, buf);
-
-               egg_buffer_get_byte (call->resp, what's the right code  GKD_SSH_RES_FAILURE);
-
-               gkd_ssh_agent_clear ();
-
-               xxxx parse xxxx;
        }
 
-       xxxx separate function xxxx
-out:
-       if (key)
-               g_bytes_unref (key);
        return gkd_ssh_agent_relay (call);
 }
 
 static gboolean
 op_remove_identity (GkdSshAgentCall *call)
 {
+       const guchar *blob;
+       gsize length;
+       gsize offset = 5;
+       GBytes *key;
+
        /* If parsing the request fails, just pass through */
        if (egg_buffer_get_byte_array (call->resp, offset, &offset, &blob, &length)) {
                key = g_bytes_new (blob, length);
-               gkd_ssh_agent_clear_preload (call->agent, key);
+               gkd_ssh_agent_client_preload_clear (call->agent, key);
                g_bytes_unref (key);
        } else {
                g_warning ("got unparseable remove request for ssh-agent");
@@ -202,7 +230,7 @@ op_remove_identity (GkdSshAgentCall *call)
 static gboolean
 op_remove_all_identities (GkdSshAgentCall *call)
 {
-       gkd_ssh_agent_clear_all (call->agent);
+       gkd_ssh_agent_client_preload_clear_all (call->agent);
        return gkd_ssh_agent_relay (call);
 }
 
diff --git a/daemon/ssh-agent/gkd-ssh-agent-private.h b/daemon/ssh-agent/gkd-ssh-agent-private.h
index 4a3c63a..d6c79cd 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-private.h
+++ b/daemon/ssh-agent/gkd-ssh-agent-private.h
@@ -97,8 +97,6 @@ gboolean              gkd_ssh_agent_read_packet                     (gint fd,
 gboolean              gkd_ssh_agent_write_packet                    (gint fd,
                                                                      EggBuffer *buffer);
 
-gboolean              gkd_ssh_agent_proto_write_signature_ecdsa     (EggBuffer *resp,
-                                                                     CK_BYTE_PTR signature,
-                                                                     CK_ULONG n_signature);
+gboolean              gkd_ssh_agent_relay                           (GkdSshAgentCall *call);
 
 #endif /*GKDSSHPRIVATE_H_*/
diff --git a/daemon/ssh-agent/gkd-ssh-agent.c b/daemon/ssh-agent/gkd-ssh-agent.c
index 354b3ca..50f5664 100644
--- a/daemon/ssh-agent/gkd-ssh-agent.c
+++ b/daemon/ssh-agent/gkd-ssh-agent.c
@@ -44,9 +44,6 @@
 typedef int socklen_t;
 #endif
 
-/* The loaded PKCS#11 modules */
-static GList *pkcs11_modules = NULL;
-
 EGG_SECURE_DECLARE (ssh_agent);
 
 static gboolean
@@ -140,8 +137,7 @@ gkd_ssh_agent_write_packet (gint fd,
 static gpointer
 run_client_thread (gpointer data)
 {
-       gint *socket = xxxx;
-       gint *agent = xxxx;
+       gint *socket = data;
        GkdSshAgentCall call;
        GkdSshAgentOperation func;
        EggBuffer req;
@@ -164,7 +160,7 @@ run_client_thread (gpointer data)
        for (;;) {
 
                /* 1. Read in the request */
-               if (!gkd_ssh_agent_read_packet (call.sock, &call.req))
+               if (!gkd_ssh_agent_read_packet (call.sock, call.req))
                        break;
 
                /* 2. Now decode the operation */
@@ -203,7 +199,6 @@ out:
 typedef struct _Client {
        GThread *thread;
        gint sock;
-       gint agent;
 } Client;
 
 /* Each client thread in this list */
@@ -221,7 +216,6 @@ gkd_ssh_agent_accept (void)
        Client *client;
        struct sockaddr_un addr;
        socklen_t addrlen;
-       GError *error = NULL;
        GList *l;
        int new_fd;
 
@@ -245,16 +239,8 @@ gkd_ssh_agent_accept (void)
                return;
        }
 
-       real_agent = gkd_ssh_agent_process_connect ();
-       if (real_agent < 0) {
-               /* Warning already printed */
-               close (new_fd);
-               return;
-       }
-
        client = g_slice_new0 (Client);
        client->sock = new_fd;
-       client->agent = real_agent;
 
        /* And create a new thread/process */
        client->thread = g_thread_new ("ssh-agent", run_client_thread, &client->sock);
@@ -278,10 +264,8 @@ gkd_ssh_agent_shutdown (void)
                client = l->data;
 
                /* Forcibly shutdown the connection */
-               if (client->sock != -1) {
+               if (client->sock != -1)
                        shutdown (client->sock, SHUT_RDWR);
-                       shutdown (client->agent, SHUT_RDWR);
-               }
                g_thread_join (client->thread);
 
                /* This is always closed by client thread */
@@ -292,7 +276,7 @@ gkd_ssh_agent_shutdown (void)
        g_list_free (socket_clients);
        socket_clients = NULL;
 
-       gkd_ssh_agent_process_cleanup ();
+       gkd_ssh_agent_client_cleanup ();
 }
 
 int
diff --git a/daemon/ssh-agent/gkd-ssh-agent.h b/daemon/ssh-agent/gkd-ssh-agent.h
index 03427d2..781ab45 100644
--- a/daemon/ssh-agent/gkd-ssh-agent.h
+++ b/daemon/ssh-agent/gkd-ssh-agent.h
@@ -33,8 +33,4 @@ void              gkd_ssh_agent_accept                  (void);
 
 void              gkd_ssh_agent_shutdown                (void);
 
-gboolean          gkd_ssh_agent_initialize              (CK_FUNCTION_LIST_PTR funcs);
-
-void              gkd_ssh_agent_uninitialize            (void);
-
 #endif /* GKDSSHAGENT_H_ */


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