[libsocialweb] keystore: Implementation of requesting API keys from kernel keyring
- From: Rob Bradford <rbradford src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsocialweb] keystore: Implementation of requesting API keys from kernel keyring
- Date: Tue, 19 Apr 2011 18:13:12 +0000 (UTC)
commit 2731f64945e0f6a292f705058a9467517e1a3aab
Author: Stef Walter <stefw collabora co uk>
Date: Thu Apr 7 14:28:08 2011 +0200
keystore: Implementation of requesting API keys from kernel keyring
Fixes: https://bugs.meego.com/show_bug.cgi?id=16373
examples/Makefile.am | 7 ++-
examples/request-api-key.sh | 13 +++++
libsocialweb-keystore/Makefile.am | 4 +-
libsocialweb-keystore/sw-keystore.c | 87 +++++++++++++++++++++++++++++++++--
4 files changed, 103 insertions(+), 8 deletions(-)
---
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 253bc4e..af04f97 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -10,4 +10,9 @@ monitor_caps_LDFLAGS = $(DBUS_GLIB_LIBS) \
$(top_builddir)/libsocialweb-client/libsocialweb-client.la
monitor_caps_SOURCES = monitor-caps.c
-EXTRA_DIST = monitor.py
+all-local:
+ chmod +x request-api-key.sh
+
+EXTRA_DIST = \
+ monitor.py \
+ request-api-key.sh
diff --git a/examples/request-api-key.sh b/examples/request-api-key.sh
new file mode 100755
index 0000000..7491e5e
--- /dev/null
+++ b/examples/request-api-key.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# This is an example program to be used with request-key and the kernel-keyring
+# Add a line like this to /etc/request-key.conf
+#
+# create user libsocialweb:* * /path/to/libsocialweb/examples/request-api-key.sh %k %d %c %S
+#
+
+KEY="THEKEYHERE
+THESECRETHERE"
+
+echo "requesting key with args: $@" >> /tmp/request-api-key.log
+keyctl instantiate $1 "$KEY" $4 || exit 1
diff --git a/libsocialweb-keystore/Makefile.am b/libsocialweb-keystore/Makefile.am
index 117c3e2..1f7b886 100644
--- a/libsocialweb-keystore/Makefile.am
+++ b/libsocialweb-keystore/Makefile.am
@@ -2,8 +2,8 @@ lib_LTLIBRARIES = libsocialweb-keystore.la
libsocialweb_keystore_ladir = $(pkgincludedir)/libsocialweb-keystore
libsocialweb_keystore_la_CFLAGS = -I$(top_srcdir) $(GIO_CFLAGS) -DG_LOG_DOMAIN=\"libsocialweb-keystore\"\
- $(GCOV_CFLAGS)
-libsocialweb_keystore_la_LIBADD = $(GIO_LIBS) $(GCOV_LDFLAGS)
+ $(GCOV_CFLAGS) $(KEYUTILS_CFLAGS)
+libsocialweb_keystore_la_LIBADD = $(GIO_LIBS) $(GCOV_LDFLAGS) $(KEYUTILS_LIBS)
libsocialweb_keystore_la_SOURCES = \
sw-keystore.c sw-keystore.h
diff --git a/libsocialweb-keystore/sw-keystore.c b/libsocialweb-keystore/sw-keystore.c
index 7046a01..4b6835b 100644
--- a/libsocialweb-keystore/sw-keystore.c
+++ b/libsocialweb-keystore/sw-keystore.c
@@ -26,11 +26,17 @@
*/
#include <config.h>
+#include <errno.h>
#include <string.h>
+#include <stdlib.h>
#include <glib.h>
#include <gio/gio.h>
#include "sw-keystore.h"
+#if WITH_KEYUTILS
+#include <keyutils.h>
+#endif
+
typedef struct {
char *key;
char *secret;
@@ -165,6 +171,70 @@ get_keys_hash (void)
return once.retval;
}
+#ifdef WITH_KEYUTILS
+
+static gboolean
+lookup_key_in_kernel (const char *service, const char **key, const char **secret)
+{
+ gchar *description;
+ key_serial_t serial;
+ KeyData *data;
+ gchar *buffer = NULL;
+ const gchar *end;
+ const gchar *line;
+ long len;
+
+ description = g_strdup_printf ("libsocialweb:%s", service);
+ serial = request_key ("user", description, service,
+ KEY_SPEC_SESSION_KEYRING);
+ g_free (description);
+
+ if (serial == -1) {
+ g_warning (G_STRLOC ": couldn't lookup key in kernel: %s",
+ g_strerror (errno));
+ return FALSE;
+ }
+
+ len = keyctl_read_alloc (serial, (void**)&buffer);
+ if (len == -1) {
+ g_warning (G_STRLOC ": couldn't read key from kernel: %s",
+ g_strerror (errno));
+ return FALSE;
+ }
+
+ data = g_new0 (KeyData, 1);
+ end = buffer + len;
+
+ /* See if there are two values separated by a line break */
+ line = memchr (buffer, '\n', len);
+ if (line == NULL)
+ line = end;
+
+ /* If either line is empty, that part becomes NULL */
+ if (line == buffer)
+ data->key = NULL;
+ else
+ data->key = g_strndup (buffer, line - buffer);
+ if (line != end) {
+ line++;
+ if (line == end)
+ data->secret = NULL;
+ else
+ data->secret = g_strndup (line, end - line);
+ }
+
+ free (buffer);
+
+ g_hash_table_replace (get_keys_hash (), g_strdup (service), data);
+ *key = data->key;
+ if (secret)
+ *secret = data->secret;
+
+ return TRUE;
+}
+
+#endif /* WITH_KEYUTILS */
+
gboolean
sw_keystore_get_key_secret (const char *service, const char **key, const char **secret)
{
@@ -180,12 +250,19 @@ sw_keystore_get_key_secret (const char *service, const char **key, const char **
if (secret)
*secret = data->secret;
return TRUE;
- } else {
- *key = NULL;
- if (secret)
- *secret = NULL;
- return FALSE;
}
+
+#if ! BUILD_TESTS
+#ifdef WITH_KEYUTILS
+ if (lookup_key_in_kernel (service, key, secret))
+ return TRUE;
+#endif
+#endif
+
+ *key = NULL;
+ if (secret)
+ *secret = NULL;
+ return FALSE;
}
const char *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]