aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJames Devine <fxmulder@gmail.com>2013-12-14 11:41:29 +0800
committerAndy Green <andy.green@linaro.org>2013-12-14 11:41:29 +0800
commit5b34c975aee5a15e382bdfbd3d5110e4101a0879 (patch)
tree965ee45accb86ef5b239b0ed06adde4be343e819 /lib
parent4ebedc2c30b9fd9f045902b3c85d51bde3a3f0fc (diff)
downloadlibwebsockets-5b34c975aee5a15e382bdfbd3d5110e4101a0879.tar.gz
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>
Diffstat (limited to 'lib')
-rw-r--r--lib/libwebsockets.c6
-rw-r--r--lib/libwebsockets.h1
-rw-r--r--lib/private-libwebsockets.h1
-rw-r--r--lib/server.c39
4 files changed, 43 insertions, 4 deletions
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index 7342e9ba..8b2fec52 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -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 */
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index cfd1f8c5..b2ba3594 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -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 {
diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
index 12b8d5a8..ea68f4bc 100644
--- a/lib/private-libwebsockets.h
+++ b/lib/private-libwebsockets.h
@@ -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
diff --git a/lib/server.c b/lib/server.c
index 6c35c98e..700a6e28 100644
--- a/lib/server.c
+++ b/lib/server.c
@@ -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);