[gnome-keyring/ssh-wip: 1/4] ssh-agent wip



commit e54a177a95d019cec8a065070da09950ca0605bf
Author: Stef Walter <stefw gnome org>
Date:   Mon Sep 23 16:38:15 2013 +0200

    ssh-agent wip

 daemon/gkd-pkcs11.c                         |   40 -------
 daemon/gkd-pkcs11.h                         |    2 -
 daemon/ssh-agent/gkd-ssh-agent-private.h    |    2 +
 daemon/ssh-agent/gkd-ssh-agent-process.c    |  165 +++++++++++++++++++++++++++
 daemon/ssh-agent/gkm-ssh-agent-connection.h |   72 ++++++++++++
 5 files changed, 239 insertions(+), 42 deletions(-)
---
diff --git a/daemon/gkd-pkcs11.c b/daemon/gkd-pkcs11.c
index b2e94c3..b3ed43b 100644
--- a/daemon/gkd-pkcs11.c
+++ b/daemon/gkd-pkcs11.c
@@ -160,46 +160,6 @@ gkd_pkcs11_startup_pkcs11 (void)
        return TRUE;
 }
 
-static void
-pkcs11_ssh_cleanup (gpointer unused)
-{
-       gkd_ssh_agent_shutdown ();
-}
-
-static gboolean
-accept_ssh_client (GIOChannel *channel, GIOCondition cond, gpointer unused)
-{
-       if (cond == G_IO_IN)
-               gkd_ssh_agent_accept ();
-       return TRUE;
-}
-
-gboolean
-gkd_pkcs11_startup_ssh (void)
-{
-       GIOChannel *channel;
-       const gchar *base_dir;
-       int sock;
-
-       base_dir = gkd_util_get_master_directory ();
-       g_return_val_if_fail (base_dir, FALSE);
-
-       sock = gkd_ssh_agent_startup (base_dir);
-       if (sock == -1)
-               return FALSE;
-
-       channel = g_io_channel_unix_new (sock);
-       g_io_add_watch (channel, G_IO_IN | G_IO_HUP, accept_ssh_client, NULL);
-       g_io_channel_unref (channel);
-
-       /* gkm-ssh-agent sets the environment variable */
-       gkd_util_push_environment ("SSH_AUTH_SOCK", g_getenv ("SSH_AUTH_SOCK"));
-
-       egg_cleanup_register (pkcs11_ssh_cleanup, NULL);
-
-       return TRUE;
-}
-
 CK_FUNCTION_LIST_PTR
 gkd_pkcs11_get_functions (void)
 {
diff --git a/daemon/gkd-pkcs11.h b/daemon/gkd-pkcs11.h
index 1da7b09..38e3f15 100644
--- a/daemon/gkd-pkcs11.h
+++ b/daemon/gkd-pkcs11.h
@@ -29,8 +29,6 @@ gboolean               gkd_pkcs11_initialize           (void);
 
 gboolean               gkd_pkcs11_startup_pkcs11       (void);
 
-gboolean               gkd_pkcs11_startup_ssh          (void);
-
 CK_FUNCTION_LIST_PTR   gkd_pkcs11_get_functions        (void);
 
 CK_FUNCTION_LIST_PTR   gkd_pkcs11_get_base_functions   (void);
diff --git a/daemon/ssh-agent/gkd-ssh-agent-private.h b/daemon/ssh-agent/gkd-ssh-agent-private.h
index efdc969..90a4aa4 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-private.h
+++ b/daemon/ssh-agent/gkd-ssh-agent-private.h
@@ -31,6 +31,8 @@
 
 #include <glib.h>
 
+gkd_ssh_agent_process_new
+
 typedef struct _GkdSshAgentCall {
        int sock;
        GList *modules;
diff --git a/daemon/ssh-agent/gkd-ssh-agent-process.c b/daemon/ssh-agent/gkd-ssh-agent-process.c
new file mode 100644
index 0000000..3e4acb2
--- /dev/null
+++ b/daemon/ssh-agent/gkd-ssh-agent-process.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2013 Red Hat Inc.
+ *
+ * Gnome keyring is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * Gnome keyring 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Stef Walter <stefw redhat com>
+ */
+
+#include "config.h"
+
+gint
+agent_start (const char *socket)
+{
+       gchar *argv[] = { SSH_AGENT, "-a", socket, NULL };
+       gchar *standard_error = NULL;
+       gchar *standard_output = NULL;
+       GError *error = NULL;
+       gint exit_status = 0;
+       gint ret = 0;
+       gchar *cmd;
+
+       if (!g_spawn_sync ("/", argv, NULL, NULL, NULL, &standard_output,
+                          &standard_error, &exit_status, &error) ||
+           !g_spawn_check_exit_status (exit_status, NULL)) {
+               cmd = g_strjoinv (" ", argv);
+               if (error != NULL) {
+                       g_warning ("couldn't run: %s: %s", cmd, error->message);
+                       g_error_free (error);
+               } else {
+                       g_warning ("failed to run: %s", cmd);
+               }
+               g_free (cmd);
+
+       /* Sucessfully running, pull out the PID */
+       } else {
+               lines = g_strsplit (standard_output, "\n", -1);
+               for (i = 0; lines[i] != NULL; i++) {
+                       g_strstrip (lines[i]);
+                       if (g_str_has_prefix (lines[i], "SSH_AGENT_PID=")) {
+                               pid = lines[i] + 16;
+                               pos = strchr (pid, ';');
+                               if (pos != NULL)
+                                       pos[0] = '\0';
+                               ret = (int)strtol (pid, 10, &endptr);
+                               if (!endptr || endptr != '\0') {
+                                       g_warning ("invalid pid received from ssh-agent: %s", pid);
+                                       ret = 0;
+                               }
+                               break;
+                       }
+               }
+               g_strfreev (lines);
+       }
+
+       if (standard_error) {
+               lines = g_strsplit (standard_error, "\n", -1);
+               for (i = 0; lines[i] != NULL; i++)
+                       g_warning ("%s", g_strchomp (lines[0]));
+               g_strfreev (lines);
+       }
+
+       g_free (standard_error);
+       g_free (standard_output);
+       return ret;
+}
+
+gboolean
+agent_check (gint pid)
+{
+       return pid && (kill (pid, 0) == 0);
+}
+
+void
+agent_terminate (gint pid)
+{
+       kill (pid, SIGTERM);
+}
+
+static gchar *
+agent_make_path (void)
+{
+       const char *directory;
+
+       directory = gkd_util_master_directory ();
+}
+
+G_LOCK (ssh_agent_process);
+static gchar *ssh_agent_path = NULL;
+static gint ssh_agent_pid;
+
+GIOStream *
+gkd_ssh_agent_process_connect (void)
+{
+       GSocketConnection *connection;
+       GSocketAddress *address;
+       const gchar *directory;
+       GError *error = NULL;
+       GSocket *sock;
+       gboolean ready;
+
+       G_LOCK (ssh_agent_process);
+
+       if (ssh_agent_path) {
+               directory = gkd_util_master_directory ();
+               ssh_agent_path = g_build_filename (directory, "ssh-actual", NULL);
+       }
+
+       ready = agent_check (ssh_agent_pid);
+       if (!ready) {
+               ssh_agent_pid = agent_start (ssh_agent_path);
+               ready = (ssh_agent_pid != 0);
+       }
+
+       G_UNLOCK (ssh_agent_pid);
+
+       if (!ready)
+               return NULL;
+
+       sock = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM,
+                            G_SOCKET_PROTOCOL_DEFAULT);
+       g_return_val_if_fail (sock != NULL, NULL);
+
+       connection = g_socket_connection_factory_create_connection (sock);
+       g_return_val_if_fail (connection != NULL, NULL);
+       g_object_unref (sock);
+
+       address = g_unix_socket_address_new (ssh_agent_path);
+       g_return_val_if_fail (address != NULL, NULL);
+
+       if (!g_socket_connection_connect (connection, address, NULL, &error)) {
+               g_warning ("couldn't connect to ssh-agent: %s", error->message);
+               g_object_unref (connection);
+               connection = NULL;
+       }
+
+       g_object_unref (address);
+       return connection;
+}
+
+void
+gkd_ssh_agent_process_cleanup (void)
+{
+       G_LOCK (ssh_agent_process);
+
+       if (ssh_agent_pid)
+               agent_terminate (ssh_agent_pid);
+       ssh_agent_pid = 0;
+
+       g_free (ssh_agent_path);
+       ssh_agent_path = NULL;
+
+       G_UNLOCK (ssh_agent_process);
+}
diff --git a/daemon/ssh-agent/gkm-ssh-agent-connection.h b/daemon/ssh-agent/gkm-ssh-agent-connection.h
new file mode 100644
index 0000000..03f8823
--- /dev/null
+++ b/daemon/ssh-agent/gkm-ssh-agent-connection.h
@@ -0,0 +1,72 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2013 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Author: Stef Walter <stefw redhat com>
+ */
+
+#ifndef __GKM_SSH_AGENT_CONNECTION_H__
+#define __GKM_SSH_AGENT_CONNECTION_H__
+
+#include <glib-object.h>
+
+#include "gkm-secret-types.h"
+
+#include "gkm/gkm-types.h"
+
+#define GKM_TYPE_SSH_AGENT_CONNECTION               (gkm_ssh_agent_connection_get_type ())
+#define GKM_SSH_AGENT_CONNECTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GKM_TYPE_SSH_AGENT_CONNECTION, GkmSshAgentConnection))
+#define GKM_SSH_AGENT_CONNECTION_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), 
GKM_TYPE_SSH_AGENT_CONNECTION, GkmSshAgentConnectionClass))
+#define GKM_IS_SSH_AGENT_CONNECTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GKM_TYPE_SSH_AGENT_CONNECTION))
+#define GKM_IS_SSH_AGENT_CONNECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), 
GKM_TYPE_SSH_AGENT_CONNECTION))
+#define GKM_SSH_AGENT_CONNECTION_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GKM_TYPE_SSH_AGENT_CONNECTION, GkmSshAgentConnectionClass))
+
+typedef struct _GkmSshAgentConnectionClass GkmSshAgentConnectionClass;
+
+struct _GkmSshAgentConnectionClass {
+       GObjectClass parent_class;
+};
+
+GType                gkm_ssh_agent_connection_get_type        (void);
+
+GkmSecret*           gkm_ssh_agent_connection_get_secret      (GkmSshAgentConnection *self,
+                                                      const gchar *identifier);
+
+const guchar*        gkm_ssh_agent_connection_get_raw         (GkmSshAgentConnection *self,
+                                                      const gchar *identifier,
+                                                      gsize *n_result);
+
+void                 gkm_ssh_agent_connection_set_secret      (GkmSshAgentConnection *self,
+                                                      const gchar *identifier,
+                                                      GkmSecret *secret);
+
+void                 gkm_ssh_agent_connection_set_transacted  (GkmSshAgentConnection *self,
+                                                      GkmTransaction *transaction,
+                                                      const gchar *identifier,
+                                                      GkmSecret *secret);
+
+void                 gkm_ssh_agent_connection_remove_secret   (GkmSshAgentConnection *self,
+                                                      const gchar *identifier);
+
+GkmSecret*           gkm_ssh_agent_connection_get_master      (GkmSshAgentConnection *self);
+
+void                 gkm_ssh_agent_connection_set_master      (GkmSshAgentConnection *self,
+                                                      GkmSecret *master);
+
+#endif /* __GKM_SSH_AGENT_CONNECTION_H__ */


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