diff options
Diffstat (limited to 'lib/confutil.c')
-rw-r--r-- | lib/confutil.c | 146 |
1 files changed, 146 insertions, 0 deletions
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; +} |