support openssl info callback
https://github.com/warmcat/libwebsockets/issues/936
This commit is contained in:
parent
1725332d47
commit
3ff720ff66
9 changed files with 115 additions and 1 deletions
|
@ -1036,6 +1036,7 @@ endforeach()
|
|||
set (temp ${CMAKE_REQUIRED_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${LIB_LIST})
|
||||
CHECK_FUNCTION_EXISTS(SSL_CTX_set1_param LWS_HAVE_SSL_CTX_set1_param)
|
||||
CHECK_FUNCTION_EXISTS(SSL_set_info_callback LWS_HAVE_SSL_SET_INFO_CALLBACK)
|
||||
CHECK_FUNCTION_EXISTS(X509_VERIFY_PARAM_set1_host LWS_HAVE_X509_VERIFY_PARAM_set1_host)
|
||||
if (LWS_WITH_ESP32)
|
||||
set(LWS_HAVE_TLS_CLIENT_METHOD 1)
|
||||
|
|
|
@ -568,6 +568,32 @@ ECDH Certs are now supported. Enable the CMake option
|
|||
|
||||
to build in support and select it at runtime.
|
||||
|
||||
@section sslinfo SSL info callbacks
|
||||
|
||||
OpenSSL allows you to receive callbacks for various events defined in a
|
||||
bitmask in openssl/ssl.h. The events include stuff like TLS Alerts.
|
||||
|
||||
By default, lws doesn't register for these callbacks.
|
||||
|
||||
However if you set the info.ssl_info_event_mask to nonzero (ie, set some
|
||||
of the bits in it like `SSL_CB_ALERT` at vhost creation time, then
|
||||
connections to that vhost will call back using LWS_CALLBACK_SSL_INFO
|
||||
for the wsi, and the `in` parameter will be pointing to a struct of
|
||||
related args:
|
||||
|
||||
```
|
||||
struct lws_ssl_info {
|
||||
int where;
|
||||
int ret;
|
||||
};
|
||||
```
|
||||
|
||||
The default callback handler in lws has a handler for LWS_CALLBACK_SSL_INFO
|
||||
which prints the related information, You can test it using the switch
|
||||
-S -s on `libwebsockets-test-server-v2.0`.
|
||||
|
||||
Returning nonzero from the callback will close the wsi.
|
||||
|
||||
@section smp SMP / Multithreaded service
|
||||
|
||||
SMP support is integrated into LWS without any internal threading. It's
|
||||
|
|
|
@ -381,6 +381,16 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
"sent %d only %d went", n, args->len);
|
||||
return n;
|
||||
#endif
|
||||
|
||||
case LWS_CALLBACK_SSL_INFO:
|
||||
{
|
||||
struct lws_ssl_info *si = in;
|
||||
|
||||
lwsl_notice("LWS_CALLBACK_SSL_INFO: where: 0x%x, ret: 0x%x\n",
|
||||
si->where, si->ret);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -453,6 +463,7 @@ lws_create_vhost(struct lws_context *context,
|
|||
vh->options = info->options;
|
||||
vh->pvo = info->pvo;
|
||||
vh->headers = info->headers;
|
||||
vh->ssl_info_event_mask = info->ssl_info_event_mask;
|
||||
if (info->keepalive_timeout)
|
||||
vh->keepalive_timeout = info->keepalive_timeout;
|
||||
else
|
||||
|
|
|
@ -829,6 +829,10 @@ struct lws_extension;
|
|||
*/
|
||||
///@{
|
||||
|
||||
struct lws_ssl_info {
|
||||
int where;
|
||||
int ret;
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: These public enums are part of the abi. If you want to add one,
|
||||
|
@ -1235,6 +1239,12 @@ enum lws_callback_reasons {
|
|||
/**< RAW mode file is writeable */
|
||||
LWS_CALLBACK_RAW_CLOSE_FILE = 66,
|
||||
/**< RAW mode wsi that adopted a file is closing */
|
||||
LWS_CALLBACK_SSL_INFO = 67,
|
||||
/**< SSL connections only. An event you registered an
|
||||
* interest in at the vhost has occurred on a connection
|
||||
* using the vhost. @in is a pointer to a
|
||||
* struct lws_ssl_info containing information about the
|
||||
* event*/
|
||||
|
||||
/****** add new things just above ---^ ******/
|
||||
|
||||
|
@ -2040,6 +2050,12 @@ struct lws_context_creation_info {
|
|||
* members added above will see 0 (default) even if the app
|
||||
* was not built against the newer headers.
|
||||
*/
|
||||
int ssl_info_event_mask;
|
||||
/**< VHOST: mask of ssl events to be reported on LWS_CALLBACK_SSL_INFO
|
||||
* callback for connections on this vhost. The mask values are of
|
||||
* the form SSL_CB_ALERT, defined in openssl/ssl.h. The default of
|
||||
* 0 means no info events will be reported.
|
||||
*/
|
||||
|
||||
void *_unused[8]; /**< dummy */
|
||||
};
|
||||
|
@ -3574,6 +3590,7 @@ enum pending_timeout {
|
|||
PENDING_TIMEOUT_AWAITING_SOCKS_GREETING_REPLY = 19,
|
||||
PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY = 20,
|
||||
PENDING_TIMEOUT_AWAITING_SOCKS_AUTH_REPLY = 21,
|
||||
PENDING_TIMEOUT_KILLED_BY_SSL_INFO = 22,
|
||||
|
||||
/****** add new things just above ---^ ******/
|
||||
};
|
||||
|
|
|
@ -890,6 +890,7 @@ struct lws_vhost {
|
|||
int ka_probes;
|
||||
int ka_interval;
|
||||
int keepalive_timeout;
|
||||
int ssl_info_event_mask;
|
||||
#ifdef LWS_WITH_ACCESS_LOG
|
||||
int log_fd;
|
||||
#endif
|
||||
|
@ -1158,6 +1159,7 @@ LWS_EXTERN void lws_feature_status_libevent(struct lws_context_creation_info *in
|
|||
#else
|
||||
#define LWS_UNIX_SOCK_ENABLED(vhost) (0)
|
||||
#endif
|
||||
|
||||
enum uri_path_states {
|
||||
URIPS_IDLE,
|
||||
URIPS_SEEN_SLASH,
|
||||
|
@ -2077,6 +2079,10 @@ lws_http_transaction_completed_client(struct lws *wsi);
|
|||
LWS_EXTERN int
|
||||
lws_context_init_client_ssl(struct lws_context_creation_info *info,
|
||||
struct lws_vhost *vhost);
|
||||
|
||||
LWS_EXTERN void
|
||||
lws_ssl_info_callback(const SSL *ssl, int where, int ret);
|
||||
|
||||
#else
|
||||
#define lws_context_init_client_ssl(_a, _b) (0)
|
||||
#endif
|
||||
|
|
|
@ -130,6 +130,11 @@ lws_ssl_client_bio_create(struct lws *wsi)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
|
||||
if (wsi->vhost->ssl_info_event_mask)
|
||||
SSL_set_info_callback(wsi->ssl, lws_ssl_info_callback);
|
||||
#endif
|
||||
|
||||
#if defined LWS_HAVE_X509_VERIFY_PARAM_set1_host
|
||||
X509_VERIFY_PARAM *param;
|
||||
(void)param;
|
||||
|
|
41
lib/ssl.c
41
lib/ssl.c
|
@ -543,6 +543,35 @@ lws_gate_accepts(struct lws_context *context, int on)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
lws_ssl_info_callback(const SSL *ssl, int where, int ret)
|
||||
{
|
||||
struct lws *wsi;
|
||||
struct lws_context *context;
|
||||
struct lws_ssl_info si;
|
||||
|
||||
context = (struct lws_context *)SSL_CTX_get_ex_data(
|
||||
SSL_get_SSL_CTX(ssl),
|
||||
openssl_SSL_CTX_private_data_index);
|
||||
if (!context)
|
||||
return;
|
||||
wsi = wsi_from_fd(context, SSL_get_fd(ssl));
|
||||
if (!wsi)
|
||||
return;
|
||||
|
||||
if (!(where & wsi->vhost->ssl_info_event_mask))
|
||||
return;
|
||||
|
||||
si.where = where;
|
||||
si.ret = ret;
|
||||
|
||||
if (user_callback_handle_rxflow(wsi->protocol->callback,
|
||||
wsi, LWS_CALLBACK_SSL_INFO,
|
||||
wsi->user_space, &si, 0))
|
||||
lws_set_timeout(wsi, PENDING_TIMEOUT_KILLED_BY_SSL_INFO, -1);
|
||||
}
|
||||
|
||||
|
||||
LWS_VISIBLE int
|
||||
lws_ssl_close(struct lws *wsi)
|
||||
{
|
||||
|
@ -551,6 +580,14 @@ lws_ssl_close(struct lws *wsi)
|
|||
if (!wsi->ssl)
|
||||
return 0; /* not handled */
|
||||
|
||||
#if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
|
||||
/* kill ssl callbacks, becausse we will remove the fd from the
|
||||
* table linking it to the wsi
|
||||
*/
|
||||
if (wsi->vhost->ssl_info_event_mask)
|
||||
SSL_set_info_callback(wsi->ssl, NULL);
|
||||
#endif
|
||||
|
||||
n = SSL_get_fd(wsi->ssl);
|
||||
SSL_shutdown(wsi->ssl);
|
||||
compatible_close(n);
|
||||
|
@ -608,6 +645,10 @@ lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd)
|
|||
compatible_close(accept_fd);
|
||||
goto fail;
|
||||
}
|
||||
#if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK)
|
||||
if (wsi->vhost->ssl_info_event_mask)
|
||||
SSL_set_info_callback(wsi->ssl, lws_ssl_info_callback);
|
||||
#endif
|
||||
if (context->simultaneous_ssl_restriction &&
|
||||
++context->simultaneous_ssl == context->simultaneous_ssl_restriction)
|
||||
/* that was the last allowed SSL connection */
|
||||
|
|
|
@ -147,5 +147,6 @@
|
|||
|
||||
#cmakedefine LWS_HAVE_TLS_CLIENT_METHOD
|
||||
#cmakedefine LWS_HAVE_TLSV1_2_CLIENT_METHOD
|
||||
#cmakedefine LWS_HAVE_SSL_SET_INFO_CALLBACK
|
||||
|
||||
${LWS_SIZEOFPTR_CODE}
|
||||
|
|
|
@ -231,6 +231,7 @@ static const struct option options[] = {
|
|||
{ "debug", required_argument, NULL, 'd' },
|
||||
{ "port", required_argument, NULL, 'p' },
|
||||
{ "ssl", no_argument, NULL, 's' },
|
||||
{ "ssl-alerts", no_argument, NULL, 'S' },
|
||||
{ "allow-non-ssl", no_argument, NULL, 'a' },
|
||||
{ "interface", required_argument, NULL, 'i' },
|
||||
{ "ssl-cert", required_argument, NULL, 'C' },
|
||||
|
@ -281,7 +282,7 @@ int main(int argc, char **argv)
|
|||
info.port = 7681;
|
||||
|
||||
while (n >= 0) {
|
||||
n = getopt_long(argc, argv, "i:hsap:d:Dr:C:K:A:R:vu:g:",
|
||||
n = getopt_long(argc, argv, "i:hsap:d:Dr:C:K:A:R:vu:g:S",
|
||||
(struct option *)options, NULL);
|
||||
if (n < 0)
|
||||
continue;
|
||||
|
@ -306,6 +307,11 @@ int main(int argc, char **argv)
|
|||
case 's':
|
||||
use_ssl = 1;
|
||||
break;
|
||||
case 'S':
|
||||
#if defined(LWS_OPENSSL_SUPPORT)
|
||||
info.ssl_info_event_mask |= SSL_CB_ALERT;
|
||||
#endif
|
||||
break;
|
||||
case 'a':
|
||||
opts |= LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT;
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue