ssl: allow cipher list to be overridden (closes #67)
This commit is contained in:
parent
b5b4a0e79b
commit
c1725bda3c
14 changed files with 45 additions and 25 deletions
|
@ -151,6 +151,9 @@ serverinfo {
|
||||||
/* ssl_dh_params: DH parameters, generate with openssl dhparam -out dh.pem 1024 */
|
/* ssl_dh_params: DH parameters, generate with openssl dhparam -out dh.pem 1024 */
|
||||||
ssl_dh_params = "etc/dh.pem";
|
ssl_dh_params = "etc/dh.pem";
|
||||||
|
|
||||||
|
/* ssl_cipher_list: A list of ciphers, dependent on your TLS backend */
|
||||||
|
#ssl_cipher_list = "EECDH+HIGH:EDH+HIGH:HIGH:!aNULL";
|
||||||
|
|
||||||
/* ssld_count: number of ssld processes you want to start, if you
|
/* ssld_count: number of ssld processes you want to start, if you
|
||||||
* have a really busy server, using N-1 where N is the number of
|
* have a really busy server, using N-1 where N is the number of
|
||||||
* cpu/cpu cores you have might be useful. A number greater than one
|
* cpu/cpu cores you have might be useful. A number greater than one
|
||||||
|
|
|
@ -289,6 +289,7 @@ struct server_info
|
||||||
char *ssl_ca_cert;
|
char *ssl_ca_cert;
|
||||||
char *ssl_cert;
|
char *ssl_cert;
|
||||||
char *ssl_dh_params;
|
char *ssl_dh_params;
|
||||||
|
char *ssl_cipher_list;
|
||||||
int ssld_count;
|
int ssld_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,11 @@ struct _ssl_ctl;
|
||||||
typedef struct _ssl_ctl ssl_ctl_t;
|
typedef struct _ssl_ctl ssl_ctl_t;
|
||||||
|
|
||||||
void init_ssld(void);
|
void init_ssld(void);
|
||||||
int start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params);
|
int start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list);
|
||||||
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);
|
void send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list);
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list);
|
||||||
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);
|
||||||
|
|
|
@ -134,7 +134,7 @@ 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);
|
int rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list);
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -327,7 +327,7 @@ rb_load_file_into_datum_t(const char *file)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
|
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
gnutls_datum_t *d_cert, *d_key;
|
gnutls_datum_t *d_cert, *d_key;
|
||||||
|
@ -402,6 +402,8 @@ rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
|
||||||
else
|
else
|
||||||
rb_lib_log("rb_setup_ssl_server: Unable to setup DH parameters");
|
rb_lib_log("rb_setup_ssl_server: Unable to setup DH parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX integrate gnutls_priority_init() */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -321,7 +321,7 @@ rb_init_ssl(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
|
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -374,6 +374,8 @@ rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX support cipher lists when added to mbedtls */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list)
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -397,7 +397,7 @@ rb_init_ssl(void)
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
|
rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile, const char *cipher_list)
|
||||||
{
|
{
|
||||||
DH *dh;
|
DH *dh;
|
||||||
unsigned long err;
|
unsigned long err;
|
||||||
|
@ -455,6 +455,12 @@ rb_setup_ssl_server(const char *cert, const char *keyfile, const char *dhfile)
|
||||||
dhfile, get_ssl_error(err));
|
dhfile, get_ssl_error(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cipher_list != NULL)
|
||||||
|
{
|
||||||
|
SSL_CTX_set_cipher_list(ssl_server_ctx, cipher_list);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -709,7 +709,7 @@ main(int argc, char *argv[])
|
||||||
if(ServerInfo.ssl_cert != NULL && ServerInfo.ssl_private_key != NULL)
|
if(ServerInfo.ssl_cert != NULL && ServerInfo.ssl_private_key != NULL)
|
||||||
{
|
{
|
||||||
/* 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))
|
if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list))
|
||||||
{
|
{
|
||||||
ilog(L_MAIN, "WARNING: Unable to setup SSL.");
|
ilog(L_MAIN, "WARNING: Unable to setup SSL.");
|
||||||
ssl_ok = 0;
|
ssl_ok = 0;
|
||||||
|
|
|
@ -2252,6 +2252,7 @@ static struct ConfEntry conf_serverinfo_table[] =
|
||||||
{ "ssl_ca_cert", CF_QSTRING, NULL, 0, &ServerInfo.ssl_ca_cert },
|
{ "ssl_ca_cert", CF_QSTRING, NULL, 0, &ServerInfo.ssl_ca_cert },
|
||||||
{ "ssl_cert", CF_QSTRING, NULL, 0, &ServerInfo.ssl_cert },
|
{ "ssl_cert", CF_QSTRING, NULL, 0, &ServerInfo.ssl_cert },
|
||||||
{ "ssl_dh_params", CF_QSTRING, NULL, 0, &ServerInfo.ssl_dh_params },
|
{ "ssl_dh_params", CF_QSTRING, NULL, 0, &ServerInfo.ssl_dh_params },
|
||||||
|
{ "ssl_cipher_list", CF_QSTRING, NULL, 0, &ServerInfo.ssl_cipher_list },
|
||||||
{ "ssld_count", CF_INT, NULL, 0, &ServerInfo.ssld_count },
|
{ "ssld_count", CF_INT, NULL, 0, &ServerInfo.ssld_count },
|
||||||
|
|
||||||
{ "default_max_clients",CF_INT, NULL, 0, &ServerInfo.default_max_clients },
|
{ "default_max_clients",CF_INT, NULL, 0, &ServerInfo.default_max_clients },
|
||||||
|
|
|
@ -870,21 +870,20 @@ 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))
|
if(!rb_setup_ssl_server(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list))
|
||||||
{
|
{
|
||||||
ilog(L_MAIN, "WARNING: Unable to setup SSL.");
|
ilog(L_MAIN, "WARNING: Unable to setup SSL.");
|
||||||
ssl_ok = 0;
|
ssl_ok = 0;
|
||||||
} else {
|
} else {
|
||||||
ssl_ok = 1;
|
ssl_ok = 1;
|
||||||
send_new_ssl_certs(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params);
|
send_new_ssl_certs(ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ServerInfo.ssld_count > get_ssld_count())
|
if(ServerInfo.ssld_count > get_ssld_count())
|
||||||
{
|
{
|
||||||
int start = ServerInfo.ssld_count - get_ssld_count();
|
int start = ServerInfo.ssld_count - get_ssld_count();
|
||||||
/* start up additional ssld if needed */
|
/* start up additional ssld if needed */
|
||||||
start_ssldaemon(start, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params);
|
start_ssldaemon(start, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* General conf */
|
/* General conf */
|
||||||
|
|
|
@ -70,7 +70,8 @@ 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);
|
||||||
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);
|
||||||
|
|
||||||
|
@ -176,7 +177,7 @@ ssl_dead(ssl_ctl_t * ctl)
|
||||||
rb_kill(ctl->pid, SIGKILL); /* make sure the process is really gone */
|
rb_kill(ctl->pid, SIGKILL); /* make sure the process is really gone */
|
||||||
ilog(L_MAIN, "ssld helper died - attempting to restart");
|
ilog(L_MAIN, "ssld helper died - attempting to restart");
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL, "ssld helper died - attempting to restart");
|
sendto_realops_snomask(SNO_GENERAL, L_ALL, "ssld helper died - attempting to restart");
|
||||||
start_ssldaemon(1, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params);
|
start_ssldaemon(1, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -204,12 +205,12 @@ restart_ssld_event(void *unused)
|
||||||
int start = ServerInfo.ssld_count - get_ssld_count();
|
int start = ServerInfo.ssld_count - get_ssld_count();
|
||||||
ilog(L_MAIN, "Attempting to restart ssld processes");
|
ilog(L_MAIN, "Attempting to restart ssld processes");
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Attempt to restart ssld processes");
|
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Attempt to restart ssld processes");
|
||||||
start_ssldaemon(start, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params);
|
start_ssldaemon(start, ServerInfo.ssl_cert, ServerInfo.ssl_private_key, ServerInfo.ssl_dh_params, ServerInfo.ssl_cipher_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params)
|
start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list)
|
||||||
{
|
{
|
||||||
rb_fde_t *F1, *F2;
|
rb_fde_t *F1, *F2;
|
||||||
rb_fde_t *P1, *P2;
|
rb_fde_t *P1, *P2;
|
||||||
|
@ -313,7 +314,8 @@ start_ssldaemon(int count, const char *ssl_cert, const char *ssl_private_key, co
|
||||||
|
|
||||||
if(ssl_cert != NULL && ssl_private_key != NULL)
|
if(ssl_cert != NULL && ssl_private_key != NULL)
|
||||||
send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key,
|
send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key,
|
||||||
ssl_dh_params != NULL ? ssl_dh_params : "");
|
ssl_dh_params != NULL ? ssl_dh_params : "",
|
||||||
|
ssl_cipher_list != NULL ? ssl_cipher_list : "");
|
||||||
}
|
}
|
||||||
ssl_read_ctl(ctl->F, ctl);
|
ssl_read_ctl(ctl->F, ctl);
|
||||||
ssl_do_pipe(P2, ctl);
|
ssl_do_pipe(P2, ctl);
|
||||||
|
@ -613,7 +615,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, const char *ssl_dh_params)
|
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)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
@ -628,8 +630,8 @@ 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", nul, ssl_cert, nul,
|
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_private_key, nul, ssl_dh_params, nul, ssl_cipher_list, nul);
|
||||||
ssl_cmd_write_queue(ctl, NULL, 0, tmpbuf, len);
|
ssl_cmd_write_queue(ctl, NULL, 0, tmpbuf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -672,7 +674,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)
|
send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char *ssl_dh_params, const char *ssl_cipher_list)
|
||||||
{
|
{
|
||||||
rb_dlink_node *ptr;
|
rb_dlink_node *ptr;
|
||||||
if(ssl_cert == NULL || ssl_private_key == NULL || ssl_dh_params == NULL)
|
if(ssl_cert == NULL || ssl_private_key == NULL || ssl_dh_params == NULL)
|
||||||
|
@ -683,7 +685,7 @@ send_new_ssl_certs(const char *ssl_cert, const char *ssl_private_key, const char
|
||||||
RB_DLINK_FOREACH(ptr, ssl_daemons.head)
|
RB_DLINK_FOREACH(ptr, ssl_daemons.head)
|
||||||
{
|
{
|
||||||
ssl_ctl_t *ctl = ptr->data;
|
ssl_ctl_t *ctl = ptr->data;
|
||||||
send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params);
|
send_new_ssl_certs_one(ctl, ssl_cert, ssl_private_key, ssl_dh_params, ssl_cipher_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -910,7 +910,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;
|
char *cert, *key, *dhparam, *cipher_list;
|
||||||
|
|
||||||
buf = (char *) &ctl_buf->buf[2];
|
buf = (char *) &ctl_buf->buf[2];
|
||||||
cert = buf;
|
cert = buf;
|
||||||
|
@ -920,8 +920,12 @@ ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
|
||||||
dhparam = buf;
|
dhparam = buf;
|
||||||
if(strlen(dhparam) == 0)
|
if(strlen(dhparam) == 0)
|
||||||
dhparam = NULL;
|
dhparam = NULL;
|
||||||
|
buf += strlen(dhparam) + 1;
|
||||||
|
cipher_list = buf;
|
||||||
|
if(strlen(cipher_list) == 0)
|
||||||
|
cipher_list = NULL;
|
||||||
|
|
||||||
if(!rb_setup_ssl_server(cert, key, dhparam))
|
if(!rb_setup_ssl_server(cert, key, dhparam, cipher_list))
|
||||||
{
|
{
|
||||||
const char *invalid = "I";
|
const char *invalid = "I";
|
||||||
mod_cmd_write_queue(ctl, invalid, strlen(invalid));
|
mod_cmd_write_queue(ctl, invalid, strlen(invalid));
|
||||||
|
|
Loading…
Reference in a new issue