diff options
author | Linus Nordberg <linus@nordu.net> | 2010-11-11 10:30:35 +0100 |
---|---|---|
committer | Linus Nordberg <linus@nordu.net> | 2010-11-11 10:30:35 +0100 |
commit | 83e82dba47aced4a93f9e431b4d8bca94c2f8517 (patch) | |
tree | 7ff1779ea924d557b6ded9bd21c0cc8a65f062dd | |
parent | f9b25cad24ec4e3e89e818457beb29cbe08eed0c (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.h | 7 | ||||
-rw-r--r-- | hostport_types.h | 6 | ||||
-rw-r--r-- | lib/Makefile.am | 13 | ||||
-rw-r--r-- | lib/attr.c | 4 | ||||
-rw-r--r-- | lib/conf.c | 23 | ||||
-rw-r--r-- | lib/configure.ac | 17 | ||||
-rw-r--r-- | lib/conn.c | 7 | ||||
-rw-r--r-- | lib/debug.c | 4 | ||||
-rw-r--r-- | lib/err.c | 14 | ||||
-rw-r--r-- | lib/examples/client.conf | 22 | ||||
-rw-r--r-- | lib/include/radsec/radsec-impl.h | 12 | ||||
-rw-r--r-- | lib/include/radsec/radsec.h | 2 | ||||
-rw-r--r-- | lib/packet.c | 62 | ||||
-rw-r--r-- | lib/radsec.c | 14 | ||||
-rw-r--r-- | lib/request.c | 12 | ||||
-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.c | 73 | ||||
-rw-r--r-- | lib/tls.h | 1 | ||||
-rw-r--r-- | radsecproxy.h | 2 |
28 files changed, 323 insertions, 56 deletions
@@ -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 @@ -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> @@ -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 @@ -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> @@ -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 @@ -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() { @@ -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/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); @@ -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/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; |