Optionally allow non-SSL connections on same port as SSL
[platform/upstream/libwebsockets.git] / lib / server.c
index 6c35c98..700a6e2 100644 (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);