Browse Source

Merge pull request #739 from hills/ssl-reload-crashes

SSL reload has hidden bugs which cause crashes
Mészáros Mihály 4 năm trước cách đây
mục cha
commit
d90c689c99

+ 23 - 50
src/apps/relay/dtls_listener.c

@@ -55,12 +55,6 @@ struct dtls_listener_relay_server_info {
   ioa_engine_handle e;
   turn_turnserver *ts;
   int verbose;
-#if DTLS_SUPPORTED
-  SSL_CTX *dtls_ctx;
-#if DTLSv1_2_SUPPORTED
-  SSL_CTX *dtls_ctx_v1_2;
-#endif
-#endif
   struct event *udp_listen_ev;
   ioa_socket_handle udp_listen_s;
   ur_addr_map *children_ss; /* map of socket children on remote addr */
@@ -288,13 +282,13 @@ static ioa_socket_handle dtls_server_input_handler(dtls_listener_relay_server_ty
 #if DTLSv1_2_SUPPORTED
 	if(get_dtls_version(ioa_network_buffer_data(nbh),
 							(int)ioa_network_buffer_get_size(nbh)) == 1) {
-		connecting_ssl = SSL_new(server->dtls_ctx_v1_2);
+		connecting_ssl = SSL_new(server->e->dtls_ctx_v1_2);
 	} else {
-		connecting_ssl = SSL_new(server->dtls_ctx);
+		connecting_ssl = SSL_new(server->e->dtls_ctx);
 	}
 #else
 	{
-		connecting_ssl = SSL_new(server->dtls_ctx);
+		connecting_ssl = SSL_new(server->e->dtls_ctx);
 	}
 #endif
 
@@ -573,13 +567,13 @@ static int create_new_connected_udp_socket(
 #if DTLSv1_2_SUPPORTED
 		if(get_dtls_version(ioa_network_buffer_data(server->sm.m.sm.nd.nbh),
 							(int)ioa_network_buffer_get_size(server->sm.m.sm.nd.nbh)) == 1) {
-			connecting_ssl = SSL_new(server->dtls_ctx_v1_2);
+			connecting_ssl = SSL_new(server->e->dtls_ctx_v1_2);
 		} else {
-			connecting_ssl = SSL_new(server->dtls_ctx);
+			connecting_ssl = SSL_new(server->e->dtls_ctx);
 		}
 #else
 		{
-			connecting_ssl = SSL_new(server->dtls_ctx);
+			connecting_ssl = SSL_new(server->e->dtls_ctx);
 		}
 #endif
 
@@ -912,14 +906,6 @@ static int init_server(dtls_listener_relay_server_type* server,
 
   if(!server) return -1;
 
-#if DTLS_SUPPORTED
-  server->dtls_ctx = e->dtls_ctx;
-
-#if DTLSv1_2_SUPPORTED
-  server->dtls_ctx_v1_2 = e->dtls_ctx_v1_2;
-#endif
-#endif
-
   server->ts = ts;
   server->connect_cb = send_socket;
 
@@ -935,36 +921,6 @@ static int init_server(dtls_listener_relay_server_type* server,
   server->verbose=verbose;
   
   server->e = e;
-  
-#if DTLS_SUPPORTED
-  if(server->dtls_ctx) {
-
-#if defined(REQUEST_CLIENT_CERT)
-	  /* If client has to authenticate, then  */
-	  SSL_CTX_set_verify(server->dtls_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback);
-#endif
-  
-	  SSL_CTX_set_read_ahead(server->dtls_ctx, 1);
-
-	  SSL_CTX_set_cookie_generate_cb(server->dtls_ctx, generate_cookie);
-	  SSL_CTX_set_cookie_verify_cb(server->dtls_ctx, verify_cookie);
-  }
-
-#if DTLSv1_2_SUPPORTED
-  if(server->dtls_ctx_v1_2) {
-
-  #if defined(REQUEST_CLIENT_CERT)
-  	  /* If client has to authenticate, then  */
-  	  SSL_CTX_set_verify(server->dtls_ctx_v1_2, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback);
-  #endif
-
-  	  SSL_CTX_set_read_ahead(server->dtls_ctx_v1_2, 1);
-
-  	  SSL_CTX_set_cookie_generate_cb(server->dtls_ctx_v1_2, generate_cookie);
-  	  SSL_CTX_set_cookie_verify_cb(server->dtls_ctx_v1_2, verify_cookie);
-    }
-#endif
-#endif
 
   return create_server_socket(server, report_creation);
 }
@@ -980,6 +936,23 @@ static int clean_server(dtls_listener_relay_server_type* server) {
 
 ///////////////////////////////////////////////////////////
 
+#if DTLS_SUPPORTED
+void setup_dtls_callbacks(SSL_CTX *ctx) {
+  if (!ctx)
+    return;
+
+#if defined(REQUEST_CLIENT_CERT)
+  /* If client has to authenticate, then  */
+  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback);
+#endif
+
+  SSL_CTX_set_read_ahead(ctx, 1);
+
+  SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie);
+  SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie);
+}
+#endif
+
 dtls_listener_relay_server_type* create_dtls_listener_server(const char* ifname,
 							     const char *local_address, 
 							     int port, 

+ 4 - 0
src/apps/relay/dtls_listener.h

@@ -50,6 +50,10 @@ typedef struct dtls_listener_relay_server_info dtls_listener_relay_server_type;
 
 ///////////////////////////////////////////
 
+#if DTLS_SUPPORTED
+void setup_dtls_callbacks(SSL_CTX *ctx);
+#endif
+
 dtls_listener_relay_server_type* create_dtls_listener_server(const char* ifname,
 							     const char *local_address, 
 							     int port,

+ 2 - 0
src/apps/relay/mainrelay.c

@@ -3198,10 +3198,12 @@ static void openssl_load_certificates(void)
 		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);
+		setup_dtls_callbacks(turn_params.dtls_ctx_v1_2);
 #else
 		set_ctx(&turn_params.dtls_ctx,"DTLS",DTLSv1_server_method());
 #endif
 		SSL_CTX_set_read_ahead(turn_params.dtls_ctx, 1);
+		setup_dtls_callbacks(turn_params.dtls_ctx);
 
 		TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS cipher suite: %s\n",turn_params.cipher_list);
 

+ 19 - 6
src/apps/relay/netengine.c

@@ -304,25 +304,38 @@ typedef struct update_ssl_ctx_cb_args {
 	struct event *next;
 } update_ssl_ctx_cb_args_t;
 
+static void replace_one_ssl_ctx(SSL_CTX **to, SSL_CTX *from)
+{
+	if (*to)
+		SSL_CTX_free(*to);
+
+	SSL_CTX_up_ref(from);
+	*to = from;
+}
+
+/*
+ * Synchronise the ioa_engine's SSL certificates with the global ones
+ */
 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;
 
+	/* No mutex with "e" as these are only used in the same event loop */
 	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;
+	replace_one_ssl_ctx(&e->tls_ctx_ssl23, params->tls_ctx_ssl23);
+	replace_one_ssl_ctx(&e->tls_ctx_v1_0, params->tls_ctx_v1_0);
 #if TLSv1_1_SUPPORTED
-	e->tls_ctx_v1_1 = params->tls_ctx_v1_1;
+	replace_one_ssl_ctx(&e->tls_ctx_v1_1, params->tls_ctx_v1_1);
 #if TLSv1_2_SUPPORTED
-	e->tls_ctx_v1_2 = params->tls_ctx_v1_2;
+	replace_one_ssl_ctx(&e->tls_ctx_v1_2, params->tls_ctx_v1_2);
 #endif
 #endif
 #if DTLS_SUPPORTED
-	e->dtls_ctx = params->dtls_ctx;
+	replace_one_ssl_ctx(&e->dtls_ctx, params->dtls_ctx);
 #endif
 #if DTLSv1_2_SUPPORTED
-	e->dtls_ctx_v1_2 = params->dtls_ctx_v1_2;
+	replace_one_ssl_ctx(&e->dtls_ctx_v1_2, params->dtls_ctx_v1_2);
 #endif
 	struct event *next = args->next;
 	pthread_mutex_unlock(&turn_params.tls_mutex);