From a35cd3200542f860f0690a927690fb955029cf35 Mon Sep 17 00:00:00 2001 From: Richard Hodges Date: Thu, 16 Jul 2020 09:18:18 +0200 Subject: [PATCH] Update WebSocket examples to set TLS SNI --- CHANGELOG.md | 1 + .../websocket_client_async_ssl_system_executor.cpp | 10 ++++++++++ .../client/async-ssl/websocket_client_async_ssl.cpp | 10 ++++++++++ .../client/coro-ssl/websocket_client_coro_ssl.cpp | 12 +++++++++++- .../client/sync-ssl/websocket_client_sync_ssl.cpp | 8 ++++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 83bedba3..dabaf57d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ Version XXX: +* Update WebSocket examples to set TLS SNI. * Add handler tracking locations to websocket. * Add handler tracking locations to tcp teardown. * Eliminate spurious uninitialised variable warning in detect_ssl. diff --git a/example/websocket/client/async-ssl-system-executor/websocket_client_async_ssl_system_executor.cpp b/example/websocket/client/async-ssl-system-executor/websocket_client_async_ssl_system_executor.cpp index 75e96362..02b62692 100644 --- a/example/websocket/client/async-ssl-system-executor/websocket_client_async_ssl_system_executor.cpp +++ b/example/websocket/client/async-ssl-system-executor/websocket_client_async_ssl_system_executor.cpp @@ -122,6 +122,16 @@ public: // Set a timeout on the operation beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30)); + // Set SNI Hostname (many hosts need this to handshake successfully) + if(! SSL_set_tlsext_host_name( + ws_.next_layer().native_handle(), + host_.c_str())) + { + ec = beast::error_code(static_cast(::ERR_get_error()), + net::error::get_ssl_category()); + return fail(ec, "connect"); + } + // Perform the SSL handshake ws_.next_layer().async_handshake( ssl::stream_base::client, diff --git a/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp b/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp index 4d413aa7..a5b0c61b 100644 --- a/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp +++ b/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp @@ -114,6 +114,16 @@ public: // Set a timeout on the operation beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30)); + // Set SNI Hostname (many hosts need this to handshake successfully) + if(! SSL_set_tlsext_host_name( + ws_.next_layer().native_handle(), + host_.c_str())) + { + ec = beast::error_code(static_cast(::ERR_get_error()), + net::error::get_ssl_category()); + return fail(ec, "connect"); + } + // Perform the SSL handshake ws_.next_layer().async_handshake( ssl::stream_base::client, diff --git a/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp b/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp index 5b4d9e9b..c649e865 100644 --- a/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp +++ b/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp @@ -71,7 +71,17 @@ do_session( if(ec) return fail(ec, "connect"); - // Update the host_ string. This will provide the value of the + // Set SNI Hostname (many hosts need this to handshake successfully) + if(! SSL_set_tlsext_host_name( + ws.next_layer().native_handle(), + host.c_str())) + { + ec = beast::error_code(static_cast(::ERR_get_error()), + net::error::get_ssl_category()); + return fail(ec, "connect"); + } + + // Update the host string. This will provide the value of the // Host HTTP header during the WebSocket handshake. // See https://tools.ietf.org/html/rfc7230#section-5.4 host += ':' + std::to_string(ep.port()); diff --git a/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp b/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp index 1a51f6b6..7118f0f6 100644 --- a/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp +++ b/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp @@ -70,6 +70,14 @@ int main(int argc, char** argv) // Make the connection on the IP address we get from a lookup auto ep = net::connect(get_lowest_layer(ws), results); + // Set SNI Hostname (many hosts need this to handshake successfully) + if(! SSL_set_tlsext_host_name(ws.next_layer().native_handle(), host.c_str())) + throw beast::system_error( + beast::error_code( + static_cast(::ERR_get_error()), + net::error::get_ssl_category()), + "Failed to set SNI Hostname"); + // Update the host_ string. This will provide the value of the // Host HTTP header during the WebSocket handshake. // See https://tools.ietf.org/html/rfc7230#section-5.4