Skip to content

Commit

Permalink
Merge pull request #236 from appearin/reload-tls-certs
Browse files Browse the repository at this point in the history
Make SIGUSR2 reload TLS certificates
  • Loading branch information
misi committed Aug 1, 2018
2 parents e37774b + 6bc4bab commit 7f27383
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 110 deletions.
68 changes: 52 additions & 16 deletions src/apps/relay/mainrelay.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ DH_1066, "", "", "",
0,
#endif

NULL, PTHREAD_MUTEX_INITIALIZER,

TURN_VERBOSE_NONE,0,0,0,
"/var/run/turnserver.pid",
DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,1,
Expand Down Expand Up @@ -175,6 +177,7 @@ static char procgroupname[1025]="\0";
////////////// Configuration functionality ////////////////////////////////

static void read_config_file(int argc, char **argv, int pass);
static void reload_ssl_certs(evutil_socket_t sock, short events, void *args);

//////////////////////////////////////////////////

Expand Down Expand Up @@ -2155,6 +2158,9 @@ int main(int argc, char **argv)

setup_server();

struct event *ev = evsignal_new(turn_params.listener.event_base, SIGUSR2, reload_ssl_certs, NULL);
event_add(ev, NULL);

drop_privileges();

run_listener_server(&(turn_params.listener));
Expand Down Expand Up @@ -2492,8 +2498,10 @@ static int ServerALPNCallback(SSL *ssl,

#endif

static void set_ctx(SSL_CTX* ctx, const char *protocol)
static void set_ctx(SSL_CTX** out, const char *protocol, const SSL_METHOD* method)
{
SSL_CTX* ctx = SSL_CTX_new(method);
int err = 0;
#if ALPN_SUPPORTED
SSL_CTX_set_alpn_select_cb(ctx, ServerALPNCallback, NULL);
#endif
Expand All @@ -2510,13 +2518,15 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol)

if (!SSL_CTX_use_certificate_chain_file(ctx, turn_params.cert_file)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: no certificate found\n", protocol);
err = 1;
} else {
print_abs_file_name(protocol, ": Certificate", turn_params.cert_file);
}

if (!SSL_CTX_use_PrivateKey_file(ctx, turn_params.pkey_file, SSL_FILETYPE_PEM)) {
if (!SSL_CTX_use_RSAPrivateKey_file(ctx, turn_params.pkey_file, SSL_FILETYPE_PEM)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: no valid private key found, or invalid private key password provided\n", protocol);
err = 1;
} else {
print_abs_file_name(protocol, ": Private RSA key", turn_params.pkey_file);
}
Expand All @@ -2526,12 +2536,14 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol)

if (!SSL_CTX_check_private_key(ctx)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: invalid private key\n", protocol);
err = 1;
}

if(turn_params.ca_cert_file[0]) {

if (!SSL_CTX_load_verify_locations(ctx, turn_params.ca_cert_file, NULL )) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot load CA from file: %s\n", turn_params.ca_cert_file);
err = 1;
}

SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(turn_params.ca_cert_file));
Expand Down Expand Up @@ -2629,10 +2641,12 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol)
*/

if(!dh) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot allocate DH suite\n",__FUNCTION__);
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot allocate DH suite\n",__FUNCTION__);
err = 1;
} else {
if (1 != SSL_CTX_set_tmp_dh (ctx, dh)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot set DH\n",__FUNCTION__);
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot set DH\n",__FUNCTION__);
err = 1;
}
DH_free (dh);
}
Expand Down Expand Up @@ -2686,8 +2700,17 @@ static void set_ctx(SSL_CTX* ctx, const char *protocol)

SSL_CTX_set_options(ctx, op);
}

if (*out == NULL) {
// Always initialize, even if issues were encountered
*out = ctx;
} else if (!err) {
SSL_CTX_free(*out);
*out = ctx;
}
}

static void openssl_load_certificates(void);
static void openssl_setup(void)
{
THREAD_setup();
Expand Down Expand Up @@ -2717,22 +2740,24 @@ static void openssl_setup(void)
adjust_key_file_names();
}

openssl_load_certificates();
}

static void openssl_load_certificates(void)
{
pthread_mutex_lock(&turn_params.tls_mutex);
if(!turn_params.no_tls) {
turn_params.tls_ctx_ssl23 = SSL_CTX_new(SSLv23_server_method()); /*compatibility mode */
set_ctx(turn_params.tls_ctx_ssl23,"SSL23");
set_ctx(&turn_params.tls_ctx_ssl23,"SSL23",SSLv23_server_method()); /*compatibility mode */
if(!turn_params.no_tlsv1) {
turn_params.tls_ctx_v1_0 = SSL_CTX_new(TLSv1_server_method());
set_ctx(turn_params.tls_ctx_v1_0,"TLS1.0");
set_ctx(&turn_params.tls_ctx_v1_0,"TLS1.0",TLSv1_server_method());
}
#if TLSv1_1_SUPPORTED
if(!turn_params.no_tlsv1_1) {
turn_params.tls_ctx_v1_1 = SSL_CTX_new(TLSv1_1_server_method());
set_ctx(turn_params.tls_ctx_v1_1,"TLS1.1");
set_ctx(&turn_params.tls_ctx_v1_1,"TLS1.1",TLSv1_1_server_method());
}
#if TLSv1_2_SUPPORTED
if(!turn_params.no_tlsv1_2) {
turn_params.tls_ctx_v1_2 = SSL_CTX_new(TLSv1_2_server_method());
set_ctx(turn_params.tls_ctx_v1_2,"TLS1.2");
set_ctx(&turn_params.tls_ctx_v1_2,"TLS1.2",TLSv1_2_server_method());
}
#endif
#endif
Expand All @@ -2748,20 +2773,31 @@ static void openssl_setup(void)
}

#if DTLSv1_2_SUPPORTED
turn_params.dtls_ctx = SSL_CTX_new(DTLS_server_method());
turn_params.dtls_ctx_v1_2 = SSL_CTX_new(DTLSv1_2_server_method());
set_ctx(turn_params.dtls_ctx_v1_2,"DTLS1.2");
set_ctx(&turn_params.dtls_ctx,"DTLS",DTLS_server_method());
set_ctx(&turn_params.dtls_ctx_v1_2,"DTLS1.2",DTLSv1_2_server_method());
SSL_CTX_set_read_ahead(turn_params.dtls_ctx_v1_2, 1);
#else
turn_params.dtls_ctx = SSL_CTX_new(DTLSv1_server_method());
set_ctx(&turn_params.dtls_ctx,"DTLS",DTLSv1_server_method());
#endif
set_ctx(turn_params.dtls_ctx,"DTLS");
SSL_CTX_set_read_ahead(turn_params.dtls_ctx, 1);

TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS cipher suite: %s\n",turn_params.cipher_list);

#endif
}
pthread_mutex_unlock(&turn_params.tls_mutex);
}

static void reload_ssl_certs(evutil_socket_t sock, short events, void *args)
{
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Reloading TLS certificates and keys");
openssl_load_certificates();
if (turn_params.tls_ctx_update_ev != NULL)
event_active(turn_params.tls_ctx_update_ev, EV_READ, 0);

UNUSED_ARG(sock);
UNUSED_ARG(events);
UNUSED_ARG(args);
}

///////////////////////////////
3 changes: 3 additions & 0 deletions src/apps/relay/mainrelay.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ typedef struct _turn_params_ {
int no_tls;
int no_dtls;

struct event *tls_ctx_update_ev;
pthread_mutex_t tls_mutex;

//////////////// Common params ////////////////////

int verbose;
Expand Down
104 changes: 60 additions & 44 deletions src/apps/relay/netengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,63 @@ void del_tls_alternate_server(const char *saddr)

//////////////////////////////////////////////////

typedef struct update_ssl_ctx_cb_args {
ioa_engine_handle engine;
turn_params_t *params;
struct event *next;
} update_ssl_ctx_cb_args_t;

static void update_ssl_ctx(evutil_socket_t sock, short events, update_ssl_ctx_cb_args_t *args)
{
ioa_engine_handle e = args->engine;
turn_params_t *params = args->params;

pthread_mutex_lock(&turn_params.tls_mutex);
e->tls_ctx_ssl23 = params->tls_ctx_ssl23;
e->tls_ctx_v1_0 = params->tls_ctx_v1_0;
#if TLSv1_1_SUPPORTED
e->tls_ctx_v1_1 = params->tls_ctx_v1_1;
#if TLSv1_2_SUPPORTED
e->tls_ctx_v1_2 = params->tls_ctx_v1_2;
#endif
#endif
#if DTLS_SUPPORTED
e->dtls_ctx = params->dtls_ctx;
#endif
#if DTLSv1_2_SUPPORTED
e->dtls_ctx_v1_2 = params->dtls_ctx_v1_2;
#endif
struct event *next = args->next;
pthread_mutex_unlock(&turn_params.tls_mutex);

if (next != NULL)
event_active(next, EV_READ, 0);

UNUSED_ARG(sock);
UNUSED_ARG(events);
}

static void set_ssl_ctx(ioa_engine_handle e, turn_params_t *params)
{
update_ssl_ctx_cb_args_t *args = (update_ssl_ctx_cb_args_t *)turn_malloc(sizeof(update_ssl_ctx_cb_args_t));
args->engine = e;
args->params = params;
args->next = NULL;

update_ssl_ctx(-1, 0, args);

struct event_base *base = e->event_base;
if (base != NULL) {
struct event *ev = event_new(base, -1, EV_PERSIST, (event_callback_fn)update_ssl_ctx, (void *)args);
pthread_mutex_lock(&turn_params.tls_mutex);
args->next = params->tls_ctx_update_ev;
params->tls_ctx_update_ev = ev;
pthread_mutex_unlock(&turn_params.tls_mutex);
}
}

//////////////////////////////////////////////////

void add_listener_addr(const char* addr) {
ioa_addr baddr;
if(make_ioa_addr((const u08bits*)addr,0,&baddr)<0) {
Expand Down Expand Up @@ -962,20 +1019,7 @@ static ioa_engine_handle create_new_listener_engine(void)
,turn_params.redis_statsdb
#endif
);
set_ssl_ctx(e, turn_params.tls_ctx_ssl23, turn_params.tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,turn_params.tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,turn_params.tls_ctx_v1_2
#endif
#endif
#if DTLS_SUPPORTED
,turn_params.dtls_ctx
#endif
#if DTLSv1_2_SUPPORTED
,turn_params.dtls_ctx_v1_2
#endif
);
set_ssl_ctx(e, &turn_params);
ioa_engine_set_rtcp_map(e, turn_params.listener.rtcpmap);
return e;
}
Expand Down Expand Up @@ -1018,23 +1062,8 @@ static void setup_listener(void)
if(!turn_params.listener.ioa_eng)
exit(-1);

set_ssl_ctx(turn_params.listener.ioa_eng, turn_params.tls_ctx_ssl23, turn_params.tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,turn_params.tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,turn_params.tls_ctx_v1_2
#endif
#endif
#if DTLS_SUPPORTED
,turn_params.dtls_ctx
#endif
#if DTLSv1_2_SUPPORTED
,turn_params.dtls_ctx_v1_2
#endif
);

set_ssl_ctx(turn_params.listener.ioa_eng, &turn_params);
turn_params.listener.rtcpmap = rtcp_map_create(turn_params.listener.ioa_eng);

ioa_engine_set_rtcp_map(turn_params.listener.ioa_eng, turn_params.listener.rtcpmap);

{
Expand Down Expand Up @@ -1592,20 +1621,7 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int
,turn_params.redis_statsdb
#endif
);
set_ssl_ctx(rs->ioa_eng, turn_params.tls_ctx_ssl23, turn_params.tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,turn_params.tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,turn_params.tls_ctx_v1_2
#endif
#endif
#if DTLS_SUPPORTED
,turn_params.dtls_ctx
#endif
#if DTLSv1_2_SUPPORTED
,turn_params.dtls_ctx_v1_2
#endif
);
set_ssl_ctx(rs->ioa_eng, &turn_params);
ioa_engine_set_rtcp_map(rs->ioa_eng, turn_params.listener.rtcpmap);
}

Expand Down
33 changes: 0 additions & 33 deletions src/apps/relay/ns_ioalib_engine_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,39 +436,6 @@ ioa_engine_handle create_ioa_engine(super_memory_t *sm,
}
}

void set_ssl_ctx(ioa_engine_handle e,
SSL_CTX *tls_ctx_ssl23,
SSL_CTX *tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,SSL_CTX *tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,SSL_CTX *tls_ctx_v1_2
#endif
#endif
#if DTLS_SUPPORTED
,SSL_CTX *dtls_ctx
#endif
#if DTLSv1_2_SUPPORTED
,SSL_CTX *dtls_ctx_v1_2
#endif
)
{
e->tls_ctx_ssl23 = tls_ctx_ssl23;
e->tls_ctx_v1_0 = tls_ctx_v1_0;
#if TLSv1_1_SUPPORTED
e->tls_ctx_v1_1 = tls_ctx_v1_1;
#if TLSv1_2_SUPPORTED
e->tls_ctx_v1_2 = tls_ctx_v1_2;
#endif
#endif
#if DTLS_SUPPORTED
e->dtls_ctx = dtls_ctx;
#endif
#if DTLSv1_2_SUPPORTED
e->dtls_ctx_v1_2 = dtls_ctx_v1_2;
#endif
}

void ioa_engine_set_rtcp_map(ioa_engine_handle e, rtcp_map *rtcpmap)
{
if(e)
Expand Down
17 changes: 0 additions & 17 deletions src/apps/relay/ns_ioalib_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,23 +258,6 @@ ioa_engine_handle create_ioa_engine(super_memory_t *sm,
#endif
);

void set_ssl_ctx(ioa_engine_handle e,
SSL_CTX *tls_ctx_ssl23,
SSL_CTX *tls_ctx_v1_0
#if TLSv1_1_SUPPORTED
,SSL_CTX *tls_ctx_v1_1
#if TLSv1_2_SUPPORTED
,SSL_CTX *tls_ctx_v1_2
#endif
#endif
#if DTLS_SUPPORTED
,SSL_CTX *dtls_ctx
#endif
#if DTLSv1_2_SUPPORTED
,SSL_CTX *dtls_ctx_v1_2
#endif
);

void ioa_engine_set_rtcp_map(ioa_engine_handle e, rtcp_map *rtcpmap);

ioa_socket_handle create_ioa_socket_from_fd(ioa_engine_handle e, ioa_socket_raw fd, ioa_socket_handle parent_s, SOCKET_TYPE st, SOCKET_APP_TYPE sat, const ioa_addr *remote_addr, const ioa_addr *local_addr);
Expand Down

0 comments on commit 7f27383

Please sign in to comment.