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.

910 lines
34 KiB

  1. //+---------------------------------------------------------------------------
  2. /////////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 2000-2002.
  6. //
  7. // File: SaferEntryCertificatePropertyPage.cpp
  8. //
  9. // Contents: Implementation of CSaferEntryCertificatePropertyPage
  10. //
  11. //----------------------------------------------------------------------------
  12. // SaferEntryCertificatePropertyPage.cpp : implementation file
  13. //
  14. #include "stdafx.h"
  15. #include <gpedit.h>
  16. #include <softpub.h>
  17. #include "compdata.h"
  18. #include "certmgr.h"
  19. #include "SaferEntryCertificatePropertyPage.h"
  20. #include "SaferUtil.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CSaferEntryCertificatePropertyPage property page
  28. CSaferEntryCertificatePropertyPage::CSaferEntryCertificatePropertyPage(
  29. CSaferEntry& rSaferEntry,
  30. CSaferEntries* pSaferEntries,
  31. LONG_PTR lNotifyHandle,
  32. LPDATAOBJECT pDataObject,
  33. bool bReadOnly,
  34. CCertMgrComponentData* pCompData,
  35. bool bNew,
  36. IGPEInformation* pGPEInformation,
  37. bool bIsMachine,
  38. bool* pbObjectCreated /* = 0 */) :
  39. CSaferPropertyPage(CSaferEntryCertificatePropertyPage::IDD, pbObjectCreated,
  40. pCompData, rSaferEntry, bNew, lNotifyHandle, pDataObject, bReadOnly,
  41. bIsMachine),
  42. m_bStoresEnumerated (false),
  43. m_bCertificateChanged (false),
  44. m_pCertContext (0),
  45. m_pSaferEntries (pSaferEntries),
  46. m_pOriginalStore (0),
  47. m_pGPEInformation (pGPEInformation),
  48. m_bFirst (true)
  49. {
  50. //{{AFX_DATA_INIT(CSaferEntryCertificatePropertyPage)
  51. // NOTE: the ClassWizard will add member initialization here
  52. //}}AFX_DATA_INIT
  53. // security review 2/25/2002 BryanWal ok
  54. ::ZeroMemory (&m_selCertStruct, sizeof (m_selCertStruct));
  55. if ( m_pSaferEntries )
  56. m_pSaferEntries->AddRef ();
  57. }
  58. CSaferEntryCertificatePropertyPage::~CSaferEntryCertificatePropertyPage()
  59. {
  60. // Clean up enumerated store list
  61. for (DWORD dwIndex = 0; dwIndex < m_selCertStruct.cDisplayStores; dwIndex++)
  62. {
  63. ASSERT (m_selCertStruct.rghDisplayStores);
  64. if ( m_selCertStruct.rghDisplayStores[dwIndex] )
  65. ::CertCloseStore (m_selCertStruct.rghDisplayStores[dwIndex], CERT_CLOSE_STORE_FORCE_FLAG);
  66. }
  67. if ( m_selCertStruct.rghDisplayStores )
  68. delete [] m_selCertStruct.rghDisplayStores;
  69. // if ( m_pCertContext )
  70. // CertFreeCertificateContext (m_pCertContext);
  71. if ( m_pSaferEntries )
  72. {
  73. m_pSaferEntries->Release ();
  74. m_pSaferEntries = 0;
  75. }
  76. if ( m_pOriginalStore )
  77. {
  78. m_pOriginalStore->Release ();
  79. m_pOriginalStore = 0;
  80. }
  81. }
  82. void CSaferEntryCertificatePropertyPage::DoDataExchange(CDataExchange* pDX)
  83. {
  84. CSaferPropertyPage::DoDataExchange(pDX);
  85. //{{AFX_DATA_MAP(CSaferEntryCertificatePropertyPage)
  86. DDX_Control(pDX, IDC_CERT_ENTRY_DESCRIPTION, m_descriptionEdit);
  87. DDX_Control(pDX, IDC_CERT_ENTRY_SECURITY_LEVEL, m_securityLevelCombo);
  88. //}}AFX_DATA_MAP
  89. }
  90. BEGIN_MESSAGE_MAP(CSaferEntryCertificatePropertyPage, CSaferPropertyPage)
  91. //{{AFX_MSG_MAP(CSaferEntryCertificatePropertyPage)
  92. ON_BN_CLICKED(IDC_CERT_ENTRY_BROWSE, OnCertEntryBrowse)
  93. ON_EN_CHANGE(IDC_CERT_ENTRY_DESCRIPTION, OnChangeCertEntryDescription)
  94. ON_CBN_SELCHANGE(IDC_CERT_ENTRY_SECURITY_LEVEL, OnSelchangeCertEntrySecurityLevel)
  95. ON_BN_CLICKED(IDC_SAFER_CERT_VIEW, OnSaferCertView)
  96. ON_EN_SETFOCUS(IDC_CERT_ENTRY_SUBJECT_NAME, OnSetfocusCertEntrySubjectName)
  97. //}}AFX_MSG_MAP
  98. END_MESSAGE_MAP()
  99. /////////////////////////////////////////////////////////////////////////////
  100. // CSaferEntryCertificatePropertyPage message handlers
  101. void CSaferEntryCertificatePropertyPage::DoContextHelp (HWND hWndControl)
  102. {
  103. _TRACE (1, L"Entering CSaferEntryCertificatePropertyPage::DoContextHelp\n");
  104. static const DWORD help_map[] =
  105. {
  106. IDC_CERT_ENTRY_SUBJECT_NAME, IDH_CERT_ENTRY_SUBJECT_NAME,
  107. IDC_CERT_ENTRY_BROWSE, IDH_CERT_ENTRY_BROWSE,
  108. IDC_CERT_ENTRY_SECURITY_LEVEL, IDH_CERT_ENTRY_SECURITY_LEVEL,
  109. IDC_CERT_ENTRY_DESCRIPTION, IDH_CERT_ENTRY_DESCRIPTION,
  110. IDC_CERT_ENTRY_LAST_MODIFIED, IDH_CERT_ENTRY_LAST_MODIFIED,
  111. 0, 0
  112. };
  113. switch (::GetDlgCtrlID (hWndControl))
  114. {
  115. case IDC_CERT_ENTRY_SUBJECT_NAME:
  116. case IDC_CERT_ENTRY_BROWSE:
  117. case IDC_CERT_ENTRY_SECURITY_LEVEL:
  118. case IDC_CERT_ENTRY_DESCRIPTION:
  119. case IDC_CERT_ENTRY_LAST_MODIFIED:
  120. if ( !::WinHelp (
  121. hWndControl,
  122. GetF1HelpFilename(),
  123. HELP_WM_HELP,
  124. (DWORD_PTR) help_map) )
  125. {
  126. _TRACE (0, L"WinHelp () failed: 0x%x\n", GetLastError ());
  127. }
  128. break;
  129. default:
  130. break;
  131. }
  132. _TRACE (-1, L"Leaving CSaferEntryCertificatePropertyPage::DoContextHelp\n");
  133. }
  134. BOOL CSaferEntryCertificatePropertyPage::OnInitDialog()
  135. {
  136. CSaferPropertyPage::OnInitDialog();
  137. HRESULT hr = S_OK;
  138. DWORD dwLevelID = m_rSaferEntry.GetLevel ();
  139. ASSERT (SAFER_LEVELID_FULLYTRUSTED == dwLevelID || SAFER_LEVELID_DISALLOWED == dwLevelID);
  140. switch (dwLevelID)
  141. {
  142. case SAFER_LEVELID_FULLYTRUSTED:
  143. hr = m_pSaferEntries->GetTrustedPublishersStore (&m_pOriginalStore);
  144. break;
  145. case SAFER_LEVELID_DISALLOWED:
  146. hr = m_pSaferEntries->GetDisallowedStore (&m_pOriginalStore);
  147. break;
  148. default:
  149. break;
  150. }
  151. CPolicyKey policyKey (m_pGPEInformation,
  152. SAFER_HKLM_REGBASE,
  153. m_bIsMachine);
  154. InitializeSecurityLevelComboBox (m_securityLevelCombo, true, dwLevelID,
  155. policyKey.GetKey (), m_pCompData->m_pdwSaferLevels,
  156. m_bIsMachine);
  157. m_descriptionEdit.SetLimitText (SAFER_MAX_DESCRIPTION_SIZE-1);
  158. m_descriptionEdit.SetWindowText (m_rSaferEntry.GetDescription ());
  159. SetDlgItemText (IDC_CERT_ENTRY_LAST_MODIFIED, m_rSaferEntry.GetLongLastModified ());
  160. CCertificate* pCert = 0;
  161. hr = m_rSaferEntry.GetCertificate (&pCert);
  162. if ( SUCCEEDED (hr) && pCert )
  163. {
  164. ASSERT (!m_pCertContext);
  165. m_pCertContext = CertDuplicateCertificateContext (pCert->GetCertContext ());
  166. if ( m_pCertContext )
  167. SetDlgItemText (IDC_CERT_ENTRY_SUBJECT_NAME, ::GetNameString (m_pCertContext, 0));
  168. pCert->Release ();
  169. }
  170. if ( !m_pCertContext )
  171. {
  172. GetDlgItem (IDC_SAFER_CERT_VIEW)->EnableWindow (FALSE);
  173. GetDlgItem (IDC_CERT_ENTRY_SUBJECT_NAME)->EnableWindow (FALSE);
  174. GetDlgItem (IDC_CERT_ENTRY_SUBJECT_NAME_LABEL)->EnableWindow (FALSE);
  175. }
  176. if ( m_bReadOnly )
  177. {
  178. m_descriptionEdit.EnableWindow (FALSE);
  179. m_securityLevelCombo.EnableWindow (FALSE);
  180. GetDlgItem (IDC_CERT_ENTRY_BROWSE)->EnableWindow (FALSE);
  181. }
  182. if ( !m_bDirty )
  183. {
  184. CString szText;
  185. VERIFY (szText.LoadString (IDS_CERTIFICATE_TITLE));
  186. SetDlgItemText (IDC_CERTIFICATE_TITLE, szText);
  187. }
  188. else
  189. {
  190. GetDlgItem (IDC_DATE_LAST_MODIFIED_LABEL)->ShowWindow (SW_HIDE);
  191. GetDlgItem (IDC_CERT_ENTRY_LAST_MODIFIED)->ShowWindow (SW_HIDE);
  192. }
  193. GetDlgItem (IDC_CERT_ENTRY_BROWSE)->SetFocus ();
  194. return TRUE; // return TRUE unless you set the focus to a control
  195. // EXCEPTION: OCX Property Pages should return FALSE
  196. }
  197. typedef struct _ENUM_ARG {
  198. DWORD dwFlags;
  199. DWORD* pcDisplayStores;
  200. HCERTSTORE ** prghDisplayStores;
  201. } ENUM_ARG, *PENUM_ARG;
  202. static BOOL WINAPI EnumSaferStoresSysCallback(
  203. IN const void* pwszSystemStore,
  204. IN DWORD /*dwFlags*/,
  205. IN PCERT_SYSTEM_STORE_INFO /*pStoreInfo*/,
  206. IN OPTIONAL void * /*pvReserved*/,
  207. IN OPTIONAL void *pvArg
  208. )
  209. {
  210. PENUM_ARG pEnumArg = (PENUM_ARG) pvArg;
  211. void* pvPara = (void*)pwszSystemStore;
  212. HCERTSTORE hNewStore = ::CertOpenStore (CERT_STORE_PROV_SYSTEM,
  213. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL,
  214. CERT_SYSTEM_STORE_CURRENT_USER, pvPara);
  215. if ( !hNewStore )
  216. {
  217. hNewStore = ::CertOpenStore (CERT_STORE_PROV_SYSTEM,
  218. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL,
  219. CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, pvPara);
  220. }
  221. if ( hNewStore )
  222. {
  223. DWORD dwCnt = *(pEnumArg->pcDisplayStores);
  224. HCERTSTORE* phStores = 0;
  225. phStores = new HCERTSTORE[dwCnt+1];
  226. if ( phStores )
  227. {
  228. DWORD dwIndex = 0;
  229. if ( *(pEnumArg->prghDisplayStores) )
  230. {
  231. for (; dwIndex < dwCnt; dwIndex++)
  232. {
  233. phStores[dwIndex] = (*(pEnumArg->prghDisplayStores))[dwIndex];
  234. }
  235. delete [] (*(pEnumArg->prghDisplayStores));
  236. }
  237. (*(pEnumArg->pcDisplayStores))++;
  238. (*(pEnumArg->prghDisplayStores)) = phStores;
  239. (*(pEnumArg->prghDisplayStores))[dwIndex] = hNewStore;
  240. }
  241. else
  242. {
  243. SetLastError (ERROR_NOT_ENOUGH_MEMORY);
  244. return FALSE;
  245. }
  246. }
  247. return TRUE;
  248. }
  249. void CSaferEntryCertificatePropertyPage::OnCertEntryBrowse()
  250. {
  251. CString szFileFilter;
  252. VERIFY (szFileFilter.LoadString (IDS_SAFER_CERTFILEFILTER));
  253. // replace "|" with 0;
  254. // security review 2/25/2002 BryanWal ok
  255. const size_t nFilterLen = wcslen (szFileFilter) + 1; //+1 is for null-term
  256. PWSTR pszFileFilter = new WCHAR [nFilterLen];
  257. if ( pszFileFilter )
  258. {
  259. // security review 2/25/2002 BryanWal ok
  260. wcscpy (pszFileFilter, szFileFilter);
  261. for (int nIndex = 0; nIndex < nFilterLen; nIndex++)
  262. {
  263. if ( L'|' == pszFileFilter[nIndex] )
  264. pszFileFilter[nIndex] = 0;
  265. }
  266. WCHAR szFile[MAX_PATH];
  267. // security review 2/25/2002 BryanWal ok
  268. ::ZeroMemory (szFile, sizeof (szFile));
  269. OPENFILENAME ofn;
  270. // security review 2/25/2002 BryanWal ok
  271. ::ZeroMemory (&ofn, sizeof (ofn));
  272. ofn.lStructSize = sizeof (OPENFILENAME);
  273. ofn.hwndOwner = m_hWnd;
  274. ofn.lpstrFilter = (PCWSTR) pszFileFilter;
  275. ofn.lpstrFile = szFile;
  276. ofn.nMaxFile = MAX_PATH;
  277. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  278. BOOL bResult = ::GetOpenFileName (&ofn);
  279. if ( bResult )
  280. {
  281. CString szFileName = ofn.lpstrFile;
  282. //
  283. // Open cert store from the file
  284. //
  285. HCERTSTORE hCertStore = NULL;
  286. PVOID FileNameVoidP = (PVOID) (LPCWSTR)szFileName;
  287. PCCERT_CONTEXT pCertContext = NULL;
  288. DWORD dwEncodingType = 0;
  289. DWORD dwContentType = 0;
  290. DWORD dwFormatType = 0;
  291. BOOL bReturn = ::CryptQueryObject (
  292. CERT_QUERY_OBJECT_FILE,
  293. FileNameVoidP,
  294. CERT_QUERY_CONTENT_FLAG_ALL,
  295. CERT_QUERY_FORMAT_FLAG_ALL,
  296. 0,
  297. &dwEncodingType,
  298. &dwContentType,
  299. &dwFormatType,
  300. &hCertStore,
  301. NULL,
  302. (const void **)&pCertContext);
  303. if ( bReturn )
  304. {
  305. //
  306. // Success. See what we get back. A store or a cert.
  307. //
  308. if ( (dwContentType == CERT_QUERY_CONTENT_SERIALIZED_STORE)
  309. && hCertStore)
  310. {
  311. CERT_ENHKEY_USAGE enhKeyUsage;
  312. // security review 2/25/2002 BryanWal ok
  313. ::ZeroMemory (&enhKeyUsage, sizeof (enhKeyUsage));
  314. enhKeyUsage.cUsageIdentifier = 1;
  315. enhKeyUsage.rgpszUsageIdentifier[0] = szOID_EFS_RECOVERY;
  316. //
  317. // We get the certificate store
  318. //
  319. pCertContext = ::CertFindCertificateInStore (
  320. hCertStore,
  321. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  322. 0,
  323. CERT_FIND_ENHKEY_USAGE,
  324. &enhKeyUsage,
  325. NULL);
  326. if ( !pCertContext )
  327. {
  328. CString caption;
  329. CString text;
  330. CThemeContextActivator activator;
  331. VERIFY (text.LoadString (IDS_FILE_CONTAINS_NO_CERT));
  332. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  333. MessageBox (text, caption, MB_OK);
  334. }
  335. if ( hCertStore )
  336. ::CertCloseStore (hCertStore, 0);
  337. }
  338. else if ( CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED == dwContentType )
  339. {
  340. GetCertFromSignedFile (szFileName);
  341. }
  342. else if ( (dwContentType != CERT_QUERY_CONTENT_CERT) || !pCertContext )
  343. {
  344. //
  345. // Neither a valid cert file nor a store file we like.
  346. //
  347. if ( hCertStore )
  348. ::CertCloseStore (hCertStore, 0);
  349. if ( pCertContext )
  350. ::CertFreeCertificateContext (pCertContext);
  351. CString ErrMsg;
  352. CThemeContextActivator activator;
  353. VERIFY (ErrMsg.LoadString (IDS_CERTFILEFORMATERR));
  354. MessageBox (ErrMsg);
  355. return;
  356. }
  357. if ( pCertContext )
  358. {
  359. if ( m_pCertContext )
  360. CertFreeCertificateContext (m_pCertContext);
  361. m_pCertContext = pCertContext;
  362. if ( m_pCertContext )
  363. {
  364. SetDlgItemText (IDC_CERT_ENTRY_SUBJECT_NAME, ::GetNameString (m_pCertContext, 0));
  365. GetDlgItem (IDC_SAFER_CERT_VIEW)->EnableWindow (TRUE);
  366. GetDlgItem (IDC_CERT_ENTRY_SUBJECT_NAME)->EnableWindow (TRUE);
  367. GetDlgItem (IDC_CERT_ENTRY_SUBJECT_NAME_LABEL)->EnableWindow (TRUE);
  368. }
  369. m_bCertificateChanged = true;
  370. m_bDirty = true;
  371. SetModified ();
  372. }
  373. if ( hCertStore )
  374. {
  375. ::CertCloseStore (hCertStore, 0);
  376. hCertStore = NULL;
  377. }
  378. }
  379. else
  380. {
  381. GetCertFromSignedFile (szFileName);
  382. }
  383. }
  384. delete [] pszFileFilter;
  385. }
  386. }
  387. void CSaferEntryCertificatePropertyPage::GetCertFromSignedFile (const CString& szFilePath)
  388. {
  389. _TRACE (1, L"Entering CSaferEntryCertificatePropertyPage::GetCertFromSignedFile (%s)\n",
  390. (PCWSTR) szFilePath);
  391. // NTRAID# 477409 SAFER: New certificate rules can't pull a
  392. // certificate out of a file.
  393. DWORD dwErr = 0;
  394. DWORD dwUIChoice = WTD_UI_NONE;
  395. DWORD dwProvFlags = WTD_REVOCATION_CHECK_NONE;
  396. WINTRUST_FILE_INFO WinTrustFileInfo;
  397. WINTRUST_DATA WinTrustData;
  398. HRESULT hr = S_OK;
  399. GUID wvtProvGuid = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  400. // security review 2/25/2002 BryanWal ok
  401. ::ZeroMemory(&WinTrustFileInfo, sizeof(WinTrustFileInfo));
  402. ::ZeroMemory(&WinTrustData, sizeof(WinTrustData));
  403. //
  404. // Setup structure to call WVT.
  405. //
  406. WinTrustFileInfo.cbStruct = sizeof (WINTRUST_FILE_INFO);
  407. WinTrustFileInfo.pcwszFilePath = (PCWSTR) szFilePath;
  408. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  409. WinTrustData.dwUIChoice = dwUIChoice;
  410. WinTrustData.dwUnionChoice = WTD_CHOICE_FILE;
  411. WinTrustData.dwStateAction = WTD_STATEACTION_VERIFY;
  412. WinTrustData.pFile = &WinTrustFileInfo;
  413. WinTrustData.dwProvFlags = dwProvFlags;
  414. hr = ::WinVerifyTrust (NULL, &wvtProvGuid, &WinTrustData);
  415. if ( SUCCEEDED (hr) )
  416. {
  417. PCRYPT_PROVIDER_DATA pProvData =
  418. WTHelperProvDataFromStateData (
  419. WinTrustData.hWVTStateData);
  420. if ( pProvData )
  421. {
  422. PCRYPT_PROVIDER_SGNR pProvSigner =
  423. ::WTHelperGetProvSignerFromChain (pProvData, 0, FALSE, 0);
  424. if ( pProvSigner )
  425. {
  426. PCRYPT_PROVIDER_CERT pProvCert =
  427. ::WTHelperGetProvCertFromChain (pProvSigner, 0);
  428. if ( pProvCert )
  429. {
  430. if ( m_pCertContext )
  431. ::CertFreeCertificateContext (m_pCertContext);
  432. // TODO: Do we need to duplicate context here?
  433. m_pCertContext = ::CertDuplicateCertificateContext
  434. (pProvCert->pCert);
  435. if ( m_pCertContext )
  436. {
  437. SetDlgItemText (IDC_CERT_ENTRY_SUBJECT_NAME, ::GetNameString (m_pCertContext, 0));
  438. GetDlgItem (IDC_SAFER_CERT_VIEW)->EnableWindow (TRUE);
  439. }
  440. m_bCertificateChanged = true;
  441. m_bDirty = true;
  442. SetModified ();
  443. //now close the data
  444. WinTrustData.dwStateAction = WTD_STATEACTION_CLOSE;
  445. if ( S_OK != ::WinVerifyTrust (NULL, &wvtProvGuid,
  446. &WinTrustData))
  447. {
  448. dwErr = GetLastError ();
  449. _TRACE (0, L"error calling WVT during close %d\n", dwErr);
  450. }
  451. }
  452. else
  453. {
  454. dwErr = GetLastError ();
  455. _TRACE (0, L"error calling WTHelperGetProvCertFromChain %d\n", dwErr);
  456. }
  457. }
  458. else
  459. {
  460. dwErr = GetLastError ();
  461. _TRACE (0, L"error calling WTHelperGetProvSignerFromChain %d\n",
  462. dwErr);
  463. }
  464. }
  465. else
  466. {
  467. dwErr = GetLastError ();
  468. _TRACE (0, L"error calling WTHelperProvDataFromStateData %d\n",
  469. dwErr);
  470. }
  471. }
  472. else
  473. {
  474. dwErr = GetLastError ();
  475. _TRACE (0, L"error calling WVT %d for %s\n",
  476. dwErr, (PCWSTR) szFilePath);
  477. }
  478. if ( 0 != dwErr )
  479. {
  480. //
  481. // Fail. Get the error code.
  482. //
  483. CString text;
  484. CString caption;
  485. CThemeContextActivator activator;
  486. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  487. text.FormatMessage (IDS_CERTFILEOPENERR, szFilePath,
  488. GetSystemMessage (dwErr));
  489. MessageBox (text, caption);
  490. }
  491. _TRACE (-1, L"Leaving CSaferEntryCertificatePropertyPage::GetCertFromSignedFile (%s): %x\n",
  492. (PCWSTR) szFilePath, dwErr);
  493. }
  494. BOOL CSaferEntryCertificatePropertyPage::OnApply()
  495. {
  496. if ( !m_bReadOnly )
  497. {
  498. ASSERT (m_pSaferEntries);
  499. if ( !m_pSaferEntries )
  500. return FALSE;
  501. CThemeContextActivator activator;
  502. if ( !m_pCertContext )
  503. {
  504. CString text;
  505. CString caption;
  506. VERIFY (text.LoadString (IDS_SAFER_MUST_CHOOSE_CERT));
  507. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  508. MessageBox (text, caption, MB_OK);
  509. GetDlgItem (IDC_CERT_ENTRY_BROWSE)->SetFocus ();
  510. return FALSE;
  511. }
  512. if ( m_bDirty )
  513. {
  514. int nCurSel = m_securityLevelCombo.GetCurSel ();
  515. ASSERT (CB_ERR < nCurSel);
  516. if ( CB_ERR < nCurSel )
  517. {
  518. CCertStore* pTrustedPublishersStore = 0;
  519. HRESULT hr = m_pSaferEntries->GetTrustedPublishersStore (&pTrustedPublishersStore);
  520. ASSERT (SUCCEEDED (hr));
  521. if ( SUCCEEDED (hr) )
  522. {
  523. CCertStore* pDisallowedStore = 0;
  524. hr = m_pSaferEntries->GetDisallowedStore (&pDisallowedStore);
  525. ASSERT (SUCCEEDED (hr));
  526. if ( SUCCEEDED (hr) )
  527. {
  528. DWORD_PTR dwLevel = m_securityLevelCombo.GetItemData (nCurSel);
  529. m_rSaferEntry.SetLevel ((DWORD) dwLevel);
  530. CCertStore* pStore = (SAFER_LEVELID_FULLYTRUSTED == dwLevel) ?
  531. pTrustedPublishersStore : pDisallowedStore;
  532. CCertificate* pCert = 0;
  533. hr = m_rSaferEntry.GetCertificate (&pCert);
  534. if ( E_NOTIMPL == hr )
  535. {
  536. // This is a new entry
  537. if ( m_pOriginalStore )
  538. m_pOriginalStore->Release ();
  539. m_pOriginalStore = pStore;
  540. m_pOriginalStore->AddRef ();
  541. CCertificate* pNewCert = new CCertificate (
  542. m_pCertContext,
  543. pStore);
  544. if ( pNewCert )
  545. {
  546. hr = m_rSaferEntry.SetCertificate (pNewCert);
  547. pNewCert->Release ();
  548. }
  549. else
  550. hr = E_OUTOFMEMORY;
  551. if ( SUCCEEDED (hr) )
  552. {
  553. CString szDescription;
  554. m_descriptionEdit.GetWindowText (szDescription);
  555. m_rSaferEntry.SetDescription (szDescription);
  556. hr = m_rSaferEntry.Save ();
  557. if ( SUCCEEDED (hr) )
  558. {
  559. pStore->Commit ();
  560. if ( m_lNotifyHandle )
  561. MMCPropertyChangeNotify (
  562. m_lNotifyHandle, // handle to a notification
  563. (LPARAM) m_pDataObject); // unique identifier
  564. if ( m_pbObjectCreated )
  565. *m_pbObjectCreated = true;
  566. m_rSaferEntry.Refresh ();
  567. GetDlgItem (IDC_DATE_LAST_MODIFIED_LABEL)->ShowWindow (SW_SHOW);
  568. GetDlgItem (IDC_CERT_ENTRY_LAST_MODIFIED)->ShowWindow (SW_SHOW);
  569. GetDlgItem (IDC_DATE_LAST_MODIFIED_LABEL)->UpdateWindow ();
  570. GetDlgItem (IDC_CERT_ENTRY_LAST_MODIFIED)->UpdateWindow ();
  571. SetDlgItemText (IDC_CERT_ENTRY_LAST_MODIFIED, m_rSaferEntry.GetLongLastModified ());
  572. m_bDirty = false;
  573. }
  574. else
  575. {
  576. CString text;
  577. CString caption;
  578. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  579. text.FormatMessage (IDS_ERROR_SAVING_ENTRY, GetSystemMessage (hr));
  580. MessageBox (text, caption, MB_OK);
  581. }
  582. }
  583. if ( pCert )
  584. pCert->Release ();
  585. }
  586. else
  587. {
  588. // We're modifying an existing entry
  589. ASSERT (m_pSaferEntries);
  590. if ( m_pSaferEntries )
  591. {
  592. // 1. If original cert has been changed, it must be removed from its
  593. // store and the new one added to the appropriate store
  594. // 2. If the security level was changed. The cert
  595. // removed from the original store, which must be Committed and
  596. // released. The cert must then be added to the new store.
  597. // 3. If both the cert and the level have been changed, same as step 2.
  598. if ( m_bCertificateChanged )
  599. {
  600. CCertificate* pNewCert = new CCertificate (
  601. ::CertDuplicateCertificateContext (m_pCertContext),
  602. pStore);
  603. if ( pNewCert )
  604. {
  605. hr = m_rSaferEntry.SetCertificate (pNewCert);
  606. }
  607. }
  608. }
  609. CString szDescription;
  610. m_descriptionEdit.GetWindowText (szDescription);
  611. m_rSaferEntry.SetDescription (szDescription);
  612. hr = m_rSaferEntry.SetLevel ((DWORD) dwLevel);
  613. if ( SUCCEEDED (hr) )
  614. {
  615. hr = m_rSaferEntry.Save ();
  616. if ( SUCCEEDED (hr) )
  617. {
  618. pDisallowedStore->Commit ();
  619. pTrustedPublishersStore->Commit ();
  620. if ( m_lNotifyHandle )
  621. MMCPropertyChangeNotify (
  622. m_lNotifyHandle, // handle to a notification
  623. (LPARAM) m_pDataObject); // unique identifier
  624. if ( m_pbObjectCreated )
  625. *m_pbObjectCreated = true;
  626. m_rSaferEntry.Refresh ();
  627. GetDlgItem (IDC_DATE_LAST_MODIFIED_LABEL)->ShowWindow (SW_SHOW);
  628. GetDlgItem (IDC_CERT_ENTRY_LAST_MODIFIED)->ShowWindow (SW_SHOW);
  629. GetDlgItem (IDC_DATE_LAST_MODIFIED_LABEL)->UpdateWindow ();
  630. GetDlgItem (IDC_CERT_ENTRY_LAST_MODIFIED)->UpdateWindow ();
  631. SetDlgItemText (IDC_CERT_ENTRY_LAST_MODIFIED, m_rSaferEntry.GetLongLastModified ());
  632. m_bDirty = false;
  633. }
  634. else
  635. {
  636. CString text;
  637. CString caption;
  638. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  639. text.FormatMessage (IDS_ERROR_SAVING_ENTRY, GetSystemMessage (hr));
  640. MessageBox (text, caption, MB_OK);
  641. }
  642. }
  643. if ( pCert )
  644. pCert->Release ();
  645. }
  646. pDisallowedStore->Release ();
  647. }
  648. pTrustedPublishersStore->Release ();
  649. }
  650. }
  651. }
  652. }
  653. if ( !m_bDirty )
  654. return CSaferPropertyPage::OnApply();
  655. else
  656. return FALSE;
  657. }
  658. void CSaferEntryCertificatePropertyPage::OnChangeCertEntryDescription()
  659. {
  660. m_bDirty = true;
  661. SetModified ();
  662. }
  663. void CSaferEntryCertificatePropertyPage::OnSelchangeCertEntrySecurityLevel()
  664. {
  665. m_bDirty = true;
  666. SetModified ();
  667. }
  668. void CSaferEntryCertificatePropertyPage::OnSaferCertView()
  669. {
  670. LaunchCommonCertDialog ();
  671. }
  672. void CSaferEntryCertificatePropertyPage::LaunchCommonCertDialog ()
  673. {
  674. _TRACE (1, L"Entering CSaferEntryCertificatePropertyPage::LaunchCommonCertDialog\n");
  675. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  676. if ( !m_pCertContext )
  677. return;
  678. HRESULT hr = S_OK;
  679. CWaitCursor waitCursor;
  680. CTypedPtrList<CPtrList, CCertStore*> storeList;
  681. // Add the Root store first on a remote machine.
  682. if ( !IsLocalComputername (m_pCompData->GetManagedComputer ()) )
  683. {
  684. storeList.AddTail (new CCertStore (CERTMGR_LOG_STORE,
  685. CERT_STORE_PROV_SYSTEM,
  686. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  687. (LPCWSTR) m_pCompData->GetManagedComputer (),
  688. ROOT_SYSTEM_STORE_NAME,
  689. ROOT_SYSTEM_STORE_NAME,
  690. _T (""), ROOT_STORE,
  691. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  692. m_pCompData->m_pConsole));
  693. }
  694. hr = m_pCompData->EnumerateLogicalStores (&storeList);
  695. if ( SUCCEEDED (hr) )
  696. {
  697. POSITION pos = 0;
  698. POSITION prevPos = 0;
  699. // Validate store handles
  700. for (pos = storeList.GetHeadPosition ();
  701. pos;)
  702. {
  703. prevPos = pos;
  704. CCertStore* pStore = storeList.GetNext (pos);
  705. ASSERT (pStore);
  706. if ( pStore )
  707. {
  708. // Do not open the userDS store
  709. if ( USERDS_STORE == pStore->GetStoreType () )
  710. {
  711. storeList.RemoveAt (prevPos);
  712. pStore->Release ();
  713. pStore = 0;
  714. }
  715. else
  716. {
  717. if ( !pStore->GetStoreHandle () )
  718. {
  719. CString caption;
  720. CString text;
  721. CThemeContextActivator activator;
  722. text.FormatMessage (IDS_CANT_OPEN_STORE_AND_FAIL, pStore->GetLocalizedName ());
  723. VERIFY (caption.LoadString (IDS_CERTIFICATE_MANAGER));
  724. MessageBox (text, caption, MB_ICONWARNING | MB_OK);
  725. break;
  726. }
  727. }
  728. }
  729. }
  730. // Proceed only if all handles are valid
  731. if ( SUCCEEDED (hr) )
  732. {
  733. CRYPTUI_VIEWCERTIFICATE_STRUCT vcs;
  734. // security review 2/25/2002 BryanWal ok
  735. ::ZeroMemory (&vcs, sizeof (vcs));
  736. vcs.dwSize = sizeof (vcs);
  737. vcs.hwndParent = m_hWnd;
  738. // Set these flags only on a remote machine.
  739. if ( !IsLocalComputername (m_pCompData->GetManagedComputer ()) )
  740. vcs.dwFlags = CRYPTUI_DONT_OPEN_STORES | CRYPTUI_WARN_UNTRUSTED_ROOT;
  741. else
  742. vcs.dwFlags = 0;
  743. vcs.pCertContext = m_pCertContext;
  744. vcs.cStores = (DWORD)storeList.GetCount ();
  745. vcs.rghStores = new HCERTSTORE[vcs.cStores];
  746. if ( vcs.rghStores )
  747. {
  748. CCertStore* pStore = 0;
  749. DWORD index = 0;
  750. for (pos = storeList.GetHeadPosition ();
  751. pos && index < vcs.cStores;
  752. index++)
  753. {
  754. pStore = storeList.GetNext (pos);
  755. ASSERT (pStore);
  756. if ( pStore )
  757. {
  758. vcs.rghStores[index] = pStore->GetStoreHandle ();
  759. }
  760. }
  761. BOOL fPropertiesChanged = FALSE;
  762. _TRACE (0, L"Calling CryptUIDlgViewCertificate()\n");
  763. CThemeContextActivator activator;
  764. ::CryptUIDlgViewCertificate (&vcs, &fPropertiesChanged);
  765. delete vcs.rghStores;
  766. }
  767. else
  768. hr = E_OUTOFMEMORY;
  769. }
  770. while (!storeList.IsEmpty () )
  771. {
  772. CCertStore* pStore = storeList.RemoveHead ();
  773. if ( pStore )
  774. {
  775. pStore->Close ();
  776. pStore->Release ();
  777. }
  778. }
  779. }
  780. _TRACE (-1, L"Leaving CSaferEntryCertificatePropertyPage::LaunchCommonCertDialog: 0x%x\n", hr);
  781. }
  782. void CSaferEntryCertificatePropertyPage::OnSetfocusCertEntrySubjectName()
  783. {
  784. if ( m_bFirst )
  785. {
  786. SendDlgItemMessage (IDC_CERT_ENTRY_SUBJECT_NAME, EM_SETSEL, (WPARAM) 0, 0);
  787. m_bFirst = false;
  788. }
  789. }