Forráskód Böngészése

Initialize SSL in mg_init_library, so https client functions can be used without initializing a server first

bel2125 8 éve
szülő
commit
de7d40f126
1 módosított fájl, 60 hozzáadás és 26 törlés
  1. 60 26
      src/civetweb.c

+ 60 - 26
src/civetweb.c

@@ -12517,7 +12517,7 @@ ssl_locking_callback(int mode, int mutex_num, const char *file, int line)
 
 #if !defined(NO_SSL_DL)
 static void *
-load_dll(struct mg_context *ctx, const char *dll_name, struct ssl_func *sw)
+load_dll(char *ebuf, size_t ebuf_len, const char *dll_name, struct ssl_func *sw)
 {
 	union {
 		void *p;
@@ -12542,11 +12542,14 @@ load_dll(struct mg_context *ctx, const char *dll_name, struct ssl_func *sw)
 		u.p = dlsym(dll_handle, fp->name);
 #endif /* _WIN32 */
 		if (u.fp == NULL) {
-			mg_cry(fc(ctx),
-			       "%s: %s: cannot find %s",
-			       __func__,
-			       dll_name,
-			       fp->name);
+			mg_snprintf(NULL,
+			            NULL, /* No truncation check for ebuf */
+			            ebuf,
+			            ebuf_len,
+			            "%s: %s: cannot find %s",
+			            __func__,
+			            dll_name,
+			            fp->name);
 			dlclose(dll_handle);
 			return NULL;
 		} else {
@@ -12572,19 +12575,20 @@ static int cryptolib_users = 0; /* Reference counter for crypto library. */
 
 
 static int
-initialize_ssl(struct mg_context *ctx)
+initialize_ssl(char *ebuf, size_t ebuf_len)
 {
+	if (ebuf_len > 0) {
+		ebuf[0] = 0;
+	}
 
 #ifdef OPENSSL_API_1_1
 #if !defined(NO_SSL_DL)
 	if (!cryptolib_dll_handle) {
-		cryptolib_dll_handle = load_dll(ctx, CRYPTO_LIB, crypto_sw);
+		cryptolib_dll_handle = load_dll(ebuf, ebuf_len, CRYPTO_LIB, crypto_sw);
 		if (!cryptolib_dll_handle) {
 			return 0;
 		}
 	}
-#else
-	(void)ctx;
 #endif /* NO_SSL_DL */
 
 	if (mg_atomic_inc(&cryptolib_users) > 1) {
@@ -12597,13 +12601,11 @@ initialize_ssl(struct mg_context *ctx)
 
 #if !defined(NO_SSL_DL)
 	if (!cryptolib_dll_handle) {
-		cryptolib_dll_handle = load_dll(ctx, CRYPTO_LIB, crypto_sw);
+		cryptolib_dll_handle = load_dll(ebuf, ebuf_len, CRYPTO_LIB, crypto_sw);
 		if (!cryptolib_dll_handle) {
 			return 0;
 		}
 	}
-#else
-	(void)ctx;
 #endif /* NO_SSL_DL */
 
 	if (mg_atomic_inc(&cryptolib_users) > 1) {
@@ -12619,10 +12621,14 @@ initialize_ssl(struct mg_context *ctx)
 	}
 	size = sizeof(pthread_mutex_t) * ((size_t)(i));
 	if ((ssl_mutexes = (pthread_mutex_t *)mg_malloc(size)) == NULL) {
-		mg_cry(fc(ctx),
-		       "%s: cannot allocate mutexes: %s",
-		       __func__,
-		       ssl_error());
+		mg_snprintf(NULL,
+		            NULL, /* No truncation check for ebuf */
+		            ebuf,
+		            ebuf_len,
+		            "%s: cannot allocate mutexes: %s",
+		            __func__,
+		            ssl_error());
+
 		return 0;
 	}
 
@@ -12729,6 +12735,7 @@ set_ssl_option(struct mg_context *ctx)
 	md5_byte_t ssl_context_id[16];
 	md5_state_t md5state;
 	int protocol_ver;
+	char ebuf[128];
 
 	/* If PEM file is not specified and the init_ssl callback
 	 * is not specified, skip SSL initialization. */
@@ -12740,14 +12747,16 @@ set_ssl_option(struct mg_context *ctx)
 		return 1;
 	}
 
-	if (!initialize_ssl(ctx)) {
+	if (!initialize_ssl(ebuf, sizeof(ebuf))) {
+		mg_cry(fc(ctx), "%s", ebuf);
 		return 0;
 	}
 
 #if !defined(NO_SSL_DL)
 	if (!ssllib_dll_handle) {
-		ssllib_dll_handle = load_dll(ctx, SSL_LIB, ssl_sw);
+		ssllib_dll_handle = load_dll(ebuf, sizeof(ebuf), SSL_LIB, ssl_sw);
 		if (!ssllib_dll_handle) {
+			mg_cry(fc(ctx), "%s", ebuf);
 			return 0;
 		}
 	}
@@ -12880,10 +12889,9 @@ set_ssl_option(struct mg_context *ctx)
 
 
 static void
-uninitialize_ssl(struct mg_context *ctx)
+uninitialize_ssl(void)
 {
 #ifdef OPENSSL_API_1_1
-	(void)ctx;
 
 	if (mg_atomic_dec(&cryptolib_users) == 0) {
 
@@ -12894,7 +12902,6 @@ uninitialize_ssl(struct mg_context *ctx)
 		CONF_modules_unload(1);
 #else
 	int i;
-	(void)ctx;
 
 	if (mg_atomic_dec(&cryptolib_users) == 0) {
 
@@ -14658,7 +14665,7 @@ master_thread_run(void *thread_func_param)
 
 #if !defined(NO_SSL)
 	if (ctx->ssl_ctx != NULL) {
-		uninitialize_ssl(ctx);
+		uninitialize_ssl();
 	}
 #endif
 	DEBUG_TRACE("%s", "exiting");
@@ -15594,14 +15601,36 @@ mg_get_system_info(char *buffer, int buflen)
 
 /* mg_init_library counter */
 static int mg_init_library_called = 0;
-
+static int mg_ssl_initialized = 0;
 
 /* Initialize this library. This function does not need to be thread safe. */
 unsigned
 mg_init_library(unsigned features)
 {
-	/* Currently we do nothing here. This is planned for Version 1.10.
-	 * For now, we just add this function, so clients can be changed early. */
+	char ebuf[128];
+
+	if (features & 2) {
+		if (mg_check_feature(2)) {
+			if (!mg_ssl_initialized) {
+				if (initialize_ssl(ebuf, sizeof(ebuf))) {
+					mg_ssl_initialized = 1;
+				} else {
+					(void)ebuf;
+					/* TODO: print error */
+					return 0;
+				}
+			} else {
+				/* ssl already initialized */
+			}
+		} else {
+			(void)ebuf;
+			/* Cannot initialize SSL, if it is not configured */
+			/* TODO: print error */
+			return 0;
+		}
+	}
+
+	/* Start Windows. */
 	if (mg_init_library_called <= 0) {
 #if defined(_WIN32) && !defined(__SYMBIAN32__)
 		WSADATA data;
@@ -15611,6 +15640,7 @@ mg_init_library(unsigned features)
 	} else {
 		mg_init_library_called++;
 	}
+
 	return mg_check_feature(features & 0xFFu);
 }
 
@@ -15627,6 +15657,10 @@ mg_exit_library(void)
 #if defined(_WIN32) && !defined(__SYMBIAN32__)
 		(void)WSACleanup();
 #endif /* _WIN32 && !__SYMBIAN32__ */
+		if (mg_ssl_initialized) {
+			uninitialize_ssl();
+			mg_ssl_initialized = 0;
+		}
 	}
 	return 1;
 }