From c84d6376d9c5a92de6b5562b36f18ec5f11b394d Mon Sep 17 00:00:00 2001 From: odrling Date: Tue, 10 Sep 2019 10:39:51 +0200 Subject: [PATCH 1/3] [updates] use https --- configure.ac | 3 ++ src/dialog_version_check.cpp | 101 ++++++++++++++++++++++------------- 2 files changed, 66 insertions(+), 38 deletions(-) diff --git a/configure.ac b/configure.ac index 157129a83..3340b579b 100644 --- a/configure.ac +++ b/configure.ac @@ -231,6 +231,9 @@ AC_DEFINE(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION, 1, PKG_CHECK_MODULES(ICU_UC, icu-uc >= icu_required_version) PKG_CHECK_MODULES(ICU_I18N, icu-i18n >= icu_required_version) +AC_CHECK_LIB([ssl], [SSL_library_init], [], [AC_MSG_FAILURE([could not find ssl])]) +AC_CHECK_LIB([crypto], [BIO_read], [], [AC_MSG_FAILURE([could not find crypto])]) + ######## ## boost ######## diff --git a/src/dialog_version_check.cpp b/src/dialog_version_check.cpp index 606b47f3e..1fe834424 100644 --- a/src/dialog_version_check.cpp +++ b/src/dialog_version_check.cpp @@ -46,7 +46,13 @@ #include #include +#include +#include +#include +#include #include +#include +#include #include #include #include @@ -67,9 +73,13 @@ #include #endif + namespace { std::mutex VersionCheckLock; +namespace ssl = boost::asio::ssl; +namespace http = boost::beast::http; + struct AegisubUpdateDescription { int major; int minor; @@ -159,7 +169,7 @@ VersionCheckerResultDialog::VersionCheckerResultDialog(wxString const& main_text main_sizer->Add(descbox, 0, wxEXPAND|wxBOTTOM, 6); std::ostringstream surl; - surl << "http://" << UPDATE_CHECKER_SERVER << UPDATE_CHECKER_BASE_URL << "/Aegisub-Japan7-" << AegisubVersion(update) << "-x64.exe"; + surl << "https://" << UPDATE_CHECKER_SERVER << UPDATE_CHECKER_BASE_URL << "/Aegisub-Japan7-" << AegisubVersion(update) << "-x64.exe"; std::string url = surl.str(); main_sizer->Add(new wxHyperlinkCtrl(this, -1, to_wx(url), to_wx(url)), 0, wxALIGN_LEFT|wxBOTTOM, 6); @@ -331,51 +341,66 @@ static wxString GetAegisubLanguage() { } AegisubUpdateDescription GetLatestVersion() { - boost::asio::ip::tcp::iostream stream; - stream.connect(UPDATE_CHECKER_SERVER, "http"); - if (!stream) - throw VersionCheckError(from_wx(_("Could not connect to updates server."))); - agi::format(stream, - "GET %s/latest HTTP/1.1\r\n" - "User-Agent: Aegisub-Japan7\r\n" - "Host: %s\r\n" - "Accept: */*\r\n" - "Connection: close\r\n\r\n" - , UPDATE_CHECKER_BASE_URL - , UPDATE_CHECKER_SERVER); + boost::asio::io_context ioc; + boost::asio::ssl::context ctx(ssl::context::method::sslv23_client); - std::string http_version; - stream >> http_version; - int status_code; - stream >> status_code; - if (!stream || http_version.substr(0, 5) != "HTTP/") - throw VersionCheckError(from_wx(_("Could not download from updates server."))); - if (status_code != 200) - throw VersionCheckError(agi::format(_("HTTP request failed, got HTTP response %d."), status_code)); + boost::asio::ip::tcp::resolver resolver(ioc); + ssl::stream stream(ioc, ctx); - stream.ignore(std::numeric_limits::max(), '\n'); + if(! SSL_set_tlsext_host_name(stream.native_handle(), UPDATE_CHECKER_SERVER)) { + boost::system::error_code ec{static_cast(::ERR_get_error()), boost::asio::error::get_ssl_category()}; + throw boost::system::system_error{ec}; + } - // Skip the headers since we don't care about them - for (auto const& header : agi::line_iterator(stream)) - if (header.empty()) break; + auto const results = resolver.resolve(UPDATE_CHECKER_SERVER, "443"); + + boost::asio::connect(stream.next_layer(), results.begin(), results.end()); + stream.handshake(boost::asio::ssl::stream_base::handshake_type::client); + + std::ostringstream s; + s << UPDATE_CHECKER_BASE_URL; + s << "/latest"; + std::string target = s.str(); + http::request req(http::verb::get, target, 11); + req.set(http::field::host, UPDATE_CHECKER_SERVER); + req.set(http::field::user_agent, "Aegisub-Japan7"); + + http::write(stream, req); + + boost::beast::flat_buffer buffer; + + http::response res; + + http::read(stream, buffer, res); + + // Gracefully close the stream + boost::system::error_code ec; + stream.shutdown(ec); + if(ec == boost::asio::error::eof) + { + // http://stackoverflow.com/questions/25587403/boost-asio-ssl-async-shutdown-always-finishes-with-an-error + ec.assign(0, ec.category()); + } + if(ec) + throw boost::system::system_error{ec}; + + std::string line; + std::ostringstream sbody; + sbody << res.body().data(); + std::stringstream body(sbody.str()); + + std::getline(body, line, '\n'); + + AegisubUpdateDescription version = ParseVersionString(line); - AegisubUpdateDescription version = AegisubUpdateDescription{0, 0, 0, "", ""}; std::ostringstream desc; - for (auto const& line : agi::line_iterator(stream)) { - - if (version.major == 0 && version.minor == 0 && version.minor == 0) { - version = ParseVersionString(line); - } else { - desc << line << "\n"; - } - + while (std::getline(body, line, '\n')) { + desc << line; } - if (version.major != 0 && version.minor != 0 && version.patch != 0) { - version.description = desc.str(); - return version; - } + version.description = desc.str(); + return version; throw VersionCheckError(from_wx(_("Could not get update from updates server."))); } From 35c92b64b57e9e7bd96179132364673ee491ea91 Mon Sep 17 00:00:00 2001 From: odrling Date: Tue, 10 Sep 2019 10:49:55 +0200 Subject: [PATCH 2/3] . --- src/dialog_version_check.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/dialog_version_check.cpp b/src/dialog_version_check.cpp index 1fe834424..dcf2109cd 100644 --- a/src/dialog_version_check.cpp +++ b/src/dialog_version_check.cpp @@ -386,9 +386,7 @@ AegisubUpdateDescription GetLatestVersion() { throw boost::system::system_error{ec}; std::string line; - std::ostringstream sbody; - sbody << res.body().data(); - std::stringstream body(sbody.str()); + std::stringstream body(res.body().data()); std::getline(body, line, '\n'); From 75d947365379e41a7704eabf8e24d1c0e5345c22 Mon Sep 17 00:00:00 2001 From: odrling Date: Tue, 10 Sep 2019 11:01:35 +0200 Subject: [PATCH 3/3] update boost --- vendor/boost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/boost b/vendor/boost index 9ccd3390c..afb333b7c 160000 --- a/vendor/boost +++ b/vendor/boost @@ -1 +1 @@ -Subproject commit 9ccd3390c8e9ef05f4cb681d15b2e14eac48886e +Subproject commit afb333b7c5101041f0280b2edf155c55114c9c95