3131#include < filesystem>
3232#include < format>
3333#include < boost/algorithm/string/predicate.hpp>
34- #include < boost/beast/core.hpp> // The HTTP client used to check for new version from Boost Beast is available from version 1.70
34+ #include < boost/beast/core.hpp>
3535#include < boost/beast/http.hpp>
3636#include < boost/beast/version.hpp>
37+ #include < boost/asio/connect.hpp>
38+ #include < boost/asio/ip/tcp.hpp>
39+ #include < boost/asio/ssl.hpp>
40+
41+ // TEST beast
42+ // #include <cstdlib>
43+
44+
45+
3746
3847#ifdef __linux__ // If on Linux...
3948 const std::string AirspaceConverter::basePath (std::filesystem::canonical(" /proc/self/exe" ).parent_path().string());
@@ -693,19 +702,43 @@ bool AirspaceConverter::CheckForNewVersion(int& versionDifference) {
693702 // The io_context is required for all I/O
694703 boost::asio::io_context ioc;
695704
705+ // The SSL context is required, and holds certificates
706+ boost::asio::ssl::context ctx (boost::asio::ssl::context::tlsv13_client);
707+
708+ // TODO: Use the default paths for finding CA certificates
709+ // ctx.set_default_verify_paths();
710+
711+ // TODO: Verify the remote server's certificate
712+ // ctx.set_verify_mode(boost::asio::ssl::verify_peer);
713+
714+ // FIXME: For now, we will not verify the server's certificate (not secure, but avoids issues with missing CA certificates)
715+ ctx.set_verify_mode (boost::asio::ssl::verify_none);
716+
696717 // These objects perform our I/O
697718 boost::asio::ip::tcp::resolver resolver (ioc);
698- boost::beast::tcp_stream stream (ioc);
719+ boost::asio::ssl::stream<boost:: beast::tcp_stream> stream (ioc, ctx );
699720
700- // Look up the domain name
721+ // Domain name
701722 const std::string host = " alus.it" ;
702- const auto results = resolver.resolve (host, " 80" );
723+
724+ // Set SNI Hostname (many hosts need this to handshake successfully)
725+ if (!SSL_set_tlsext_host_name (stream.native_handle (), host.c_str ()))
726+ throw boost::beast::system_error (static_cast <int >(::ERR_get_error ()), boost::asio::error::get_ssl_category ());
727+
728+ // Set the expected hostname in the peer certificate for verification
729+ stream.set_verify_callback (boost::asio::ssl::host_name_verification (host));
730+
731+ // Look up the domain name
732+ const auto results = resolver.resolve (host, " 443" );
703733
704734 // Make the connection on the IP address we get from a lookup
705- stream.connect (results);
735+ boost::beast::get_lowest_layer (stream).connect (results);
736+
737+ // Perform the SSL handshake
738+ stream.handshake (boost::asio::ssl::stream_base::client);
706739
707740 // Set up an HTTP GET request message (for HTTPS more libs would be required)
708- boost::beast::http::request<boost::beast::http::string_body> req{boost::beast::http::verb::get, " /AirspaceConverter/lastVersion.txt" , 11 };
741+ boost::beast::http::request<boost::beast::http::string_body> req{ boost::beast::http::verb::get, " /AirspaceConverter/lastVersion.txt" , 11 };
709742 req.set (boost::beast::http::field::host, host);
710743 req.set (boost::beast::http::field::user_agent, BOOST_BEAST_VERSION_STRING );
711744
@@ -716,24 +749,20 @@ bool AirspaceConverter::CheckForNewVersion(int& versionDifference) {
716749 boost::beast::flat_buffer buffer;
717750
718751 // Declare a container to hold the response
719- boost::beast::http::response<boost::beast::http::string_body > res;
752+ boost::beast::http::response<boost::beast::http::dynamic_body > res;
720753
721754 // Receive the HTTP response
722755 boost::beast::http::read (stream, buffer, res);
723756
724- // Gracefully close the socket
757+ // Gracefully close the stream
725758 boost::beast::error_code ec;
726- stream.socket (). shutdown (boost::asio::ip::tcp::socket::shutdown_both, ec);
759+ stream.shutdown (ec);
727760
728761 // Not_connected happens sometimes: so don't bother reporting it.
729- if (ec && ec != boost::beast::errc::not_connected) {
730- throw boost::beast::system_error{ec};
731- }
762+ if (ec && ec != boost::beast::errc::not_connected) throw boost::beast::system_error{ec};
732763
733- // If we get here then the connection is closed gracefully
734-
735- // The content is the latest version string
736- const std::string latestVersion = res.body ();
764+ // If we get here then the connection is closed gracefully: The content is the latest version string
765+ const std::string latestVersion = boost::beast::buffers_to_string (res.body ().data ());
737766 const int latestVersionNumber = VersionToNumber (latestVersion);
738767 if (latestVersionNumber > 0 ) {
739768 versionDifference = latestVersionNumber - runningVersionNumber;
0 commit comments