diff --git a/Source/HTTPClient.cpp b/Source/HTTPClient.cpp index dde588a0..eaf1f7ff 100644 --- a/Source/HTTPClient.cpp +++ b/Source/HTTPClient.cpp @@ -20,7 +20,21 @@ #include "Main.h" #include -BOOL HTTPGetFile (CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *responseCode) +__declspec(thread) bool invalidCN = false; + +static void CALLBACK WinHTTPStatusCallback(HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInformation, DWORD dwStatusInformationLength) +{ + if (dwStatusInformationLength != 4) + return; + + if ((*(DWORD*)lpvStatusInformation) & ~(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID | WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA)) + return; + + if ((*(DWORD*)lpvStatusInformation) & WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID) + invalidCN = true; +} + +BOOL HTTPGetFile(CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *responseCode, HTTPGetFileWin81TLSSNIBugHandler h) { HINTERNET hSession = NULL; HINTERNET hConnect = NULL; @@ -54,10 +68,14 @@ BOOL HTTPGetFile (CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *response if (urlComponents.nPort == 443) secure = TRUE; +retry: hSession = WinHttpOpen(OBS_VERSION_STRING, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (!hSession) goto failure; + if (secure) + WinHttpSetStatusCallback(hSession, WinHTTPStatusCallback, WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, NULL); + hConnect = WinHttpConnect(hSession, hostName, secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0); if (!hConnect) goto failure; @@ -68,11 +86,20 @@ BOOL HTTPGetFile (CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *response BOOL bResults = WinHttpSendRequest(hRequest, extraHeaders, extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); - // End the request. - if (bResults) - bResults = WinHttpReceiveResponse(hRequest, NULL); - else + if (!bResults) + { + DWORD err = GetLastError(); + if (err == ERROR_WINHTTP_SECURE_FAILURE && invalidCN && h && h()) + { + secure = 0; + WinHttpSetStatusCallback(hSession, nullptr, WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, NULL); + goto retry; + } goto failure; + } + + // End the request. + bResults = WinHttpReceiveResponse(hRequest, NULL); TCHAR statusCode[8]; DWORD statusCodeLen; @@ -121,7 +148,10 @@ BOOL HTTPGetFile (CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *response failure: if (hSession) + { + WinHttpSetStatusCallback(hSession, nullptr, WINHTTP_CALLBACK_FLAG_SECURE_FAILURE, NULL); WinHttpCloseHandle(hSession); + } if (hConnect) WinHttpCloseHandle(hConnect); if (hRequest) diff --git a/Source/HTTPClient.h b/Source/HTTPClient.h index 3b36402f..b6fdad73 100644 --- a/Source/HTTPClient.h +++ b/Source/HTTPClient.h @@ -19,6 +19,8 @@ #pragma once -BOOL HTTPGetFile (CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *responseCode); +typedef bool(HTTPGetFileWin81TLSSNIBugHandler)(); + +BOOL HTTPGetFile(CTSTR url, CTSTR outputPath, CTSTR extraHeaders, int *responseCode, HTTPGetFileWin81TLSSNIBugHandler h = nullptr); String CreateHTTPURL(String host, String path, String extra=String(), bool secure=false); \ No newline at end of file diff --git a/Source/Updater.cpp b/Source/Updater.cpp index a387be7b..d4fd06d3 100644 --- a/Source/Updater.cpp +++ b/Source/Updater.cpp @@ -99,7 +99,7 @@ BOOL CalculateFileHash (TCHAR *path, BYTE *hash) #define MANIFEST_URL "https://builds.catchexception.org/update.json" #define UPDATER_PATH "/updates/org.catchexception.builds.updater.exe" #define UPDATE_CHANNEL "master" -*/ +//*/ #ifndef MANIFEST_WITH_ARCHIVES #define MANIFEST_WITH_ARCHIVES 0 @@ -372,6 +372,11 @@ bool ParseUpdateManifest (TCHAR *path, BOOL *updatesAvailable, String &descripti #endif } +bool Win81TLSSNIBugHandler() +{ + return OSGetVersion() == 8 && OBSMessageBox(hwndMain, Str("Updater.Win81TLSSNIBug"), nullptr, MB_YESNOCANCEL | MB_DEFBUTTON2) == IDYES; +} + DWORD WINAPI CheckUpdateThread (VOID *arg) { int responseCode; @@ -421,7 +426,11 @@ DWORD WINAPI CheckUpdateThread (VOID *arg) scat(extraHeaders, strGUID); } +#if MANIFEST_WITH_ARCHIVES + if (HTTPGetFile(TEXT(MANIFEST_URL), manifestPath, extraHeaders, &responseCode, Win81TLSSNIBugHandler)) +#else if (HTTPGetFile(TEXT(MANIFEST_URL), manifestPath, extraHeaders, &responseCode)) +#endif { if (responseCode == 200 || responseCode == 304) { diff --git a/rundir/locale/en.txt b/rundir/locale/en.txt index cbff61fb..f1316674 100644 --- a/rundir/locale/en.txt +++ b/rundir/locale/en.txt @@ -381,6 +381,7 @@ Updater.NewUpdates="The following updates are available:\r\n\r\n" Updater.RunningWarning="OBS will be restarted to install the updates.\r\n\r\nAre you sure you want to continue?" Updater.UpdatesAvailable="Updates are available" Updater.NoUpdatesAvailable="No updates are available" +Updater.Win81TLSSNIBug="Due to a bug in Windows 8.1 the secure update check failed. Do you want to retry the update check via an insecure connection?" MainMenu.Help.LogFiles="Log Files" MainMenu.Help.AnalyzeCurrentLog="Analyze current Log File"