diff --git a/changelog b/changelog index 101f57a4..9c598a19 100644 --- a/changelog +++ b/changelog @@ -90,6 +90,16 @@ to your original connection. additional library, "libhubbub". This allows lws to do html rewriting on the fly, adjusting proxied urls in a lightweight and fast way. +11) There's a new context creation flag LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT, +this is included automatically if you give any other SSL-related option flag. +If you give no SSL-related option flag, nor this one directly, then even +though SSL support may be compiled in, it is never initialized nor used for the +whole lifetime of the lws context. + +Conversely in order to prepare the context to use SSL, even though, eg, you +are not listening on SSL but will use SSL client connections later, you must +give this flag explicitly to make sure SSL is initialized. + User API additions ------------------ diff --git a/lib/client-parser.c b/lib/client-parser.c index 704a424c..4036941c 100644 --- a/lib/client-parser.c +++ b/lib/client-parser.c @@ -64,9 +64,9 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) case LWSWSOPC_TEXT_FRAME: wsi->u.ws.rsv_first_msg = (c & 0x70); wsi->u.ws.continuation_possible = 1; - wsi->u.ws.check_utf8 = - !!(wsi->context->options & - LWS_SERVER_OPTION_VALIDATE_UTF8); + wsi->u.ws.check_utf8 = lws_check_opt( + wsi->context->options, + LWS_SERVER_OPTION_VALIDATE_UTF8); wsi->u.ws.utf8 = 0; break; case LWSWSOPC_BINARY_FRAME: @@ -344,7 +344,8 @@ spill: switch (wsi->u.ws.opcode) { case LWSWSOPC_CLOSE: pp = (unsigned char *)&wsi->u.ws.rx_ubuf[LWS_PRE]; - if (wsi->context->options & LWS_SERVER_OPTION_VALIDATE_UTF8 && + if (lws_check_opt(wsi->context->options, + LWS_SERVER_OPTION_VALIDATE_UTF8) && wsi->u.ws.rx_ubuf_head > 2 && lws_check_utf8(&wsi->u.ws.utf8, pp + 2, wsi->u.ws.rx_ubuf_head - 2)) diff --git a/lib/context.c b/lib/context.c index 2574f222..884e123b 100644 --- a/lib/context.c +++ b/lib/context.c @@ -84,7 +84,7 @@ lws_create_context(struct lws_context_creation_info *info) lwsl_notice("Libwebsockets version: %s\n", library_version); #if LWS_POSIX #ifdef LWS_USE_IPV6 - if (!(info->options & LWS_SERVER_OPTION_DISABLE_IPV6)) + if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_IPV6)) lwsl_notice("IPV6 compiled in and enabled\n"); else lwsl_notice("IPV6 compiled in but disabled\n"); diff --git a/lib/libev.c b/lib/libev.c index 8b33ed71..17430936 100644 --- a/lib/libev.c +++ b/lib/libev.c @@ -23,7 +23,7 @@ void lws_feature_status_libev(struct lws_context_creation_info *info) { - if (info->options & LWS_SERVER_OPTION_LIBEV) + if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBEV)) lwsl_notice("libev support compiled in and enabled\n"); else lwsl_notice("libev support compiled in but disabled\n"); @@ -137,7 +137,7 @@ lws_libev_destroyloop(struct lws_context *context, int tsi) { struct lws_context_per_thread *pt = &context->pt[tsi]; - if (!(context->options & LWS_SERVER_OPTION_LIBEV)) + if (!lws_check_opt(context->options, LWS_SERVER_OPTION_LIBEV)) return; if (!pt->io_loop_ev) diff --git a/lib/libuv.c b/lib/libuv.c index abea7566..92d44eea 100644 --- a/lib/libuv.c +++ b/lib/libuv.c @@ -24,7 +24,7 @@ void lws_feature_status_libuv(struct lws_context_creation_info *info) { - if (info->options & LWS_SERVER_OPTION_LIBUV) + if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBUV)) lwsl_notice("libuv support compiled in and enabled\n"); else lwsl_notice("libuv support compiled in but disabled\n"); @@ -160,7 +160,7 @@ lws_libuv_destroyloop(struct lws_context *context, int tsi) struct lws_context_per_thread *pt = &context->pt[tsi]; int m; - if (!(context->options & LWS_SERVER_OPTION_LIBUV)) + if (!lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV)) return; if (!pt->io_loop_uv) diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index a43d773e..c6359ed2 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -290,22 +290,29 @@ struct lws; * add it at where specified so existing users are unaffected. */ enum lws_context_options { - LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = (1 << 1), + LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = (1 << 1) | + (1 << 12), LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = (1 << 2), - LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = (1 << 3), + LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = (1 << 3) | + (1 << 12), LWS_SERVER_OPTION_LIBEV = (1 << 4), LWS_SERVER_OPTION_DISABLE_IPV6 = (1 << 5), LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = (1 << 6), LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = (1 << 7), LWS_SERVER_OPTION_VALIDATE_UTF8 = (1 << 8), - LWS_SERVER_OPTION_SSL_ECDH = (1 << 9), + LWS_SERVER_OPTION_SSL_ECDH = (1 << 9) | + (1 << 12), LWS_SERVER_OPTION_LIBUV = (1 << 10), LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS = (1 << 11) | - (1 << 3), + (1 << 3) | + (1 << 12), + LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT = (1 << 12), /****** add new things just above ---^ ******/ }; +#define lws_check_opt(c, f) (((c) & (f)) == (f)) + /* * NOTE: These public enums are part of the abi. If you want to add one, * add it at where specified so existing users are unaffected. diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 3021b12d..58e8b707 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -724,7 +724,7 @@ LWS_EXTERN void lws_libev_destroyloop(struct lws_context *context, int tsi); LWS_EXTERN void lws_libev_run(const struct lws_context *context, int tsi); -#define LWS_LIBEV_ENABLED(context) (context->options & LWS_SERVER_OPTION_LIBEV) +#define LWS_LIBEV_ENABLED(context) lws_check_opt(context->options, LWS_SERVER_OPTION_LIBEV) LWS_EXTERN void lws_feature_status_libev(struct lws_context_creation_info *info); #else #define lws_libev_accept(_a, _b) ((void) 0) @@ -752,7 +752,7 @@ LWS_EXTERN void lws_libuv_run(const struct lws_context *context, int tsi); LWS_EXTERN void lws_libuv_destroyloop(struct lws_context *context, int tsi); -#define LWS_LIBUV_ENABLED(context) (context->options & LWS_SERVER_OPTION_LIBUV) +#define LWS_LIBUV_ENABLED(context) lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV) LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info); #else #define lws_libuv_accept(_a, _b) ((void) 0) @@ -772,7 +772,7 @@ LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info) #ifdef LWS_USE_IPV6 #define LWS_IPV6_ENABLED(context) \ - (!(context->options & LWS_SERVER_OPTION_DISABLE_IPV6)) + (!lws_check_opt(context->options, LWS_SERVER_OPTION_DISABLE_IPV6)) #else #define LWS_IPV6_ENABLED(context) (0) #endif diff --git a/lib/server.c b/lib/server.c index 5a19a16a..48cbc314 100644 --- a/lib/server.c +++ b/lib/server.c @@ -1287,7 +1287,7 @@ LWS_VISIBLE void lws_server_get_canonical_hostname(struct lws_context *context, struct lws_context_creation_info *info) { - if (info->options & LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME) + if (lws_check_opt(info->options, LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME)) return; #if LWS_POSIX /* find canonical hostname */ diff --git a/lib/ssl.c b/lib/ssl.c index c817a9a2..c21271d2 100644 --- a/lib/ssl.c +++ b/lib/ssl.c @@ -92,12 +92,12 @@ static int lws_context_ssl_init_ecdh(struct lws_context *context) { #ifdef LWS_SSL_SERVER_WITH_ECDH_CERT - int KeyType; EC_KEY *EC_key = NULL; - X509 *x; EVP_PKEY *pkey; + int KeyType; + X509 *x; - if (!(context->options & LWS_SERVER_OPTION_SSL_ECDH)) + if (!lws_check_opt(context->options, LWS_SERVER_OPTION_SSL_ECDH)) return 0; lwsl_notice(" Using ECDH certificate support\n"); @@ -179,20 +179,25 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info, int error; int n; +#ifdef USE_WOLFSSL +#ifdef USE_OLD_CYASSL + lwsl_notice(" Compiled with CyaSSL support\n"); +#else + lwsl_notice(" Compiled with wolfSSL support\n"); +#endif +#else + lwsl_notice(" Compiled with OpenSSL support\n"); +#endif + + if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) { + lwsl_notice(" SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT\n"); + return 0; + } + if (info->port != CONTEXT_PORT_NO_LISTEN) { context->use_ssl = info->ssl_cert_filepath != NULL; -#ifdef USE_WOLFSSL -#ifdef USE_OLD_CYASSL - lwsl_notice(" Compiled with CyaSSL support\n"); -#else - lwsl_notice(" Compiled with wolfSSL support\n"); -#endif -#else - lwsl_notice(" Compiled with OpenSSL support\n"); -#endif - if (info->ssl_cipher_list) lwsl_notice(" SSL ciphers: '%s'\n", info->ssl_cipher_list); @@ -258,10 +263,10 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info, /* as a server, are we requiring clients to identify themselves? */ - if (info->options & LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) { + if (lws_check_opt(info->options, LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT)) { int verify_options = SSL_VERIFY_PEER; - if (!(info->options & LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED)) + if (!lws_check_opt(info->options, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED)) verify_options |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; SSL_CTX_set_session_id_context(context->ssl_ctx, @@ -291,7 +296,7 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info, LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS, context->ssl_ctx, NULL, 0); - if (info->options & LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT) + if (lws_check_opt(info->options, LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT)) /* Normally SSL listener rejects non-ssl, optionally allow */ context->allow_non_ssl_on_ssl_port = 1; @@ -357,6 +362,9 @@ lws_context_init_server_ssl(struct lws_context_creation_info *info, LWS_VISIBLE void lws_ssl_destroy(struct lws_context *context) { + if (!lws_check_opt(context->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) + return; + if (context->ssl_ctx) SSL_CTX_free(context->ssl_ctx); if (!context->user_supplied_ssl_ctx && context->ssl_client_ctx) @@ -394,6 +402,9 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info, SSL_METHOD *method; struct lws wsi; + if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) + return 0; + if (info->provided_client_ssl_ctx) { /* use the provided OpenSSL context if given one */ context->ssl_client_ctx = info->provided_client_ssl_ctx; @@ -441,7 +452,7 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info, info->ssl_cipher_list); #ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS - if (!(info->options & LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS)) + if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS)) /* loads OS default CA certs */ SSL_CTX_set_default_verify_paths(context->ssl_client_ctx); #endif @@ -757,8 +768,8 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd) SSL_shutdown(wsi->ssl); SSL_free(wsi->ssl); wsi->ssl = NULL; - if (context->options & - LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS) + if (lws_check_opt(context->options, + LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS)) wsi->redirect_to_https = 1; goto accepted; } diff --git a/test-server/test-client.c b/test-server/test-client.c index 93c92aa3..b35260db 100644 --- a/test-server/test-client.c +++ b/test-server/test-client.c @@ -362,6 +362,9 @@ int main(int argc, char **argv) info.gid = -1; info.uid = -1; + if (use_ssl) + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + context = lws_create_context(&info); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n"); diff --git a/test-server/test-echo.c b/test-server/test-echo.c index 6c1729ea..75390f67 100644 --- a/test-server/test-echo.c +++ b/test-server/test-echo.c @@ -438,6 +438,9 @@ int main(int argc, char **argv) info.gid = -1; info.uid = -1; info.options = opts | LWS_SERVER_OPTION_VALIDATE_UTF8; + + if (use_ssl) + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; #ifndef LWS_NO_EXTENSIONS info.extensions = exts; #endif diff --git a/test-server/test-fraggle.c b/test-server/test-fraggle.c index 51b5903e..2137e7b5 100644 --- a/test-server/test-fraggle.c +++ b/test-server/test-fraggle.c @@ -336,6 +336,9 @@ int main(int argc, char **argv) info.uid = -1; info.options = opts; + if (use_ssl) + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + context = lws_create_context(&info); if (context == NULL) { fprintf(stderr, "libwebsocket init failed\n"); diff --git a/test-server/test-ping.c b/test-server/test-ping.c index ff2d8e35..640bc9d0 100644 --- a/test-server/test-ping.c +++ b/test-server/test-ping.c @@ -441,6 +441,9 @@ int main(int argc, char **argv) info.gid = -1; info.uid = -1; + if (use_ssl) + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + context = lws_create_context(&info); if (context == NULL) { fprintf(stderr, "Creating libwebsocket context failed\n");