summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@src.gnome.org>2018-02-13 16:14:32 +0100
committerDaiki Ueno <dueno@src.gnome.org>2018-02-13 16:14:32 +0100
commitd128015f19d91d8b63795bc81a288df9f465890e (patch)
tree9450a0b69a3b8f9f4576d7ea5fcdf13ccb7c2020
parente8aabea3e1c73732113efd0b0bfa8bd20e3dbacc (diff)
downloadgnome-keyring-wip/dueno/ssh-agent.tar.gz
ssh-agent: move preloaded key management out of GkdSshAgentProcesswip/dueno/ssh-agent
-rw-r--r--daemon/ssh-agent/gkd-ssh-agent-ops.c71
-rw-r--r--daemon/ssh-agent/gkd-ssh-agent-private.h2
-rw-r--r--daemon/ssh-agent/gkd-ssh-agent-process.c44
-rw-r--r--daemon/ssh-agent/gkd-ssh-agent.c13
4 files changed, 68 insertions, 62 deletions
diff --git a/daemon/ssh-agent/gkd-ssh-agent-ops.c b/daemon/ssh-agent/gkd-ssh-agent-ops.c
index 2d82b1b9..04af5356 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-ops.c
+++ b/daemon/ssh-agent/gkd-ssh-agent-ops.c
@@ -44,6 +44,43 @@ EGG_SECURE_DECLARE (ssh_agent_ops);
/* ---------------------------------------------------------------------------- */
static gboolean
+lookup_key (GkdSshAgentCall *call,
+ GBytes *key)
+{
+ gboolean ret;
+ g_mutex_lock (call->lock);
+ ret = g_hash_table_contains (call->keys, key);
+ g_mutex_unlock (call->lock);
+ return ret;
+}
+
+static void
+add_key (GkdSshAgentCall *call,
+ GBytes *key)
+{
+ g_mutex_lock (call->lock);
+ g_hash_table_add (call->keys, g_bytes_ref (key));
+ g_mutex_unlock (call->lock);
+}
+
+static void
+remove_key (GkdSshAgentCall *call,
+ GBytes *key)
+{
+ g_mutex_lock (call->lock);
+ g_hash_table_remove (call->keys, key);
+ g_mutex_lock (call->lock);
+}
+
+static void
+clear_keys (GkdSshAgentCall *call)
+{
+ g_mutex_lock (call->lock);
+ g_hash_table_remove_all (call->keys);
+ g_mutex_unlock (call->lock);
+}
+
+static gboolean
op_add_identity (GkdSshAgentCall *call)
{
const guchar *blob;
@@ -53,17 +90,16 @@ op_add_identity (GkdSshAgentCall *call)
gboolean ret;
/* If parsing the request fails, just pass through */
- if (egg_buffer_get_byte_array (call->req, offset, &offset, &blob, &length)) {
+ ret = egg_buffer_get_byte_array (call->req, offset, &offset, &blob, &length);
+ if (ret)
key = g_bytes_new (blob, length);
- } else {
+ else
g_warning ("got unparseable add identity request for ssh-agent");
- }
ret = gkd_ssh_agent_process_call (call->process, call->req, call->resp);
-
if (key) {
if (ret)
- gkd_ssh_agent_process_add_key (call->process, key);
+ add_key (call, key);
g_bytes_unref (key);
}
@@ -128,7 +164,7 @@ op_request_identities (GkdSshAgentCall *call)
g_hash_table_iter_init (&iter, answer);
while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL))
- gkd_ssh_agent_process_add_key (call->process, key);
+ add_key (call, key);
added = 0;
@@ -177,7 +213,7 @@ load_key_if_necessary (GkdSshAgentCall *call,
if (!filename)
return;
- if (gkd_ssh_agent_process_lookup_key (call->process, key))
+ if (lookup_key (call, key))
return;
interaction = gkd_ssh_interaction_new (key);
@@ -193,7 +229,7 @@ load_key_if_necessary (GkdSshAgentCall *call,
g_message ("the %s command failed: %s", argv[0], error->message);
} else {
- gkd_ssh_agent_process_add_key (call->process, key);
+ add_key (call, key);
}
g_clear_error (&error);
@@ -231,17 +267,17 @@ op_remove_identity (GkdSshAgentCall *call)
gboolean ret;
/* If parsing the request fails, just pass through */
- if (egg_buffer_get_byte_array (call->resp, offset, &offset, &blob, &length)) {
+ ret = egg_buffer_get_byte_array (call->resp, offset, &offset, &blob, &length);
+ if (ret)
key = g_bytes_new (blob, length);
- } else {
+ else
g_warning ("got unparseable remove request for ssh-agent");
- }
/* If the key doesn't exist what happens here? */
ret = gkd_ssh_agent_process_call (call->process, call->req, call->resp);
if (key) {
if (ret)
- gkd_ssh_agent_process_remove_key (call->process, key);
+ remove_key (call, key);
g_bytes_unref (key);
}
return ret;
@@ -250,12 +286,13 @@ op_remove_identity (GkdSshAgentCall *call)
static gboolean
op_remove_all_identities (GkdSshAgentCall *call)
{
- if (gkd_ssh_agent_process_call (call->process, call->req, call->resp)) {
- gkd_ssh_agent_process_clear_keys (call->process);
- return TRUE;
- }
+ gboolean ret;
- return FALSE;
+ ret = gkd_ssh_agent_process_call (call->process, call->req, call->resp);
+ if (ret)
+ clear_keys (call);
+
+ return ret;
}
const GkdSshAgentOperation gkd_ssh_agent_operations[GKD_SSH_OP_MAX] = {
diff --git a/daemon/ssh-agent/gkd-ssh-agent-private.h b/daemon/ssh-agent/gkd-ssh-agent-private.h
index 0ca97ace..f2e74b46 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-private.h
+++ b/daemon/ssh-agent/gkd-ssh-agent-private.h
@@ -34,6 +34,8 @@ typedef struct _GkdSshAgentCall {
EggBuffer *req;
EggBuffer *resp;
GkdSshAgentProcess *process;
+ GHashTable *keys;
+ GMutex *lock;
} GkdSshAgentCall;
/* -----------------------------------------------------------------------------
diff --git a/daemon/ssh-agent/gkd-ssh-agent-process.c b/daemon/ssh-agent/gkd-ssh-agent-process.c
index 03a9846c..ff8a1cff 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-process.c
+++ b/daemon/ssh-agent/gkd-ssh-agent-process.c
@@ -23,8 +23,6 @@
#include "gkd-ssh-agent-process.h"
#include "gkd-ssh-agent-private.h"
-#include "daemon/gkd-util.h"
-
#include <glib-unix.h>
#include <glib/gstdio.h>
@@ -45,7 +43,6 @@ struct _GkdSshAgentProcess
gchar *path;
gint socket_fd; /* socket opened by the ssh-agent process */
gint output_fd; /* stdout of the ssh-agent process */
- GHashTable *keys; /* keys actually known to the ssh-agent process */
GMutex lock;
GPid pid;
guint output_id;
@@ -60,8 +57,6 @@ gkd_ssh_agent_process_init (GkdSshAgentProcess *self)
{
self->socket_fd = -1;
self->output_fd = -1;
- self->keys = g_hash_table_new_full (g_bytes_hash, g_bytes_equal,
- (GDestroyNotify)g_bytes_unref, NULL);
g_mutex_init (&self->lock);
}
@@ -80,8 +75,6 @@ gkd_ssh_agent_process_finalize (GObject *object)
g_source_remove (self->child_id);
if (self->pid)
kill (self->pid, SIGTERM);
- if (self->keys)
- g_hash_table_unref (self->keys);
g_unlink (self->path);
g_free (self->path);
g_mutex_clear (&self->lock);
@@ -358,43 +351,6 @@ gkd_ssh_agent_process_call (GkdSshAgentProcess *self,
gkd_ssh_agent_read_packet (self->socket_fd, resp);
}
-gboolean
-gkd_ssh_agent_process_lookup_key (GkdSshAgentProcess *self,
- GBytes *key)
-{
- gboolean ret;
- g_mutex_lock (&self->lock);
- ret = g_hash_table_contains (self->keys, key);
- g_mutex_unlock (&self->lock);
- return ret;
-}
-
-void
-gkd_ssh_agent_process_add_key (GkdSshAgentProcess *self,
- GBytes *key)
-{
- g_mutex_lock (&self->lock);
- g_hash_table_add (self->keys, g_bytes_ref (key));
- g_mutex_unlock (&self->lock);
-}
-
-void
-gkd_ssh_agent_process_remove_key (GkdSshAgentProcess *self,
- GBytes *key)
-{
- g_mutex_lock (&self->lock);
- g_hash_table_remove (self->keys, key);
- g_mutex_lock (&self->lock);
-}
-
-void
-gkd_ssh_agent_process_clear_keys (GkdSshAgentProcess *self)
-{
- g_mutex_lock (&self->lock);
- g_hash_table_remove_all (self->keys);
- g_mutex_unlock (&self->lock);
-}
-
GkdSshAgentProcess *
gkd_ssh_agent_process_new (const gchar *path)
{
diff --git a/daemon/ssh-agent/gkd-ssh-agent.c b/daemon/ssh-agent/gkd-ssh-agent.c
index 765ddf97..bafd49d6 100644
--- a/daemon/ssh-agent/gkd-ssh-agent.c
+++ b/daemon/ssh-agent/gkd-ssh-agent.c
@@ -52,6 +52,9 @@ static char process_path[1024] = { 0, };
/* The ssh-agent process */
static GkdSshAgentProcess *process = NULL;
+static GHashTable *keys = NULL;
+static GMutex keys_lock;
+
static gboolean
agent_relay (GkdSshAgentCall *call)
{
@@ -76,10 +79,11 @@ run_client_thread (gpointer data)
egg_buffer_init_full (&resp, 128, (EggBufferAllocator)g_realloc);
call.req = &req;
call.resp = &resp;
-
call.process = process;
if (!gkd_ssh_agent_process_connect (call.process))
goto out;
+ call.keys = keys;
+ call.lock = &keys_lock;
for (;;) {
@@ -202,6 +206,10 @@ gkd_ssh_agent_shutdown (void)
g_object_unref (process);
process = NULL;
+
+ g_mutex_clear (&keys_lock);
+ g_hash_table_unref (keys);
+ keys = NULL;
}
int
@@ -244,6 +252,9 @@ gkd_ssh_agent_startup (const gchar *prefix)
unlink (process_path);
process = gkd_ssh_agent_process_new (process_path);
+ keys = g_hash_table_new_full (g_bytes_hash, g_bytes_equal,
+ (GDestroyNotify)g_bytes_unref, NULL);
+ g_mutex_init (&keys_lock);
return sock;
}