[libsocialweb] keystore: Implementation of requesting API keys from kernel keyring



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]