Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

795 lines
29 KiB

  1. //-----------------------------------------------------------------------------
  2. // America Online for Windows
  3. //-----------------------------------------------------------------------------
  4. // Copyright (c) 1987-2001 America Online, Inc. All rights reserved. This
  5. // software contains valuable confidential and proprietary information of
  6. // America Online and is subject to applicable licensing agreements.
  7. // Unauthorized reproduction, transmission, or distribution of this file and
  8. // its contents is a violation of applicable laws.
  9. //-----------------------------------------------------------------------------
  10. // $Workfile: AOLInstall.cpp $ $Author: RobrtLarson $
  11. // $Date: 05/02/01 $
  12. //-----------------------------------------------------------------------------
  13. #include "precomp.h"
  14. #include <Softpub.h>
  15. #include <WinCrypt.h>
  16. #include <WinTrust.h>
  17. #include <ImageHlp.h>
  18. #include "AOLFindBundledInstaller_AOLCode.h"
  19. #ifdef _DEBUG
  20. #define new DEBUG_NEW
  21. #undef THIS_FILE
  22. static char THIS_FILE[] = __FILE__;
  23. #endif
  24. #define SWAPWORDS(x) (((x) << 16) | ((x) >> 16))
  25. // define encoding method
  26. #define ENCODING (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
  27. #define INSTALLER 0x0001
  28. #define CLIENT 0x0002
  29. #define COUNTRY_PICKER 0x0004
  30. #define SERVICE_AOL 0x0010
  31. #define SERVICE_CS 0x0020
  32. // Local function prototypes
  33. BOOL GetExeType(LPSTR lpszExePath, WORD &wExeType);
  34. BOOL ExtractCertificateInfo(LPSTR lpszFileName, HCERTSTORE *hCertStore);
  35. PCCERT_CONTEXT WINAPI CryptGetSignerCertificateCallback(void *pvGetArg,
  36. DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hCertStore);
  37. BOOL CheckCertificateName(HCERTSTORE hCertStore);
  38. LPSTR GetCommonName(CERT_NAME_BLOB pCertNameBlob);
  39. BOOL VerifyFileInfo(WORD &ExeType, LPSTR lpszInstaller, PBOOL pbOldClient);
  40. BOOL VerifyCertificate(LPSTR lpszInstaller);
  41. _pfn_CertCloseStore g_pfn_CertCloseStore = NULL;
  42. _pfn_CryptVerifyMessageSignature g_pfn_CryptVerifyMessageSignature = NULL;
  43. _pfn_ImageGetCertificateData g_pfn_ImageGetCertificateData = NULL;
  44. _pfn_ImageGetCertificateHeader g_pfn_ImageGetCertificateHeader = NULL;
  45. _pfn_CertGetSubjectCertificateFromStore g_pfn_CertGetSubjectCertificateFromStore = NULL;
  46. _pfn_CertDuplicateStore g_pfn_CertDuplicateStore = NULL;
  47. _pfn_CertEnumCertificatesInStore g_pfn_CertEnumCertificatesInStore = NULL;
  48. _pfn_CertRDNValueToStrA g_pfn_CertRDNValueToStrA = NULL;
  49. _pfn_CertFindRDNAttr g_pfn_CertFindRDNAttr = NULL;
  50. _pfn_CryptDecodeObject g_pfn_CryptDecodeObject = NULL;
  51. _pfn_VerQueryValueA g_pfn_VerQueryValueA = NULL;
  52. _pfn_GetFileVersionInfoA g_pfn_GetFileVersionInfoA = NULL;
  53. _pfn_GetFileVersionInfoSizeA g_pfn_GetFileVersionInfoSizeA = NULL;
  54. _pfn_WinVerifyTrust g_pfn_WinVerifyTrust = NULL;
  55. HMODULE g_hCRYPT32 = NULL;
  56. HMODULE g_hWINTRUST = NULL;
  57. HMODULE g_hVERSION = NULL;
  58. HMODULE g_hIMAGEHLP = NULL;
  59. void UnloadDependencies()
  60. {
  61. g_pfn_CertCloseStore = NULL;
  62. g_pfn_CryptVerifyMessageSignature = NULL;
  63. g_pfn_ImageGetCertificateData = NULL;
  64. g_pfn_ImageGetCertificateHeader = NULL;
  65. g_pfn_CertGetSubjectCertificateFromStore = NULL;
  66. g_pfn_CertDuplicateStore = NULL;
  67. g_pfn_CertEnumCertificatesInStore = NULL;
  68. g_pfn_CertRDNValueToStrA = NULL;
  69. g_pfn_CertFindRDNAttr = NULL;
  70. g_pfn_CryptDecodeObject = NULL;
  71. g_pfn_VerQueryValueA = NULL;
  72. g_pfn_GetFileVersionInfoA = NULL;
  73. g_pfn_GetFileVersionInfoSizeA = NULL;
  74. g_pfn_WinVerifyTrust = NULL;
  75. if (g_hCRYPT32) {
  76. FreeLibrary(g_hCRYPT32);
  77. g_hCRYPT32 = NULL;
  78. }
  79. if (g_hWINTRUST) {
  80. FreeLibrary(g_hWINTRUST);
  81. g_hWINTRUST = NULL;
  82. }
  83. if (g_hVERSION) {
  84. FreeLibrary(g_hVERSION);
  85. g_hVERSION = NULL;
  86. }
  87. if (g_hIMAGEHLP) {
  88. FreeLibrary(g_hIMAGEHLP);
  89. g_hIMAGEHLP = NULL;
  90. }
  91. }
  92. BOOL LoadDependencies()
  93. {
  94. BOOL bSuccess = FALSE;
  95. if (!(g_hCRYPT32 = LoadLibraryA("CRYPT32.DLL"))) {
  96. goto eh;
  97. }
  98. if (!(g_hWINTRUST = LoadLibraryA("WINTRUST.DLL"))) {
  99. goto eh;
  100. }
  101. if (!(g_hVERSION = LoadLibraryA("VERSION.DLL"))) {
  102. goto eh;
  103. }
  104. if (!(g_hIMAGEHLP = LoadLibraryA("IMAGEHLP.DLL"))) {
  105. goto eh;
  106. }
  107. if (!(g_pfn_CertCloseStore = (_pfn_CertCloseStore) GetProcAddress(g_hCRYPT32, "CertCloseStore"))) { goto eh; }
  108. if (!(g_pfn_CryptVerifyMessageSignature = (_pfn_CryptVerifyMessageSignature) GetProcAddress(g_hCRYPT32, "CryptVerifyMessageSignature"))) { goto eh; }
  109. if (!(g_pfn_ImageGetCertificateData = (_pfn_ImageGetCertificateData) GetProcAddress(g_hIMAGEHLP, "ImageGetCertificateData"))) { goto eh; }
  110. if (!(g_pfn_ImageGetCertificateHeader = (_pfn_ImageGetCertificateHeader) GetProcAddress(g_hIMAGEHLP, "ImageGetCertificateHeader"))) { goto eh; }
  111. if (!(g_pfn_CertGetSubjectCertificateFromStore = (_pfn_CertGetSubjectCertificateFromStore) GetProcAddress(g_hCRYPT32, "CertGetSubjectCertificateFromStore"))) { goto eh; }
  112. if (!(g_pfn_CertDuplicateStore = (_pfn_CertDuplicateStore) GetProcAddress(g_hCRYPT32, "CertDuplicateStore"))) { goto eh; }
  113. if (!(g_pfn_CertEnumCertificatesInStore = (_pfn_CertEnumCertificatesInStore) GetProcAddress(g_hCRYPT32, "CertEnumCertificatesInStore"))) { goto eh; }
  114. if (!(g_pfn_CertRDNValueToStrA = (_pfn_CertRDNValueToStrA) GetProcAddress(g_hCRYPT32, "CertRDNValueToStrA"))) { goto eh; }
  115. if (!(g_pfn_CertFindRDNAttr = (_pfn_CertFindRDNAttr) GetProcAddress(g_hCRYPT32, "CertFindRDNAttr"))) { goto eh; }
  116. if (!(g_pfn_CryptDecodeObject = (_pfn_CryptDecodeObject) GetProcAddress(g_hCRYPT32, "CryptDecodeObject"))) { goto eh; }
  117. if (!(g_pfn_VerQueryValueA = (_pfn_VerQueryValueA) GetProcAddress(g_hVERSION, "VerQueryValueA"))) { goto eh; }
  118. if (!(g_pfn_GetFileVersionInfoA = (_pfn_GetFileVersionInfoA) GetProcAddress(g_hVERSION, "GetFileVersionInfoA"))) { goto eh; }
  119. if (!(g_pfn_GetFileVersionInfoSizeA = (_pfn_GetFileVersionInfoSizeA) GetProcAddress(g_hVERSION, "GetFileVersionInfoSizeA"))) { goto eh; }
  120. if (!(g_pfn_WinVerifyTrust = (_pfn_WinVerifyTrust) GetProcAddress(g_hWINTRUST, "WinVerifyTrust"))) { goto eh; }
  121. bSuccess = TRUE;
  122. eh:
  123. if (!bSuccess) {
  124. UnloadDependencies();
  125. }
  126. return bSuccess;
  127. }
  128. //-----------------------------------------------------------------------------
  129. // LocateInstaller
  130. // This functions searches for a valid AOL or CompuServe install program
  131. // based on the default value found in a registry key. This install program
  132. // is then validated by checking the Certificates and verifying that the
  133. // program file has not been modified since being signed by America Online.
  134. //
  135. // AOL Registry Key:
  136. // HKLM\Software\America Online\Installers
  137. //
  138. // CompuServe Registry Key:
  139. // HKLM\Software\CompuServe\Installers
  140. //-----------------------------------------------------------------------------
  141. // Function parameters:
  142. // LPSTR lpszInstaller Returned installer command line,
  143. // NULL if no valid installer located
  144. // Note: allowance should be made in the
  145. // length of this string for an optional
  146. // parameter on the command line of MAX_PATH
  147. // length.
  148. // UINT uiPathSize Length of lpszInstaller parameter
  149. // BOOL *pbMessage TRUE - display App Compat message
  150. // FALSE - do not display App Compat message
  151. //-----------------------------------------------------------------------------
  152. BOOL LocateInstaller_Internal(LPSTR lpszInstaller, UINT uiPathSize, BOOL *pbMessage)
  153. {
  154. BOOL bResult = FALSE,
  155. bCheckCert = TRUE,
  156. bOldClient = FALSE;
  157. HKEY hKey;
  158. LONG lRet;
  159. CHAR szModuleName[MAX_PATH];
  160. WORD wExeType = 0;
  161. // Default to no App Compat message
  162. *pbMessage = FALSE;
  163. // Get the name of the file that is executing
  164. DWORD dwLen = GetModuleFileNameA(NULL, szModuleName, sizeof(szModuleName));
  165. if (0 == dwLen)
  166. { return FALSE; }
  167. // Determine the type of exe this is
  168. bResult = GetExeType(szModuleName, wExeType);
  169. if (bResult)
  170. {
  171. // Check if this is the uninstaller calling the client
  172. if ((CLIENT & wExeType) && (NULL != strstr(_strlwr(GetCommandLineA()), "regall")))
  173. { return FALSE; }
  174. // If the program we are running is valid, then let it run
  175. if (VerifyFileInfo(wExeType, szModuleName, &bOldClient))
  176. { return FALSE; }
  177. // If this is an client <= 4.0 then display message if not bundled installer found
  178. if (bOldClient)
  179. { *pbMessage = TRUE; }
  180. // Open registry key
  181. if (SERVICE_AOL & wExeType)
  182. {
  183. lRet = RegOpenKeyA(HKEY_LOCAL_MACHINE,
  184. "Software\\America Online\\Installers", &hKey);
  185. }
  186. else if (SERVICE_CS & wExeType)
  187. {
  188. lRet = RegOpenKeyA(HKEY_LOCAL_MACHINE,
  189. "Software\\CompuServe\\Installers", &hKey);
  190. }
  191. else
  192. { return FALSE; } // Don't know what this is
  193. if (ERROR_SUCCESS != lRet)
  194. { return FALSE; } // No bundled version of AOL/CS located in registry
  195. // Get size of registry key data
  196. ULONG cbSize;
  197. DWORD dwType;
  198. lRet = RegQueryValueExA(hKey, NULL, NULL, &dwType, NULL, &cbSize);
  199. if ((ERROR_SUCCESS != lRet) ||
  200. (cbSize > uiPathSize) ||
  201. (REG_SZ != dwType))
  202. {
  203. RegCloseKey(hKey);
  204. return FALSE;
  205. }
  206. // See if we need to check the certificate for the installer
  207. lRet = RegQueryValueExA(hKey, "CC", NULL, &dwType, NULL, &cbSize);
  208. if ((ERROR_SUCCESS == lRet) && (cbSize > 0))
  209. { bCheckCert = FALSE; }
  210. lpszInstaller[0] = '\"';
  211. // Get registry key data
  212. cbSize = uiPathSize - 1;
  213. lRet = RegQueryValueExA(hKey, NULL, NULL, NULL, (UCHAR *)&lpszInstaller[1], &cbSize);
  214. RegCloseKey(hKey);
  215. if (ERROR_SUCCESS == lRet)
  216. {
  217. // Check for correct installer version
  218. bResult = VerifyFileInfo(wExeType, &lpszInstaller[1], NULL);
  219. if (bResult && bCheckCert)
  220. {
  221. // Get certificate store
  222. HCERTSTORE hCertStore = NULL;
  223. bResult = ExtractCertificateInfo(&lpszInstaller[1], &hCertStore);
  224. if (bResult)
  225. {
  226. // Check certificates for AOL/CS signature
  227. bResult = CheckCertificateName(hCertStore);
  228. if (bResult)
  229. {
  230. // Check that file has not been modified
  231. bResult = VerifyCertificate(&lpszInstaller[1]);
  232. }
  233. }
  234. // Close the certificate store
  235. if (NULL != hCertStore)
  236. { (*g_pfn_CertCloseStore)(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); }
  237. }
  238. }
  239. }
  240. if (bResult)
  241. {
  242. StringCchCatA(lpszInstaller, uiPathSize, "\"");
  243. // Check if Message should be displayed to user
  244. if (CLIENT & wExeType)
  245. { *pbMessage = TRUE; }
  246. else
  247. {
  248. // Add command line parameter
  249. if (COUNTRY_PICKER & wExeType)
  250. {
  251. StringCchPrintfA(lpszInstaller, uiPathSize, "%s -p \"%s\"", lpszInstaller, szModuleName);
  252. }
  253. }
  254. }
  255. else
  256. { lpszInstaller[0] = '\0'; }
  257. return bResult;
  258. }
  259. BOOL LocateInstaller(LPSTR lpszInstaller, UINT uiPathSize, BOOL *pbMessage)
  260. {
  261. BOOL bSuccess = FALSE;
  262. if (!LoadDependencies()) {
  263. goto eh;
  264. }
  265. if (!LocateInstaller_Internal(lpszInstaller, uiPathSize, pbMessage)) {
  266. goto eh;
  267. }
  268. bSuccess = TRUE;
  269. eh:
  270. UnloadDependencies();
  271. return bSuccess;
  272. }
  273. //-----------------------------------------------------------------------------
  274. // GetExeType
  275. // This functions determines whether the executible is an AOL/CS client or
  276. // and AOL/CS installer.
  277. //-----------------------------------------------------------------------------
  278. // Function parameters:
  279. // LPSTR lpszExePath Fully qualified path to executible
  280. // WORD &wExeType Returned executible type
  281. // AOL or CS
  282. // Client or Installer
  283. //-----------------------------------------------------------------------------
  284. BOOL GetExeType(LPSTR lpszExePath, WORD &wExeType)
  285. {
  286. // Set string to lower case for comparisons
  287. _strlwr(lpszExePath);
  288. BOOL bSuccess = FALSE;
  289. LPSTR pszTemp = strrchr(lpszExePath, '\\');
  290. if (NULL == pszTemp)
  291. { return FALSE; }
  292. pszTemp++; // Get to beginning of exe name
  293. // Determine if this is an AOL/CS client
  294. if (0 == _stricmp(pszTemp, "waol.exe"))
  295. {
  296. wExeType = SERVICE_AOL | CLIENT;
  297. return TRUE;
  298. }
  299. else if ((0 == _stricmp(pszTemp, "wcs2000.exe")) ||
  300. (0 == _stricmp(pszTemp, "cs3.exe")))
  301. {
  302. wExeType = SERVICE_CS | CLIENT;
  303. return TRUE;
  304. }
  305. else if ((NULL != strstr(pszTemp, "cs2000")) ||
  306. (NULL != strstr(pszTemp, "setupcs2k")) ||
  307. (NULL != strstr(pszTemp, "setupcs2000")) ||
  308. (0 == _stricmp(pszTemp, "d41000b.exe")) ||
  309. (0 == _stricmp(pszTemp, "d41510b.exe")) ||
  310. (0 == _stricmp(pszTemp, "d41540b.exe")))
  311. {
  312. // These are CS installers w/ "America Online, Inc." in version info.
  313. wExeType = SERVICE_CS | INSTALLER;
  314. return TRUE;
  315. }
  316. else if (0 == _stricmp(pszTemp, "wgw.exe"))
  317. { return FALSE; } // There is no bundled installer for Gateway
  318. else if (0 == _stricmp(pszTemp, "wwm.exe"))
  319. { return FALSE; } // There is no bundled installer for Wal-Mart
  320. // Determine AOL/CS installer
  321. // Get size of version info in file
  322. DWORD dwHandle = 0;
  323. DWORD dwVerInfoSize = (*g_pfn_GetFileVersionInfoSizeA)(lpszExePath, &dwHandle);
  324. // Allocate memory for version info
  325. BYTE *lpVerInfo = NULL;
  326. __try
  327. {
  328. lpVerInfo = (BYTE *)HeapAlloc(GetProcessHeap(), 0, dwVerInfoSize);
  329. if (NULL == lpVerInfo)
  330. { __leave; }
  331. // Get version info from file
  332. BOOL bResult = (*g_pfn_GetFileVersionInfoA)(lpszExePath, NULL, dwVerInfoSize, lpVerInfo);
  333. if (!bResult)
  334. { __leave; }
  335. // Get Language code page
  336. DWORD *pdwTrans;
  337. UINT uiBytes;
  338. DWORD dwLangCodepage = 0;
  339. bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, "\\VarFileInfo\\Translation", (VOID **)&pdwTrans, &uiBytes);
  340. if (bResult)
  341. { dwLangCodepage = SWAPWORDS(*pdwTrans); } // Translate language code page to something we can use
  342. else
  343. { dwLangCodepage = 0x040904e4; } // Try English multilanguage code page
  344. // Obtain the "CompanyName" from the version info
  345. CHAR szQuery[MAX_PATH];
  346. PCHAR pszVerInfo;
  347. StringCchPrintfA(szQuery, MAX_PATH,"\\StringFileInfo\\%08X\\CompanyName", dwLangCodepage);
  348. bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, szQuery, (VOID **)&pszVerInfo, &uiBytes);
  349. if (!bResult)
  350. { __leave; }
  351. // Check "CompanyName"
  352. if ((NULL != strstr(pszVerInfo, "America Online")) ||
  353. (NULL != strstr(pszVerInfo, "AOL")))
  354. {
  355. wExeType = SERVICE_AOL | INSTALLER;
  356. bSuccess = TRUE;
  357. __leave;
  358. }
  359. if (0 == strcmp("CompuServe Interactive Services, Inc.", pszVerInfo))
  360. {
  361. wExeType = SERVICE_CS | INSTALLER;
  362. bSuccess = TRUE;
  363. __leave;
  364. }
  365. }
  366. __finally
  367. {
  368. if (NULL != lpVerInfo)
  369. { HeapFree(GetProcessHeap(), 0, lpVerInfo); }
  370. }
  371. return bSuccess;
  372. }
  373. //-----------------------------------------------------------------------------
  374. // ExtractCertificateInfo
  375. // This functions obtains and verifies the certificate store for the
  376. // installer.
  377. //-----------------------------------------------------------------------------
  378. // Function parameters:
  379. // LPSTR lpszFileName Fully qualified path to installer
  380. // HCERTSTORE *hCertStore Handle to the certificate store
  381. //-----------------------------------------------------------------------------
  382. BOOL ExtractCertificateInfo(LPSTR lpszFileName, HCERTSTORE *hCertStore)
  383. {
  384. WIN_CERTIFICATE CertificateHeader;
  385. LPWIN_CERTIFICATE pbCertificate = NULL;
  386. BOOL bResult = FALSE;
  387. HANDLE hFile = NULL;
  388. DWORD dwSize;
  389. CRYPT_VERIFY_MESSAGE_PARA CryptVerifyMessagePara;
  390. __try
  391. {
  392. // Open file
  393. hFile = CreateFileA(lpszFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING,
  394. FILE_ATTRIBUTE_NORMAL, NULL);
  395. if (hFile == INVALID_HANDLE_VALUE)
  396. { __leave; }
  397. // Get Certificate Header
  398. bResult = (*g_pfn_ImageGetCertificateHeader)(hFile, 0, &CertificateHeader);
  399. if (!bResult)
  400. { __leave; }
  401. // Allocate Memory for Certificate Blob
  402. pbCertificate = (LPWIN_CERTIFICATE)HeapAlloc(GetProcessHeap(), 0,
  403. CertificateHeader.dwLength);
  404. if (NULL == pbCertificate)
  405. {
  406. bResult = FALSE;
  407. __leave;
  408. }
  409. // Get Certificate Blob
  410. dwSize = CertificateHeader.dwLength;
  411. bResult = (*g_pfn_ImageGetCertificateData)(hFile, 0, pbCertificate, &dwSize);
  412. if (!bResult)
  413. { __leave; }
  414. // Zero out CRYPT_VERIFY_MESSAGE_PARA structure
  415. ZeroMemory(&CryptVerifyMessagePara, sizeof(CryptVerifyMessagePara));
  416. CryptVerifyMessagePara.cbSize = sizeof(CryptVerifyMessagePara);
  417. CryptVerifyMessagePara.dwMsgAndCertEncodingType = ENCODING;
  418. CryptVerifyMessagePara.pfnGetSignerCertificate = CryptGetSignerCertificateCallback;
  419. // Pass Address of certificate store to callback
  420. CryptVerifyMessagePara.pvGetArg = (LPVOID)hCertStore;
  421. // Verify the message and call callback
  422. bResult = (*g_pfn_CryptVerifyMessageSignature)(&CryptVerifyMessagePara, 0,
  423. pbCertificate->bCertificate, dwSize, NULL, NULL, NULL);
  424. }
  425. __finally
  426. {
  427. if (NULL != pbCertificate)
  428. { HeapFree(GetProcessHeap(), 0, pbCertificate); }
  429. if (NULL != hFile)
  430. { CloseHandle(hFile); }
  431. }
  432. return bResult;
  433. }
  434. //-----------------------------------------------------------------------------
  435. // CryptGetSignerCertificateCallback
  436. // This functions is the callback function for CryptVerifyMessageSignature.
  437. //-----------------------------------------------------------------------------
  438. // Function parameters:
  439. // See MicroSoft documentation for details.
  440. //-----------------------------------------------------------------------------
  441. PCCERT_CONTEXT WINAPI CryptGetSignerCertificateCallback(void *pvGetArg,
  442. DWORD dwCertEncodingType, PCERT_INFO pSignerId, HCERTSTORE hCertStore)
  443. {
  444. if (NULL == hCertStore)
  445. { return FALSE; }
  446. *((HCERTSTORE *)pvGetArg) = (*g_pfn_CertDuplicateStore)(hCertStore);
  447. return (*g_pfn_CertGetSubjectCertificateFromStore)(hCertStore, dwCertEncodingType,
  448. pSignerId);
  449. }
  450. //-----------------------------------------------------------------------------
  451. // CheckCertificateName
  452. // This functions checks the certificate name to verify that it is signed by
  453. // America Online.
  454. //-----------------------------------------------------------------------------
  455. // Function parameters:
  456. // HCERTSTORE hCertStore Handle to the certificate store
  457. //-----------------------------------------------------------------------------
  458. BOOL CheckCertificateName(HCERTSTORE hCertStore)
  459. {
  460. BOOL bReturn = FALSE;
  461. PCCERT_CONTEXT pCertContext = NULL;
  462. PCCERT_CONTEXT pPrevContext = NULL;
  463. LPSTR szSubject = NULL;
  464. if (NULL != hCertStore)
  465. {
  466. do
  467. {
  468. pCertContext = (*g_pfn_CertEnumCertificatesInStore)(hCertStore, pPrevContext);
  469. if (NULL != pCertContext)
  470. {
  471. // Get Subject common name, if not then get organization name
  472. szSubject = GetCommonName(pCertContext->pCertInfo->Subject);
  473. if (NULL != szSubject)
  474. {
  475. // Check name of certificate signer
  476. if (0 == strcmp(szSubject, "America Online, Inc."))
  477. { bReturn = TRUE; }
  478. HeapFree(GetProcessHeap(), 0, szSubject);
  479. }
  480. pPrevContext = pCertContext;
  481. }
  482. } while (pCertContext);
  483. }
  484. return bReturn;
  485. }
  486. //-----------------------------------------------------------------------------
  487. // GetCommonName
  488. // This functions obtains the common name from the certificate store
  489. //-----------------------------------------------------------------------------
  490. // Function parameters:
  491. // CERT_NAME_BLOB pCertNameBlob Pointer to the blob that contains the name
  492. //-----------------------------------------------------------------------------
  493. LPSTR GetCommonName(CERT_NAME_BLOB pCertNameBlob)
  494. {
  495. BOOL bReturn = FALSE;
  496. BOOL bResult;
  497. PCERT_NAME_INFO pCertName = NULL;
  498. PCERT_RDN_ATTR pCertAttr;
  499. LPSTR szName = NULL;
  500. DWORD dwSize;
  501. __try
  502. {
  503. // Find out size of decrypted blob
  504. (*g_pfn_CryptDecodeObject)(ENCODING, X509_NAME, pCertNameBlob.pbData,
  505. pCertNameBlob.cbData, 0, NULL, &dwSize);
  506. // Allocate memory for decrypted blob
  507. pCertName = (PCERT_NAME_INFO)HeapAlloc(GetProcessHeap(), 0, dwSize);
  508. if (NULL == pCertName)
  509. { __leave; }
  510. // Decode the certificate blob
  511. bResult = (*g_pfn_CryptDecodeObject)(ENCODING, X509_NAME, pCertNameBlob.pbData,
  512. pCertNameBlob.cbData, 0, pCertName, &dwSize);
  513. if (!bResult)
  514. { __leave; }
  515. // Get common name
  516. pCertAttr = (*g_pfn_CertFindRDNAttr)(szOID_COMMON_NAME, pCertName);
  517. if (NULL == pCertAttr)
  518. {
  519. // Get organization name if no common name found
  520. pCertAttr = (*g_pfn_CertFindRDNAttr)(szOID_ORGANIZATION_NAME, pCertName);
  521. if (NULL == pCertAttr)
  522. { __leave; }
  523. }
  524. // Find out size of name
  525. dwSize = (*g_pfn_CertRDNValueToStrA)(pCertAttr->dwValueType, &pCertAttr->Value, NULL, 0);
  526. // Allocate memory for name
  527. szName = (LPSTR)HeapAlloc(GetProcessHeap(), 0, dwSize);
  528. if (NULL == szName)
  529. { __leave; }
  530. // Obtain name from decrypted blob
  531. (*g_pfn_CertRDNValueToStrA)(pCertAttr->dwValueType, &pCertAttr->Value, szName, dwSize);
  532. bReturn = TRUE;
  533. }
  534. __finally
  535. {
  536. if (NULL != pCertName)
  537. { HeapFree(GetProcessHeap(), 0, pCertName); }
  538. if (!bReturn)
  539. {
  540. if (NULL != szName)
  541. { HeapFree(GetProcessHeap(), 0, szName); }
  542. }
  543. }
  544. if (bReturn)
  545. { return szName; }
  546. else
  547. { return NULL; }
  548. }
  549. //-----------------------------------------------------------------------------
  550. // VerifyFileInfo
  551. // This functions verifies that the installer is valid based on the version
  552. // information stored in the file.
  553. //-----------------------------------------------------------------------------
  554. // Function parameters:
  555. // INSTALLER_TYPE InstallerType Specifies whether to look for AOL or CS
  556. // LPSTR lpszInstaller Fully qualified path to installer
  557. // PBOOL pbOldClient Is is a client older then 5.0
  558. //-----------------------------------------------------------------------------
  559. BOOL VerifyFileInfo(WORD &wExeType, LPSTR lpszInstaller, PBOOL pbOldClient)
  560. {
  561. BOOL bReturn = FALSE;
  562. BOOL bResult;
  563. BYTE *lpVerInfo = NULL;
  564. __try
  565. {
  566. // Get size of version info in file
  567. DWORD dwHandle = 0;
  568. DWORD dwVerInfoSize = (*g_pfn_GetFileVersionInfoSizeA)(lpszInstaller, &dwHandle);
  569. // Allocate memory for version info
  570. lpVerInfo = (BYTE *)HeapAlloc(GetProcessHeap(), 0, dwVerInfoSize);
  571. if (NULL == lpVerInfo)
  572. { __leave; }
  573. // Get version info from file
  574. bResult = (*g_pfn_GetFileVersionInfoA)(lpszInstaller, NULL, dwVerInfoSize, lpVerInfo);
  575. if (!bResult)
  576. { __leave; }
  577. // Get Language code page
  578. DWORD *pdwTrans;
  579. UINT uiBytes;
  580. DWORD dwLangCodepage = 0;
  581. bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, "\\VarFileInfo\\Translation", (VOID **)&pdwTrans, &uiBytes);
  582. if (bResult)
  583. { dwLangCodepage = SWAPWORDS(*pdwTrans); } // Translate language code page to something we can use
  584. else
  585. { dwLangCodepage = 0x040904e4; } // Try English multilanguage code page
  586. // Obtain the "CompanyName" from the version info
  587. CHAR szQuery[MAX_PATH];
  588. PCHAR pszVerInfo;
  589. StringCchPrintfA(szQuery, MAX_PATH, "\\StringFileInfo\\%08X\\CompanyName", dwLangCodepage);
  590. bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, szQuery, (VOID **)&pszVerInfo, &uiBytes);
  591. if (!bResult)
  592. { __leave; }
  593. // Check "CompanyName"
  594. if (SERVICE_AOL & wExeType)
  595. {
  596. if ((NULL == strstr(pszVerInfo, "America Online")) &&
  597. (NULL == strstr(pszVerInfo, "AOL")))
  598. { __leave; }
  599. }
  600. else if (SERVICE_CS & wExeType)
  601. {
  602. if (0 != strcmp("CompuServe Interactive Services, Inc.", pszVerInfo))
  603. { __leave; }
  604. }
  605. else
  606. { __leave; }
  607. // Get fixed file info
  608. VS_FIXEDFILEINFO* pVS_FFI;
  609. bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, "\\", (VOID **)&pVS_FFI, &uiBytes);
  610. if (!bResult)
  611. { __leave; }
  612. // Check if this is the Country Picker
  613. StringCchPrintfA(szQuery, MAX_PATH, "\\StringFileInfo\\%08X\\ProductName", dwLangCodepage);
  614. bResult = (*g_pfn_VerQueryValueA)(lpVerInfo, szQuery, (VOID **)&pszVerInfo, &uiBytes);
  615. if ((bResult) && (NULL != strstr(pszVerInfo, "Country Picker")))
  616. {
  617. wExeType |= COUNTRY_PICKER;
  618. if (0x00010005 > pVS_FFI->dwProductVersionMS)
  619. { __leave; }
  620. }
  621. else
  622. {
  623. if ((0x00060000 > pVS_FFI->dwProductVersionMS) ||
  624. ((0x00060000 >= pVS_FFI->dwProductVersionMS) &&
  625. (0x00020000 > pVS_FFI->dwProductVersionLS)))
  626. {
  627. if ((NULL != pbOldClient) &&
  628. (CLIENT & wExeType) &&
  629. (0x00050000 > pVS_FFI->dwProductVersionMS))
  630. { *pbOldClient = TRUE; }
  631. __leave;
  632. }
  633. }
  634. bReturn = TRUE;
  635. }
  636. __finally
  637. {
  638. if (NULL != lpVerInfo)
  639. { HeapFree(GetProcessHeap(), 0, lpVerInfo); }
  640. }
  641. return bReturn;
  642. }
  643. //-----------------------------------------------------------------------------
  644. // VerifyCertificate
  645. // This functions verifies that the install has not been modified since
  646. // being signed by America Online.
  647. //-----------------------------------------------------------------------------
  648. // Function parameters:
  649. // LPSTR lpszInstaller Fully qualified path to installer
  650. //-----------------------------------------------------------------------------
  651. BOOL VerifyCertificate(LPSTR lpszInstaller)
  652. {
  653. GUID ActionGUID = WIN_SPUB_ACTION_PUBLISHED_SOFTWARE;
  654. GUID SubjectPeImage = WIN_TRUST_SUBJTYPE_PE_IMAGE;
  655. WIN_TRUST_SUBJECT_FILE Subject;
  656. // Subject.lpPath is a WCHAR string, must convert
  657. LPWSTR lpwszInstaller = NULL;
  658. int cchUnicodeSize = 0;
  659. cchUnicodeSize = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
  660. lpszInstaller, -1, NULL, 0);
  661. lpwszInstaller = (LPWSTR)malloc(cchUnicodeSize * sizeof(WCHAR));
  662. if (0 == MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, lpszInstaller,
  663. -1, lpwszInstaller, cchUnicodeSize))
  664. {
  665. if (lpwszInstaller)
  666. { free(lpwszInstaller); }
  667. return FALSE;
  668. }
  669. Subject.lpPath = lpwszInstaller;
  670. Subject.hFile = INVALID_HANDLE_VALUE; // Open the using the lpPath field
  671. WIN_TRUST_ACTDATA_CONTEXT_WITH_SUBJECT ActionData;
  672. ActionData.Subject = &Subject;
  673. ActionData.hClientToken = NULL;
  674. ActionData.SubjectType = &SubjectPeImage;
  675. // Verify the file has not be changed since being signed
  676. HRESULT hr = (*g_pfn_WinVerifyTrust)((HWND)INVALID_HANDLE_VALUE, &ActionGUID, (WINTRUST_DATA *) &ActionData);
  677. if (lpwszInstaller)
  678. { free(lpwszInstaller); }
  679. if (S_OK == hr)
  680. { return TRUE; }
  681. else
  682. { return FALSE; }
  683. }