summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordu.net>2010-11-11 10:30:35 +0100
committerLinus Nordberg <linus@nordu.net>2010-11-11 10:30:35 +0100
commit83e82dba47aced4a93f9e431b4d8bca94c2f8517 (patch)
tree7ff1779ea924d557b6ded9bd21c0cc8a65f062dd
parentf9b25cad24ec4e3e89e818457beb29cbe08eed0c (diff)
Bringing up TLS connections working.
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.
-rw-r--r--hostport.h7
-rw-r--r--hostport_types.h6
-rw-r--r--lib/Makefile.am13
-rw-r--r--lib/attr.c4
-rw-r--r--lib/conf.c23
-rw-r--r--lib/configure.ac17
-rw-r--r--lib/conn.c7
-rw-r--r--lib/debug.c4
-rw-r--r--lib/err.c14
-rw-r--r--lib/examples/client.conf22
-rw-r--r--lib/include/radsec/radsec-impl.h12
-rw-r--r--lib/include/radsec/radsec.h2
-rw-r--r--lib/packet.c62
-rw-r--r--lib/radsec.c14
-rw-r--r--lib/request.c12
-rw-r--r--lib/rsp_debug.c (renamed from debug.c)4
-rw-r--r--lib/rsp_debug.h (renamed from debug.h)0
-rw-r--r--lib/rsp_hash.c (renamed from hash.c)4
-rw-r--r--lib/rsp_hash.h (renamed from hash.h)0
-rw-r--r--lib/rsp_list.c (renamed from list.c)6
-rw-r--r--lib/rsp_list.h (renamed from list.h)0
-rw-r--r--lib/rsp_tlscommon.c (renamed from tlscommon.c)65
-rw-r--r--lib/rsp_tlscommon.h (renamed from tlscommon.h)1
-rw-r--r--lib/rsp_util.c (renamed from util.c)4
-rw-r--r--lib/rsp_util.h (renamed from util.h)0
-rw-r--r--lib/tls.c73
-rw-r--r--lib/tls.h1
-rw-r--r--radsecproxy.h2
28 files changed, 323 insertions, 56 deletions
diff --git a/hostport.h b/hostport.h
index 425bb8f..01237e2 100644
--- a/hostport.h
+++ b/hostport.h
@@ -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
index 0000000..01fb443
--- /dev/null
+++ b/hostport_types.h
@@ -0,0 +1,6 @@
+struct hostportres {
+ char *host;
+ char *port;
+ uint8_t prefixlen;
+ struct addrinfo *addrinfo;
+};
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 5d7cd0a..ca7de1f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -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
diff --git a/lib/attr.c b/lib/attr.c
index 4e66235..29384d5 100644
--- a/lib/attr.c
+++ b/lib/attr.c
@@ -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>
diff --git a/lib/conf.c b/lib/conf.c
index cedb84c..c235ffe 100644
--- a/lib/conf.c
+++ b/lib/conf.c
@@ -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"),
diff --git a/lib/configure.ac b/lib/configure.ac
index 5ae729f..2039233 100644
--- a/lib/configure.ac
+++ b/lib/configure.ac
@@ -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
diff --git a/lib/conn.c b/lib/conn.c
index 62105e6..b65b1da 100644
--- a/lib/conn.c
+++ b/lib/conn.c
@@ -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)
{
diff --git a/lib/debug.c b/lib/debug.c
index e6c6afe..604ab23 100644
--- a/lib/debug.c
+++ b/lib/debug.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 <freeradius/libradius.h>
#include <radsec/radsec.h>
diff --git a/lib/err.c b/lib/err.c
index 51e4421..8d26d3c 100644
--- 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_ */
diff --git a/lib/examples/client.conf b/lib/examples/client.conf
index fe2ded5..e939756 100644
--- a/lib/examples/client.conf
+++ b/lib/examples/client.conf
@@ -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 */
+ }
+}
diff --git a/lib/include/radsec/radsec-impl.h b/lib/include/radsec/radsec-impl.h
index 6e5ee83..2b3d878 100644
--- a/lib/include/radsec/radsec-impl.h
+++ b/lib/include/radsec/radsec-impl.h
@@ -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 {
diff --git a/lib/include/radsec/radsec.h b/lib/include/radsec/radsec.h
index 8e97072..d80c296 100644
--- a/lib/include/radsec/radsec.h
+++ b/lib/include/radsec/radsec.h
@@ -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,
};
diff --git a/lib/packet.c b/lib/packet.c
index cdd094a..154abc8 100644
--- a/lib/packet.c
+++ b/lib/packet.c
@@ -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;
}
diff --git a/lib/radsec.c b/lib/radsec.c
index b7ac9ba..40d14fc 100644
--- a/lib/radsec.c
+++ b/lib/radsec.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 <stdlib.h>
#include <stdint.h>
@@ -12,6 +16,12 @@
#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);
diff --git a/lib/request.c b/lib/request.c
index 5cb87bb..bc6f795 100644
--- a/lib/request.c
+++ b/lib/request.c
@@ -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
diff --git a/debug.c b/lib/rsp_debug.c
index 3bbcd0a..dd7c053 100644
--- a/debug.c
+++ b/lib/rsp_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;
diff --git a/debug.h b/lib/rsp_debug.h
index 803f406..803f406 100644
--- a/debug.h
+++ b/lib/rsp_debug.h
diff --git a/hash.c b/lib/rsp_hash.c
index fd3c04b..cc37e7f 100644
--- a/hash.c
+++ b/lib/rsp_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() {
diff --git a/hash.h b/lib/rsp_hash.h
index 48f54a3..48f54a3 100644
--- a/hash.h
+++ b/lib/rsp_hash.h
diff --git a/list.c b/lib/rsp_list.c
index 58ab7aa..b6cfe33 100644
--- a/list.c
+++ b/lib/rsp_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() {
diff --git a/list.h b/lib/rsp_list.h
index 80c0128..80c0128 100644
--- a/list.h
+++ b/lib/rsp_list.h
diff --git a/tlscommon.c b/lib/rsp_tlscommon.c
index 6d36ebb..6002c41 100644
--- a/tlscommon.c
+++ b/lib/rsp_tlscommon.c
@@ -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>
@@ -31,15 +35,30 @@
#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;
diff --git a/tlscommon.h b/lib/rsp_tlscommon.h
index 084cb1c..d7e0930 100644
--- a/tlscommon.h
+++ b/lib/rsp_tlscommon.h
@@ -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);
diff --git a/util.c b/lib/rsp_util.c
index 5235d8a..22b8352 100644
--- a/util.c
+++ b/lib/rsp_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;
diff --git a/util.h b/lib/rsp_util.h
index d8d002c..d8d002c 100644
--- a/util.h
+++ b/lib/rsp_util.h
diff --git a/lib/tls.c b/lib/tls.c
new file mode 100644
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
index 0000000..7e10a46
--- /dev/null
+++ b/lib/tls.h
@@ -0,0 +1 @@
+int rs_tls_init (struct rs_connection *conn);
diff --git a/radsecproxy.h b/radsecproxy.h
index 7528f7f..09b5d6e 100644
--- a/radsecproxy.h
+++ b/radsecproxy.h
@@ -107,7 +107,7 @@ struct clsrvconf {
struct server *servers;
};
-#include "tlscommon.h"
+#include "rsp_tlscommon.h"
struct client {
struct clsrvconf *conf;