Source code of Windows XP (NT5)
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.

2459 lines
75 KiB

  1. //*********************************************************************
  2. //* Microsoft Windows **
  3. //* Copyright(c) Microsoft Corp., 1995 **
  4. //*********************************************************************
  5. //
  6. // content.cpp - "Content" property sheet
  7. //
  8. // HISTORY:
  9. //
  10. // 5/17/97 t-ashlm created
  11. #include "inetcplp.h"
  12. #include <wab.h>
  13. #include <cryptui.h>
  14. #include <msiehost.h>
  15. #include <schannel.h>
  16. #include <mluisupp.h>
  17. //
  18. // Private Functions and Structures
  19. //
  20. // WINTRUST / SOFTPUB
  21. // definition from WINTRUST.H
  22. // extern "C" BOOL WINAPI OpenPersonalTrustDBDialog(HWND hwndParent);
  23. typedef BOOL (WINAPI *WINTRUSTDLGPROC)(HWND hwndParent);
  24. WINTRUSTDLGPROC g_WinTrustDlgProc = (WINTRUSTDLGPROC)NULL;
  25. SSL_EMPTY_CACHE_FN_W g_pfnSslEmptyCacheW = (SSL_EMPTY_CACHE_FN_W)NULL;
  26. #ifdef WALLET
  27. BOOL IsWallet3Installed();
  28. BOOL IsWalletAddressAvailable(VOID);
  29. BOOL IsWalletPaymentAvailable(VOID);
  30. #endif
  31. HRESULT ShowModalDialog(HWND hwndParent, IMoniker *pmk, VARIANT *pvarArgIn, TCHAR* pchOptions, VARIANT *pvArgOut);
  32. HCERTSTORE PFXImportCertStore(CRYPT_DATA_BLOB* pPFX, LPCWSTR szPassword, DWORD dwFlags);
  33. BOOL PFXExportCertStore(HCERTSTORE hStore, CRYPT_DATA_BLOB* pPFX, LPCWSTR szPassword, DWORD dwFlags);
  34. BOOL _AorW_GetFileNameFromBrowse(HWND hDlg,
  35. LPWSTR pszFilename,
  36. UINT cchFilename,
  37. LPCWSTR pszWorkingDir,
  38. LPCWSTR pszExt,
  39. LPCWSTR pszFilter,
  40. LPCWSTR pszTitle);
  41. INT_PTR CALLBACK AutoSuggestDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  42. INT_PTR CALLBACK WalletDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  43. //BUBUG: The following prototype should be rermoved when we have updated our Crypto API to latest version
  44. BOOL WINAPI WTHelperIsInRootStore(PCCERT_CONTEXT pCertContext);
  45. //////////////////////////////////////////////
  46. // stolen from \inet\schannel\sspi\spreg.h
  47. #define REG_SITECERT_BASE TEXT("System\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\CertificationAuthorities")
  48. #define REG_SITECERT_CERT_VAL TEXT("CACert")
  49. #define SITECERTKEYLEN 80 // FEATURE: should probably grab this value somewhere
  50. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  51. #include <initguid.h>
  52. // Use the wallet "payment" guid for JIT (different for alpha and x86...)
  53. #ifdef _ALPHA_
  54. // {B7FB4D5C-9FBE-11D0-8965-0000F822DEA9}
  55. DEFINE_GUID(CLSID_WalletPayment, 0xb7fb4d5c, 0x9fbe, 0x11d0, 0x89, 0x65, 0x0, 0x0, 0xf8, 0x22, 0xde, 0xa9);
  56. #else
  57. // {87D3CB66-BA2E-11CF-B9D6-00A0C9083362}
  58. DEFINE_GUID(CLSID_WalletPayment, 0x87d3cb66, 0xba2e, 0x11cf, 0xb9, 0xd6, 0x0, 0xa0, 0xc9, 0x08, 0x33, 0x62);
  59. #endif
  60. // WAB GUID for JIT
  61. DEFINE_GUID(CLSID_WAB, 0x32714800, 0x2E5F, 0x11d0, 0x8B, 0x85, 0x00, 0xAA, 0x00, 0x44, 0xF9, 0x41);
  62. #define EKU_CODESIGN_OFF 0
  63. #define EKU_EMAIL_OFF 1
  64. #define EKU_CLIENT_OFF 2
  65. #define EKU_SERVER_OFF 3
  66. #define EKU_DISABLE_OFF 4
  67. const LPSTR g_rgszEnhkeyUsage[] =
  68. {
  69. szOID_PKIX_KP_CODE_SIGNING,
  70. szOID_PKIX_KP_EMAIL_PROTECTION,
  71. szOID_PKIX_KP_CLIENT_AUTH,
  72. szOID_PKIX_KP_SERVER_AUTH,
  73. szOID_YESNO_TRUST_ATTR,
  74. NULL
  75. };
  76. typedef struct {
  77. HWND hDlg; // handle to window
  78. HRESULT hrUseRatings; // error=not installed; S_OK=enabled; S_FALSE=disabled
  79. HINSTANCE hWinTrust; // WINTRUST/SOFTPUB library handle
  80. HINSTANCE hSChannel; // schannel library handle
  81. } CONTENTPAGE, *LPCONTENTPAGE;
  82. BOOL ContentDlgApplyNow( LPCONTENTPAGE pCon );
  83. BOOL ContentDlgEnableControls( IN HWND hDlg );
  84. BOOL ContentDlgInit( IN HWND hDlg );
  85. VOID DisplayWalletPaymentDialog(HWND hWnd);
  86. VOID DisplayWalletAddressDialog(HWND hWnd);
  87. STDAPI ResetProfileSharing(HWND hwnd);
  88. EXTERN_C HRESULT ClearAutoSuggestForForms(DWORD dwClear);
  89. //
  90. // SecurityDlgEnableControls()
  91. //
  92. // Does initalization for Security Dlg.
  93. //
  94. // History:
  95. //
  96. // 6/17/96 t-gpease moved
  97. //
  98. BOOL ContentDlgEnableControls( IN HWND hDlg )
  99. {
  100. HKEY hkey=NULL;
  101. if( g_restrict.fRatings )
  102. {
  103. EnableWindow( GetDlgItem(hDlg, IDC_RATINGS_TURN_ON), FALSE );
  104. EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_RATINGS_BUTTON), FALSE );
  105. #if 0 // don't diable the text
  106. EnableDlgItem( hDlg, IDC_RATINGS_TEXT, FALSE);
  107. EnableDlgItem( hDlg, IDC_ADVANCED_RATINGS_GROUPBOX, FALSE);
  108. #endif
  109. }
  110. if( g_restrict.fCertif || g_restrict.fCertifPub)
  111. EnableWindow( GetDlgItem(hDlg, IDC_SECURITY_PUBLISHERS_BUTTON), FALSE );
  112. if( g_restrict.fCertif || g_restrict.fCertifPers || g_restrict.fCertifSite)
  113. EnableWindow( GetDlgItem(hDlg, IDC_SECURITY_SITES_BUTTON), FALSE );
  114. if( g_restrict.fProfiles )
  115. {
  116. EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PROFILE), FALSE);
  117. }
  118. if (hkey)
  119. RegCloseKey(hkey);
  120. #ifdef WALLET
  121. if (g_restrict.fWallet)
  122. {
  123. EnableWindow(GetDlgItem(hDlg, IDC_PROGRAMS_WALLET_SETTINGS), FALSE);
  124. }
  125. #endif
  126. return TRUE;
  127. }
  128. void InitRatingsButton(HWND hDlg, HRESULT hrEnabled)
  129. {
  130. TCHAR szBuf[MAX_RES_LEN+1];
  131. UINT idString;
  132. BOOL fEnableSettingsButton;
  133. if (FAILED(hrEnabled)) {
  134. /* Ratings are not installed. Disable the Settings button and
  135. * set the other button to say "Enable".
  136. */
  137. idString = IDS_RATINGS_TURN_ON;
  138. fEnableSettingsButton = FALSE;
  139. }
  140. else {
  141. idString = (hrEnabled == S_OK) ? IDS_RATINGS_TURN_OFF : IDS_RATINGS_TURN_ON;
  142. fEnableSettingsButton = TRUE;
  143. }
  144. EnableWindow(GetDlgItem(hDlg, IDC_ADVANCED_RATINGS_BUTTON), fEnableSettingsButton);
  145. if (MLLoadString(
  146. idString,
  147. szBuf, sizeof(szBuf)) > 0) {
  148. SetDlgItemText(hDlg, IDC_RATINGS_TURN_ON, szBuf);
  149. }
  150. }
  151. //
  152. // ContentDlgInit()
  153. //
  154. // Does initalization for Content Dlg.
  155. //
  156. //
  157. BOOL ContentDlgInit( HWND hDlg)
  158. {
  159. LPCONTENTPAGE pCon;
  160. pCon = (LPCONTENTPAGE)LocalAlloc(LPTR, sizeof(*pCon));
  161. if (!pCon)
  162. {
  163. EndDialog(hDlg, 0);
  164. return FALSE; // no memory?
  165. }
  166. // tell dialog where to get info
  167. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pCon);
  168. // save the handle to the page
  169. pCon->hDlg = hDlg;
  170. // Load the Ratings DLL (if possible)
  171. g_hinstRatings = LoadLibrary(c_tszRatingsDLL);
  172. // if not..
  173. if (!g_hinstRatings)
  174. g_restrict.fRatings = TRUE; // disable Ratings section
  175. // set ratings dialog items...
  176. // if MSRATING.DLL not around, then don't do this call. By not
  177. // doing this, it will keep the "Enable Ratings" text on the button
  178. // but greyed off.
  179. if (g_hinstRatings)
  180. pCon->hrUseRatings = RatingEnabledQuery();
  181. InitRatingsButton(hDlg, pCon->hrUseRatings);
  182. // if we can't find WINTRUST or SOFTPUB disable the
  183. // "Publishers" button.
  184. pCon->hWinTrust = LoadLibrary(TEXT("wintrust.dll"));
  185. if ( pCon->hWinTrust )
  186. {
  187. g_WinTrustDlgProc =
  188. (WINTRUSTDLGPROC) GetProcAddress(pCon->hWinTrust, "OpenPersonalTrustDBDialog");
  189. // didn't find the procecdure
  190. if (!g_WinTrustDlgProc)
  191. {
  192. // release library and try the other DLL.
  193. FreeLibrary(pCon->hWinTrust);
  194. //
  195. // We can also find the same function on NT machines (and
  196. // possibly future Win95s) in SOFTPUB.DLL so make another
  197. // check there too.
  198. //
  199. pCon->hWinTrust = LoadLibrary(TEXT("softpub.dll"));
  200. }
  201. }
  202. if (pCon->hWinTrust && !g_WinTrustDlgProc)
  203. g_WinTrustDlgProc = (WINTRUSTDLGPROC)
  204. GetProcAddress(pCon->hWinTrust, "OpenPersonalTrustDBDialog");
  205. // if after all this, we can't find the procedure...
  206. if (!g_WinTrustDlgProc)
  207. {
  208. // disable the button
  209. EnableDlgItem(hDlg, IDC_SECURITY_PUBLISHERS_BUTTON, FALSE);
  210. }
  211. // Only present UI for flushing the SSL cache on Whistler or greater
  212. // This is the minimum version which has the default behavior of
  213. // maintaining the SSL cache for all processes in a logon session.
  214. //
  215. // Note: This support was also added for Win2K SP2, but no cache
  216. // clearing functionality was added. It's also not enabled
  217. // by default.
  218. if (IsOS(OS_WHISTLERORGREATER))
  219. {
  220. pCon->hSChannel = LoadLibrary(TEXT("SCHANNEL.DLL"));
  221. if (pCon->hSChannel)
  222. {
  223. g_pfnSslEmptyCacheW = (SSL_EMPTY_CACHE_FN_W) GetProcAddress(pCon->hSChannel, "SslEmptyCacheW");
  224. }
  225. }
  226. if(!g_pfnSslEmptyCacheW)
  227. {
  228. ShowWindow(GetDlgItem(hDlg, IDC_SECURITY_CLEAR_SSL_CACHE_BUTTON), SW_HIDE);
  229. EnableWindow( GetDlgItem(hDlg, IDC_SECURITY_CLEAR_SSL_CACHE_BUTTON), FALSE );
  230. }
  231. #ifdef WALLET
  232. EnableDlgItem(hDlg, IDC_PROGRAMS_WALLET_SETTINGS, TRUE);
  233. #endif
  234. ContentDlgEnableControls(hDlg);
  235. return TRUE;
  236. }
  237. //
  238. // ContentOnCommand()
  239. //
  240. // Handles Content Dialog's window messages
  241. //
  242. // History:
  243. //
  244. // 6/17/96 t-gpease created
  245. //
  246. void ContentOnCommand(LPCONTENTPAGE pCon, UINT id, UINT nCmd)
  247. {
  248. switch (id) {
  249. case IDC_ADVANCED_RATINGS_BUTTON:
  250. {
  251. RatingSetupUI(pCon->hDlg, (LPCSTR) NULL);
  252. }
  253. break; // IDC_ADVANCED_RATINGS_BUTTON
  254. case IDC_RATINGS_TURN_ON:
  255. {
  256. if (SUCCEEDED(RatingEnable(pCon->hDlg, (LPCSTR)NULL,
  257. pCon->hrUseRatings != S_OK)))
  258. {
  259. pCon->hrUseRatings = RatingEnabledQuery();
  260. InitRatingsButton(pCon->hDlg, pCon->hrUseRatings);
  261. }
  262. }
  263. break;
  264. case IDC_SECURITY_CLEAR_SSL_CACHE_BUTTON:
  265. {
  266. if (g_pfnSslEmptyCacheW && (*g_pfnSslEmptyCacheW)(NULL, 0))
  267. {
  268. DWORD dwCount;
  269. // Leverage a private cache header data counter
  270. // that was never used to avoid passing a reg value.
  271. if (IncrementUrlCacheHeaderData(CACHE_HEADER_DATA_DOWNLOAD_PARTIAL, &dwCount))
  272. {
  273. // Display message about clearing the cache OK.
  274. TCHAR szText[MAX_PATH], szTitle[80];
  275. MLLoadShellLangString(IDS_CLEAR_SSL_CACHE_TEXT, szText, ARRAYSIZE(szText));
  276. MLLoadShellLangString(IDS_CLEAR_SSL_CACHE_TITLE, szTitle, ARRAYSIZE(szTitle));
  277. MessageBox(pCon->hDlg, szText, szTitle, MB_ICONINFORMATION | MB_OK);
  278. }
  279. }
  280. }
  281. break;
  282. case IDC_SECURITY_SITES_BUTTON:
  283. {
  284. CRYPTUI_CERT_MGR_STRUCT ccm = {0};
  285. ccm.dwSize = sizeof(ccm);
  286. ccm.hwndParent = pCon->hDlg;
  287. CryptUIDlgCertMgr(&ccm);
  288. // if (!g_hinstCryptui)
  289. // {
  290. // EnableWindow(GetDlgItem(pCon->hDlg, IDC_SECURITY_SITES_BUTTON), FALSE);
  291. // }
  292. }
  293. break;
  294. case IDC_SECURITY_PUBLISHERS_BUTTON:
  295. {
  296. if (g_WinTrustDlgProc)
  297. {
  298. g_WinTrustDlgProc(pCon->hDlg);
  299. }
  300. }
  301. break;
  302. #ifdef WALLET
  303. case IDC_PROGRAMS_WALLET_SETTINGS:
  304. {
  305. HRESULT hr = S_OK;
  306. // See if wallet is installed at all
  307. if (!IsWalletPaymentAvailable())
  308. {
  309. uCLSSPEC clsspec;
  310. clsspec.tyspec = TYSPEC_CLSID;
  311. clsspec.tagged_union.clsid = CLSID_WalletPayment;
  312. // If wallet isn't installed, ask user if they'd like to install it
  313. hr = FaultInIEFeature(NULL, &clsspec, NULL, FIEF_FLAG_FORCE_JITUI);
  314. }
  315. if (SUCCEEDED(hr))
  316. {
  317. // Wallet is installed
  318. if (IsWallet3Installed())
  319. {
  320. // if wallet 3.0 is installed, we want to invoke the wallet UI directly
  321. DisplayWalletPaymentDialog(pCon->hDlg);
  322. }
  323. else
  324. {
  325. // otherwise we need to pop up this intermediate dialog
  326. DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_WALLET_SETTINGS), pCon->hDlg, WalletDlgProc);
  327. }
  328. }
  329. }
  330. break;
  331. #endif
  332. case IDC_AUTOSUGGEST_SETTINGS:
  333. {
  334. DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_AUTOSUGGEST_SETTINGS), pCon->hDlg, AutoSuggestDlgProc);
  335. }
  336. break;
  337. case IDC_EDIT_PROFILE:
  338. {
  339. HMODULE hInstWAB = NULL;
  340. LPWABOBJECT lpWABObject = NULL;
  341. LPADRBOOK lpAdrBook = NULL;
  342. HRESULT hr=S_OK;
  343. // Ask user to JIT in WAB if it's not installed
  344. uCLSSPEC clsspec;
  345. clsspec.tyspec = TYSPEC_CLSID;
  346. clsspec.tagged_union.clsid = CLSID_WAB;
  347. // If WAB isn't installed, ask user if they'd like to install it
  348. hr = FaultInIEFeature(NULL, &clsspec, NULL, FIEF_FLAG_FORCE_JITUI);
  349. if (FAILED(hr))
  350. {
  351. break;
  352. }
  353. // Figure out the location of the wab dll and try opening it.
  354. TCHAR szWABDllPath[MAX_PATH];
  355. DWORD dwType = 0;
  356. ULONG cbData = sizeof(szWABDllPath) * sizeof(TCHAR);
  357. HKEY hKey = NULL;
  358. SBinary SBMe = { 0, 0};
  359. *szWABDllPath = '\0';
  360. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey))
  361. {
  362. RegQueryValueEx( hKey, TEXT(""), NULL, &dwType, (LPBYTE) szWABDllPath, &cbData);
  363. RegCloseKey(hKey);
  364. }
  365. if (lstrlen(szWABDllPath) > 0 )
  366. {
  367. hInstWAB = LoadLibrary(szWABDllPath);
  368. }
  369. if (hInstWAB)
  370. {
  371. LPWABOPEN lpfnWABOpen = (LPWABOPEN) GetProcAddress(hInstWAB, "WABOpen");
  372. if (lpfnWABOpen)
  373. {
  374. hr = lpfnWABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  375. if (NULL == lpAdrBook || NULL == lpWABObject)
  376. hr = E_UNEXPECTED;
  377. }
  378. else
  379. {
  380. hr = HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND); // Not the right dll anyway!!
  381. }
  382. }
  383. else
  384. {
  385. hr = HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND);
  386. }
  387. DWORD dwAction = 0;
  388. // Good so far, call GetMe. WAB may create a new entry in this call.
  389. if (SUCCEEDED(hr))
  390. {
  391. hr = lpWABObject->GetMe(lpAdrBook, 0, &dwAction, &SBMe, 0);
  392. if (0 == SBMe.cb || NULL == SBMe.lpb)
  393. hr = E_UNEXPECTED;
  394. }
  395. // This shows the final UI. If WAB created a new entry in GetMe, they
  396. // already showed this UI and we don't need to do it again.
  397. if (SUCCEEDED(hr) && !(dwAction & WABOBJECT_ME_NEW))
  398. {
  399. hr = lpAdrBook->Details( (LPULONG) &pCon->hDlg,
  400. NULL,
  401. NULL,
  402. SBMe.cb,
  403. (LPENTRYID)SBMe.lpb,
  404. NULL,
  405. NULL,
  406. NULL,
  407. 0);
  408. }
  409. if (lpWABObject)
  410. {
  411. if (SBMe.lpb != NULL)
  412. lpWABObject->FreeBuffer(SBMe.lpb);
  413. lpWABObject->Release();
  414. }
  415. if (lpAdrBook)
  416. lpAdrBook->Release();
  417. if (hInstWAB)
  418. FreeLibrary(hInstWAB);
  419. }
  420. }
  421. } // ContentOnCommand()
  422. /****************************************************************
  423. Name: ContentDlgProc
  424. SYNOPSIS: Set various security issue settings.
  425. ****************************************************************/
  426. INT_PTR CALLBACK ContentDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  427. {
  428. LPCONTENTPAGE pCon;
  429. if (uMsg == WM_INITDIALOG)
  430. return ContentDlgInit( hDlg );
  431. else
  432. pCon = (LPCONTENTPAGE) GetWindowLongPtr(hDlg, DWLP_USER);
  433. if (!pCon)
  434. return FALSE;
  435. switch (uMsg)
  436. {
  437. case WM_COMMAND:
  438. ContentOnCommand(pCon, LOWORD(wParam), HIWORD(wParam));
  439. return TRUE;
  440. case WM_NOTIFY:
  441. {
  442. NMHDR *lpnm = (NMHDR *) lParam;
  443. ASSERT(lpnm);
  444. switch (lpnm->code) {
  445. case PSN_QUERYCANCEL:
  446. case PSN_KILLACTIVE:
  447. case PSN_RESET:
  448. SetWindowLongPtr( pCon->hDlg, DWLP_MSGRESULT, FALSE );
  449. return TRUE;
  450. case PSN_APPLY:
  451. break;
  452. }
  453. break;
  454. }
  455. case WM_HELP: // F1
  456. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  457. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  458. break;
  459. case WM_CONTEXTMENU: // right mouse click
  460. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  461. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  462. break;
  463. case WM_DESTROY:
  464. ASSERT(pCon);
  465. if (pCon)
  466. {
  467. if (pCon->hWinTrust)
  468. {
  469. FreeLibrary(pCon->hWinTrust);
  470. g_WinTrustDlgProc = NULL;
  471. }
  472. if (pCon->hSChannel)
  473. {
  474. FreeLibrary(pCon->hSChannel);
  475. g_pfnSslEmptyCacheW = NULL;
  476. }
  477. LocalFree(pCon);
  478. }
  479. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NULL);
  480. break;
  481. }
  482. return FALSE;
  483. }
  484. typedef struct tagSITECERTDIALOGINFO {
  485. HWND hDlg;
  486. HWND hwndList;
  487. HWND hwndCombo;
  488. int iSel;
  489. HCERTSTORE hCertStore;
  490. BOOL fInitializing;
  491. } SITECERTDIALOGINFO, *LPSITECERTDIALOGINFO;
  492. BOOL _SearchKeyUsage(CERT_ENHKEY_USAGE *pUsage, LPSTR pszUsageIdentifier)
  493. {
  494. DWORD i;
  495. for (i = 0; i < pUsage->cUsageIdentifier; i++)
  496. {
  497. if (StrCmpA(pUsage->rgpszUsageIdentifier[i], pszUsageIdentifier) == 0)
  498. {
  499. return(TRUE);
  500. }
  501. }
  502. return(FALSE);
  503. }
  504. BOOL _IsKnownUsage(char *pszTest)
  505. {
  506. char **ppszKnown;
  507. ppszKnown = (char **)g_rgszEnhkeyUsage;
  508. while (*ppszKnown)
  509. {
  510. if (StrCmpA(*ppszKnown, pszTest) == 0)
  511. {
  512. return(TRUE);
  513. }
  514. ppszKnown++;
  515. }
  516. return(FALSE);
  517. }
  518. void __AddAllKnownEKU(PCCERT_CONTEXT pCert)
  519. {
  520. char **ppszKnown;
  521. ppszKnown = (char **)g_rgszEnhkeyUsage;
  522. while (*ppszKnown)
  523. {
  524. CertAddEnhancedKeyUsageIdentifier(pCert, *ppszKnown);
  525. ppszKnown++;
  526. }
  527. }
  528. BOOL _AnyKnownUsage(CERT_ENHKEY_USAGE *pUsage)
  529. {
  530. DWORD i;
  531. for (i = 0; i < pUsage->cUsageIdentifier; i++)
  532. {
  533. if (_IsKnownUsage(pUsage->rgpszUsageIdentifier[i]))
  534. {
  535. return(TRUE);
  536. }
  537. }
  538. return(FALSE);
  539. }
  540. BOOL _IsUsageEnabled(PCCERT_CONTEXT pCertContext, LPSTR pszUsageIdentifier, BOOL * pfFound)
  541. {
  542. CERT_ENHKEY_USAGE *pUsage;
  543. DWORD cbUsage;
  544. *pfFound = FALSE;
  545. //
  546. // first, check the Extensions to see if we should even display it!
  547. //
  548. cbUsage = 0;
  549. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
  550. if (cbUsage > 0)
  551. {
  552. //
  553. // we have some... make sure ours is in the list
  554. //
  555. if (!(pUsage = (CERT_ENHKEY_USAGE *)LocalAlloc(LPTR, cbUsage)))
  556. {
  557. return(FALSE);
  558. }
  559. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &cbUsage);
  560. if (!(_SearchKeyUsage(pUsage, pszUsageIdentifier)))
  561. {
  562. LocalFree((void *)pUsage);
  563. return(FALSE);
  564. }
  565. LocalFree((void *)pUsage);
  566. }
  567. *pfFound = TRUE; // the cert should go in the list!
  568. //
  569. // ethier there where no assertions made by the CA or we found it! continue on...
  570. //
  571. //
  572. // second, check the properties to see if we should check the box
  573. //
  574. cbUsage = 0;
  575. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
  576. if (cbUsage > 0)
  577. {
  578. //
  579. // we have properties... make sure we aren't disabled
  580. //
  581. if (!(pUsage = (CERT_ENHKEY_USAGE *)LocalAlloc(LPTR, cbUsage)))
  582. {
  583. return(FALSE);
  584. }
  585. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &cbUsage);
  586. if (_SearchKeyUsage(pUsage, g_rgszEnhkeyUsage[EKU_DISABLE_OFF]))
  587. {
  588. //
  589. // the user has disabled the cert... keep it in the list un-checked
  590. //
  591. LocalFree((void *)pUsage);
  592. return(FALSE);
  593. }
  594. if (!(_SearchKeyUsage(pUsage, pszUsageIdentifier)))
  595. {
  596. //
  597. // the user has set some, but, disabled this one... keep in the list un-checked
  598. //
  599. LocalFree((void *)pUsage);
  600. return(FALSE);
  601. }
  602. LocalFree((void *)pUsage);
  603. }
  604. return(TRUE);
  605. }
  606. BOOL SiteCert_InitListView(LPSITECERTDIALOGINFO pscdi)
  607. {
  608. PCCERT_CONTEXT pCertContext = NULL;
  609. // delete all items currently in the listview
  610. // we'll get called back via LVN_DELETEITEM with the lParam so we can free the cert context
  611. ListView_DeleteAllItems(pscdi->hwndList);
  612. pscdi->hCertStore = CertOpenSystemStoreA(NULL, "ROOT");
  613. if (pscdi->hCertStore)
  614. {
  615. LPSTR pszEnhkeyUsage;
  616. INT_PTR iSel;
  617. iSel = SendMessage(pscdi->hwndCombo, CB_GETCURSEL, 0,0);
  618. pszEnhkeyUsage = (LPSTR)SendMessage(pscdi->hwndCombo, CB_GETITEMDATA, iSel, 0);
  619. while (pCertContext = CertEnumCertificatesInStore(pscdi->hCertStore, pCertContext))
  620. {
  621. CHAR szCertA[MAX_PATH];
  622. TCHAR szCert[MAX_PATH];
  623. DWORD cbszCert = ARRAYSIZE(szCertA);
  624. DWORD dwEnabled;
  625. BOOL fFound;
  626. dwEnabled = _IsUsageEnabled(pCertContext, (LPSTR)pszEnhkeyUsage, &fFound);
  627. // if not found, then continue with next
  628. if (!fFound)
  629. continue;
  630. //ParseX509EncodedCertificateForListBoxEntry(pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, szCert, &cbszCert);
  631. ParseX509EncodedCertificateForListBoxEntry((BYTE *)pCertContext, -1, szCertA, &cbszCert);
  632. #ifdef UNICODE
  633. SHAnsiToUnicode(szCertA, szCert, ARRAYSIZE(szCert));
  634. #else
  635. StrCpy(szCert, szCertA);
  636. #endif
  637. LV_ITEM lvi = { 0 };
  638. lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
  639. lvi.iItem = -1;
  640. lvi.pszText = szCert; // (LPSTR)pCertContext->pCertInfo->Subject.pbData;
  641. lvi.cchTextMax = ARRAYSIZE(szCert); // pCertContext->pCertInfo->Subject.cbData;
  642. lvi.stateMask = LVIS_STATEIMAGEMASK;
  643. lvi.state = dwEnabled ? 0x00002000 : 0x00001000;
  644. lvi.lParam = (LPARAM)CertDuplicateCertificateContext(pCertContext);
  645. // insert and set state
  646. ListView_SetItemState(pscdi->hwndList,
  647. ListView_InsertItem(pscdi->hwndList, &lvi),
  648. dwEnabled ? 0x00002000 : 0x00001000,
  649. LVIS_STATEIMAGEMASK);
  650. }
  651. // show the items
  652. ListView_RedrawItems(pscdi->hwndList, 0, ListView_GetItemCount(pscdi->hwndList));
  653. }
  654. return TRUE;
  655. }
  656. //////////////////////////////////////////////////////////////////////////
  657. ////
  658. //// 08-Sep-1997: pberkman
  659. ////
  660. //// PRIVATE function: _SiteCertAdjustProperties
  661. ////
  662. //// based on what the user just checked/unchecked, set the
  663. //// appropriate OID usage or remove it.
  664. ////
  665. void _SiteCertAdjustProperties(LPSITECERTDIALOGINFO pscdi, NM_LISTVIEW *pListView)
  666. {
  667. DWORD_PTR dwSel;
  668. char *pszOID;
  669. DWORD cbUsage;
  670. CERT_ENHKEY_USAGE *pUsage;
  671. //
  672. // if we are in the initdialog get out!
  673. //
  674. if (pscdi->fInitializing)
  675. {
  676. return;
  677. }
  678. //
  679. // make sure we have the property set
  680. //
  681. dwSel = SendMessage(pscdi->hwndCombo, CB_GETCURSEL, 0, 0);
  682. if (dwSel == CB_ERR)
  683. {
  684. return;
  685. }
  686. pszOID = (char*) SendMessage(pscdi->hwndCombo, CB_GETITEMDATA, (WPARAM)dwSel, 0);
  687. if (!(pszOID) || ((DWORD_PTR)pszOID == CB_ERR))
  688. {
  689. return;
  690. }
  691. if (pListView->uNewState & 0x00001000) // unchecked
  692. {
  693. //
  694. // the user unchecked one of the certs.
  695. //
  696. // 1. if there are no properties, add all others -- HACKHACK!
  697. //
  698. cbUsage = 0;
  699. CertGetEnhancedKeyUsage((PCCERT_CONTEXT)pListView->lParam, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
  700. NULL, &cbUsage);
  701. if (cbUsage == 0)
  702. {
  703. // add all
  704. __AddAllKnownEKU((PCCERT_CONTEXT)pListView->lParam);
  705. // remove this one
  706. CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
  707. }
  708. else
  709. {
  710. if (!(pUsage = (CERT_ENHKEY_USAGE *)LocalAlloc(LPTR, cbUsage)))
  711. {
  712. return;
  713. }
  714. CertGetEnhancedKeyUsage((PCCERT_CONTEXT)pListView->lParam, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
  715. pUsage, &cbUsage);
  716. //
  717. // 2. if there are properties.
  718. // a. if this is the last known one, and it matches this, delete it and add the "disable"
  719. //
  720. if (pUsage->cUsageIdentifier == 1)
  721. {
  722. if (StrCmpA(pUsage->rgpszUsageIdentifier[0], pszOID) == 0)
  723. {
  724. CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
  725. CertAddEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam,
  726. g_rgszEnhkeyUsage[EKU_DISABLE_OFF]);
  727. }
  728. }
  729. else
  730. {
  731. //
  732. // b. if there are more than one, just try to remove this one
  733. //
  734. CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
  735. }
  736. LocalFree((void *)pUsage);
  737. }
  738. return;
  739. }
  740. if (pListView->uNewState & 0x00002000) // checked
  741. {
  742. CertAddEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
  743. //
  744. // just in case, remove the disable!
  745. //
  746. CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam,
  747. g_rgszEnhkeyUsage[EKU_DISABLE_OFF]);
  748. }
  749. }
  750. BOOL SiteCert_OnNotify(LPSITECERTDIALOGINFO pscdi, WPARAM wParam, LPARAM lParam)
  751. {
  752. NM_LISTVIEW *pnmlv = (NM_LISTVIEW *)lParam;
  753. switch (pnmlv->hdr.code) {
  754. case LVN_ITEMCHANGED:
  755. {
  756. // check the current state of selection
  757. int iSel = ListView_GetNextItem(pscdi->hwndList, -1, LVNI_SELECTED);
  758. // check to see if we need to enable/disable the "DELETE" and "VIEW" buttons
  759. EnableWindow(GetDlgItem(pscdi->hDlg, IDC_DELETECERT), iSel != -1);
  760. EnableWindow(GetDlgItem(pscdi->hDlg, IDC_VIEWCERT), iSel != -1);
  761. if ((pnmlv->uChanged & LVIF_STATE) && (GetFocus() == pscdi->hwndList))
  762. {
  763. _SiteCertAdjustProperties(pscdi, pnmlv);
  764. }
  765. break;
  766. }
  767. case LVN_DELETEITEM:
  768. CertFreeCertificateContext((PCCERT_CONTEXT)pnmlv->lParam);
  769. break;
  770. }
  771. return TRUE;
  772. }
  773. typedef struct tagNEWSITECERTINFO
  774. {
  775. LPVOID lpvCertData;
  776. DWORD cbCert;
  777. BOOL fCertEnabled;
  778. BOOL fNetworkClient;
  779. BOOL fNetworkServer;
  780. BOOL fSecureEmail;
  781. BOOL fSoftwarePublishing;
  782. } NEWSITECERTINFO, *LPNEWSITECERTINFO;
  783. BOOL NewSiteCert_AddCert(LPNEWSITECERTINFO pnsci)
  784. {
  785. HCERTSTORE hCertStore = NULL;
  786. PCCERT_CONTEXT pCertContext;
  787. BOOL fRet = FALSE;
  788. hCertStore = CertOpenSystemStoreA(NULL, "ROOT");
  789. if (hCertStore)
  790. {
  791. pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
  792. (LPBYTE)(pnsci->lpvCertData),
  793. pnsci->cbCert);
  794. if (pCertContext)
  795. {
  796. if (CertCompareCertificateName(X509_ASN_ENCODING,
  797. &pCertContext->pCertInfo->Subject,
  798. &pCertContext->pCertInfo->Issuer))
  799. {
  800. CertFreeCertificateContext(pCertContext);
  801. fRet = CertAddEncodedCertificateToStore(hCertStore,
  802. X509_ASN_ENCODING,
  803. (LPBYTE)(pnsci->lpvCertData),
  804. pnsci->cbCert,
  805. CERT_STORE_ADD_REPLACE_EXISTING,
  806. &pCertContext);
  807. if (fRet)
  808. {
  809. # define l_USAGE_MAX 24
  810. CERT_ENHKEY_USAGE ceku = {0};
  811. LPSTR rgpszUsageIdentifier[l_USAGE_MAX];
  812. if (pnsci->fNetworkClient)
  813. {
  814. rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_CLIENT_OFF];
  815. if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
  816. ceku.cUsageIdentifier++;
  817. }
  818. if (pnsci->fNetworkServer)
  819. {
  820. rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_SERVER_OFF];
  821. if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
  822. ceku.cUsageIdentifier++;
  823. }
  824. if (pnsci->fSecureEmail)
  825. {
  826. rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_EMAIL_OFF];
  827. if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
  828. ceku.cUsageIdentifier++;
  829. }
  830. if (pnsci->fSoftwarePublishing)
  831. {
  832. rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_CODESIGN_OFF];
  833. if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
  834. ceku.cUsageIdentifier++;
  835. }
  836. if (!(pnsci->fCertEnabled))
  837. {
  838. // turn everything off!!!
  839. rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_DISABLE_OFF];
  840. if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
  841. ceku.cUsageIdentifier++;
  842. }
  843. //
  844. // now, add any "unknown" extensions that the CA may have put on just
  845. // so verification will succeed!
  846. //
  847. CERT_ENHKEY_USAGE *pUsage;
  848. DWORD cbUsage;
  849. DWORD i;
  850. pUsage = NULL;
  851. cbUsage = 0;
  852. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
  853. if (cbUsage > 0)
  854. {
  855. if (pUsage = (PCERT_ENHKEY_USAGE)LocalAlloc(LMEM_FIXED, cbUsage))
  856. {
  857. CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
  858. pUsage, &cbUsage);
  859. for (i = 0; i < pUsage->cUsageIdentifier; i++)
  860. {
  861. if (ceku.cUsageIdentifier >= l_USAGE_MAX)
  862. {
  863. break;
  864. }
  865. if (pUsage->rgpszUsageIdentifier[i])
  866. {
  867. if (!(_IsKnownUsage(pUsage->rgpszUsageIdentifier[i])))
  868. {
  869. rgpszUsageIdentifier[ceku.cUsageIdentifier] = pUsage->rgpszUsageIdentifier[i];
  870. ceku.cUsageIdentifier++;
  871. }
  872. }
  873. }
  874. }
  875. }
  876. ceku.rgpszUsageIdentifier = (LPSTR *)rgpszUsageIdentifier;
  877. fRet = CertSetEnhancedKeyUsage(pCertContext, &ceku);
  878. if (pUsage)
  879. {
  880. LocalFree((void *)pUsage);
  881. }
  882. CertFreeCertificateContext(pCertContext);
  883. }
  884. }
  885. }
  886. CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG);
  887. }
  888. return fRet;
  889. }
  890. //////////////////////////////////////////////////////////////////////////
  891. ////
  892. //// 15-Aug-1997: pberkman
  893. ////
  894. //// PRIVATE function: NewSiteCert_SetAvailableAuthorityCheckboxes
  895. ////
  896. //// set the check boxes in the "New Site Certificate" dialog box
  897. //// based on the Authority Extensions and Properties.
  898. ////
  899. //// if there are no Authority Ext or Prop's, then the certificate
  900. //// has the potential for the user to enable for all. Otherwise,
  901. //// the user can ONLY select the ones that the issuer (or MS) has
  902. //// entrusted the certificate for.
  903. ////
  904. typedef struct l_CERTUSAGES_
  905. {
  906. char *pszOID;
  907. DWORD dwControlId;
  908. BOOL fEnabled;
  909. } l_CERTUSAGES;
  910. BOOL NewSiteCert_SetAvailableAuthorityCheckboxes(HWND hDlg, LPNEWSITECERTINFO pnsci,
  911. BOOL fInitialize)
  912. {
  913. l_CERTUSAGES asUsages[] =
  914. {
  915. szOID_PKIX_KP_CLIENT_AUTH, IDC_CHECK_NETWORK_CLIENT, FALSE,
  916. szOID_PKIX_KP_SERVER_AUTH, IDC_CHECK_NETWORK_SERVER, FALSE,
  917. szOID_PKIX_KP_EMAIL_PROTECTION, IDC_CHECK_SECURE_EMAIL, FALSE,
  918. szOID_PKIX_KP_CODE_SIGNING, IDC_CHECK_SOFTWARE_PUBLISHING, FALSE,
  919. NULL, 0, FALSE
  920. };
  921. l_CERTUSAGES *psUsages;
  922. PCCERT_CONTEXT pCertContext;
  923. DWORD cbUsage;
  924. PCERT_ENHKEY_USAGE pUsage;
  925. if (fInitialize)
  926. {
  927. CheckDlgButton(hDlg, IDC_CHECK_ENABLE_CERT, BST_CHECKED);
  928. CheckDlgButton(hDlg, IDC_CHECK_NETWORK_CLIENT, BST_CHECKED);
  929. CheckDlgButton(hDlg, IDC_CHECK_NETWORK_SERVER, BST_CHECKED);
  930. CheckDlgButton(hDlg, IDC_CHECK_SECURE_EMAIL, BST_CHECKED);
  931. CheckDlgButton(hDlg, IDC_CHECK_SOFTWARE_PUBLISHING, BST_CHECKED);
  932. }
  933. pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
  934. (LPBYTE)(pnsci->lpvCertData),
  935. pnsci->cbCert);
  936. if (!(pCertContext))
  937. {
  938. psUsages = &asUsages[0];
  939. while (psUsages->pszOID)
  940. {
  941. EnableWindow(GetDlgItem(hDlg, psUsages->dwControlId), TRUE);
  942. psUsages++;
  943. }
  944. return(FALSE);
  945. }
  946. cbUsage = 0;
  947. CertGetEnhancedKeyUsage(pCertContext, 0, NULL, &cbUsage);
  948. if (cbUsage < 1)
  949. {
  950. // none defined... leave all enabled.
  951. CertFreeCertificateContext(pCertContext);
  952. psUsages = &asUsages[0];
  953. while (psUsages->pszOID)
  954. {
  955. EnableWindow(GetDlgItem(hDlg, psUsages->dwControlId), TRUE);
  956. psUsages++;
  957. }
  958. return(TRUE);
  959. }
  960. if (!(pUsage = (PCERT_ENHKEY_USAGE)LocalAlloc(LMEM_FIXED, cbUsage)))
  961. {
  962. CertFreeCertificateContext(pCertContext);
  963. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  964. return(FALSE);
  965. }
  966. if (!(CertGetEnhancedKeyUsage(pCertContext, 0, pUsage, &cbUsage)))
  967. {
  968. CertFreeCertificateContext(pCertContext);
  969. LocalFree(pUsage);
  970. return(FALSE);
  971. }
  972. if (pUsage->cUsageIdentifier == 0)
  973. {
  974. CertFreeCertificateContext(pCertContext);
  975. LocalFree(pUsage);
  976. // none defined... leave all enabled.
  977. return(TRUE);
  978. }
  979. CertFreeCertificateContext(pCertContext);
  980. for (int i = 0; i < (int)pUsage->cUsageIdentifier; i++)
  981. {
  982. psUsages = &asUsages[0];
  983. while (psUsages->pszOID)
  984. {
  985. if (StrCmpA(pUsage->rgpszUsageIdentifier[i], psUsages->pszOID) == 0)
  986. {
  987. psUsages->fEnabled = TRUE;
  988. }
  989. psUsages++;
  990. }
  991. }
  992. LocalFree(pUsage);
  993. psUsages = &asUsages[0];
  994. while (psUsages->pszOID)
  995. {
  996. if (fInitialize)
  997. {
  998. CheckDlgButton(hDlg, psUsages->dwControlId,
  999. (psUsages->fEnabled) ? BST_CHECKED : BST_UNCHECKED);
  1000. }
  1001. EnableWindow(GetDlgItem(hDlg, psUsages->dwControlId), psUsages->fEnabled);
  1002. psUsages++;
  1003. }
  1004. return(TRUE);
  1005. }
  1006. void NewSiteCert_CenterDialog(HWND hDlg)
  1007. {
  1008. RECT rcDlg;
  1009. RECT rcArea;
  1010. RECT rcCenter;
  1011. HWND hWndParent;
  1012. HWND hWndCenter;
  1013. DWORD dwStyle;
  1014. int w_Dlg;
  1015. int h_Dlg;
  1016. int xLeft;
  1017. int yTop;
  1018. GetWindowRect(hDlg, &rcDlg);
  1019. dwStyle = (DWORD)GetWindowLong(hDlg, GWL_STYLE);
  1020. if (dwStyle & WS_CHILD)
  1021. {
  1022. hWndCenter = GetParent(hDlg);
  1023. hWndParent = GetParent(hDlg);
  1024. GetClientRect(hWndParent, &rcArea);
  1025. GetClientRect(hWndCenter, &rcCenter);
  1026. MapWindowPoints(hWndCenter, hWndParent, (POINT *)&rcCenter, 2);
  1027. }
  1028. else
  1029. {
  1030. hWndCenter = GetWindow(hDlg, GW_OWNER);
  1031. if (hWndCenter)
  1032. {
  1033. dwStyle = (DWORD)GetWindowLong(hWndCenter, GWL_STYLE);
  1034. if (!(dwStyle & WS_VISIBLE) || (dwStyle & WS_MINIMIZE))
  1035. {
  1036. hWndCenter = NULL;
  1037. }
  1038. }
  1039. SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
  1040. if (hWndCenter)
  1041. {
  1042. GetWindowRect(hWndCenter, &rcCenter);
  1043. }
  1044. else
  1045. {
  1046. rcCenter = rcArea;
  1047. }
  1048. }
  1049. w_Dlg = rcDlg.right - rcDlg.left;
  1050. h_Dlg = rcDlg.bottom - rcDlg.top;
  1051. xLeft = (rcCenter.left + rcCenter.right) / 2 - w_Dlg / 2;
  1052. yTop = (rcCenter.top + rcCenter.bottom) / 2 - h_Dlg / 2;
  1053. if (xLeft < rcArea.left)
  1054. {
  1055. xLeft = rcArea.left;
  1056. }
  1057. else if ((xLeft + w_Dlg) > rcArea.right)
  1058. {
  1059. xLeft = rcArea.right - w_Dlg;
  1060. }
  1061. if (yTop < rcArea.top)
  1062. {
  1063. yTop = rcArea.top;
  1064. }
  1065. else if ((yTop + h_Dlg) > rcArea.bottom)
  1066. {
  1067. yTop = rcArea.bottom - h_Dlg;
  1068. }
  1069. SetWindowPos(hDlg, NULL, xLeft, yTop, -1, -1, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
  1070. }
  1071. INT_PTR CALLBACK NewSiteCert_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  1072. {
  1073. LPNEWSITECERTINFO pnsci = (LPNEWSITECERTINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  1074. switch (uMsg) {
  1075. case WM_INITDIALOG:
  1076. {
  1077. DWORD dwFileSize;
  1078. DWORD cbRead;
  1079. HANDLE hf;
  1080. LPTSTR lpszCmdLine = (LPTSTR)lParam;
  1081. DWORD dwError;
  1082. hf = CreateFile(lpszCmdLine, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  1083. if (hf == INVALID_HANDLE_VALUE)
  1084. {
  1085. dwError = GetLastError();
  1086. goto initError;
  1087. }
  1088. dwFileSize = GetFileSize(hf, NULL);
  1089. if (dwFileSize == (unsigned)-1)
  1090. goto initError;
  1091. pnsci = (LPNEWSITECERTINFO)LocalAlloc(LPTR, sizeof(*pnsci));
  1092. if (!pnsci)
  1093. goto initError;
  1094. pnsci->lpvCertData = LocalAlloc(LPTR, dwFileSize);
  1095. if (!pnsci->lpvCertData)
  1096. goto initError;
  1097. pnsci->cbCert = dwFileSize;
  1098. if (!ReadFile(hf, pnsci->lpvCertData, dwFileSize, &cbRead, NULL) || cbRead != dwFileSize)
  1099. goto initError;
  1100. SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pnsci); // save pointer to cert
  1101. //
  1102. // ok check to make sure that 1) it's a cert file and 2) it's a root!
  1103. //
  1104. PCCERT_CONTEXT pCertContext;
  1105. dwError = S_FALSE;
  1106. pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
  1107. (LPBYTE)(pnsci->lpvCertData),
  1108. pnsci->cbCert);
  1109. if (pCertContext)
  1110. {
  1111. if (CertCompareCertificateName(X509_ASN_ENCODING,
  1112. &pCertContext->pCertInfo->Subject,
  1113. &pCertContext->pCertInfo->Issuer))
  1114. {
  1115. dwError = S_OK;
  1116. }
  1117. CertFreeCertificateContext(pCertContext);
  1118. }
  1119. if (dwError != S_OK)
  1120. {
  1121. goto initError;
  1122. }
  1123. NewSiteCert_SetAvailableAuthorityCheckboxes(hDlg, pnsci, TRUE);
  1124. NewSiteCert_CenterDialog(hDlg);
  1125. break;
  1126. initError:
  1127. TCHAR szTitle[MAX_PATH + 1];
  1128. TCHAR szError[MAX_PATH + 1];
  1129. MLLoadShellLangString(IDS_CERT_FILE_INVALID, &szError[0], MAX_PATH);
  1130. MLLoadShellLangString(IDS_ERROR, &szTitle[0], MAX_PATH);
  1131. MessageBox(GetFocus(), &szError[0], &szTitle[0], MB_OK | MB_ICONERROR);
  1132. EndDialog(hDlg, IDCANCEL);
  1133. return FALSE;
  1134. }
  1135. case WM_COMMAND:
  1136. switch (LOWORD(wParam))
  1137. {
  1138. case IDOK:
  1139. {
  1140. pnsci->fCertEnabled = IsDlgButtonChecked(hDlg, IDC_CHECK_ENABLE_CERT);
  1141. pnsci->fNetworkClient = IsDlgButtonChecked(hDlg, IDC_CHECK_NETWORK_CLIENT);
  1142. pnsci->fNetworkServer = IsDlgButtonChecked(hDlg, IDC_CHECK_NETWORK_SERVER);
  1143. pnsci->fSecureEmail = IsDlgButtonChecked(hDlg, IDC_CHECK_SECURE_EMAIL);
  1144. pnsci->fSoftwarePublishing = IsDlgButtonChecked(hDlg, IDC_CHECK_SOFTWARE_PUBLISHING);
  1145. NewSiteCert_AddCert(pnsci);
  1146. EndDialog(hDlg, IDOK);
  1147. break;
  1148. }
  1149. case IDCANCEL:
  1150. EndDialog(hDlg, IDCANCEL);
  1151. break;
  1152. case IDC_VIEWCERT:
  1153. ShowX509EncodedCertificate(hDlg, (LPBYTE)pnsci->lpvCertData, pnsci->cbCert);
  1154. break;
  1155. case IDC_CHECK_ENABLE_CERT:
  1156. if (HIWORD(wParam) == BN_CLICKED)
  1157. {
  1158. BOOL fEnableCert;
  1159. fEnableCert = IsDlgButtonChecked(hDlg, IDC_CHECK_ENABLE_CERT);
  1160. if (!(fEnableCert))
  1161. {
  1162. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_NETWORK_CLIENT), fEnableCert);
  1163. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_NETWORK_SERVER), fEnableCert);
  1164. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_SECURE_EMAIL), fEnableCert);
  1165. EnableWindow(GetDlgItem(hDlg, IDC_CHECK_SOFTWARE_PUBLISHING), fEnableCert);
  1166. }
  1167. else
  1168. {
  1169. NewSiteCert_SetAvailableAuthorityCheckboxes(hDlg, pnsci, FALSE);
  1170. }
  1171. }
  1172. return(FALSE);
  1173. default:
  1174. return FALSE;
  1175. }
  1176. return TRUE;
  1177. break;
  1178. case WM_HELP: // F1
  1179. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  1180. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1181. break;
  1182. case WM_CONTEXTMENU: // right mouse click
  1183. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  1184. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1185. break;
  1186. case WM_DESTROY:
  1187. if (pnsci)
  1188. {
  1189. if (pnsci->lpvCertData)
  1190. LocalFree(pnsci->lpvCertData);
  1191. LocalFree(pnsci);
  1192. }
  1193. break;
  1194. }
  1195. return FALSE;
  1196. }
  1197. STDAPI SiteCert_RunFromCmdLine(HINSTANCE hinst, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, int nCmdShow)
  1198. {
  1199. if ((!lpszCmdLine) || (*lpszCmdLine == TEXT('\0')))
  1200. return -1;
  1201. DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_NEWSITECERT),
  1202. NULL, NewSiteCert_DlgProc, (LPARAM)lpszCmdLine);
  1203. return 0;
  1204. }
  1205. // Helper function for ExportPFX
  1206. #define NUM_KNOWN_STORES 5
  1207. BOOL OpenAndAllocKnownStores(DWORD *pchStores, HCERTSTORE **ppahStores)
  1208. {
  1209. HCERTSTORE hStore;
  1210. int i;
  1211. static const LPCTSTR rszStoreNames[NUM_KNOWN_STORES] = {
  1212. TEXT("ROOT"),
  1213. TEXT("TRUST"),
  1214. TEXT("CA"),
  1215. TEXT("MY"),
  1216. TEXT("SPC")
  1217. };
  1218. *pchStores = 0;
  1219. if (NULL == ((*ppahStores) = (HCERTSTORE *) LocalAlloc(LPTR, sizeof(HCERTSTORE) * NUM_KNOWN_STORES)))
  1220. {
  1221. return (FALSE);
  1222. }
  1223. for (i=0; i< NUM_KNOWN_STORES; i++)
  1224. {
  1225. (*ppahStores)[i] = NULL;
  1226. if (hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
  1227. 0,
  1228. 0,
  1229. CERT_SYSTEM_STORE_CURRENT_USER |
  1230. CERT_STORE_READONLY_FLAG |
  1231. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  1232. rszStoreNames[i]))
  1233. (*ppahStores)[(*pchStores)++] = hStore;
  1234. }
  1235. return(TRUE);
  1236. }
  1237. // Helper function for ExportPFX
  1238. void CloseAndFreeKnownStores(HCERTSTORE *pahStores)
  1239. {
  1240. int i;
  1241. for (i=0; i<NUM_KNOWN_STORES; i++)
  1242. {
  1243. if (pahStores[i] != NULL)
  1244. {
  1245. CertCloseStore(pahStores[i], 0);
  1246. }
  1247. }
  1248. LocalFree(pahStores);
  1249. }
  1250. enum {PFX_IMPORT, PFX_EXPORT};
  1251. typedef struct
  1252. {
  1253. HWND hDlg; // handle to window
  1254. DWORD dwImportExport; // import or export?
  1255. BOOL fUseExisting; // use existing cert if collision on import
  1256. PCCERT_CONTEXT pCertContext; // context to export or NULL
  1257. LPWSTR pwszPassword; // password for import/export
  1258. LPWSTR pwszPassword2; // prompt user twice on exports!
  1259. LPTSTR pszPath; // file for import/export
  1260. } IMPORTEXPORT, *LPIMPORTEXPORT;
  1261. #define MAX_PASSWORD 32
  1262. // CreateCertFile: change working directory to "MyDocs", do CreateFile, restore old working directory
  1263. HANDLE CreateCertFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  1264. DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
  1265. {
  1266. TCHAR szOldDir[MAX_PATH];
  1267. TCHAR szCertDir[MAX_PATH];
  1268. HANDLE hFile;
  1269. LPITEMIDLIST pidl;
  1270. GetCurrentDirectory(ARRAYSIZE(szOldDir), szOldDir);
  1271. if (SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &pidl) == NOERROR)
  1272. {
  1273. SHGetPathFromIDList(pidl, szCertDir);
  1274. SetCurrentDirectory(szCertDir);
  1275. ILFree(pidl);
  1276. }
  1277. hFile = CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
  1278. dwCreationDistribution, dwFlagsAndAttributes, hTemplateFile);
  1279. SetCurrentDirectory(szOldDir);
  1280. return hFile;
  1281. }
  1282. //////////////////////////////////////////////////////////////////////////
  1283. //
  1284. // 09-Sep-1997 pberkman:
  1285. // determine if the exact cert is in the passed store
  1286. //
  1287. BOOL __IsCertInStore(PCCERT_CONTEXT pCertContext, HCERTSTORE hStore)
  1288. {
  1289. //
  1290. // can't do it the fast way -- do it the slow way!
  1291. //
  1292. BYTE *pbHash;
  1293. DWORD cbHash;
  1294. CRYPT_HASH_BLOB sBlob;
  1295. PCCERT_CONTEXT pWorkContext;
  1296. cbHash = 0;
  1297. if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, NULL, &cbHash)))
  1298. {
  1299. return(FALSE);
  1300. }
  1301. if (cbHash < 1)
  1302. {
  1303. return(FALSE);
  1304. }
  1305. if (!(pbHash = new BYTE[cbHash]))
  1306. {
  1307. return(FALSE);
  1308. }
  1309. if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pbHash, &cbHash)))
  1310. {
  1311. delete pbHash;
  1312. return(FALSE);
  1313. }
  1314. sBlob.cbData = cbHash;
  1315. sBlob.pbData = pbHash;
  1316. pWorkContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
  1317. CERT_FIND_SHA1_HASH, &sBlob, NULL);
  1318. delete pbHash;
  1319. if (pWorkContext)
  1320. {
  1321. CertFreeCertificateContext(pWorkContext);
  1322. return(TRUE);
  1323. }
  1324. return(FALSE);
  1325. }
  1326. //////////////////////////////////////////////////////////////////////////
  1327. //
  1328. // 09-Sep-1997 pberkman:
  1329. // importing a cert from a file.
  1330. //
  1331. BOOL ImportPFX(LPIMPORTEXPORT pImp)
  1332. {
  1333. # define MY_STORE 0
  1334. # define CA_STORE 1
  1335. # define ROOT_STORE 2
  1336. # define MAX_STORE 3
  1337. HCERTSTORE pahStores[MAX_STORE];
  1338. HCERTSTORE hCertStore;
  1339. BOOL fAdded;
  1340. DWORD dwAddFlags;
  1341. HANDLE hFile;
  1342. CRYPT_DATA_BLOB sData;
  1343. BOOL fRet;
  1344. PCCERT_CONTEXT pCertCtxt;
  1345. DWORD cbRead;
  1346. DWORD dwImportFlags;
  1347. int i;
  1348. fRet = FALSE;
  1349. dwImportFlags = CRYPT_EXPORTABLE;
  1350. pCertCtxt = NULL;
  1351. hCertStore = NULL;
  1352. for (i = 0; i < MAX_STORE; i++)
  1353. {
  1354. pahStores[i] = NULL;
  1355. }
  1356. ZeroMemory(&sData, sizeof(CRYPT_DATA_BLOB));
  1357. hFile = CreateCertFile(pImp->pszPath, GENERIC_READ, FILE_SHARE_READ,
  1358. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  1359. if (hFile == INVALID_HANDLE_VALUE)
  1360. {
  1361. goto Cleanup;
  1362. }
  1363. dwAddFlags = (pImp->fUseExisting) ? CERT_STORE_ADD_USE_EXISTING :
  1364. CERT_STORE_ADD_REPLACE_EXISTING;
  1365. sData.cbData = GetFileSize(hFile, NULL);
  1366. sData.pbData = (PBYTE)LocalAlloc(LMEM_FIXED, sData.cbData);
  1367. if (!(sData.pbData))
  1368. {
  1369. goto Cleanup;
  1370. }
  1371. if (!(ReadFile(hFile, sData.pbData, sData.cbData, &cbRead, NULL)))
  1372. {
  1373. goto Cleanup;
  1374. }
  1375. if ((pImp->pwszPassword) && (!(*pImp->pwszPassword))) // if no password, use null.
  1376. {
  1377. pImp->pwszPassword = NULL;
  1378. }
  1379. if (!(hCertStore = PFXImportCertStore(&sData, pImp->pwszPassword, dwImportFlags)))
  1380. {
  1381. goto Cleanup;
  1382. }
  1383. //
  1384. // now we have in memory hStore enumerate the cert contexts
  1385. // and drop them into destination store
  1386. //
  1387. if (!(pahStores[MY_STORE] = CertOpenSystemStoreA(NULL, "MY")) ||
  1388. !(pahStores[CA_STORE] = CertOpenSystemStoreA(NULL, "CA")) ||
  1389. !(pahStores[ROOT_STORE] = CertOpenSystemStoreA(NULL, "ROOT")))
  1390. {
  1391. goto Cleanup;
  1392. }
  1393. while (pCertCtxt = CertEnumCertificatesInStore(hCertStore, pCertCtxt))
  1394. {
  1395. fAdded = FALSE;
  1396. cbRead = 0;
  1397. CertGetCertificateContextProperty(pCertCtxt, CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbRead);
  1398. if (cbRead > 0) // pfx added a public key prop
  1399. {
  1400. CertAddCertificateContextToStore(pahStores[MY_STORE], pCertCtxt, dwAddFlags, NULL);
  1401. continue;
  1402. }
  1403. //
  1404. // first, check if we already have this cert in one of our stores
  1405. //
  1406. for (i = 0; i < MAX_STORE; i++)
  1407. {
  1408. if (__IsCertInStore(pCertCtxt, pahStores[i]))
  1409. {
  1410. //
  1411. // the same cert, exactly, is already in one of our stores!
  1412. //
  1413. fAdded = TRUE;
  1414. break;
  1415. }
  1416. }
  1417. if (!(fAdded))
  1418. {
  1419. CertAddCertificateContextToStore(pahStores[CA_STORE], pCertCtxt, dwAddFlags, NULL);
  1420. }
  1421. }
  1422. fRet = TRUE;
  1423. Cleanup:
  1424. if (sData.pbData)
  1425. {
  1426. LocalFree(sData.pbData);
  1427. }
  1428. if (hFile != INVALID_HANDLE_VALUE)
  1429. {
  1430. CloseHandle(hFile);
  1431. }
  1432. if (hCertStore)
  1433. {
  1434. CertCloseStore(hCertStore, 0);
  1435. }
  1436. for (i = 0; i < MAX_STORE; i++)
  1437. {
  1438. if (pahStores[i])
  1439. {
  1440. CertCloseStore(pahStores[i], 0);
  1441. }
  1442. }
  1443. return(fRet);
  1444. }
  1445. typedef PCCERT_CONTEXT (* PFNWTHELPER) (PCCERT_CONTEXT /* pChildContext */,
  1446. DWORD /* chStores */,
  1447. HCERTSTORE * /* pahStores */,
  1448. FILETIME * /* psftVerifyAsOf*/,
  1449. DWORD /* dwEncoding */,
  1450. DWORD * /* pdwConfidence */,
  1451. DWORD * /* pdwError */ );
  1452. BOOL ExportPFX(LPIMPORTEXPORT pImp)
  1453. {
  1454. BOOL fRet = FALSE;
  1455. HANDLE hFile = NULL;
  1456. CRYPT_DATA_BLOB sData;
  1457. DWORD cbRead;
  1458. HCERTSTORE hSrcCertStore;
  1459. DWORD dwExportFlags = 4; // 4 == EXPORT_PRIVATE_KEYS;
  1460. TCHAR szText[MAX_PATH], szTitle[80];
  1461. PCCERT_CONTEXT pTempCertContext;
  1462. HCERTSTORE *phCertStores = NULL;
  1463. DWORD chCertStores = 0;
  1464. DWORD dwConfidence;
  1465. DWORD dwError;
  1466. HINSTANCE hiWintrust = NULL;
  1467. PFNWTHELPER WTHelperCertFindIssuerCertificate;
  1468. if (!pImp->pCertContext)
  1469. return FALSE;
  1470. ZeroMemory(&sData, sizeof(CRYPT_DATA_BLOB));
  1471. // create an in memory store
  1472. hSrcCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY,
  1473. PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
  1474. 0,
  1475. 0,
  1476. NULL);
  1477. if (!CertAddCertificateContextToStore(hSrcCertStore, pImp->pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL))
  1478. goto Cleanup;
  1479. // Load helper function from wintrust.dll
  1480. hiWintrust = LoadLibrary(TEXT("WINTRUST.DLL"));
  1481. WTHelperCertFindIssuerCertificate = (PFNWTHELPER) GetProcAddress(hiWintrust,"WTHelperCertFindIssuerCertificate");
  1482. if (WTHelperCertFindIssuerCertificate)
  1483. {
  1484. // Load all the top level stores, so we can export from them if necessary
  1485. if (OpenAndAllocKnownStores(&chCertStores, &phCertStores))
  1486. {
  1487. // Find the intermediate certifcates, and add them to the store that we will be exporting
  1488. pTempCertContext = pImp->pCertContext;
  1489. while (NULL != ( pTempCertContext = WTHelperCertFindIssuerCertificate(pTempCertContext,
  1490. chCertStores,
  1491. phCertStores,
  1492. NULL,
  1493. X509_ASN_ENCODING,
  1494. &dwConfidence,
  1495. &dwError)))
  1496. {
  1497. CertAddCertificateContextToStore(hSrcCertStore, pTempCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
  1498. // Break out if we find a root (self-signed) cert
  1499. if (CertCompareCertificateName(X509_ASN_ENCODING,
  1500. &pTempCertContext->pCertInfo->Subject,
  1501. &pTempCertContext->pCertInfo->Issuer))
  1502. break;
  1503. }
  1504. CloseAndFreeKnownStores(phCertStores);
  1505. }
  1506. }
  1507. //
  1508. // This first call simply gets the size of the crypt blob
  1509. //
  1510. if (!PFXExportCertStore(hSrcCertStore, &sData, pImp->pwszPassword, dwExportFlags))
  1511. {
  1512. goto Cleanup;
  1513. }
  1514. // Alloc based on cbData
  1515. sData.pbData = (PBYTE)LocalAlloc(LMEM_FIXED, sData.cbData);
  1516. //
  1517. // Now actually get the data
  1518. //
  1519. if (!(*pImp->pwszPassword)) // no password use null
  1520. pImp->pwszPassword = NULL;
  1521. if (!PFXExportCertStore(hSrcCertStore, &sData, pImp->pwszPassword, dwExportFlags))
  1522. {
  1523. goto Cleanup;
  1524. }
  1525. // Open the PFX file
  1526. hFile = CreateCertFile(pImp->pszPath,
  1527. GENERIC_WRITE,
  1528. FILE_SHARE_READ,
  1529. NULL,
  1530. OPEN_ALWAYS,
  1531. FILE_ATTRIBUTE_NORMAL,
  1532. NULL);
  1533. if (hFile == INVALID_HANDLE_VALUE) {
  1534. goto Cleanup;
  1535. }
  1536. // Write to it
  1537. if (!WriteFile(hFile,
  1538. sData.pbData,
  1539. sData.cbData,
  1540. &cbRead,
  1541. NULL)) {
  1542. goto Cleanup;
  1543. }
  1544. // Display message about certs exporting OK.
  1545. MLLoadShellLangString(IDS_CERT_EXPORTOKTEXT, szText, ARRAYSIZE(szText));
  1546. MLLoadShellLangString(IDS_CERT_EXPORTOKTITLE, szTitle, ARRAYSIZE(szTitle));
  1547. MessageBox(pImp->hDlg, szText, szTitle, MB_ICONINFORMATION | MB_OK);
  1548. fRet = TRUE;
  1549. Cleanup:
  1550. if (hiWintrust)
  1551. FreeLibrary(hiWintrust);
  1552. if (hSrcCertStore)
  1553. CertCloseStore(hSrcCertStore, 0);
  1554. if (hFile != INVALID_HANDLE_VALUE)
  1555. CloseHandle(hFile);
  1556. if (sData.pbData)
  1557. LocalFree(sData.pbData);
  1558. return fRet;
  1559. }
  1560. INT_PTR CALLBACK ImportExportDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  1561. {
  1562. LPIMPORTEXPORT pImp;
  1563. if (uMsg == WM_INITDIALOG)
  1564. {
  1565. pImp = (LPIMPORTEXPORT)lParam; // this is passed in to us
  1566. if (!pImp)
  1567. {
  1568. EndDialog(hDlg, 0);
  1569. return FALSE;
  1570. }
  1571. // tell dialog where to get info
  1572. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pImp);
  1573. // save handle to the page
  1574. pImp->hDlg = hDlg;
  1575. // limit the password to 32 chars
  1576. SendMessage(GetDlgItem(hDlg, IDC_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0);
  1577. //
  1578. // 03-Oct-1997 pberkman: always verify password!
  1579. //
  1580. if (pImp->dwImportExport == PFX_EXPORT)
  1581. {
  1582. SendMessage(GetDlgItem(hDlg, IDC_PASSWORD2), EM_LIMITTEXT, MAX_PASSWORD, 0);
  1583. }
  1584. SHAutoComplete(GetDlgItem(hDlg, IDC_FILENAME), SHACF_DEFAULT); // This control exists in both IDD_PFX_IMPORT and IDD_PFX_EXPORT
  1585. // only set these on import, since they don't exist on export =)
  1586. // =========================================================================
  1587. // 03-Oct-1997 pberkman: no user decisions!
  1588. //
  1589. // if (pImp->dwImportExport == PFX_IMPORT)
  1590. // {
  1591. // CheckRadioButton(hDlg, IDC_USE_EXISTING, IDC_USE_FILE, IDC_USE_EXISTING);
  1592. // }
  1593. // ==========================================================================
  1594. SetFocus(GetDlgItem(hDlg, IDC_PASSWORD));
  1595. } // WM_INITDIALOG
  1596. else
  1597. pImp = (LPIMPORTEXPORT)GetWindowLongPtr(hDlg, DWLP_USER);
  1598. if (!pImp)
  1599. return FALSE;
  1600. switch (uMsg)
  1601. {
  1602. case WM_COMMAND:
  1603. switch (LOWORD(wParam))
  1604. {
  1605. case IDC_CERT_BROWSE:
  1606. {
  1607. TCHAR szFilenameBrowse[MAX_PATH];
  1608. TCHAR szExt[MAX_PATH];
  1609. TCHAR szFilter[MAX_PATH];
  1610. int ret;
  1611. LPITEMIDLIST pidl;
  1612. TCHAR szWorkingDir[MAX_PATH];
  1613. szFilenameBrowse[0] = 0;
  1614. MLLoadString(IDS_PFX_EXT, szExt, ARRAYSIZE(szExt));
  1615. int cchFilter = MLLoadString(IDS_PFX_FILTER, szFilter, ARRAYSIZE(szFilter)-1);
  1616. // Make sure we have a double null termination on the filter
  1617. szFilter[cchFilter + 1] = 0;
  1618. if (SHGetSpecialFolderLocation(hDlg, CSIDL_PERSONAL, &pidl) == NOERROR)
  1619. {
  1620. SHGetPathFromIDList(pidl, szWorkingDir);
  1621. ILFree(pidl);
  1622. }
  1623. ret = _AorW_GetFileNameFromBrowse(hDlg, szFilenameBrowse, ARRAYSIZE(szFilenameBrowse), szWorkingDir,
  1624. szExt, szFilter, NULL);
  1625. if (ret > 0)
  1626. {
  1627. SetDlgItemText(hDlg, IDC_FILENAME, szFilenameBrowse);
  1628. }
  1629. break;
  1630. }
  1631. case IDOK:
  1632. {
  1633. TCHAR szPassword[MAX_PASSWORD];
  1634. TCHAR szPassword2[MAX_PASSWORD];
  1635. TCHAR szPath[MAX_PATH];
  1636. BOOL bRet;
  1637. szPassword[0] = NULL;
  1638. GetWindowText(GetDlgItem(hDlg, IDC_PASSWORD), szPassword, ARRAYSIZE(szPassword));
  1639. GetWindowText(GetDlgItem(hDlg, IDC_FILENAME), szPath, ARRAYSIZE(szPath));
  1640. //
  1641. // 03-Oct-1997 pberkman: always double check password!
  1642. //
  1643. if (pImp->dwImportExport == PFX_EXPORT)
  1644. {
  1645. szPassword2[0] = NULL;
  1646. GetWindowText(GetDlgItem(hDlg, IDC_PASSWORD2), szPassword2, ARRAYSIZE(szPassword2));
  1647. if (StrCmp(szPassword, szPassword2) != 0)
  1648. {
  1649. TCHAR szTitle[MAX_PATH + 1];
  1650. TCHAR szError[MAX_PATH + 1];
  1651. MLLoadShellLangString(IDS_PASSWORDS_NOMATCH, &szError[0], MAX_PATH);
  1652. MLLoadShellLangString(IDS_ERROR, &szTitle[0], MAX_PATH);
  1653. MessageBox(GetFocus(), &szError[0], &szTitle[0], MB_OK | MB_ICONERROR);
  1654. SetFocus(GetDlgItem(hDlg, IDC_PASSWORD));
  1655. break;
  1656. }
  1657. }
  1658. // Add a default extension on export
  1659. if (pImp->dwImportExport == PFX_EXPORT)
  1660. if (szPath[0] != TEXT('\0') && PathAddExtension(szPath, TEXT(".PFX")))
  1661. SetWindowText(GetDlgItem(hDlg, IDC_FILENAME), szPath);
  1662. #ifndef UNICODE
  1663. WCHAR wszPassword[MAX_PASSWORD];
  1664. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPassword, -1, wszPassword, ARRAYSIZE(wszPassword));
  1665. pImp->pwszPassword = wszPassword;
  1666. #else
  1667. pImp->pwszPassword = szPassword;
  1668. #endif
  1669. pImp->pszPath = szPath;
  1670. if (pImp->dwImportExport == PFX_IMPORT)
  1671. {
  1672. // =========================================================================
  1673. // 03-Oct-1997 pberkman: no user decisions!
  1674. //
  1675. // pImp->fUseExisting = IsDlgButtonChecked(hDlg, IDC_USE_EXISTING);
  1676. // =========================================================================
  1677. pImp->fUseExisting = FALSE;
  1678. bRet = ImportPFX(pImp);
  1679. if (!(bRet) && (GetLastError() == NTE_BAD_DATA))
  1680. {
  1681. // message....
  1682. }
  1683. }
  1684. else
  1685. {
  1686. bRet = ExportPFX(pImp);
  1687. }
  1688. EndDialog(hDlg, bRet);
  1689. break;
  1690. }
  1691. case IDCANCEL:
  1692. EndDialog(hDlg, TRUE); // Cancel is not an error
  1693. break;
  1694. }
  1695. break;
  1696. case WM_NOTIFY:
  1697. break;
  1698. // No context sensitive help yet...
  1699. #if 0
  1700. case WM_HELP: // F1
  1701. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  1702. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1703. break;
  1704. case WM_CONTEXTMENU: // right mouse click
  1705. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  1706. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1707. break;
  1708. #endif
  1709. case WM_DESTROY:
  1710. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NULL);
  1711. break;
  1712. }
  1713. return FALSE;
  1714. }
  1715. #ifdef UNIX
  1716. EXTERN_C
  1717. #endif
  1718. INT_PTR ImportExportPFX(HWND hwndParent, DWORD dwImportExport, LPBYTE pbCert, DWORD cbCert)
  1719. {
  1720. IMPORTEXPORT imp;
  1721. if (pbCert)
  1722. {
  1723. CRYPT_HASH_BLOB hashBlob;
  1724. HCERTSTORE hMy = CertOpenSystemStoreA(NULL, "MY");
  1725. DWORD cbSHA1Hash;
  1726. LPBYTE pbSHA1Hash;
  1727. if (!hMy)
  1728. return FALSE;
  1729. if (CryptHashCertificate(NULL, 0, 0, pbCert, cbCert, NULL, &cbSHA1Hash))
  1730. {
  1731. pbSHA1Hash = (LPBYTE)LocalAlloc(LPTR, cbSHA1Hash);
  1732. if (!pbSHA1Hash)
  1733. return FALSE;
  1734. if (CryptHashCertificate(NULL, 0, 0, pbCert, cbCert, pbSHA1Hash, &cbSHA1Hash))
  1735. {
  1736. hashBlob.cbData = cbSHA1Hash;
  1737. hashBlob.pbData = pbSHA1Hash;
  1738. imp.pCertContext = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_HASH, &hashBlob, NULL);
  1739. if (!(imp.pCertContext))
  1740. return FALSE;
  1741. }
  1742. LocalFree(pbSHA1Hash);
  1743. }
  1744. CertCloseStore(hMy, 0);
  1745. }
  1746. imp.dwImportExport = dwImportExport;
  1747. return DialogBoxParam(MLGetHinst(),
  1748. dwImportExport == PFX_IMPORT ? MAKEINTRESOURCE(IDD_PFX_IMPORT) : MAKEINTRESOURCE(IDD_PFX_EXPORT),
  1749. hwndParent, ImportExportDlgProc, (LPARAM)&imp);
  1750. }
  1751. //BUBUG: The following function should be rermoved when we have updated our Crypto API to latest
  1752. BOOL WINAPI WTHelperIsInRootStore(PCCERT_CONTEXT pCertContext)
  1753. {
  1754. HCERTSTORE hStore;
  1755. if (!(hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
  1756. 0,
  1757. NULL,
  1758. CERT_SYSTEM_STORE_CURRENT_USER |
  1759. CERT_STORE_READONLY_FLAG |
  1760. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  1761. "ROOT")))
  1762. {
  1763. return(FALSE);
  1764. }
  1765. //
  1766. // can't do it the fast way -- do it the slow way!
  1767. //
  1768. BYTE *pbHash;
  1769. DWORD cbHash;
  1770. CRYPT_HASH_BLOB sBlob;
  1771. PCCERT_CONTEXT pWorkContext;
  1772. cbHash = 0;
  1773. if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, NULL, &cbHash)))
  1774. {
  1775. CertCloseStore(hStore, 0);
  1776. return(FALSE);
  1777. }
  1778. if (cbHash < 1)
  1779. {
  1780. CertCloseStore(hStore, 0);
  1781. return(FALSE);
  1782. }
  1783. if (!(pbHash = new BYTE[cbHash]))
  1784. {
  1785. CertCloseStore(hStore, 0);
  1786. return(FALSE);
  1787. }
  1788. if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pbHash, &cbHash)))
  1789. {
  1790. delete pbHash;
  1791. CertCloseStore(hStore, 0);
  1792. return(FALSE);
  1793. }
  1794. sBlob.cbData = cbHash;
  1795. sBlob.pbData = pbHash;
  1796. pWorkContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
  1797. CERT_FIND_SHA1_HASH, &sBlob, NULL);
  1798. delete pbHash;
  1799. if (pWorkContext)
  1800. {
  1801. CertFreeCertificateContext(pWorkContext);
  1802. CertCloseStore(hStore, 0);
  1803. return(TRUE);
  1804. }
  1805. CertCloseStore(hStore, 0);
  1806. return(FALSE);
  1807. }
  1808. //============================================================================
  1809. const TCHAR c_szRegKeySMIEM[] = TEXT("Software\\Microsoft\\Internet Explorer\\Main");
  1810. const TCHAR c_szRegValFormSuggest[] = TEXT("Use FormSuggest");
  1811. const TCHAR c_szRegValFormSuggestPW[] = TEXT("FormSuggest Passwords");
  1812. const TCHAR c_szRegValFormSuggestPWAsk[] = TEXT("FormSuggest PW Ask");
  1813. const TCHAR c_szYes[] = TEXT("yes");
  1814. const TCHAR c_szNo[] = TEXT("no");
  1815. inline void SetValueHelper(HWND hDlg, int id, LPTSTR *ppszData, DWORD *pcbData)
  1816. {
  1817. if (IsDlgButtonChecked(hDlg, id))
  1818. {
  1819. *ppszData = (LPTSTR)c_szYes;
  1820. *pcbData = sizeof(c_szYes);
  1821. }
  1822. else
  1823. {
  1824. *ppszData = (LPTSTR)c_szNo;
  1825. *pcbData = sizeof(c_szNo);
  1826. }
  1827. }
  1828. INT_PTR CALLBACK AutoSuggestDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1829. {
  1830. switch (uMsg)
  1831. {
  1832. case WM_INITDIALOG:
  1833. {
  1834. CheckDlgButton(hDlg, IDC_AUTOSUGGEST_ENABLEADDR,
  1835. (SHRegGetBoolUSValue(REGSTR_PATH_AUTOCOMPLETE, REGSTR_VAL_USEAUTOSUGGEST, FALSE, /*default:*/TRUE)) ?
  1836. BST_CHECKED : BST_UNCHECKED);
  1837. if (g_restrict.fFormSuggest)
  1838. {
  1839. EnableDlgItem(hDlg, IDC_AUTOSUGGEST_ENABLEFORM, FALSE);
  1840. }
  1841. else
  1842. {
  1843. CheckDlgButton(hDlg, IDC_AUTOSUGGEST_ENABLEFORM,
  1844. (SHRegGetBoolUSValue(c_szRegKeySMIEM, c_szRegValFormSuggest, FALSE, /*default:*/FALSE)) ?
  1845. BST_CHECKED : BST_UNCHECKED);
  1846. }
  1847. if (g_restrict.fFormPasswords)
  1848. {
  1849. EnableDlgItem(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS, FALSE);
  1850. EnableDlgItem(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS, FALSE);
  1851. }
  1852. else
  1853. {
  1854. CheckDlgButton(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS,
  1855. (SHRegGetBoolUSValue(c_szRegKeySMIEM, c_szRegValFormSuggestPWAsk, FALSE, /*default:*/TRUE)) ?
  1856. BST_CHECKED : BST_UNCHECKED);
  1857. if (SHRegGetBoolUSValue(c_szRegKeySMIEM, c_szRegValFormSuggestPW, FALSE, /*default:*/TRUE))
  1858. {
  1859. CheckDlgButton(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS, BST_CHECKED);
  1860. }
  1861. else
  1862. {
  1863. EnableDlgItem(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS, FALSE);
  1864. }
  1865. }
  1866. }
  1867. return TRUE;
  1868. case WM_COMMAND:
  1869. {
  1870. switch (LOWORD(wParam))
  1871. {
  1872. case IDC_AUTOSUGGEST_SAVEPASSWORDS:
  1873. EnableDlgItem(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS,
  1874. IsDlgButtonChecked(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS));
  1875. break;
  1876. case IDC_AUTOSUGGEST_CLEARFORM:
  1877. case IDC_AUTOSUGGEST_CLEARPASSWORDS:
  1878. {
  1879. BOOL fPasswords = (LOWORD(wParam) == IDC_AUTOSUGGEST_CLEARPASSWORDS);
  1880. DWORD dwClear = (fPasswords) ?
  1881. IECMDID_ARG_CLEAR_FORMS_PASSWORDS_ONLY : IECMDID_ARG_CLEAR_FORMS_ALL_BUT_PASSWORDS;
  1882. if (IDOK == MsgBox(hDlg, ((fPasswords) ? IDS_CLEAR_FORMPASSWORDS : IDS_CLEAR_FORMSUGGEST), MB_ICONQUESTION, MB_OKCANCEL))
  1883. {
  1884. HCURSOR hOldCursor = NULL;
  1885. HCURSOR hNewCursor = NULL;
  1886. #ifndef UNIX
  1887. hNewCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));
  1888. #else
  1889. // IEUNIX - Getting rid of redundant MAKEINTRESOURCE
  1890. hNewCursor = LoadCursor(NULL, IDC_WAIT);
  1891. #endif
  1892. if (hNewCursor)
  1893. hOldCursor = SetCursor(hNewCursor);
  1894. // Clear all strings
  1895. ClearAutoSuggestForForms(dwClear);
  1896. // Also reset profile assistant sharing (very discoverable here)
  1897. if (!g_restrict.fProfiles)
  1898. {
  1899. ResetProfileSharing(hDlg);
  1900. }
  1901. if(hOldCursor)
  1902. SetCursor(hOldCursor);
  1903. }
  1904. }
  1905. break;
  1906. case IDOK:
  1907. {
  1908. DWORD cbData; LPTSTR pszData;
  1909. SetValueHelper(hDlg, IDC_AUTOSUGGEST_ENABLEADDR, &pszData, &cbData);
  1910. SHSetValue(HKEY_CURRENT_USER, REGSTR_PATH_AUTOCOMPLETE, REGSTR_VAL_USEAUTOSUGGEST,
  1911. REG_SZ, pszData, cbData);
  1912. if (!g_restrict.fFormSuggest)
  1913. {
  1914. SetValueHelper(hDlg, IDC_AUTOSUGGEST_ENABLEFORM, &pszData, &cbData);
  1915. SHSetValue(HKEY_CURRENT_USER, c_szRegKeySMIEM, c_szRegValFormSuggest,
  1916. REG_SZ, pszData, cbData);
  1917. }
  1918. if (!g_restrict.fFormPasswords)
  1919. {
  1920. SetValueHelper(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS, &pszData, &cbData);
  1921. SHSetValue(HKEY_CURRENT_USER, c_szRegKeySMIEM, c_szRegValFormSuggestPW,
  1922. REG_SZ, pszData, cbData);
  1923. SetValueHelper(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS, &pszData, &cbData);
  1924. SHSetValue(HKEY_CURRENT_USER, c_szRegKeySMIEM, c_szRegValFormSuggestPWAsk,
  1925. REG_SZ, pszData, cbData);
  1926. }
  1927. }
  1928. // fall through
  1929. case IDCANCEL:
  1930. {
  1931. EndDialog(hDlg, LOWORD(wParam));
  1932. }
  1933. break;
  1934. }
  1935. }
  1936. return TRUE;
  1937. case WM_HELP: // F1
  1938. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  1939. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1940. break;
  1941. case WM_CONTEXTMENU: // right mouse click
  1942. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  1943. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1944. break;
  1945. case WM_DESTROY:
  1946. break;
  1947. }
  1948. return FALSE;
  1949. }
  1950. #ifdef WALLET
  1951. // This intermediate dialog is only displayed for wallet 2.x users
  1952. INT_PTR CALLBACK WalletDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1953. {
  1954. switch (uMsg)
  1955. {
  1956. case WM_INITDIALOG:
  1957. {
  1958. EnableDlgItem(hDlg, IDC_PROGRAMS_WALLET_PAYBUTTON, IsWalletPaymentAvailable());
  1959. EnableDlgItem(hDlg, IDC_PROGRAMS_WALLET_ADDRBUTTON, IsWalletAddressAvailable());
  1960. }
  1961. return TRUE;
  1962. case WM_COMMAND:
  1963. {
  1964. switch (LOWORD(wParam))
  1965. {
  1966. case IDC_PROGRAMS_WALLET_PAYBUTTON:
  1967. DisplayWalletPaymentDialog(hDlg);
  1968. break;
  1969. case IDC_PROGRAMS_WALLET_ADDRBUTTON:
  1970. DisplayWalletAddressDialog(hDlg);
  1971. break;
  1972. case IDOK:
  1973. case IDCANCEL:
  1974. {
  1975. EndDialog(hDlg, LOWORD(wParam));
  1976. }
  1977. break;
  1978. }
  1979. }
  1980. return TRUE;
  1981. case WM_HELP: // F1
  1982. ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
  1983. HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1984. break;
  1985. case WM_CONTEXTMENU: // right mouse click
  1986. ResWinHelp( (HWND) wParam, IDS_HELPFILE,
  1987. HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
  1988. break;
  1989. case WM_DESTROY:
  1990. break;
  1991. }
  1992. return FALSE;
  1993. }
  1994. #endif