X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=base%2Fapplications%2Frapps%2Floaddlg.cpp;h=fe9ec04decebc4347ad6f371eb0fd4a8b9cd7047;hp=d9d5aec84a441ab73fbc8bad4982b3e83f60dde5;hb=a6d2172cccd5262d1a7e8a82693ab73469274b14;hpb=3b777fd133808ef4488f61b085be34ef4f89e448 diff --git a/base/applications/rapps/loaddlg.cpp b/base/applications/rapps/loaddlg.cpp index d9d5aec84a4..fe9ec04dece 100644 --- a/base/applications/rapps/loaddlg.cpp +++ b/base/applications/rapps/loaddlg.cpp @@ -47,8 +47,8 @@ #include "misc.h" #ifdef USE_CERT_PINNING -#define CERT_ISSUER_INFO "BE\r\nGlobalSign nv-sa\r\nGlobalSign Domain Validation CA - SHA256 - G2" -#define CERT_SUBJECT_INFO "Domain Control Validated\r\n*.reactos.org" +#define CERT_ISSUER_INFO "US\r\nLet's Encrypt\r\nLet's Encrypt Authority X3" +#define CERT_SUBJECT_INFO "rapps.reactos.org" #endif enum DownloadStatus @@ -331,61 +331,52 @@ HRESULT WINAPI CDownloadDialog_Constructor(HWND Dlg, BOOL *pbCancelled, REFIID r } #ifdef USE_CERT_PINNING -static BOOL CertIsValid(HINTERNET hInternet, LPWSTR lpszHostName) +typedef CHeapPtr CLocalPtr; + +static BOOL CertGetSubjectAndIssuer(HINTERNET hFile, CLocalPtr& subjectInfo, CLocalPtr& issuerInfo) { - HINTERNET hConnect; - HINTERNET hRequest; DWORD certInfoLength; - BOOL Ret = FALSE; - INTERNET_CERTIFICATE_INFOW certInfo; + INTERNET_CERTIFICATE_INFOA certInfo; + DWORD size, flags; - hConnect = InternetConnectW(hInternet, lpszHostName, INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_SECURE, 0); - if (hConnect) + size = sizeof(flags); + if (!InternetQueryOptionA(hFile, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size)) { - hRequest = HttpOpenRequestW(hConnect, L"HEAD", NULL, NULL, NULL, NULL, INTERNET_FLAG_SECURE, 0); - if (hRequest != NULL) - { - Ret = HttpSendRequestW(hRequest, L"", 0, NULL, 0); - if (Ret) - { - certInfoLength = sizeof(certInfo); - Ret = InternetQueryOptionW(hRequest, - INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, - &certInfo, - &certInfoLength); - if (Ret) - { - if (certInfo.lpszEncryptionAlgName) - LocalFree(certInfo.lpszEncryptionAlgName); - if (certInfo.lpszIssuerInfo) - { - if (strcmp((LPSTR) certInfo.lpszIssuerInfo, CERT_ISSUER_INFO) != 0) - Ret = FALSE; - LocalFree(certInfo.lpszIssuerInfo); - } - if (certInfo.lpszProtocolName) - LocalFree(certInfo.lpszProtocolName); - if (certInfo.lpszSignatureAlgName) - LocalFree(certInfo.lpszSignatureAlgName); - if (certInfo.lpszSubjectInfo) - { - if (strcmp((LPSTR) certInfo.lpszSubjectInfo, CERT_SUBJECT_INFO) != 0) - Ret = FALSE; - LocalFree(certInfo.lpszSubjectInfo); - } - } - } - InternetCloseHandle(hRequest); - } - InternetCloseHandle(hConnect); + return FALSE; + } + + if (!flags & SECURITY_FLAG_SECURE) + { + return FALSE; } - return Ret; + + /* Despite what the header indicates, the implementation of INTERNET_CERTIFICATE_INFO is not Unicode-aware. */ + certInfoLength = sizeof(certInfo); + if (!InternetQueryOptionA(hFile, + INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT, + &certInfo, + &certInfoLength)) + { + return FALSE; + } + + subjectInfo.Attach(certInfo.lpszSubjectInfo); + issuerInfo.Attach(certInfo.lpszIssuerInfo); + + if (certInfo.lpszProtocolName) + LocalFree(certInfo.lpszProtocolName); + if (certInfo.lpszSignatureAlgName) + LocalFree(certInfo.lpszSignatureAlgName); + if (certInfo.lpszEncryptionAlgName) + LocalFree(certInfo.lpszEncryptionAlgName); + + return certInfo.lpszSubjectInfo && certInfo.lpszIssuerInfo; } #endif inline VOID MessageBox_LoadString(HWND hMainWnd, INT StringID) { - ATL::CString szMsgText; + ATL::CStringW szMsgText; if (szMsgText.LoadStringW(StringID)) { MessageBoxW(hMainWnd, szMsgText.GetString(), NULL, MB_OK | MB_ICONERROR); @@ -612,6 +603,8 @@ DWORD WINAPI CDownloadManager::ThreadFunc(LPVOID param) LPCWSTR szCaption = static_cast(param)->szCaption; ATL::CStringW szNewCaption; + const DWORD dwUrlConnectFlags = INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION; + if (InfoArray.GetSize() <= 0) { MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD); @@ -629,6 +622,19 @@ DWORD WINAPI CDownloadManager::ThreadFunc(LPVOID param) SendMessageW(Item, PBM_SETPOS, 0, 0); } + // is this URL an update package for RAPPS? if so store it in a different place + if (InfoArray[iAppId].szUrl == APPLICATION_DATABASE_URL) + { + bCab = TRUE; + if (!GetStorageDirectory(Path)) + goto end; + } + else + { + bCab = FALSE; + Path = SettingsInfo.szDownloadDir; + } + // Change caption to show the currently downloaded app if (!bCab) { @@ -657,18 +663,6 @@ DWORD WINAPI CDownloadManager::ThreadFunc(LPVOID param) if (q && q > p && (q - p) > 0) filenameLength -= wcslen(q - 1) * sizeof(WCHAR); - // is this URL an update package for RAPPS? if so store it in a different place - if (InfoArray[iAppId].szUrl == APPLICATION_DATABASE_URL) - { - bCab = TRUE; - if (!GetStorageDirectory(Path)) - goto end; - } - else - { - Path = SettingsInfo.szDownloadDir; - } - // is the path valid? can we access it? if (GetFileAttributesW(Path.GetString()) == INVALID_FILE_ATTRIBUTES) { @@ -703,6 +697,7 @@ DWORD WINAPI CDownloadManager::ThreadFunc(LPVOID param) switch (SettingsInfo.Proxy) { case 0: // preconfig + default: hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); break; case 1: // direct (no proxy) @@ -711,31 +706,11 @@ DWORD WINAPI CDownloadManager::ThreadFunc(LPVOID param) case 2: // use proxy hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PROXY, SettingsInfo.szProxyServer, SettingsInfo.szNoProxyFor, 0); break; - default: // preconfig - hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); - break; } if (!hOpen) goto end; - hFile = InternetOpenUrlW(hOpen, InfoArray[iAppId].szUrl.GetString(), NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_KEEP_CONNECTION, 0); - - if (!hFile) - { - MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2); - goto end; - } - - if (!HttpQueryInfoW(hFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwStatusLen, NULL)) - goto end; - - if (dwStatus != HTTP_STATUS_OK) - { - MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD); - goto end; - } - dwStatusLen = sizeof(dwStatus); memset(&urlComponents, 0, sizeof(urlComponents)); @@ -753,10 +728,44 @@ DWORD WINAPI CDownloadManager::ThreadFunc(LPVOID param) dwContentLen = 0; if (urlComponents.nScheme == INTERNET_SCHEME_HTTP || urlComponents.nScheme == INTERNET_SCHEME_HTTPS) - HttpQueryInfoW(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwContentLen, &dwStatus, 0); + { + hFile = InternetOpenUrlW(hOpen, InfoArray[iAppId].szUrl.GetString(), NULL, 0, + dwUrlConnectFlags, + 0); + if (!hFile) + { + MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2); + goto end; + } + + // query connection + if (!HttpQueryInfoW(hFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwStatusLen, NULL)) + goto end; + + if (dwStatus != HTTP_STATUS_OK) + { + MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD); + goto end; + } + + // query content length + HttpQueryInfoW(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwContentLen, &dwStatusLen, NULL); + } if (urlComponents.nScheme == INTERNET_SCHEME_FTP) + { + // force passive mode on FTP + hFile = InternetOpenUrlW(hOpen, InfoArray[iAppId].szUrl.GetString(), NULL, 0, + dwUrlConnectFlags | INTERNET_FLAG_PASSIVE, + 0); + if (!hFile) + { + MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2); + goto end; + } + dwContentLen = FtpGetFileSize(hFile, &dwStatus); + } if (!dwContentLen) { @@ -764,20 +773,42 @@ DWORD WINAPI CDownloadManager::ThreadFunc(LPVOID param) SetProgressMarquee(Item, TRUE); } + free(urlComponents.lpszScheme); + free(urlComponents.lpszHostName); + #ifdef USE_CERT_PINNING // are we using HTTPS to download the RAPPS update package? check if the certificate is original if ((urlComponents.nScheme == INTERNET_SCHEME_HTTPS) && - (wcscmp(InfoArray[iAppId].szUrl, APPLICATION_DATABASE_URL) == 0) && - (!CertIsValid(hOpen, urlComponents.lpszHostName))) + (wcscmp(InfoArray[iAppId].szUrl, APPLICATION_DATABASE_URL) == 0)) { - MessageBox_LoadString(hMainWnd, IDS_CERT_DOES_NOT_MATCH); - goto end; + CLocalPtr subjectName, issuerName; + CStringW szMsgText; + bool bAskQuestion = false; + if (!CertGetSubjectAndIssuer(hFile, subjectName, issuerName)) + { + szMsgText.LoadStringW(IDS_UNABLE_TO_QUERY_CERT); + bAskQuestion = true; + } + else + { + if (strcmp(subjectName, CERT_SUBJECT_INFO) || + strcmp(issuerName, CERT_ISSUER_INFO)) + { + szMsgText.Format(IDS_MISMATCH_CERT_INFO, (char*)subjectName, (const char*)issuerName); + bAskQuestion = true; + } + } + + if (bAskQuestion) + { + if (MessageBoxW(hMainWnd, szMsgText.GetString(), NULL, MB_YESNO | MB_ICONERROR) != IDYES) + { + goto end; + } + } } #endif - free(urlComponents.lpszScheme); - free(urlComponents.lpszHostName); - hOut = CreateFileW(Path.GetString(), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); if (hOut == INVALID_HANDLE_VALUE)