summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-09-23 16:38:15 +0200
committerDaiki Ueno <dueno@src.gnome.org>2018-02-12 15:11:38 +0100
commit617f3841f780fef5ff1cd8839840769df6184162 (patch)
tree7f4a8658ef8825cbb54db17c7b4cc869cc92f798
parent641c87f9508265b1f0ef544e029c19bf6d409347 (diff)
downloadgnome-keyring-617f3841f780fef5ff1cd8839840769df6184162.tar.gz
ssh-agent wip
-rw-r--r--daemon/gkd-pkcs11.c40
-rw-r--r--daemon/gkd-pkcs11.h2
-rw-r--r--daemon/ssh-agent/gkd-ssh-agent-private.h2
-rw-r--r--daemon/ssh-agent/gkd-ssh-agent-process.c165
-rw-r--r--daemon/ssh-agent/gkm-ssh-agent-connection.h72
5 files changed, 239 insertions, 42 deletions
diff --git a/daemon/gkd-pkcs11.c b/daemon/gkd-pkcs11.c
index 71fdfe21..5f407fa2 100644
--- a/daemon/gkd-pkcs11.c
+++ b/daemon/gkd-pkcs11.c
@@ -157,46 +157,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 1da7b091..38e3f152 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 a6c35a44..175759f4 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 00000000..3e4acb2f
--- /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 00000000..03f8823f
--- /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__ */