diff options
author | Stef Walter <stefw@gnome.org> | 2013-09-23 16:38:15 +0200 |
---|---|---|
committer | Daiki Ueno <dueno@src.gnome.org> | 2018-02-12 15:11:38 +0100 |
commit | 617f3841f780fef5ff1cd8839840769df6184162 (patch) | |
tree | 7f4a8658ef8825cbb54db17c7b4cc869cc92f798 | |
parent | 641c87f9508265b1f0ef544e029c19bf6d409347 (diff) | |
download | gnome-keyring-617f3841f780fef5ff1cd8839840769df6184162.tar.gz |
ssh-agent wip
-rw-r--r-- | daemon/gkd-pkcs11.c | 40 | ||||
-rw-r--r-- | daemon/gkd-pkcs11.h | 2 | ||||
-rw-r--r-- | daemon/ssh-agent/gkd-ssh-agent-private.h | 2 | ||||
-rw-r--r-- | daemon/ssh-agent/gkd-ssh-agent-process.c | 165 | ||||
-rw-r--r-- | 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 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__ */ |