Skip to content
This repository has been archived by the owner on Jun 24, 2021. It is now read-only.

Commit

Permalink
Added SNI support (OpenSSL)
Browse files Browse the repository at this point in the history
  • Loading branch information
ManiacTwister committed Jan 12, 2020
1 parent 9055088 commit fa3ea12
Show file tree
Hide file tree
Showing 17 changed files with 449 additions and 29 deletions.
14 changes: 14 additions & 0 deletions doc/ircd.conf.example
Original file line number Diff line number Diff line change
Expand Up @@ -557,3 +557,17 @@ modules {
path = "modules";
path = "modules/autoload";
};

/*
vhost "selfsigned.hades.arpa" {
ssl_private_key = "etc/selfssl.key";
ssl_cert = "etc/selfssl.pem";
};

vhost "oldca.hades.arpa" {
ssl_private_key = "etc/oldssl.key";
ssl_cert = "etc/oldssl2.pem";
ssl_dh_params = "etc/olddh.pem";
ssl_cipher_list = "kEECDH+HIGH:kEDH+HIGH:HIGH:!RC4:!aNULL";;
};
*/
14 changes: 14 additions & 0 deletions doc/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1360,3 +1360,17 @@ modules {
/* module: the name of a module to load on startup/rehash */
#module = "some_module.so";
};

/*
vhost "selfsigned.hades.arpa" {
ssl_private_key = "etc/selfssl.key";
ssl_cert = "etc/selfssl.pem";
};

vhost "oldca.hades.arpa" {
ssl_private_key = "etc/oldssl.key";
ssl_cert = "etc/oldssl2.pem";
ssl_dh_params = "etc/olddh.pem";
ssl_cipher_list = "kEECDH+HIGH:kEDH+HIGH:HIGH:!RC4:!aNULL";
};
*/
14 changes: 13 additions & 1 deletion include/s_newconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ extern rb_dlink_list xline_conf_list;
extern rb_dlink_list resv_conf_list;
extern rb_dlink_list nd_list;
extern rb_dlink_list tgchange_list;
extern rb_dlink_list vhost_conf_list;

extern struct _rb_patricia_tree_t *tgchange_tree;

Expand Down Expand Up @@ -245,5 +246,16 @@ extern void add_nd_entry(const char *name);
extern void free_nd_entry(struct nd_entry *);
extern unsigned long get_nd_count(void);

#endif
struct vhost_conf
{
char *hostname;
char *ssl_private_key;
char *ssl_cert;
char *ssl_dh_params;
char *ssl_cipher_list;
rb_dlink_node node;
};
extern struct vhost_conf *make_vhost_conf(void);
extern void free_vhost_conf(struct vhost_conf *);

#endif
4 changes: 2 additions & 2 deletions include/sslproc.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ int start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key
ssl_ctl_t *start_ssld_accept(rb_fde_t *sslF, rb_fde_t *plainF, uint32_t id);
ssl_ctl_t *start_ssld_connect(rb_fde_t *sslF, rb_fde_t *plainF, uint32_t id);
void start_zlib_session(void *data);
void send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list, const int method);
void send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list, const int method, const char *hostname);
void send_remove_ssl_vhost(const char *hostname);
void ssld_decrement_clicount(ssl_ctl_t *ctl);
int get_ssld_count(void);
void ssld_foreach_info(void (*func)(void *data, pid_t pid, int cli_count, enum ssld_status status), void *data);

#endif

2 changes: 1 addition & 1 deletion libratbox/include/commio-ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#ifndef _COMMIO_SSL_H
#define _COMMIO_SSL_H

int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list);
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list, const char *hostname);
int rb_init_ssl(void);

int rb_ssl_listen(rb_fde_t *F, int backlog, int defer_accept);
Expand Down
3 changes: 2 additions & 1 deletion libratbox/include/rb_commio.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,10 @@ ssize_t rb_writev(rb_fde_t *, struct rb_iovec *vector, int count);
ssize_t rb_read(rb_fde_t *, void *buf, int count);
int rb_pipe(rb_fde_t **, rb_fde_t **, const char *desc);

int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list);
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list, const char *hostname);
int rb_ssl_listen(rb_fde_t *, int backlog, int defer_accept);
int rb_listen(rb_fde_t *, int backlog, int defer_accept);
int rb_remove_ssl_vserver(const char *hostname);

const char *rb_inet_ntop(int af, const void *src, char *dst, unsigned int size);
int rb_inet_pton(int af, const char *src, void *dst);
Expand Down
2 changes: 2 additions & 0 deletions libratbox/src/export-syms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ rb_setselect
rb_settimeout
rb_setup_fd
rb_setup_ssl_server
rb_setup_ssl_server_hostname
rb_remove_ssl_vserver
rb_socket
rb_socketpair
rb_ssl_listen
Expand Down
9 changes: 8 additions & 1 deletion libratbox/src/gnutls.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,9 +496,16 @@ rb_init_ssl(void)
return 1;
}

int
rb_remove_ssl_vserver(const char *hostname)
{
errno = ENOSYS;
return -1;
}

int
rb_setup_ssl_server(const char *const certfile, const char *keyfile,
const char *const dhfile, const char *cipherlist)
const char *const dhfile, const char *cipherlist, const char *hostname)
{
if(certfile == NULL)
{
Expand Down
9 changes: 8 additions & 1 deletion libratbox/src/mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,9 +455,16 @@ rb_init_ssl(void)
return 1;
}

int
rb_remove_ssl_vserver(const char *hostname)
{
errno = ENOSYS;
return -1;
}

int
rb_setup_ssl_server(const char *const certfile, const char *keyfile,
const char *const dhfile, const char *const cipherlist)
const char *const dhfile, const char *const cipherlist, const char *hostname)
{
if(certfile == NULL)
{
Expand Down
9 changes: 8 additions & 1 deletion libratbox/src/nossl.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include <commio-ssl.h>

int
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list)
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list, const char *hostname)
{
errno = ENOSYS;
return 0;
Expand All @@ -48,6 +48,13 @@ rb_init_ssl(void)

}

int
rb_remove_ssl_vserver(const char *hostname)
{
errno = ENOSYS;
return -1;
}

int
rb_ssl_listen(rb_fde_t *F, int backlog, int defer_accept)
{
Expand Down
110 changes: 104 additions & 6 deletions libratbox/src/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,31 @@ typedef enum

#define SSL_P(x) ((SSL *)((x)->ssl))


typedef struct ssl_vhost_s
{
char *hostname;
SSL_CTX *ctx;
rb_dlink_node node;
} ssl_vhost;

static SSL_CTX *ssl_ctx = NULL;
rb_dlink_list ssl_vhosts;

rb_dlink_node *
find_ssl_vhost(const char *hostname)
{
ssl_vhost *vhost_p;
rb_dlink_node *ptr;

RB_DLINK_FOREACH(ptr, ssl_vhosts.head)
{
vhost_p = ptr->data;

if(!strcmp(hostname,vhost_p->hostname))
return ptr;
}
return NULL;
}

struct ssl_connect
{
Expand Down Expand Up @@ -337,9 +359,65 @@ rb_init_ssl(void)
return 1;
}

static int rb_ssl_servername_cb(SSL *s, int *ad, void *arg)
{
ssl_vhost *vhost_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;

const char * servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);

rb_lib_log("Hostname in TLS extension?");
if (servername)
{
rb_lib_log("Hostname in TLS extension %s", servername);

RB_DLINK_FOREACH_SAFE(ptr, next_ptr, ssl_vhosts.head)
{
vhost_p = ptr->data;

if (strcmp(servername, vhost_p->hostname) != 0)
continue;

if (vhost_p->ctx)
{
rb_lib_log("Switching server context %s", servername);
SSL_set_SSL_CTX(s,vhost_p->ctx);
}
}
}
return SSL_TLSEXT_ERR_OK;
}

void
free_ssl_vhost(ssl_vhost *vhost_p)
{
if(vhost_p == NULL)
return;

rb_free(vhost_p->hostname);

SSL_CTX_free(vhost_p->ctx);
rb_free(vhost_p);
}

int
rb_remove_ssl_vserver(const char *hostname)
{
rb_dlink_node *ptr = find_ssl_vhost(hostname);
if(ptr != NULL && ptr) {
rb_dlinkDelete(ptr, &ssl_vhosts);
free_ssl_vhost(ptr->data);
return 1;
}

return 0;
}

int
rb_setup_ssl_server(const char *const certfile, const char *keyfile,
const char *const dhfile, const char *cipherlist)
const char *const dhfile, const char *cipherlist,
const char *hostname)
{
if(certfile == NULL)
{
Expand Down Expand Up @@ -419,6 +497,7 @@ rb_setup_ssl_server(const char *const certfile, const char *keyfile,
SSL_CTX_free(ssl_ctx_new);
return 0;
}
SSL_CTX_set_tlsext_servername_callback(ssl_ctx_new, rb_ssl_servername_cb);

SSL_CTX_set_session_cache_mode(ssl_ctx_new, SSL_SESS_CACHE_OFF);
SSL_CTX_set_verify(ssl_ctx_new, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
Expand Down Expand Up @@ -472,14 +551,33 @@ rb_setup_ssl_server(const char *const certfile, const char *keyfile,
# endif
#endif

rb_lib_log("%s: TLS configuration successful", __func__);
if(hostname == NULL) {
if(ssl_ctx)
SSL_CTX_free(ssl_ctx);

if(ssl_ctx)
SSL_CTX_free(ssl_ctx);
ssl_ctx = ssl_ctx_new;
} else {
ssl_vhost *vhost_p = NULL;

ssl_ctx = ssl_ctx_new;
rb_lib_log("rb_setup_ssl_server: SETUP [%s]", hostname);
rb_dlink_node *ptr = find_ssl_vhost(hostname);
if(ptr != NULL && ptr)
vhost_p = ptr->data;

if(vhost_p == NULL) {
vhost_p = rb_malloc(sizeof(ssl_vhost));
vhost_p->hostname = rb_strdup(hostname);

rb_dlinkAdd(vhost_p, &vhost_p->node, &ssl_vhosts);
}

if(vhost_p->ctx)
SSL_CTX_free(vhost_p->ctx);

vhost_p->ctx = ssl_ctx_new;
}

rb_lib_log("%s: TLS configuration successful", __func__);
return 1;
}

Expand Down
20 changes: 18 additions & 2 deletions src/ircd.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,11 @@ int
main(int argc, char *argv[])
{
int fd;

#ifdef HAVE_LIBCRYPTO
struct vhost_conf *vhost_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
#endif
/* Check to see if the user is running us as root, which is a nono */
if(geteuid() == 0)
{
Expand Down Expand Up @@ -676,13 +680,25 @@ main(int argc, char *argv[])
if(ServerInfo.ssl_cert != NULL && ServerInfo.ssl_private_key != NULL)
{
/* just do the rb_setup_ssl_server to validate the config */
if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list))
if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list, NULL))
{
ilog(L_MAIN, "WARNING: Unable to setup SSL.");
ircd_ssl_ok = 0;
}
else
ircd_ssl_ok = 1;
#ifdef HAVE_LIBCRYPTO
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, vhost_conf_list.head)
{
vhost_p = ptr->data;
if(rb_setup_ssl_server(vhost_p->ssl_cert, vhost_p->ssl_private_key,
vhost_p->ssl_dh_params ? vhost_p->ssl_dh_params : ServerInfo.ssl_dh_params,
vhost_p->ssl_cipher_list ? vhost_p->ssl_cipher_list : ServerInfo.ssl_cipher_list, vhost_p->hostname))
{
ircd_ssl_ok = 1;
}
}
#endif
}

if (testing_conf)
Expand Down
Loading

0 comments on commit fa3ea12

Please sign in to comment.