瀏覽代碼

Add new callback get_external_ssl_ctx

Frank Hilliger 7 年之前
父節點
當前提交
fbac820438
共有 2 個文件被更改,包括 50 次插入0 次删除
  1. 11 0
      include/civetweb.h
  2. 39 0
      src/civetweb.c

+ 11 - 0
include/civetweb.h

@@ -254,6 +254,17 @@ struct mg_callbacks {
 	    -1: initializing ssl fails. */
 	    -1: initializing ssl fails. */
 	int (*init_ssl)(void *ssl_context, void *user_data);
 	int (*init_ssl)(void *ssl_context, void *user_data);
 
 
+	/* Called when civetweb is about to create a SSL_CTX.
+	Parameters:
+	   ssl_ctx: SSL_CTX pointer 
+	     user_data: parameter user_data passed when starting the server.
+	   Return value:
+	     0: civetweb will continue to create the context, just as if the callback would not be present. 
+	        The value in *ssl_ctx when the function returns is ignored.
+	     1: civetweb will copy the value from *ssl_ctx to the civetweb context and doesn't create its own.
+	    -1: initializing ssl fails.*/
+	int (*get_external_ssl_ctx)( void **ssl_ctx, void *user_data );	
+
 #if defined(MG_LEGACY_INTERFACE)
 #if defined(MG_LEGACY_INTERFACE)
 	/* Called when websocket request is received, before websocket handshake.
 	/* Called when websocket request is received, before websocket handshake.
 	   Return value:
 	   Return value:

+ 39 - 0
src/civetweb.c

@@ -14345,6 +14345,36 @@ set_ssl_option(struct mg_context *ctx)
 		return 1;
 		return 1;
 	}
 	}
 
 
+	/* Check for external SSL_CTX */
+	SSL_CTX* ssl_ctx = 0;
+	callback_ret =
+	    (ctx->callbacks.get_external_ssl_ctx == NULL)
+	        ? 0
+	        : (ctx->callbacks.get_external_ssl_ctx(&ssl_ctx, ctx->user_data));
+
+	if (callback_ret < 0) {
+		mg_cry(fc(ctx), "get_external_ssl_ctx callback returned error: %i", callback_ret);
+		return 0;
+	}
+	else if (callback_ret > 0) {
+		ctx->ssl_ctx = 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(ebuf, sizeof(ebuf), SSL_LIB, ssl_sw);
+			if (!ssllib_dll_handle) {
+				mg_cry(fc(ctx), "%s", ebuf);
+				return 0;
+			}
+		}
+#endif /* NO_SSL_DL */
+		return 1;
+	}
+	/* else continue */	
+	
 	/* If PEM file is not specified and the init_ssl callback
 	/* If PEM file is not specified and the init_ssl callback
 	 * is not specified, setup will fail. */
 	 * is not specified, setup will fail. */
 	if (((pem = ctx->config[SSL_CERTIFICATE]) == NULL)
 	if (((pem = ctx->config[SSL_CERTIFICATE]) == NULL)
@@ -16662,7 +16692,16 @@ free_context(struct mg_context *ctx)
 #ifndef NO_SSL
 #ifndef NO_SSL
 	/* Deallocate SSL context */
 	/* Deallocate SSL context */
 	if (ctx->ssl_ctx != NULL) {
 	if (ctx->ssl_ctx != NULL) {
+	  SSL_CTX* ssl_ctx = 0;
+      int callback_ret =
+	    (ctx->callbacks.get_external_ssl_ctx == NULL)
+	        ? 0
+	        : (ctx->callbacks.get_external_ssl_ctx(&ssl_ctx, ctx->user_data));
+
+	  if (callback_ret == 0) {
 		SSL_CTX_free(ctx->ssl_ctx);
 		SSL_CTX_free(ctx->ssl_ctx);
+	  }
+	  // else ignore error and ommit SSL_CTX_free in case callback_ret is 1
 	}
 	}
 #endif /* !NO_SSL */
 #endif /* !NO_SSL */