From d640207c74e0aaf5b4a3faf61c38e17796bf76a2 Mon Sep 17 00:00:00 2001
From: Linus Nordberg <linus@nordberg.se>
Date: Mon, 11 Feb 2013 16:41:47 +0100
Subject: Add support for configuring client connections too.

We're moving x509 and psk config from rs_realm to rs_peer while
allowing these to be configured on the realm level and overriden at
peer level.

Also, add support for printing the read configuration, for debugging.
---
 lib/confutil.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 146 insertions(+)
 create mode 100644 lib/confutil.c

(limited to 'lib/confutil.c')

diff --git a/lib/confutil.c b/lib/confutil.c
new file mode 100644
index 0000000..3a1d639
--- /dev/null
+++ b/lib/confutil.c
@@ -0,0 +1,146 @@
+/* Copyright 2013 NORDUnet A/S. All rights reserved.
+   See LICENSE for licensing information.  */
+
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <radsec/radsec.h>
+#include <radsec/radsec-impl.h>
+
+#if 0
+/* This code triggers the memory-stomping-detector of electric fence */
+
+#define MEMCHUNK 30
+
+static int
+print_to_buf (const struct rs_context *ctx,
+              char **buf_ptr, ssize_t *i_ptr, ssize_t *len_ptr,
+              const char *fmt, ...)
+{
+  char *buf = *buf_ptr;
+  ssize_t i = *i_ptr;
+  ssize_t len = *len_ptr;
+
+  va_list args;
+  for (;;)
+    {
+      int n;
+      va_start (args, fmt);
+      fprintf (stdout, "sprintf (%p + %ld, %ld, \"%s\") -->",
+               buf, i, len, buf);
+      fflush (stdout);
+      n = vsnprintf (buf + i, len - i, fmt, args);
+      fprintf (stdout, "%d\n", n);
+      va_end (args);
+      if (n < 0)
+        return -RSE_INTERNAL;
+      if (n >= len - i)
+        {
+          int newlen = len + MEMCHUNK;
+          buf = rs_realloc (ctx, buf, newlen);
+          if (buf == NULL)
+            return -RSE_NOMEM;
+          len = newlen;
+          continue;
+        }
+      len -= n;
+      i += n;
+
+      *buf_ptr = buf;
+      *i_ptr = i;
+      *len_ptr = len;
+      return RSE_OK;
+    }
+}
+#endif  /* 0 */
+
+static int
+pp (char **out, size_t *len, const char *fmt, ...)
+{
+  int n;
+  va_list args;
+  va_start (args, fmt);
+  n = vsnprintf (*out, *len, fmt, args);
+  va_end (args);
+  if (n == -1 || n >= *len)
+    return -RSE_INTERNAL;
+  *out += n;
+  *len -= n;
+  return RSE_OK;
+}
+
+int
+rs_context_print_config (struct rs_context *ctx, char **buf_out)
+{
+  char *buf = rs_malloc (ctx, 8192);
+  char *out = NULL;
+  size_t len = 8192;
+  struct rs_config *cfg = ctx->config;
+  struct rs_realm *r = NULL;
+  struct rs_peer *p = NULL;
+  char *peer_type[] = {"<no type>", "client", "server"};
+  char *realm_type[] = {"<no type>", "UDP", "TCP", "TLS", "DTLS"};
+  char *cred_type[] = {"<no type>", "PSK", "DHE_PSK", "RSA_PSK"};
+
+  out = buf;
+  assert (out);
+  assert (cfg);
+
+  for (r = cfg->realms; r != NULL; r = r->next)
+    {
+      if (pp (&out, &len, "realm %s {\n", r->name)
+          || pp (&out, &len, "\ttype = \"%s\"\n\ttimeout = %d\n\tretries = %d\n",
+                 realm_type[r->type],
+                 r->timeout,
+                 r->retries))
+        return -RSE_INTERNAL;
+      for (p = r->peers; p != NULL; p = p->next)
+        {
+          if (pp (&out, &len,
+                  "\t%s {\n"
+                  "\t\thostname = \"%s\"\n"
+                  "\t\tservice = \"%s\"\n"
+                  "\t\tsecret = \"%s\"\n",
+                  peer_type[p->type],
+                  p->hostname,
+                  p->service,
+                  p->secret))
+            return -RSE_INTERNAL;
+          if (p->cacertfile)
+            if (pp (&out, &len, "\t\tcacertfile = \"%s\"\n", p->cacertfile))
+              return -RSE_INTERNAL;
+          if (p->certfile)
+            if (pp (&out, &len, "\t\tcertfile = \"%s\"\n", p->certfile))
+              return -RSE_INTERNAL;
+          if (p->certkeyfile)
+            if (pp (&out, &len, "\t\tcertkeyfile = \"%s\"\n", p->certkeyfile))
+              return -RSE_INTERNAL;
+          if (p->transport_cred)
+            {
+              if (pp (&out, &len, "\t\tpskex = \"%s\"\n",
+                      cred_type[p->transport_cred->type])
+                  || pp (&out, &len, "\t\tpskid = \"%s\"\n",
+                         p->transport_cred->identity)
+                  || pp (&out, &len,
+                         "\t\t%s = \"%s\"\n", (p->transport_cred->secret_encoding
+                                               == RS_KEY_ENCODING_ASCII_HEX
+                                               ? "pskhexstr" : "pskstr"),
+                         p->transport_cred->secret))
+                return -RSE_INTERNAL;
+            }
+          if (pp (&out, &len, "\t}\n"))
+            return -RSE_INTERNAL;
+        }
+      if (pp (&out, &len, "}\n"))
+        return -RSE_INTERNAL;
+    }
+
+  if (buf_out)
+    *buf_out = buf;
+  return RSE_OK;
+}
-- 
cgit v1.1