Bringing up TLS connections working.
authorLinus Nordberg <linus@nordu.net>
Thu, 11 Nov 2010 09:30:35 +0000 (10:30 +0100)
committerLinus Nordberg <linus@nordu.net>
Thu, 11 Nov 2010 09:30:35 +0000 (10:30 +0100)
NOTE: Clean up of resources not yet sane.  Expect resource leakages.

NOTE: Most failure cases are not handled properly.  With the wind at
your back and the sun shining, it might work.

28 files changed:
hostport.h
hostport_types.h [new file with mode: 0644]
lib/Makefile.am
lib/attr.c
lib/conf.c
lib/configure.ac
lib/conn.c
lib/debug.c
lib/err.c
lib/examples/client.conf
lib/include/radsec/radsec-impl.h
lib/include/radsec/radsec.h
lib/packet.c
lib/radsec.c
lib/request.c
lib/rsp_debug.c [moved from debug.c with 99% similarity]
lib/rsp_debug.h [moved from debug.h with 100% similarity]
lib/rsp_hash.c [moved from hash.c with 98% similarity]
lib/rsp_hash.h [moved from hash.h with 100% similarity]
lib/rsp_list.c [moved from list.c with 97% similarity]
lib/rsp_list.h [moved from list.h with 100% similarity]
lib/rsp_tlscommon.c [moved from tlscommon.c with 93% similarity]
lib/rsp_tlscommon.h [moved from tlscommon.h with 98% similarity]
lib/rsp_util.c [moved from util.c with 99% similarity]
lib/rsp_util.h [moved from util.h with 100% similarity]
lib/tls.c [new file with mode: 0644]
lib/tls.h [new file with mode: 0644]
radsecproxy.h

index 425bb8f..01237e2 100644 (file)
@@ -6,12 +6,7 @@
  * copyright notice and this permission notice appear in all copies.
  */
 
-struct hostportres {
-    char *host;
-    char *port;
-    uint8_t prefixlen;
-    struct addrinfo *addrinfo;
-};
+#include "hostport_types.h"
 
 struct hostportres *newhostport(char *hostport, char *default_port, uint8_t prefixok);
 int addhostport(struct list **hostports, char **hostport, char *portdefault, uint8_t prefixok);
diff --git a/hostport_types.h b/hostport_types.h
new file mode 100644 (file)
index 0000000..01fb443
--- /dev/null
@@ -0,0 +1,6 @@
+struct hostportres {
+    char *host;
+    char *port;
+    uint8_t prefixlen;
+    struct addrinfo *addrinfo;
+};
index 5d7cd0a..ca7de1f 100644 (file)
@@ -13,7 +13,16 @@ libradsec_la_SOURCES = \
        debug.c \
        err.c \
        packet.c \
+       radsec.c \
        request.c \
-       radsec.c
+       tls.c
+
+libradsec_la_SOURCES += \
+       rsp_debug.c \
+       rsp_hash.c \
+       rsp_list.c \
+       rsp_tlscommon.c \
+       rsp_util.c
+
 libradsec_la_LDFLAGS = -version-info 0:0:0
-libradsec_la_CFLAGS = $(CFLAGS) #-DDEBUG -DDEBUG_LEVENT
+libradsec_la_CFLAGS = $(CFLAGS) -DDEBUG -DDEBUG_LEVENT
index 4e66235..29384d5 100644 (file)
@@ -1,5 +1,9 @@
 /* See the file COPYING for licensing information.  */
 
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <freeradius/libradius.h>
 #include <radsec/radsec.h>
 #include <radsec/radsec-impl.h>
index cedb84c..c235ffe 100644 (file)
@@ -1,3 +1,9 @@
+/* See the file COPYING for licensing information.  */
+
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <confuse.h>
 #include <string.h>
 #include <radsec/radsec.h>
@@ -6,7 +12,11 @@
 #if 0
   # example of client config
   config NAME {
-      type = "UDP|TCP|TLS|DTLS"
+      type = "UDP"|"TCP"|"TLS"|"DTLS"
+      cacertfile = STRING
+      #cacertpath = STRING
+      certfile = STRING
+      certkeyfile = STRING
       server {
           hostname = STRING
          service = STRING
@@ -33,6 +43,10 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)
   cfg_opt_t config_opts[] =
     {
       CFG_STR ("type", "UDP", CFGF_NONE),
+      CFG_STR ("cacertfile", NULL, CFGF_NONE),
+      /*CFG_STR ("cacertpath", NULL, CFGF_NONE),*/
+      CFG_STR ("certfile", NULL, CFGF_NONE),
+      CFG_STR ("certkeyfile", NULL, CFGF_NONE),
       CFG_SEC ("server", server_opts, CFGF_MULTI),
       CFG_END ()
     };
@@ -62,6 +76,7 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)
        ctx->realms = r;
       cfg_config = cfg_getnsec (cfg, "config", i);
       r->name = strdup (cfg_title (cfg_config));
+
       typestr = cfg_getstr (cfg_config, "type");
       if (!strcmp (typestr, "UDP"))
        r->type = RS_CONN_TYPE_UDP;
@@ -75,6 +90,11 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)
        return rs_err_ctx_push_fl (ctx, RSE_CONFIG, __FILE__, __LINE__,
                                   "%s: invalid connection type", typestr);
 
+      r->cacertfile = cfg_getstr (cfg_config, "cacertfile");
+      /*r->cacertpath = cfg_getstr (cfg_config, "cacertpath");*/
+      r->certfile = cfg_getstr (cfg_config, "certfile");
+      r->certkeyfile = cfg_getstr (cfg_config, "certkeyfile");
+
       /* Add peers, one per server stanza.  */
       for (j = 0; j < cfg_size (cfg_config, "server"); j++)
        {
@@ -82,6 +102,7 @@ rs_context_read_config(struct rs_context *ctx, const char *config_file)
          if (!p)
            return rs_err_ctx_push_fl (ctx, RSE_NOMEM, __FILE__, __LINE__,
                                       NULL);
+         p->realm = r;
 
          cfg_server = cfg_getnsec (cfg_config, "server", j);
          _rs_resolv (&p->addr, r->type, cfg_getstr (cfg_server, "hostname"),
index 5ae729f..2039233 100644 (file)
@@ -11,6 +11,13 @@ AC_PROG_LIBTOOL
 # Checks for programs.
 AC_PROG_CC
 
+# Enable-knobs.
+AH_TEMPLATE([RS_ENABLE_TLS], [TLS (RadSec) enabled])
+AH_TEMPLATE([RADPROT_TLS], [])
+AC_ARG_ENABLE([tls], AS_HELP_STRING([--enable-tls], [enable TLS (RadSec)]),
+    [AC_DEFINE([RS_ENABLE_TLS])
+     AC_DEFINE([RADPROT_TLS])])
+
 # Checks for libraries.
 AC_CHECK_LIB([confuse], [cfg_init],,
     AC_MSG_ERROR([required library libconfuse not found]))
@@ -18,9 +25,15 @@ AC_CHECK_LIB([event_core], [event_get_version],,
     AC_MSG_ERROR([required library libevent_core not found]))
 AC_CHECK_LIB([freeradius-radius], [rad_alloc],,
     AC_MSG_ERROR([required library libfreeradius-radius not found]))
+dnl TODO: Only do this if --enable-tls or --enable-dtls.
+#AC_CHECK_LIB([ssl], [SSL_new],,
+#    AC_MSG_ERROR([required library libssl not found]))
+AC_CHECK_LIB([event_openssl], [bufferevent_openssl_socket_new],,
+    AC_MSG_ERROR([required library event_openssl not found]))
 
 # Checks for header files.
-AC_CHECK_HEADERS([netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h unistd.h])
+AC_CHECK_HEADERS(
+    [netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h unistd.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_TYPE_SIZE_T
@@ -28,8 +41,6 @@ AC_TYPE_SSIZE_T
 AC_TYPE_UINT8_T
 
 # Checks for library functions.
-AC_FUNC_MALLOC
-AC_FUNC_REALLOC
 AC_CHECK_FUNCS([memset socket strdup strerror strrchr])
 
 AC_CONFIG_FILES([Makefile
index 62105e6..b65b1da 100644 (file)
@@ -1,6 +1,11 @@
 /* See the file COPYING for licensing information.  */
 
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <assert.h>
+#include <event2/event.h>
 #include <radsec/radsec.h>
 #include <radsec/radsec-impl.h>
 
@@ -49,7 +54,7 @@ _rs_resolv (struct evutil_addrinfo **addr, rs_conn_type_t type,
   struct evutil_addrinfo hints, *res = NULL;
 
   memset (&hints, 0, sizeof(struct evutil_addrinfo));
-  hints.ai_family = AF_UNSPEC; /* v4 or v6.  */
+  hints.ai_family = AF_INET;   /* IPv4 only.  TODO: Set AF_UNSPEC.  */
   hints.ai_flags = AI_ADDRCONFIG;
   switch (type)
     {
index e6c6afe..604ab23 100644 (file)
@@ -1,5 +1,9 @@
 /* See the file COPYING for licensing information.  */
 
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <freeradius/libradius.h>
 #include <radsec/radsec.h>
index 51e4421..8d26d3c 100644 (file)
--- a/lib/err.c
+++ b/lib/err.c
@@ -1,5 +1,9 @@
 /* See the file COPYING for licensing information.  */
 
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
@@ -8,8 +12,8 @@
 
 const char *_errtxt[] = {
   "SUCCESS",                   /* 0 RSE_OK */
-  "NOMEM",                     /* 1 RSE_NOMEM */
-  "NYI -- not yet implemented",        /* 2 RSE_NOSYS */
+  "out of memory",             /* 1 RSE_NOMEM */
+  "not yet implemented",       /* 2 RSE_NOSYS */
   "invalid handle"             /* 3 RSE_INVALID_CTX */
   "invalid connection"         /* 4 RSE_INVALID_CONN */
   "connection type mismatch"   /* 5 RSE_CONN_TYPE_MISMATCH */
@@ -19,9 +23,9 @@ const char *_errtxt[] = {
   "libevent error"             /* 9 RSE_EVENT */
   "connection error"           /* 10 RSE_CONNERR */
   "invalid configuration file" /* 11 RSE_CONFIG */
-  "authentication failed"      /*  RSE_BADAUTH */
-  "ERR 13"                     /*  RSE_ */
-  "ERR 14"                     /*  RSE_ */
+  "authentication failed"      /* 12 RSE_BADAUTH */
+  "internal error"             /* 13 RSE_INTERNAL */
+  "SSL error"                  /* 14 RSE_SSLERR */
   "ERR 15"                     /*  RSE_ */
   "ERR 16"                     /*  RSE_ */
   "ERR 17"                     /*  RSE_ */
index fe2ded5..e939756 100644 (file)
@@ -1,4 +1,4 @@
-config blocking {
+config blocking-udp {
     type = "UDP"
     server {
         hostname = "localhost"
@@ -8,3 +8,23 @@ config blocking {
        tries = 10            /* optional */
     }
 }
+config blocking-tls {
+    type = "TLS"
+
+    cacertfile = "/home/linus/nordberg-ca.crt"
+    #cacertpath = 
+    certfile = "/home/linus/p/radsecproxy/src/maatuska.nordberg.se.crt"
+    certkeyfile = "/home/linus/p/radsecproxy/src/maatuska.nordberg.se.key"
+    #certkeypwd = "passphrase"
+    #cacheexpiry = <seconds>
+    #crlcheck = "on" | "off"
+    #policyoids = ?
+    
+    server {
+        hostname = "localhost"
+       service = "4433"
+       secret = "sikrit"
+       timeout = 1         /* optional */
+       tries = 10            /* optional */
+    }
+}
index 6e5ee83..2b3d878 100644 (file)
@@ -5,6 +5,9 @@
 
 #include <freeradius/libradius.h>
 #include <event2/util.h>
+#if defined(RS_ENABLE_TLS)
+#include <openssl/ssl.h>
+#endif
 
 /* Constants.  */
 #define RS_HEADER_LEN 4
@@ -32,6 +35,7 @@ struct rs_error {
 
 struct rs_peer {
     struct rs_connection *conn;
+    struct rs_realm *realm;
     struct evutil_addrinfo *addr;
     int fd;                    /* Socket.  */
     char is_connecting;                /* FIXME: replace with a single state member */
@@ -45,6 +49,10 @@ struct rs_peer {
 struct rs_realm {
     char *name;
     enum rs_conn_type type;
+    char *cacertfile;
+    char *cacertpath;
+    char *certfile;
+    char *certkeyfile;
     struct rs_peer *peers;
     struct rs_realm *next;
 };
@@ -69,6 +77,10 @@ struct rs_connection {
     struct rs_error *err;
     int nextid;
     int user_dispatch_flag : 1;        /* User does the dispatching.  */
+#if defined(RS_ENABLE_TLS)
+    SSL_CTX *tls_ctx;
+    SSL *tls_ssl;
+#endif
 };
 
 struct rs_packet {
index 8e97072..d80c296 100644 (file)
@@ -18,6 +18,8 @@ enum rs_err_code {
     RSE_CONNERR = 10,
     RSE_CONFIG = 11,
     RSE_BADAUTH = 12,
+    RSE_INTERNAL = 13,
+    RSE_SSLERR = 14,
     RSE_SOME_ERROR = 21,
 };
 
index cdd094a..154abc8 100644 (file)
@@ -1,12 +1,22 @@
 /* See the file COPYING for licensing information.  */
 
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 #include <freeradius/libradius.h>
 #include <event2/event.h>
 #include <event2/bufferevent.h>
+#if defined RS_ENABLE_TLS
+#include <event2/bufferevent_ssl.h>
+#include <openssl/err.h>
+#endif
 #include <radsec/radsec.h>
 #include <radsec/radsec-impl.h>
+#include "tls.h"
 #if defined DEBUG
 #include <netdb.h>
 #include <sys/socket.h>
@@ -89,7 +99,7 @@ _event_cb (struct bufferevent *bev, short events, void *ctx)
   struct rs_packet *pkt = (struct rs_packet *)ctx;
   struct rs_connection *conn;
   struct rs_peer *p;
-  int err;
+  unsigned long err;
 
   assert (pkt);
   assert (pkt->conn);
@@ -103,7 +113,6 @@ _event_cb (struct bufferevent *bev, short events, void *ctx)
       p->is_connected = 1;
       if (conn->callbacks.connected_cb)
        conn->callbacks.connected_cb (conn->user_data);
-
 #if defined (DEBUG)
       fprintf (stderr, "%s: connected\n", __func__);
 #endif
@@ -114,7 +123,24 @@ _event_cb (struct bufferevent *bev, short events, void *ctx)
       /* Packet will be freed in write callback.  */
     }
   else if (events & BEV_EVENT_ERROR)
-    rs_err_conn_push_fl (pkt->conn, RSE_CONNERR, __FILE__, __LINE__, NULL);
+    {
+#if defined RS_ENABLE_TLS
+      if (conn->tls_ssl)       /* FIXME: correct check?  */
+       {
+         for (err = bufferevent_get_openssl_error (conn->bev);
+              err;
+              err = bufferevent_get_openssl_error (conn->bev))
+           {
+             fprintf (stderr, "%s: openssl error: %s\n", __func__,
+                      ERR_error_string (err, NULL)); /* DEBUG, until verified that pushed errors will actually be handled  */
+             rs_err_conn_push_fl (pkt->conn, RSE_SSLERR, __FILE__, __LINE__,
+                                  "%d", err);
+           }
+       }
+#endif
+      rs_err_conn_push_fl (pkt->conn, RSE_CONNERR, __FILE__, __LINE__, NULL);
+      fprintf (stderr, "%s: BEV_EVENT_ERROR\n", __func__); /* DEBUG, until verified that pushed errors will actually be handled  */
+    }
 }
 
 static void
@@ -301,13 +327,41 @@ _pick_peer (struct rs_connection *conn)
 static int
 _init_bev (struct rs_connection *conn, struct rs_peer *peer)
 {
-  if (!conn->bev)
+  if (conn->bev)
+    return RSE_OK;
+
+  switch (conn->type)
     {
+    case RS_CONN_TYPE_UDP:
+    case RS_CONN_TYPE_TCP:
       conn->bev = bufferevent_socket_new (conn->evb, peer->fd, 0);
       if (!conn->bev)
        return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
                                    "bufferevent_socket_new");
+      break;
+    case RS_CONN_TYPE_TLS:
+      if (rs_tls_init (conn))
+       return -1;
+      /* Would be convenient to pass BEV_OPT_CLOSE_ON_FREE but things
+        seem to break when be_openssl_ctrl() (in libevent) calls
+        SSL_set_bio() after BIO_new_socket() with flag=1.  */
+      conn->bev =
+       bufferevent_openssl_socket_new (conn->evb, peer->fd, conn->tls_ssl,
+                                       BUFFEREVENT_SSL_CONNECTING, 0);
+      if (!conn->bev)
+       return rs_err_conn_push_fl (conn, RSE_EVENT, __FILE__, __LINE__,
+                                   "bufferevent_openssl_socket_new");
+
+      break;
+    case RS_CONN_TYPE_DTLS:
+      return rs_err_conn_push_fl (conn, RSE_NOSYS, __FILE__, __LINE__,
+                                 "%s: NYI", __func__);
+    default:
+      return rs_err_conn_push_fl (conn, RSE_INTERNAL, __FILE__, __LINE__,
+                                 "%s: invalid connection type: %d", __func__,
+                                 conn->type);
     }
+
   return RSE_OK;
 }
 
index b7ac9ba..40d14fc 100644 (file)
@@ -1,5 +1,9 @@
 /* See the file COPYING for licensing information.  */
 
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <event2/util.h>
 #include <radsec/radsec.h>
 #include <radsec/radsec-impl.h>
+#if defined RS_ENABLE_TLS
+#include <regex.h>
+#include "rsp_list.h"
+#include "../radsecproxy.h"
+#endif
+#include "rsp_debug.h"
 
 int
 rs_context_create(struct rs_context **ctx, const char *dict)
@@ -48,10 +58,14 @@ rs_context_create(struct rs_context **ctx, const char *dict)
        }
       free (buf1);
       free (buf2);
+#if defined RS_ENABLE_TLS
+      ssl_init ();
+#endif
 #if defined (DEBUG)
       fr_log_fp = stderr;
       fr_debug_flag = 1;
 #endif
+      debug_init ("libradsec");        /* radsecproxy compat, FIXME: remove */
 
       memset (h, 0, sizeof(struct rs_context));
       fr_randinit (&h->fr_randctx, 0);
index 5cb87bb..bc6f795 100644 (file)
@@ -1,5 +1,9 @@
 /* See the file COPYING for licensing information.  */
 
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <time.h>
 #include <assert.h>
 #include <event2/event.h>
@@ -39,25 +43,25 @@ _timer_cb(evutil_socket_t fd, short what, void *arg)
 static void
 _rs_req_connected(void *user_data)
 {
-  struct rs_request *request = (struct rs_request *)user_data;
+  //struct rs_request *request = (struct rs_request *)user_data;
 }
 
 static void
 _rs_req_disconnected(void *user_data)
 {
-  struct rs_request *request = (struct rs_request *)user_data;
+  //struct rs_request *request = (struct rs_request *)user_data;
 }
 
 static void
 _rs_req_packet_received(const struct rs_packet *pkt, void *user_data)
 {
-  struct rs_request *request = (struct rs_request *)user_data;
+  //struct rs_request *request = (struct rs_request *)user_data;
 }
 
 static void
 _rs_req_packet_sent(void *user_data)
 {
-  struct rs_request *request = (struct rs_request *)user_data;
+  //struct rs_request *request = (struct rs_request *)user_data;
 }
 
 int
similarity index 99%
rename from debug.c
rename to lib/rsp_debug.c
index 3bbcd0a..dd7c053 100644 (file)
--- a/debug.c
@@ -19,8 +19,8 @@
 #include <syslog.h>
 #include <errno.h>
 #include <assert.h>
-#include "debug.h"
-#include "util.h"
+#include "rsp_debug.h"
+#include "rsp_util.h"
 
 static char *debug_ident = NULL;
 static uint8_t debug_level = DBG_INFO;
similarity index 100%
rename from debug.h
rename to lib/rsp_debug.h
similarity index 98%
rename from hash.c
rename to lib/rsp_hash.c
index fd3c04b..cc37e7f 100644 (file)
--- a/hash.c
@@ -9,8 +9,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
-#include "list.h"
-#include "hash.h"
+#include "rsp_list.h"
+#include "rsp_hash.h"
 
 /* allocates and initialises hash structure; returns NULL if malloc fails */
 struct hash *hash_create() {
similarity index 100%
rename from hash.h
rename to lib/rsp_hash.h
similarity index 97%
rename from list.c
rename to lib/rsp_list.c
index 58ab7aa..b6cfe33 100644 (file)
--- a/list.c
@@ -6,9 +6,13 @@
  * copyright notice and this permission notice appear in all copies.
  */
 
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
-#include "list.h"
+#include "rsp_list.h"
 
 /* allocates and initialises list structure; returns NULL if malloc fails */
 struct list *list_create() {
similarity index 100%
rename from list.h
rename to lib/rsp_list.h
similarity index 93%
rename from tlscommon.c
rename to lib/rsp_tlscommon.c
index 6d36ebb..6002c41 100644 (file)
@@ -6,6 +6,10 @@
  * copyright notice and this permission notice appear in all copies.
  */
 
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #if defined(RADPROT_TLS) || defined(RADPROT_DTLS)
 #include <signal.h>
 #include <sys/socket.h>
 #include <openssl/err.h>
 #include <openssl/md5.h>
 #include <openssl/x509v3.h>
-#include "debug.h"
-#include "list.h"
-#include "hash.h"
-#include "util.h"
-#include "hostport.h"
-#include "radsecproxy.h"
+#include "rsp_debug.h"
+#include "rsp_list.h"
+#include "rsp_hash.h"
+#include "rsp_util.h"
+#include "../hostport_types.h"
+#include "../radsecproxy.h"
 
 static struct hash *tlsconfs = NULL;
 
+void ssl_init(void) {
+    time_t t;
+    pid_t pid;
+
+    SSL_load_error_strings();
+    SSL_library_init();
+
+    while (!RAND_status()) {
+       t = time(NULL);
+       pid = getpid();
+       RAND_seed((unsigned char *)&t, sizeof(time_t));
+       RAND_seed((unsigned char *)&pid, sizeof(pid));
+    }
+}
+
 static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) {
     int pwdlen = strlen(userdata);
     if (rwflag != 0 || pwdlen > size) /* not for decryption or too large */
@@ -165,7 +184,8 @@ static int tlsaddcacrl(SSL_CTX *ctx, struct tls *conf) {
        return 0;
     }
 
-    calist = conf->cacertfile ? SSL_load_client_CA_file(conf->cacertfile) : NULL;
+       calist = conf->cacertfile ? SSL_load_client_CA_file(conf->cacertfile) : NULL;
+
     if (!conf->cacertfile || calist) {
        if (conf->cacertpath) {
            if (!calist)
@@ -208,38 +228,39 @@ static SSL_CTX *tlscreatectx(uint8_t type, struct tls *conf) {
 #ifdef RADPROT_TLS
     case RAD_TLS:
        ctx = SSL_CTX_new(TLSv1_method());
-#ifdef DEBUG
-       SSL_CTX_set_info_callback(ctx, ssl_info_callback);
-#endif
        break;
 #endif
 #ifdef RADPROT_DTLS
     case RAD_DTLS:
        ctx = SSL_CTX_new(DTLSv1_method());
-#ifdef DEBUG
-       SSL_CTX_set_info_callback(ctx, ssl_info_callback);
-#endif
        SSL_CTX_set_read_ahead(ctx, 1);
        break;
 #endif
     }
     if (!ctx) {
        debug(DBG_ERR, "tlscreatectx: Error initialising SSL/TLS in TLS context %s", conf->name);
+       while ((error = ERR_get_error()))
+           debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL));
        return NULL;
     }
+#ifdef DEBUG
+       SSL_CTX_set_info_callback(ctx, ssl_info_callback);
+#endif
 
     if (conf->certkeypwd) {
        SSL_CTX_set_default_passwd_cb_userdata(ctx, conf->certkeypwd);
        SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
     }
-    if (!SSL_CTX_use_certificate_chain_file(ctx, conf->certfile) ||
-       !SSL_CTX_use_PrivateKey_file(ctx, conf->certkeyfile, SSL_FILETYPE_PEM) ||
-       !SSL_CTX_check_private_key(ctx)) {
-       while ((error = ERR_get_error()))
-           debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL));
-       debug(DBG_ERR, "tlscreatectx: Error initialising SSL/TLS in TLS context %s", conf->name);
-       SSL_CTX_free(ctx);
-       return NULL;
+    if (conf->certfile || conf->certkeyfile) {
+       if (!SSL_CTX_use_certificate_chain_file(ctx, conf->certfile) ||
+           !SSL_CTX_use_PrivateKey_file(ctx, conf->certkeyfile, SSL_FILETYPE_PEM) ||
+           !SSL_CTX_check_private_key(ctx)) {
+           while ((error = ERR_get_error()))
+               debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL));
+           debug(DBG_ERR, "tlscreatectx: Error initialising SSL/TLS (certfile issues) in TLS context %s", conf->name);
+           SSL_CTX_free(ctx);
+           return NULL;
+       }
     }
 
     if (conf->policyoids) {
@@ -526,6 +547,7 @@ int verifyconfcert(X509 *cert, struct clsrvconf *conf) {
     return 1;
 }
 
+#if 0
 int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
     struct tls *conf;
     long int expiry = LONG_MIN;
@@ -596,6 +618,7 @@ errexit:
     free(conf);
     return 0;
 }
+#endif
 
 int addmatchcertattr(struct clsrvconf *conf) {
     char *v;
similarity index 98%
rename from tlscommon.h
rename to lib/rsp_tlscommon.h
index 084cb1c..d7e0930 100644 (file)
@@ -26,6 +26,7 @@ struct tls {
 };
 
 #if defined(RADPROT_TLS) || defined(RADPROT_DTLS)
+void ssl_init();
 struct tls *tlsgettls(char *alt1, char *alt2);
 SSL_CTX *tlsgetctx(uint8_t type, struct tls *t);
 X509 *verifytlscert(SSL *ssl);
similarity index 99%
rename from util.c
rename to lib/rsp_util.c
index 5235d8a..22b8352 100644 (file)
--- a/util.c
@@ -22,8 +22,8 @@
 #include <errno.h>
 #include <sys/select.h>
 #include <stdarg.h>
-#include "debug.h"
-#include "util.h"
+#include "rsp_debug.h"
+#include "rsp_util.h"
 
 char *stringcopy(const char *s, int len) {
     char *r;
similarity index 100%
rename from util.h
rename to lib/rsp_util.h
diff --git a/lib/tls.c b/lib/tls.c
new file mode 100644 (file)
index 0000000..15929d2
--- /dev/null
+++ b/lib/tls.c
@@ -0,0 +1,73 @@
+/* See the file COPYING for licensing information.  */
+
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <openssl/ssl.h>
+#include <radsec/radsec.h>
+#include <radsec/radsec-impl.h>
+
+#include <regex.h>
+#include "rsp_list.h"
+#include "../radsecproxy.h"
+
+static struct tls *
+_get_tlsconf (const struct rs_context *ctx, const struct rs_realm *realm)
+{
+  struct tls *c = rs_malloc (ctx, sizeof (struct tls));
+
+  if (c)
+    {
+      memset (c, 0, sizeof (struct tls));
+      /* TODO: Make sure old radsecproxy code doesn't free these all
+        of a sudden, or strdup them.  */
+      c->name = realm->name;
+      c->cacertfile = realm->cacertfile;
+      c->cacertpath = NULL;    /* NYI */
+      c->certfile = realm->certfile;
+      c->certkeyfile = realm->certkeyfile;
+      c->certkeypwd = NULL;    /* NYI */
+      c->cacheexpiry = 0;      /* NYI */
+      c->crlcheck = 0;         /* NYI */
+      c->policyoids = (char **) NULL; /* NYI */
+    }
+
+  return c;
+}
+
+int
+rs_tls_init (struct rs_connection *conn)
+{
+  struct rs_context *ctx;
+  struct tls *tlsconf;
+  SSL_CTX *ssl_ctx;
+  SSL *ssl;
+  assert (conn->ctx);
+  ctx = conn->ctx;
+
+  tlsconf = _get_tlsconf (ctx, conn->active_peer->realm);
+  assert (tlsconf);
+  ssl_ctx = tlsgetctx (RADPROT_TLS, tlsconf);
+  if (!ssl_ctx)
+    {
+      /* TODO: check radsecproxy error  */
+      return rs_err_conn_push_fl (conn, RSE_SOME_ERROR, __FILE__, __LINE__,
+                                 NULL);
+    }
+
+  ssl = SSL_new (ssl_ctx);
+  if (!ssl)
+    {
+      /* TODO: check and report SSL error  */
+      /* TODO: free ssl_ctx  */
+      return rs_err_conn_push_fl (conn, RSE_SOME_ERROR, __FILE__, __LINE__,
+                                 NULL);
+    }
+
+  conn->tls_ctx = ssl_ctx;
+  conn->tls_ssl = ssl;
+  rs_free (ctx, tlsconf);
+  return RSE_OK;
+}
diff --git a/lib/tls.h b/lib/tls.h
new file mode 100644 (file)
index 0000000..7e10a46
--- /dev/null
+++ b/lib/tls.h
@@ -0,0 +1 @@
+int rs_tls_init (struct rs_connection *conn);
index 7528f7f..09b5d6e 100644 (file)
@@ -107,7 +107,7 @@ struct clsrvconf {
     struct server *servers;
 };
 
-#include "tlscommon.h"
+#include "rsp_tlscommon.h"
 
 struct client {
     struct clsrvconf *conf;