Added SNI support (OpenSSL)

This commit is contained in:
ManiacTwister 2018-11-21 20:03:48 +01:00
parent 0b79494ec9
commit 074e23e4e2
17 changed files with 422 additions and 28 deletions

View file

@ -557,3 +557,17 @@ modules {
path = "modules"; path = "modules";
path = "modules/autoload"; 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";;
};
*/

View file

@ -1360,3 +1360,17 @@ modules {
/* module: the name of a module to load on startup/rehash */ /* module: the name of a module to load on startup/rehash */
#module = "some_module.so"; #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";
};
*/

View file

@ -53,6 +53,7 @@ extern rb_dlink_list xline_conf_list;
extern rb_dlink_list resv_conf_list; extern rb_dlink_list resv_conf_list;
extern rb_dlink_list nd_list; extern rb_dlink_list nd_list;
extern rb_dlink_list tgchange_list; extern rb_dlink_list tgchange_list;
extern rb_dlink_list vhost_conf_list;
extern struct _rb_patricia_tree_t *tgchange_tree; extern struct _rb_patricia_tree_t *tgchange_tree;
@ -245,5 +246,16 @@ extern void add_nd_entry(const char *name);
extern void free_nd_entry(struct nd_entry *); extern void free_nd_entry(struct nd_entry *);
extern unsigned long get_nd_count(void); 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

View file

@ -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_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); ssl_ctl_t *start_ssld_connect(rb_fde_t *sslF, rb_fde_t *plainF, uint32_t id);
void start_zlib_session(void *data); 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); void ssld_decrement_clicount(ssl_ctl_t *ctl);
int get_ssld_count(void); 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); void ssld_foreach_info(void (*func)(void *data, pid_t pid, int cli_count, enum ssld_status status), void *data);
#endif #endif

View file

@ -25,7 +25,7 @@
#ifndef _COMMIO_SSL_H #ifndef _COMMIO_SSL_H
#define _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_init_ssl(void);
int rb_ssl_listen(rb_fde_t *F, int backlog, int defer_accept); int rb_ssl_listen(rb_fde_t *F, int backlog, int defer_accept);

View file

@ -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); 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_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_ssl_listen(rb_fde_t *, int backlog, int defer_accept);
int rb_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); 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); int rb_inet_pton(int af, const char *src, void *dst);

View file

@ -48,6 +48,8 @@ rb_setselect
rb_settimeout rb_settimeout
rb_setup_fd rb_setup_fd
rb_setup_ssl_server rb_setup_ssl_server
rb_setup_ssl_server_hostname
rb_remove_ssl_vserver
rb_socket rb_socket
rb_socketpair rb_socketpair
rb_ssl_listen rb_ssl_listen

View file

@ -498,7 +498,7 @@ rb_init_ssl(void)
int int
rb_setup_ssl_server(const char *const certfile, const char *keyfile, 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, char *hostname)
{ {
if(certfile == NULL) if(certfile == NULL)
{ {

View file

@ -457,7 +457,7 @@ rb_init_ssl(void)
int int
rb_setup_ssl_server(const char *const certfile, const char *keyfile, 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) if(certfile == NULL)
{ {

View file

@ -34,7 +34,7 @@
#include <commio-ssl.h> #include <commio-ssl.h>
int 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; errno = ENOSYS;
return 0; return 0;

View file

@ -41,9 +41,31 @@ typedef enum
#define SSL_P(x) ((SSL *)((x)->ssl)) #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; 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 struct ssl_connect
{ {
@ -337,9 +359,65 @@ rb_init_ssl(void)
return 1; 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 int
rb_setup_ssl_server(const char *const certfile, const char *keyfile, 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) if(certfile == NULL)
{ {
@ -419,6 +497,7 @@ rb_setup_ssl_server(const char *const certfile, const char *keyfile,
SSL_CTX_free(ssl_ctx_new); SSL_CTX_free(ssl_ctx_new);
return 0; 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_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); SSL_CTX_set_verify(ssl_ctx_new, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
@ -472,14 +551,33 @@ rb_setup_ssl_server(const char *const certfile, const char *keyfile,
# endif # endif
#endif #endif
rb_lib_log("%s: TLS configuration successful", __func__);
if(hostname == NULL) {
if(ssl_ctx) if(ssl_ctx)
SSL_CTX_free(ssl_ctx); SSL_CTX_free(ssl_ctx);
ssl_ctx = ssl_ctx_new; ssl_ctx = ssl_ctx_new;
} else {
ssl_vhost *vhost_p = NULL;
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; return 1;
} }

View file

@ -535,6 +535,9 @@ int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int fd; int fd;
struct vhost_conf *vhost_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
/* Check to see if the user is running us as root, which is a nono */ /* Check to see if the user is running us as root, which is a nono */
if(geteuid() == 0) if(geteuid() == 0)
@ -712,13 +715,25 @@ main(int argc, char *argv[])
} }
/* just do the rb_setup_ssl_server to validate the config */ /* 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."); ilog(L_MAIN, "WARNING: Unable to setup SSL.");
ircd_ssl_ok = 0; ircd_ssl_ok = 0;
} }
else else
ircd_ssl_ok = 1; ircd_ssl_ok = 1;
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, vhost_conf_list.head)
{
vhost_p = ptr->data;
ilog(L_MAIN, "WARNING: h:%s c:%s k:%s d:%s ci:%s", vhost_p->hostname, vhost_p->ssl_cert, vhost_p->ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list);
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;
}
}
} }
if (testing_conf) if (testing_conf)

View file

@ -46,6 +46,7 @@ static struct Class *yy_class = NULL;
static struct remote_conf *yy_shared = NULL; static struct remote_conf *yy_shared = NULL;
static struct server_conf *yy_server = NULL; static struct server_conf *yy_server = NULL;
static struct vhost_conf *yy_vhost = NULL;
static rb_dlink_list yy_aconf_list; static rb_dlink_list yy_aconf_list;
static rb_dlink_list yy_oper_list; static rb_dlink_list yy_oper_list;
@ -1439,6 +1440,71 @@ conf_set_connect_class(void *data)
yy_server->class_name = rb_strdup(data); yy_server->class_name = rb_strdup(data);
} }
static int
conf_begin_vhost(struct TopConf *tc)
{
if(yy_vhost)
free_vhost_conf(yy_vhost);
yy_vhost = make_vhost_conf();
if(conf_cur_block_name != NULL) {
yy_vhost->hostname = rb_strdup(conf_cur_block_name);
}
return 0;
}
static int
conf_end_vhost(struct TopConf *tc)
{
if(EmptyString(yy_vhost->hostname))
{
conf_report_error("Ignoring vhost block -- missing hostname.");
return 0;
}
if(EmptyString(yy_vhost->ssl_cert) || EmptyString(yy_vhost->ssl_private_key))
{
conf_report_error("Ignoring vhost block for %s -- no ssl_cert or ssl_private_key file provided.",
yy_vhost->hostname);
return 0;
}
rb_dlinkAdd(yy_vhost, &yy_vhost->node, &vhost_conf_list);
yy_vhost = NULL;
return 0;
}
static void
conf_set_vhost_ssl_private_key(void *data)
{
if (yy_vhost->ssl_private_key)
rb_free(yy_vhost->ssl_private_key);
yy_vhost->ssl_private_key = rb_strdup((char *) data);
}
static void
conf_set_vhost_ssl_cert(void *data)
{
if (yy_vhost->ssl_cert)
rb_free(yy_vhost->ssl_cert);
yy_vhost->ssl_cert = rb_strdup((char *) data);
}
static void
conf_set_vhost_ssl_dh_params(void *data)
{
if (yy_vhost->ssl_dh_params)
rb_free(yy_vhost->ssl_dh_params);
yy_vhost->ssl_dh_params = rb_strdup((char *) data);
}
static void
conf_set_vhost_ssl_cipher_list(void *data)
{
if (yy_vhost->ssl_cipher_list)
rb_free(yy_vhost->ssl_cipher_list);
yy_vhost->ssl_cipher_list = rb_strdup((char *) data);
}
static void static void
conf_set_exempt_ip(void *data) conf_set_exempt_ip(void *data)
{ {
@ -1457,6 +1523,15 @@ conf_set_exempt_ip(void *data)
add_conf_by_address(yy_tmp->host, CONF_EXEMPTDLINE, NULL, NULL, yy_tmp); add_conf_by_address(yy_tmp->host, CONF_EXEMPTDLINE, NULL, NULL, yy_tmp);
} }
static struct ConfEntry conf_vhost_table[] =
{
{ "ssl_private_key", CF_QSTRING, conf_set_vhost_ssl_private_key, 0, NULL },
{ "ssl_cert", CF_QSTRING, conf_set_vhost_ssl_cert, 0, NULL },
{ "ssl_dh_params", CF_QSTRING, conf_set_vhost_ssl_dh_params, 0, NULL },
{ "ssl_cipher_list", CF_QSTRING, conf_set_vhost_ssl_cipher_list, 0, NULL },
{ "\0", 0, NULL, 0, NULL }
};
static int static int
conf_cleanup_cluster(struct TopConf *tc) conf_cleanup_cluster(struct TopConf *tc)
{ {
@ -2592,6 +2667,7 @@ newconf_init()
add_conf_item("shared", "flags", CF_STRING | CF_FLIST, conf_set_shared_flags); add_conf_item("shared", "flags", CF_STRING | CF_FLIST, conf_set_shared_flags);
add_top_conf("connect", conf_begin_connect, conf_end_connect, conf_connect_table); add_top_conf("connect", conf_begin_connect, conf_end_connect, conf_connect_table);
add_top_conf("vhost", conf_begin_vhost, conf_end_vhost, conf_vhost_table);
add_top_conf("exempt", NULL, NULL, NULL); add_top_conf("exempt", NULL, NULL, NULL);
add_conf_item("exempt", "ip", CF_QSTRING, conf_set_exempt_ip); add_conf_item("exempt", "ip", CF_QSTRING, conf_set_exempt_ip);

View file

@ -860,6 +860,10 @@ read_conf(void)
static void static void
validate_conf(void) validate_conf(void)
{ {
struct vhost_conf *vhost_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
if(ConfigFileEntry.default_ident_timeout < 1) if(ConfigFileEntry.default_ident_timeout < 1)
ConfigFileEntry.default_ident_timeout = IDENT_TIMEOUT_DEFAULT; ConfigFileEntry.default_ident_timeout = IDENT_TIMEOUT_DEFAULT;
@ -875,13 +879,27 @@ validate_conf(void)
if(ServerInfo.ssld_count < 1) if(ServerInfo.ssld_count < 1)
ServerInfo.ssld_count = 1; ServerInfo.ssld_count = 1;
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."); ilog(L_MAIN, "WARNING: Unable to setup SSL.");
ircd_ssl_ok = 0; ircd_ssl_ok = 0;
} else { } else {
ircd_ssl_ok = 1; ircd_ssl_ok = 1;
send_new_ssl_certs(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list, ConfigFileEntry.certfp_method); send_new_ssl_certs(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list, ConfigFileEntry.certfp_method, NULL);
}
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_cipher_list, vhost_p->hostname))
{
ircd_ssl_ok = 1;
send_new_ssl_certs(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, ConfigFileEntry.certfp_method, vhost_p->hostname);
}
} }
if(ServerInfo.ssld_count > get_ssld_count()) if(ServerInfo.ssld_count > get_ssld_count())
@ -1462,6 +1480,7 @@ static void
clear_out_old_conf(void) clear_out_old_conf(void)
{ {
struct Class *cltmp; struct Class *cltmp;
struct vhost_conf *vhost_p;
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
@ -1547,6 +1566,14 @@ clear_out_old_conf(void)
rb_dlinkDestroy(ptr, &service_list); rb_dlinkDestroy(ptr, &service_list);
} }
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, vhost_conf_list.head)
{
vhost_p = ptr->data;
send_remove_ssl_vhost(vhost_p->hostname);
rb_dlinkDelete(ptr, &vhost_conf_list);
free_vhost_conf(ptr->data);
}
/* remove any aliases... -- nenolod */ /* remove any aliases... -- nenolod */
if (alias_dict != NULL) if (alias_dict != NULL)
{ {

View file

@ -56,6 +56,7 @@ rb_dlink_list xline_conf_list;
rb_dlink_list resv_conf_list; /* nicks only! */ rb_dlink_list resv_conf_list; /* nicks only! */
rb_dlink_list nd_list; /* nick delay */ rb_dlink_list nd_list; /* nick delay */
rb_dlink_list tgchange_list; rb_dlink_list tgchange_list;
rb_dlink_list vhost_conf_list;
rb_patricia_tree_t *tgchange_tree; rb_patricia_tree_t *tgchange_tree;
@ -805,3 +806,42 @@ find_tgchange(const char *host)
return NULL; return NULL;
} }
struct vhost_conf *
find_ssl_vhost(const char *hostname)
{
struct vhost_conf *vhost_p;
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, vhost_conf_list.head)
{
vhost_p = ptr->data;
if(!strcmp(hostname,vhost_p->hostname))
return vhost_p;
}
return NULL;
}
struct vhost_conf *
make_vhost_conf(void)
{
struct vhost_conf *vhost_p = rb_malloc(sizeof(struct vhost_conf));
return vhost_p;
}
void
free_vhost_conf(struct vhost_conf *vhost_p)
{
s_assert(vhost_p != NULL);
if(vhost_p == NULL)
return;
rb_free(vhost_p->hostname);
rb_free(vhost_p->ssl_private_key);
rb_free(vhost_p->ssl_cert);
rb_free(vhost_p->ssl_dh_params);
rb_free(vhost_p->ssl_cipher_list);
rb_free(vhost_p);
}
// TODO: Free vhost_conf_list

View file

@ -25,6 +25,7 @@
#include "stdinc.h" #include "stdinc.h"
#include "s_conf.h" #include "s_conf.h"
#include "s_newconf.h"
#include "logger.h" #include "logger.h"
#include "listener.h" #include "listener.h"
#include "sslproc.h" #include "sslproc.h"
@ -70,7 +71,9 @@ struct _ssl_ctl
static void send_new_ssl_certs_one(ssl_ctl_t * ctl, const char *ssl_cert, static void send_new_ssl_certs_one(ssl_ctl_t * ctl, const char *ssl_cert,
const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_private_key, const char *ssl_dh_params,
const char *ssl_cipher_list); const char *ssl_cipher_list, const char *hostname);
static void send_remove_ssl_vhost_one(ssl_ctl_t * ctl, const char *hostname);
static void send_init_prng(ssl_ctl_t * ctl, prng_seed_t seedtype, const char *path); static void send_init_prng(ssl_ctl_t * ctl, prng_seed_t seedtype, const char *path);
static void send_certfp_method(ssl_ctl_t *ctl, int method); static void send_certfp_method(ssl_ctl_t *ctl, int method);
@ -256,6 +259,10 @@ start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, co
char s_pid[10]; char s_pid[10];
pid_t pid; pid_t pid;
int started = 0, i; int started = 0, i;
struct vhost_conf *vhost_p;
rb_dlink_node *ptr;
rb_dlink_node *next_ptr;
if(ssld_wait) if(ssld_wait)
return 0; return 0;
@ -341,8 +348,16 @@ start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, co
send_init_prng(ctl, RB_PRNG_DEFAULT, NULL); send_init_prng(ctl, RB_PRNG_DEFAULT, NULL);
send_certfp_method(ctl, ConfigFileEntry.certfp_method); send_certfp_method(ctl, ConfigFileEntry.certfp_method);
if(ssl_cert != NULL) if(ssl_cert != NULL) {
send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params, ssl_cipher_list); send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params, ssl_cipher_list, NULL);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, vhost_conf_list.head)
{
vhost_p = ptr->data;
send_new_ssl_certs_one(ctl, vhost_p->ssl_cert, vhost_p->ssl_private_key,
vhost_p->ssl_dh_params ? vhost_p->ssl_dh_params : ssl_dh_params,
vhost_p->ssl_cipher_list ? vhost_p->ssl_cipher_list : ssl_cipher_list, vhost_p->hostname);
}
}
} }
ssl_read_ctl(ctl->F, ctl); ssl_read_ctl(ctl->F, ctl);
ssl_do_pipe(P2, ctl); ssl_do_pipe(P2, ctl);
@ -671,7 +686,7 @@ ssl_cmd_write_queue(ssl_ctl_t * ctl, rb_fde_t ** F, int count, const void *buf,
static void static void
send_new_ssl_certs_one(ssl_ctl_t * ctl, const char *ssl_cert, const char *ssl_private_key, send_new_ssl_certs_one(ssl_ctl_t * ctl, const char *ssl_cert, const char *ssl_private_key,
const char *ssl_dh_params, const char *ssl_cipher_list) const char *ssl_dh_params, const char *ssl_cipher_list, const char *hostname)
{ {
size_t len; size_t len;
@ -684,7 +699,10 @@ send_new_ssl_certs_one(ssl_ctl_t * ctl, const char *ssl_cert, const char *ssl_pr
if (ssl_cipher_list == NULL) if (ssl_cipher_list == NULL)
ssl_cipher_list = ""; ssl_cipher_list = "";
len = strlen(ssl_cert) + strlen(ssl_private_key) + strlen(ssl_dh_params) + strlen(ssl_cipher_list) + 6; if (hostname == NULL)
hostname = "";
len = strlen(ssl_cert) + strlen(ssl_private_key) + strlen(ssl_dh_params) + strlen(ssl_cipher_list) + strlen(hostname) + 6;
if(len > sizeof(tmpbuf)) if(len > sizeof(tmpbuf))
{ {
sendto_realops_snomask(SNO_GENERAL, L_ALL, sendto_realops_snomask(SNO_GENERAL, L_ALL,
@ -695,8 +713,47 @@ send_new_ssl_certs_one(ssl_ctl_t * ctl, const char *ssl_cert, const char *ssl_pr
len, sizeof(tmpbuf)); len, sizeof(tmpbuf));
return; return;
} }
len = rb_snprintf(tmpbuf, sizeof(tmpbuf), "K%c%s%c%s%c%s%c%s%c", nul, ssl_cert, len = rb_snprintf(tmpbuf, sizeof(tmpbuf), "K%c%s%c%s%c%s%c%s%c%s%c", nul, ssl_cert,
nul, ssl_private_key, nul, ssl_dh_params, nul, ssl_cipher_list, nul); nul, ssl_private_key, nul, ssl_dh_params, nul, ssl_cipher_list, nul, hostname, nul);
ssl_cmd_write_queue(ctl, NULL, 0, tmpbuf, len);
}
void
send_remove_ssl_vhost(const char *hostname)
{
rb_dlink_node *ptr;
if(hostname == NULL)
{
return;
}
RB_DLINK_FOREACH(ptr, ssl_daemons.head)
{
ssl_ctl_t *ctl = ptr->data;
send_remove_ssl_vhost_one(ctl, hostname);
}
}
static void
send_remove_ssl_vhost_one(ssl_ctl_t * ctl, const char *hostname)
{
size_t len;
if(hostname == NULL)
return;
len = strlen(hostname) + 3;
if(len > sizeof(tmpbuf))
{
sendto_realops_snomask(SNO_GENERAL, L_ALL,
"Parameters for send_init_prng too long (%zd > %zd) to pass to ssld, not sending...",
len, sizeof(tmpbuf));
ilog(L_MAIN,
"Parameters for send_init_prng too long (%zd > %zd) to pass to ssld, not sending...",
len, sizeof(tmpbuf));
return;
}
len = rb_snprintf(tmpbuf, sizeof(tmpbuf), "D%c%s%c", nul, hostname, nul);
ssl_cmd_write_queue(ctl, NULL, 0, tmpbuf, len); ssl_cmd_write_queue(ctl, NULL, 0, tmpbuf, len);
} }
@ -739,7 +796,7 @@ send_certfp_method(ssl_ctl_t *ctl, int method)
} }
void 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) 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)
{ {
rb_dlink_node *ptr; rb_dlink_node *ptr;
if(ssl_cert == NULL) if(ssl_cert == NULL)
@ -755,7 +812,7 @@ send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char
continue; continue;
send_certfp_method(ctl, method); send_certfp_method(ctl, method);
send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params, ssl_cipher_list); send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params, ssl_cipher_list, hostname);
} }
} }

View file

@ -925,7 +925,7 @@ static void
ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf) ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
{ {
char *buf; char *buf;
char *cert, *key, *dhparam, *cipher_list; char *cert, *key, *dhparam, *cipher_list, *hostname;
buf = (char *) &ctl_buf->buf[2]; buf = (char *) &ctl_buf->buf[2];
cert = buf; cert = buf;
@ -935,6 +935,8 @@ ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
dhparam = buf; dhparam = buf;
buf += strlen(dhparam) + 1; buf += strlen(dhparam) + 1;
cipher_list = buf; cipher_list = buf;
buf += strlen(cipher_list) + 1;
hostname = buf;
if(strlen(key) == 0) if(strlen(key) == 0)
key = cert; key = cert;
if(strlen(dhparam) == 0) if(strlen(dhparam) == 0)
@ -942,7 +944,15 @@ ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
if(strlen(cipher_list) == 0) if(strlen(cipher_list) == 0)
cipher_list = NULL; cipher_list = NULL;
if(!rb_setup_ssl_server(cert, key, dhparam, cipher_list)) int ret;
if(strlen(hostname) == 0) {
ret = rb_setup_ssl_server(cert, key, dhparam, cipher_list, NULL);
} else {
ret = rb_setup_ssl_server(cert, key, dhparam, cipher_list, hostname);
return;
}
if(!ret)
{ {
const char *invalid = "I"; const char *invalid = "I";
mod_cmd_write_queue(ctl, invalid, strlen(invalid)); mod_cmd_write_queue(ctl, invalid, strlen(invalid));
@ -950,6 +960,24 @@ ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
} }
} }
static void
ssl_remove_ssl_vhost(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
{
char *buf;
char *hostname;
buf = (char *) &ctl_buf->buf[2];
hostname = buf;
if(!rb_remove_ssl_vserver(hostname))
{
const char *invalid = "I";
mod_cmd_write_queue(ctl, invalid, strlen(invalid));
return;
}
}
static void static void
send_nossl_support(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb) send_nossl_support(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
{ {
@ -1054,6 +1082,16 @@ mod_process_cmd_recv(mod_ctl_t * ctl)
ssl_new_keys(ctl, ctl_buf); ssl_new_keys(ctl, ctl_buf);
break; break;
} }
case 'D':
{
if(!ssld_ssl_ok)
{
send_nossl_support(ctl, ctl_buf);
break;
}
ssl_remove_ssl_vhost(ctl, ctl_buf);
break;
}
case 'I': case 'I':
init_prng(ctl, ctl_buf); init_prng(ctl, ctl_buf);
break; break;