1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

Optionally allow non-SSL connections on same port as SSL

If enabled one listening socket will accept both SSL and plain HTTP connections.

Do not enable if you regard SSL handshake as some kind of security, eg, use
client-side certs to restrict access.

AG: changed flag names, added extra comments, changelog, add -a in test server

Signed-off-by: James Devine <fxmulder@gmail.com>
Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
James Devine 2013-12-14 11:41:29 +08:00 committed by Andy Green
parent 4ebedc2c30
commit 5b34c975ae
6 changed files with 54 additions and 5 deletions

View file

@ -20,6 +20,12 @@ processing is protected by a 5s timeout.
The chunks are stored in a malloc'd buffer of size protocols[0].rx_buffer_size.
New server option you can enable from user code
LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT allows non-SSL connections to
also be accepted on an SSL listening port. It's disabled unless you enable
it explicitly.
User api changes
----------------

View file

@ -1892,6 +1892,7 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
#ifdef LWS_OPENSSL_SUPPORT
context->use_ssl = 0;
context->allow_non_ssl_on_ssl_port = 0;
context->ssl_ctx = NULL;
context->ssl_client_ctx = NULL;
openssl_websocket_private_data_index = 0;
@ -2135,6 +2136,11 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
context->ssl_ctx, NULL, 0);
}
if(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;
}
if (context->use_ssl) {
/* openssl init for server sockets */

View file

@ -138,6 +138,7 @@ LWS_VISIBLE LWS_EXTERN void lwsl_hexdump(void *buf, size_t len);
enum libwebsocket_context_options {
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2,
LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = 4,
LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = 8
};
enum libwebsocket_callback_reasons {

View file

@ -289,6 +289,7 @@ struct libwebsocket_context {
#ifdef LWS_OPENSSL_SUPPORT
int use_ssl;
int allow_non_ssl_on_ssl_port;
SSL_CTX *ssl_ctx;
SSL_CTX *ssl_client_ctx;
#endif

View file

@ -354,6 +354,37 @@ int lws_server_socket_service(struct libwebsocket_context *context,
wsi->user_space, (void *)(long)wsi->sock, POLLOUT);
lws_latency_pre(context, wsi);
n = recv(wsi->sock, context->service_buffer,
sizeof(context->service_buffer), MSG_PEEK);
/*
* optionally allow non-SSL connect on SSL listening socket
* This is disabled by default, if enabled it goes around any
* SSL-level access control (eg, client-side certs) so leave
* it disabled unless you know it's not a problem for you
*/
if (context->allow_non_ssl_on_ssl_port && n >= 1 &&
context->service_buffer[0] >= ' ') {
/*
* TLS content-type for Handshake is 0x16
* TLS content-type for ChangeCipherSpec Record is 0x14
*
* A non-ssl session will start with the HTTP method in
* ASCII. If we see it's not a legit SSL handshake
* kill the SSL for this connection and try to handle
* as a HTTP connection upgrade directly.
*/
wsi->use_ssl = 0;
SSL_shutdown(wsi->ssl);
SSL_free(wsi->ssl);
wsi->ssl = NULL;
goto accepted;
}
/* normal SSL connection processing path */
n = SSL_accept(wsi->ssl);
lws_latency(context, wsi,
"SSL_accept LWS_CONNMODE_SSL_ACK_PENDING\n", n, n == 1);
@ -378,7 +409,6 @@ int lws_server_socket_service(struct libwebsocket_context *context,
if (m == SSL_ERROR_WANT_WRITE) {
context->fds[
wsi->position_in_fds_table].events |= POLLOUT;
/* external POLL support via protocol 0 */
context->protocols[0].callback(context, wsi,
LWS_CALLBACK_SET_MODE_POLL_FD,
@ -387,13 +417,14 @@ int lws_server_socket_service(struct libwebsocket_context *context,
break;
}
lwsl_debug("SSL_accept failed skt %u: %s\n",
pollfd->fd,
ERR_error_string(m, NULL));
pollfd->fd,
ERR_error_string(m, NULL));
libwebsocket_close_and_free_session(context, wsi,
LWS_CLOSE_STATUS_NOSTATUS);
LWS_CLOSE_STATUS_NOSTATUS);
break;
}
accepted:
/* OK, we are accepted */
libwebsocket_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);

View file

@ -715,6 +715,7 @@ static struct option options[] = {
{ "debug", required_argument, NULL, 'd' },
{ "port", required_argument, NULL, 'p' },
{ "ssl", no_argument, NULL, 's' },
{ "allow-non-ssl", no_argument, NULL, 'a' },
{ "interface", required_argument, NULL, 'i' },
{ "closetest", no_argument, NULL, 'c' },
#ifndef LWS_NO_DAEMONIZE
@ -749,7 +750,7 @@ int main(int argc, char **argv)
info.port = 7681;
while (n >= 0) {
n = getopt_long(argc, argv, "ci:hsp:d:Dr:", options, NULL);
n = getopt_long(argc, argv, "ci:hsap:d:Dr:", options, NULL);
if (n < 0)
continue;
switch (n) {
@ -767,6 +768,9 @@ int main(int argc, char **argv)
case 's':
use_ssl = 1;
break;
case 'a':
opts |= LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT;
break;
case 'p':
info.port = atoi(optarg);
break;