Added SNI support (OpenSSL)
This commit is contained in:
parent
0b79494ec9
commit
074e23e4e2
17 changed files with 422 additions and 28 deletions
|
@ -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";;
|
||||
};
|
||||
*/
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -498,7 +498,7 @@ rb_init_ssl(void)
|
|||
|
||||
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, char *hostname)
|
||||
{
|
||||
if(certfile == NULL)
|
||||
{
|
||||
|
|
|
@ -457,7 +457,7 @@ rb_init_ssl(void)
|
|||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
17
src/ircd.c
17
src/ircd.c
|
@ -535,6 +535,9 @@ int
|
|||
main(int argc, char *argv[])
|
||||
{
|
||||
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 */
|
||||
if(geteuid() == 0)
|
||||
|
@ -712,13 +715,25 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
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)
|
||||
|
|
|
@ -46,6 +46,7 @@ static struct Class *yy_class = NULL;
|
|||
|
||||
static struct remote_conf *yy_shared = 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_oper_list;
|
||||
|
@ -1439,6 +1440,71 @@ conf_set_connect_class(void *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
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
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_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_conf_item("exempt", "ip", CF_QSTRING, conf_set_exempt_ip);
|
||||
|
|
31
src/s_conf.c
31
src/s_conf.c
|
@ -860,6 +860,10 @@ read_conf(void)
|
|||
static void
|
||||
validate_conf(void)
|
||||
{
|
||||
struct vhost_conf *vhost_p;
|
||||
rb_dlink_node *ptr;
|
||||
rb_dlink_node *next_ptr;
|
||||
|
||||
if(ConfigFileEntry.default_ident_timeout < 1)
|
||||
ConfigFileEntry.default_ident_timeout = IDENT_TIMEOUT_DEFAULT;
|
||||
|
||||
|
@ -875,13 +879,27 @@ validate_conf(void)
|
|||
if(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.");
|
||||
ircd_ssl_ok = 0;
|
||||
} else {
|
||||
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())
|
||||
|
@ -1462,6 +1480,7 @@ static void
|
|||
clear_out_old_conf(void)
|
||||
{
|
||||
struct Class *cltmp;
|
||||
struct vhost_conf *vhost_p;
|
||||
rb_dlink_node *ptr;
|
||||
rb_dlink_node *next_ptr;
|
||||
|
||||
|
@ -1547,6 +1566,14 @@ clear_out_old_conf(void)
|
|||
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 */
|
||||
if (alias_dict != NULL)
|
||||
{
|
||||
|
|
|
@ -56,6 +56,7 @@ rb_dlink_list xline_conf_list;
|
|||
rb_dlink_list resv_conf_list; /* nicks only! */
|
||||
rb_dlink_list nd_list; /* nick delay */
|
||||
rb_dlink_list tgchange_list;
|
||||
rb_dlink_list vhost_conf_list;
|
||||
|
||||
rb_patricia_tree_t *tgchange_tree;
|
||||
|
||||
|
@ -805,3 +806,42 @@ find_tgchange(const char *host)
|
|||
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
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "stdinc.h"
|
||||
|
||||
#include "s_conf.h"
|
||||
#include "s_newconf.h"
|
||||
#include "logger.h"
|
||||
#include "listener.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,
|
||||
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_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];
|
||||
pid_t pid;
|
||||
int started = 0, i;
|
||||
struct vhost_conf *vhost_p;
|
||||
rb_dlink_node *ptr;
|
||||
rb_dlink_node *next_ptr;
|
||||
|
||||
|
||||
if(ssld_wait)
|
||||
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_certfp_method(ctl, ConfigFileEntry.certfp_method);
|
||||
|
||||
if(ssl_cert != NULL)
|
||||
send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params, ssl_cipher_list);
|
||||
if(ssl_cert != NULL) {
|
||||
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_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
|
||||
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;
|
||||
|
||||
|
@ -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)
|
||||
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))
|
||||
{
|
||||
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));
|
||||
return;
|
||||
}
|
||||
len = rb_snprintf(tmpbuf, sizeof(tmpbuf), "K%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);
|
||||
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, 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);
|
||||
}
|
||||
|
||||
|
@ -739,7 +796,7 @@ send_certfp_method(ssl_ctl_t *ctl, 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)
|
||||
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;
|
||||
if(ssl_cert == NULL)
|
||||
|
@ -755,7 +812,7 @@ send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char
|
|||
continue;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
42
ssld/ssld.c
42
ssld/ssld.c
|
@ -925,7 +925,7 @@ static void
|
|||
ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
|
||||
{
|
||||
char *buf;
|
||||
char *cert, *key, *dhparam, *cipher_list;
|
||||
char *cert, *key, *dhparam, *cipher_list, *hostname;
|
||||
|
||||
buf = (char *) &ctl_buf->buf[2];
|
||||
cert = buf;
|
||||
|
@ -935,6 +935,8 @@ ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
|
|||
dhparam = buf;
|
||||
buf += strlen(dhparam) + 1;
|
||||
cipher_list = buf;
|
||||
buf += strlen(cipher_list) + 1;
|
||||
hostname = buf;
|
||||
if(strlen(key) == 0)
|
||||
key = cert;
|
||||
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)
|
||||
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";
|
||||
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
|
||||
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);
|
||||
break;
|
||||
}
|
||||
case 'D':
|
||||
{
|
||||
if(!ssld_ssl_ok)
|
||||
{
|
||||
send_nossl_support(ctl, ctl_buf);
|
||||
break;
|
||||
}
|
||||
ssl_remove_ssl_vhost(ctl, ctl_buf);
|
||||
break;
|
||||
}
|
||||
case 'I':
|
||||
init_prng(ctl, ctl_buf);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue