diff --git a/.drone.star b/.drone.star index 9e403b51..9c309c55 100644 --- a/.drone.star +++ b/.drone.star @@ -15,7 +15,7 @@ def main(ctx): alljobs=[] customizedjobs = [ linux_cxx("GCC 10, Debug + Coverage", "g++-10", packages="g++-10 libssl-dev libffi-dev binutils-gold gdb mlocate", image="cppalliance/droneubuntu2004:1", buildtype="boost_v1", buildscript="drone", environment={"GCOV": "gcov-10", "LCOV_VERSION": "1.15", "VARIANT": "beast_coverage", "TOOLSET": "gcc", "COMPILER": "g++-10", "CXXSTD": "14", "DRONE_BEFORE_INSTALL" : "beast_coverage", "CODECOV_TOKEN": {"from_secret": "codecov_token"}}, globalenv=globalenv, privileged=True), - linux_cxx("Default clang++ with libc++", "clang++-libc++", packages="libc++-dev mlocate", image="cppalliance/droneubuntu1604:1", buildtype="boost_v1", buildscript="drone", environment={ "B2_TOOLSET": "clang-7", "B2_CXXSTD": "17,2a", "VARIANT": "debug", "TOOLSET": "clang", "COMPILER": "clang++-libc++", "CXXSTD": "11", "CXX_FLAGS": "-stdlib=libc++ -stdlib=libc++", "TRAVISCLANG" : "yes" }, globalenv=globalenv), + linux_cxx("Default clang++ with libc++", "clang++-libc++", packages="libc++-dev mlocate", image="cppalliance/droneubuntu1804:1", buildtype="boost_v1", buildscript="drone", environment={ "B2_TOOLSET": "clang-7", "B2_CXXSTD": "17,2a", "VARIANT": "debug", "TOOLSET": "clang", "COMPILER": "clang++-libc++", "CXXSTD": "11", "CXX_FLAGS": "-stdlib=libc++ -stdlib=libc++", "TRAVISCLANG" : "yes" }, globalenv=globalenv), linux_cxx("GCC Valgrind", "g++", packages="g++-14 libssl-dev valgrind", image="cppalliance/droneubuntu2404:1", buildtype="boost_v1", buildscript="drone", environment={ "VARIANT": "beast_valgrind", "TOOLSET": "gcc", "COMPILER": "g++", "CXXSTD": "11" }, globalenv=globalenv), linux_cxx("Default g++", "g++", packages="mlocate", image="cppalliance/droneubuntu1604:1", buildtype="boost_v1", buildscript="drone", environment={ "VARIANT": "release", "TOOLSET": "gcc", "COMPILER": "g++", "CXXSTD": "11" }, globalenv=globalenv), linux_cxx("GCC 8, C++17, libstdc++, release", "g++-8", packages="g++-8 mlocate", image="cppalliance/droneubuntu1604:1", buildtype="boost_v1", buildscript="drone", environment={ "VARIANT": "release", "TOOLSET": "gcc", "COMPILER": "g++-8", "CXXSTD" : "17" }, globalenv=globalenv), diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 02d677e5..a0a0766c 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -43,7 +43,7 @@ jobs: python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY - name: Fuzz corpus - uses: actions/cache@v3.3.1 + uses: actions/cache@v4 id: cache-corpus with: path: ${{ github.workspace }}/corpus.tar diff --git a/example/http/client/async-ssl-system-executor/http_client_async_ssl_system_executor.cpp b/example/http/client/async-ssl-system-executor/http_client_async_ssl_system_executor.cpp index 48b7cbab..85888f85 100644 --- a/example/http/client/async-ssl-system-executor/http_client_async_ssl_system_executor.cpp +++ b/example/http/client/async-ssl-system-executor/http_client_async_ssl_system_executor.cpp @@ -77,7 +77,19 @@ public: // Set SNI Hostname (many hosts need this to handshake successfully) if(! SSL_set_tlsext_host_name(stream_.native_handle(), host)) { - beast::error_code ec{static_cast(::ERR_get_error()), net::error::get_ssl_category()}; + beast::error_code ec{ + static_cast(::ERR_get_error()), + net::error::get_ssl_category()}; + std::cerr << ec.message() << "\n"; + return; + } + + // Set the expected hostname in the peer certificate for verification + if(! SSL_set1_host(stream_.native_handle(), host)) + { + beast::error_code ec{ + static_cast(::ERR_get_error()), + net::error::get_ssl_category()}; std::cerr << ec.message() << "\n"; return; } diff --git a/example/http/client/async-ssl/http_client_async_ssl.cpp b/example/http/client/async-ssl/http_client_async_ssl.cpp index 61d10bd9..69d96ce4 100644 --- a/example/http/client/async-ssl/http_client_async_ssl.cpp +++ b/example/http/client/async-ssl/http_client_async_ssl.cpp @@ -69,7 +69,19 @@ public: // Set SNI Hostname (many hosts need this to handshake successfully) if(! SSL_set_tlsext_host_name(stream_.native_handle(), host)) { - beast::error_code ec{static_cast(::ERR_get_error()), net::error::get_ssl_category()}; + beast::error_code ec{ + static_cast(::ERR_get_error()), + net::error::get_ssl_category()}; + std::cerr << ec.message() << "\n"; + return; + } + + // Set the expected hostname in the peer certificate for verification + if(! SSL_set1_host(stream_.native_handle(), host)) + { + beast::error_code ec{ + static_cast(::ERR_get_error()), + net::error::get_ssl_category()}; std::cerr << ec.message() << "\n"; return; } diff --git a/example/http/client/awaitable-ssl/http_client_awaitable_ssl.cpp b/example/http/client/awaitable-ssl/http_client_awaitable_ssl.cpp index 3c3606af..739926c6 100644 --- a/example/http/client/awaitable-ssl/http_client_awaitable_ssl.cpp +++ b/example/http/client/awaitable-ssl/http_client_awaitable_ssl.cpp @@ -51,9 +51,17 @@ do_session( auto stream = ssl::stream{ executor, ctx }; // Set SNI Hostname (many hosts need this to handshake successfully) - if(!SSL_set_tlsext_host_name(stream.native_handle(), host.c_str())) + if(! SSL_set_tlsext_host_name(stream.native_handle(), host.c_str())) { - throw boost::system::system_error( + throw beast::system_error( + static_cast(::ERR_get_error()), + net::error::get_ssl_category()); + } + + // Set the expected hostname in the peer certificate for verification + if(! SSL_set1_host(stream.native_handle(), host.c_str())) + { + throw beast::system_error( static_cast(::ERR_get_error()), net::error::get_ssl_category()); } diff --git a/example/http/client/coro-ssl/http_client_coro_ssl.cpp b/example/http/client/coro-ssl/http_client_coro_ssl.cpp index 0ce2a79e..08d2e46d 100644 --- a/example/http/client/coro-ssl/http_client_coro_ssl.cpp +++ b/example/http/client/coro-ssl/http_client_coro_ssl.cpp @@ -65,6 +65,14 @@ do_session( return; } + // Set the expected hostname in the peer certificate for verification + if(! SSL_set1_host(stream.native_handle(), host.c_str())) + { + ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); + std::cerr << ec.message() << "\n"; + return; + } + // Look up the domain name auto const results = resolver.async_resolve(host, port, yield[ec]); if(ec) diff --git a/example/http/client/sync-ssl/http_client_sync_ssl.cpp b/example/http/client/sync-ssl/http_client_sync_ssl.cpp index 8b0e0bb1..e634c0fa 100644 --- a/example/http/client/sync-ssl/http_client_sync_ssl.cpp +++ b/example/http/client/sync-ssl/http_client_sync_ssl.cpp @@ -69,8 +69,17 @@ int main(int argc, char** argv) // Set SNI Hostname (many hosts need this to handshake successfully) if(! SSL_set_tlsext_host_name(stream.native_handle(), host)) { - beast::error_code ec{static_cast(::ERR_get_error()), net::error::get_ssl_category()}; - throw beast::system_error{ec}; + throw beast::system_error( + static_cast(::ERR_get_error()), + net::error::get_ssl_category()); + } + + // Set the expected hostname in the peer certificate for verification + if(! SSL_set1_host(stream.native_handle(), host)) + { + throw beast::system_error( + static_cast(::ERR_get_error()), + net::error::get_ssl_category()); } // Look up the domain name 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 eede770e..3b93e8c1 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 @@ -116,13 +116,17 @@ public: 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())) + 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"); + ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); + return fail(ec, "connect"); + } + + // Set the expected hostname in the peer certificate for verification + if(! SSL_set1_host(ws_.next_layer().native_handle(), host_.c_str())) + { + ec.assign(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 @@ -252,6 +256,9 @@ int main(int argc, char** argv) // The SSL context is required, and holds certificates ssl::context ctx{ssl::context::tlsv12_client}; + // Verify the remote server's certificate + ctx.set_verify_mode(ssl::verify_peer); + // This holds the root certificate used for verification load_root_certificates(ctx); 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 b4af2c62..3dde0e50 100644 --- a/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp +++ b/example/websocket/client/async-ssl/websocket_client_async_ssl.cpp @@ -108,12 +108,16 @@ public: 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())) + 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()); + ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); + return fail(ec, "connect"); + } + + // Set the expected hostname in the peer certificate for verification + if(! SSL_set1_host(ws_.next_layer().native_handle(), host_.c_str())) + { + ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); return fail(ec, "connect"); } @@ -246,6 +250,9 @@ int main(int argc, char** argv) // The SSL context is required, and holds certificates ssl::context ctx{ssl::context::tlsv12_client}; + // Verify the remote server's certificate + ctx.set_verify_mode(ssl::verify_peer); + // This holds the root certificate used for verification load_root_certificates(ctx); 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 a658f8d2..19783a76 100644 --- a/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp +++ b/example/websocket/client/coro-ssl/websocket_client_coro_ssl.cpp @@ -71,12 +71,16 @@ do_session( return fail(ec, "connect"); // Set SNI Hostname (many hosts need this to handshake successfully) - if(! SSL_set_tlsext_host_name( - ws.next_layer().native_handle(), - host.c_str())) + 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()); + ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); + return fail(ec, "connect"); + } + + // Set the expected hostname in the peer certificate for verification + if(! SSL_set1_host(ws.next_layer().native_handle(), host.c_str())) + { + ec.assign(static_cast(::ERR_get_error()), net::error::get_ssl_category()); return fail(ec, "connect"); } @@ -163,6 +167,9 @@ int main(int argc, char** argv) // The SSL context is required, and holds certificates ssl::context ctx{ssl::context::tlsv12_client}; + // Verify the remote server's certificate + ctx.set_verify_mode(ssl::verify_peer); + // This holds the root certificate used for verification load_root_certificates(ctx); 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 429b5da0..30b88a39 100644 --- a/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp +++ b/example/websocket/client/sync-ssl/websocket_client_sync_ssl.cpp @@ -56,6 +56,9 @@ int main(int argc, char** argv) // The SSL context is required, and holds certificates ssl::context ctx{ssl::context::tlsv12_client}; + // Verify the remote server's certificate + ctx.set_verify_mode(ssl::verify_peer); + // This holds the root certificate used for verification load_root_certificates(ctx); @@ -71,11 +74,19 @@ int main(int argc, char** argv) // 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"); + static_cast(::ERR_get_error()), + net::error::get_ssl_category()); + } + + // Set the expected hostname in the peer certificate for verification + if(! SSL_set1_host(ws.next_layer().native_handle(), host.c_str())) + { + throw beast::system_error( + static_cast(::ERR_get_error()), + net::error::get_ssl_category()); + } // Update the host_ string. This will provide the value of the // Host HTTP header during the WebSocket handshake.