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.

1098 lines
34 KiB

  1. //+---------------------------------------------------------------------------
  2. /////////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 2000-2001.
  6. //
  7. // File: SaferEntry.cpp
  8. //
  9. // Contents: Implementation of CSaferEntry
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "stdafx.h"
  13. #include <gpedit.h>
  14. #include "SaferEntry.h"
  15. #include "PolicyKey.h"
  16. #include "SaferLevel.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. extern HKEY g_hkeyLastSaferRegistryScope;
  23. const DWORD AUTHZ_UNKNOWN_LEVEL = 0xFFFFFFFF;
  24. extern GUID g_guidExtension;
  25. extern GUID g_guidRegExt;
  26. extern GUID g_guidSnapin;
  27. extern PCWSTR pcszNEWLINE;
  28. //////////////////////////////////////////////////////////////////////
  29. // Construction/Destruction
  30. //////////////////////////////////////////////////////////////////////
  31. CSaferEntry::CSaferEntry (
  32. SAFER_ENTRY_TYPE saferEntryType,
  33. bool bIsMachine,
  34. PCWSTR pszMachineName,
  35. PCWSTR pszObjectName,
  36. PSAFER_IDENTIFICATION_HEADER pAuthzInfo,
  37. DWORD dwLevelID,
  38. IGPEInformation* pGPEInformation,
  39. CCertificate* pCertificate,
  40. CSaferEntries* pSaferEntries,
  41. CRSOPObjectArray& rRSOPArray,
  42. PCWSTR pszRSOPRegistryKey)
  43. : CCertMgrCookie (bIsMachine ? CERTMGR_SAFER_COMPUTER_ENTRY : CERTMGR_SAFER_USER_ENTRY,
  44. pszMachineName, pszObjectName),
  45. m_pAuthzInfo (pAuthzInfo),
  46. m_dwLevelID (dwLevelID),
  47. m_dwOriginalLevelID (dwLevelID),
  48. m_pCertificate (pCertificate),
  49. m_pSaferEntries (pSaferEntries),
  50. m_pGPEInformation (pGPEInformation),
  51. m_saferEntryType (saferEntryType),
  52. m_dwFlags (0),
  53. m_bDeleted (false),
  54. m_cbFileHash (0),
  55. m_UrlZoneId (0),
  56. m_szRSOPRegistryKey (pszRSOPRegistryKey),
  57. m_hashAlgid (0),
  58. m_bIsComputer (bIsMachine)
  59. {
  60. ::ZeroMemory (&m_nHashFileSize, sizeof (__int64));
  61. ::ZeroMemory (m_rgbFileHash, SAFER_MAX_HASH_SIZE);
  62. m_szDisplayName = pszObjectName;
  63. if ( m_pCertificate )
  64. m_pCertificate->AddRef ();
  65. if ( m_pSaferEntries )
  66. m_pSaferEntries->AddRef ();
  67. if ( m_pGPEInformation )
  68. {
  69. m_pGPEInformation->AddRef ();
  70. CPolicyKey policyKey (m_pGPEInformation,
  71. SAFER_HKLM_REGBASE,
  72. bIsMachine);
  73. if ( AUTHZ_UNKNOWN_LEVEL == m_dwLevelID )
  74. {
  75. // Bug 264556 Set better Security level defaults for new Safer rules
  76. m_dwLevelID = CSaferLevel::ReturnDefaultLevel (
  77. m_pGPEInformation,
  78. m_bIsComputer,
  79. rRSOPArray);
  80. if ( SAFER_LEVELID_FULLYTRUSTED == m_dwLevelID )
  81. m_dwLevelID = SAFER_LEVELID_DISALLOWED;
  82. else
  83. m_dwLevelID = SAFER_LEVELID_FULLYTRUSTED;
  84. }
  85. m_szLevelFriendlyName = SaferGetLevelFriendlyName (m_dwLevelID,
  86. policyKey.GetKey (), m_bIsComputer);
  87. }
  88. else
  89. {
  90. m_szLevelFriendlyName = SaferGetLevelFriendlyName (m_dwLevelID, 0,
  91. m_bIsComputer);
  92. }
  93. if ( SAFER_ENTRY_TYPE_URLZONE == m_saferEntryType )
  94. {
  95. if ( m_pAuthzInfo )
  96. {
  97. ASSERT (SaferIdentityTypeUrlZone == m_pAuthzInfo->dwIdentificationType);
  98. PSAFER_URLZONE_IDENTIFICATION pURLEntry =
  99. reinterpret_cast <PSAFER_URLZONE_IDENTIFICATION> (m_pAuthzInfo);
  100. ASSERT (pURLEntry->header.cbStructSize ==
  101. sizeof (SAFER_URLZONE_IDENTIFICATION));
  102. m_UrlZoneId = pURLEntry->UrlZoneId;
  103. }
  104. else
  105. {
  106. // This is a new entry
  107. m_UrlZoneId = URLZONE_TRUSTED;
  108. }
  109. }
  110. }
  111. CSaferEntry::~CSaferEntry()
  112. {
  113. if ( m_pAuthzInfo )
  114. LocalFree (m_pAuthzInfo);
  115. if ( m_pCertificate )
  116. m_pCertificate->Release ();
  117. if ( m_pSaferEntries )
  118. m_pSaferEntries->Release ();
  119. if ( m_pGPEInformation )
  120. m_pGPEInformation->Release ();
  121. }
  122. CString CSaferEntry::GetDescription()
  123. {
  124. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  125. CString szDescription;
  126. if ( SAFER_ENTRY_TYPE_URLZONE == m_saferEntryType )
  127. {
  128. switch (m_UrlZoneId)
  129. {
  130. case URLZONE_LOCAL_MACHINE:
  131. VERIFY (szDescription.LoadString (IDS_URLZONE_LOCAL_MACHINE_DESCRIPTION));
  132. break;
  133. case URLZONE_INTRANET:
  134. VERIFY (szDescription.LoadString (IDS_URLZONE_INTRANET_DESCRIPTION));
  135. break;
  136. case URLZONE_TRUSTED:
  137. VERIFY (szDescription.LoadString (IDS_URLZONE_TRUSTED_DESCRIPTION));
  138. break;
  139. case URLZONE_INTERNET:
  140. VERIFY (szDescription.LoadString (IDS_URLZONE_INTERNET_DESCRIPTION));
  141. break;
  142. case URLZONE_UNTRUSTED:
  143. VERIFY (szDescription.LoadString (IDS_URLZONE_UNTRUSTED_DESCRIPTION));
  144. break;
  145. default:
  146. ASSERT (0);
  147. break;
  148. }
  149. }
  150. else if ( m_pAuthzInfo )
  151. {
  152. switch (m_pAuthzInfo->dwIdentificationType)
  153. {
  154. case SaferIdentityTypeImageName:
  155. {
  156. PSAFER_PATHNAME_IDENTIFICATION pNameEntry =
  157. (PSAFER_PATHNAME_IDENTIFICATION) m_pAuthzInfo;
  158. ASSERT (pNameEntry->header.cbStructSize >=
  159. sizeof (SAFER_PATHNAME_IDENTIFICATION));
  160. szDescription = pNameEntry->Description;
  161. }
  162. break;
  163. case SaferIdentityTypeImageHash:
  164. {
  165. PSAFER_HASH_IDENTIFICATION pHashEntry =
  166. (PSAFER_HASH_IDENTIFICATION) m_pAuthzInfo;
  167. ASSERT (pHashEntry->header.cbStructSize ==
  168. sizeof (SAFER_HASH_IDENTIFICATION));
  169. szDescription = pHashEntry->Description;
  170. }
  171. break;
  172. case SaferIdentityTypeUrlZone:
  173. ASSERT (0);
  174. break;
  175. default:
  176. ASSERT (0);
  177. break;
  178. }
  179. }
  180. else if ( m_pCertificate )
  181. {
  182. // Is certificate
  183. szDescription = m_pCertificate->GetDescription ();
  184. }
  185. m_szDescription = szDescription;
  186. return szDescription;
  187. }
  188. SAFER_ENTRY_TYPE CSaferEntry::GetType () const
  189. {
  190. return m_saferEntryType;
  191. }
  192. CString CSaferEntry::GetTypeString() const
  193. {
  194. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  195. CString szType;
  196. switch (m_saferEntryType)
  197. {
  198. case SAFER_ENTRY_TYPE_PATH:
  199. VERIFY (szType.LoadString (IDS_CodeIdentityType_ImageName));
  200. break;
  201. case SAFER_ENTRY_TYPE_HASH:
  202. VERIFY (szType.LoadString (IDS_CodeIdentityType_ImageHash));
  203. break;
  204. case SAFER_ENTRY_TYPE_URLZONE:
  205. VERIFY (szType.LoadString (IDS_CodeIdentityType_UrlZone));
  206. break;
  207. case SAFER_ENTRY_TYPE_CERT:
  208. VERIFY (szType.LoadString (IDS_CodeIdentityType_Certificate));
  209. break;
  210. default:
  211. ASSERT (0);
  212. break;
  213. }
  214. return szType;
  215. }
  216. CString CSaferEntry::GetLevelFriendlyName() const
  217. {
  218. return m_szLevelFriendlyName;
  219. }
  220. CString CSaferEntry::GetShortLastModified() const
  221. {
  222. CString szDate;
  223. if ( m_pAuthzInfo )
  224. {
  225. VERIFY (SUCCEEDED (FormatDate (m_pAuthzInfo->lastModified, szDate, DATE_SHORTDATE, true)) );
  226. }
  227. else if ( m_pCertificate )
  228. {
  229. szDate = m_pCertificate->GetShortLastModified ();
  230. }
  231. return szDate;
  232. }
  233. CString CSaferEntry::GetLongLastModified() const
  234. {
  235. CString szDate;
  236. if ( m_pAuthzInfo )
  237. {
  238. VERIFY (SUCCEEDED (FormatDate (m_pAuthzInfo->lastModified, szDate, DATE_LONGDATE, true)) );
  239. }
  240. else if ( m_pCertificate )
  241. {
  242. szDate = m_pCertificate->GetLongLastModified ();
  243. }
  244. return szDate;
  245. }
  246. HRESULT CSaferEntry::GetCertificate(CCertificate **ppCert)
  247. {
  248. ASSERT (ppCert);
  249. if ( !ppCert )
  250. return E_POINTER;
  251. if ( !m_pCertificate )
  252. return E_NOTIMPL;
  253. *ppCert = m_pCertificate;
  254. m_pCertificate->AddRef ();
  255. return S_OK;
  256. }
  257. HRESULT CSaferEntry::SetCertificate(CCertificate *pCert)
  258. {
  259. ASSERT (m_pSaferEntries);
  260. if ( !m_pSaferEntries )
  261. return E_FAIL;
  262. HRESULT hr = S_OK;
  263. CCertStore* pStore = 0;
  264. switch (m_dwLevelID)
  265. {
  266. case SAFER_LEVELID_FULLYTRUSTED:
  267. hr = m_pSaferEntries->GetTrustedPublishersStore (&pStore);
  268. break;
  269. case SAFER_LEVELID_DISALLOWED:
  270. hr = m_pSaferEntries->GetDisallowedStore (&pStore);
  271. break;
  272. default:
  273. hr = E_FAIL;
  274. break;
  275. }
  276. if ( SUCCEEDED (hr) )
  277. {
  278. if ( m_pCertificate )
  279. {
  280. m_pCertificate->DeleteFromStore (false);
  281. m_pCertificate->Release ();
  282. m_pCertificate = 0;
  283. }
  284. if ( pCert )
  285. {
  286. m_pCertificate = pCert;
  287. m_pCertificate->AddRef ();
  288. hr = pStore->AddCertificateContext (m_pCertificate->GetCertContext (), 0, false);
  289. if ( SUCCEEDED (hr) )
  290. {
  291. m_pCertificate->GetNewCertContext ();
  292. }
  293. }
  294. }
  295. return hr;
  296. }
  297. void CSaferEntry::SetDescription(const CString& szDescription)
  298. {
  299. m_szDescription = szDescription;
  300. }
  301. HRESULT CSaferEntry::GetSaferEntriesNode(CSaferEntries **ppSaferEntries)
  302. {
  303. if ( !ppSaferEntries )
  304. return E_POINTER;
  305. if ( !m_pSaferEntries )
  306. return E_NOTIMPL;
  307. m_pSaferEntries->AddRef ();
  308. *ppSaferEntries = m_pSaferEntries;
  309. return S_OK;
  310. }
  311. DWORD CSaferEntry::GetLevel() const
  312. {
  313. return m_dwLevelID;
  314. }
  315. HRESULT CSaferEntry::SetLevel(DWORD dwLevelID)
  316. {
  317. HRESULT hr = S_OK;
  318. if ( m_dwLevelID != dwLevelID )
  319. {
  320. m_dwLevelID = dwLevelID;
  321. // Get the new "friendly name"
  322. if ( m_pGPEInformation )
  323. {
  324. CPolicyKey policyKey (m_pGPEInformation,
  325. SAFER_HKLM_REGBASE,
  326. m_bIsComputer);
  327. m_szLevelFriendlyName = SaferGetLevelFriendlyName (dwLevelID,
  328. policyKey.GetKey (),
  329. m_bIsComputer);
  330. }
  331. else
  332. {
  333. m_szLevelFriendlyName = SaferGetLevelFriendlyName (dwLevelID, 0,
  334. m_bIsComputer);
  335. }
  336. }
  337. return hr;
  338. }
  339. CString CSaferEntry::GetPath()
  340. {
  341. CString szPath;
  342. if ( m_pAuthzInfo )
  343. {
  344. if ( SaferIdentityTypeImageName == m_pAuthzInfo->dwIdentificationType )
  345. {
  346. PSAFER_PATHNAME_IDENTIFICATION pNameEntry =
  347. (PSAFER_PATHNAME_IDENTIFICATION) m_pAuthzInfo;
  348. ASSERT (pNameEntry->header.cbStructSize >=
  349. sizeof (SAFER_PATHNAME_IDENTIFICATION));
  350. ASSERT (SaferIdentityTypeImageName == m_pAuthzInfo->dwIdentificationType);
  351. szPath = pNameEntry->ImageName;
  352. }
  353. }
  354. m_szPath = szPath;
  355. return szPath;
  356. }
  357. void CSaferEntry::SetPath(const CString &szPath)
  358. {
  359. m_szPath = szPath;
  360. }
  361. HRESULT CSaferEntry::Save()
  362. {
  363. _TRACE (1, L"Entering CSaferEntry::Save\n");
  364. HRESULT hr = S_OK;
  365. ASSERT (!m_bDeleted);
  366. if ( m_bDeleted )
  367. return E_FAIL;
  368. if ( m_pCertificate )
  369. {
  370. hr = m_pCertificate->SetDescription (m_szDescription);
  371. if ( SUCCEEDED (hr) )
  372. {
  373. hr = m_pCertificate->SetLastModified ();
  374. if ( SUCCEEDED (hr) )
  375. {
  376. // If the level has changed, then the cert must be removed
  377. // from the current level store added to the new one.
  378. if ( m_dwOriginalLevelID != m_dwLevelID )
  379. {
  380. CCertStore* pStore = 0;
  381. switch (m_dwLevelID)
  382. {
  383. case SAFER_LEVELID_FULLYTRUSTED:
  384. hr = m_pSaferEntries->GetTrustedPublishersStore (&pStore);
  385. break;
  386. case SAFER_LEVELID_DISALLOWED:
  387. hr = m_pSaferEntries->GetDisallowedStore (&pStore);
  388. break;
  389. default:
  390. hr = E_FAIL;
  391. break;
  392. }
  393. if ( SUCCEEDED (hr) )
  394. {
  395. m_pCertificate->DeleteFromStore (true);
  396. hr = pStore->AddCertificateContext (m_pCertificate->GetCertContext (), 0, false);
  397. if ( SUCCEEDED (hr) )
  398. {
  399. m_pCertificate->SetStore (pStore);
  400. hr = PolicyChanged ();
  401. }
  402. }
  403. }
  404. if ( SUCCEEDED (hr) )
  405. m_szDisplayName = m_pCertificate->GetSubjectName ();
  406. }
  407. }
  408. }
  409. else if ( m_pGPEInformation )
  410. {
  411. BOOL bRVal = TRUE;
  412. CPolicyKey policyKey (m_pGPEInformation,
  413. SAFER_HKLM_REGBASE,
  414. m_bIsComputer);
  415. hr = SetRegistryScope (policyKey.GetKey (), m_bIsComputer);
  416. if ( SUCCEEDED (hr) )
  417. {
  418. DWORD dwInBufferSize = 0;
  419. switch (m_saferEntryType)
  420. {
  421. case SAFER_ENTRY_TYPE_PATH:
  422. dwInBufferSize = sizeof (SAFER_PATHNAME_IDENTIFICATION);
  423. break;
  424. case SAFER_ENTRY_TYPE_HASH:
  425. dwInBufferSize = sizeof (SAFER_HASH_IDENTIFICATION);
  426. break;
  427. case SAFER_ENTRY_TYPE_URLZONE:
  428. dwInBufferSize = sizeof (SAFER_URLZONE_IDENTIFICATION);
  429. break;
  430. default:
  431. ASSERT (0);
  432. break;
  433. }
  434. SAFER_LEVEL_HANDLE hLevel = 0;
  435. // If this entry is not being created for the first time
  436. // and the level has changed, delete this object from its original
  437. // level.
  438. if ( m_pAuthzInfo &&
  439. AUTHZ_UNKNOWN_LEVEL != m_dwOriginalLevelID &&
  440. m_dwOriginalLevelID != m_dwLevelID )
  441. {
  442. bRVal = SaferCreateLevel(SAFER_SCOPEID_REGISTRY,
  443. m_dwOriginalLevelID,
  444. SAFER_LEVEL_OPEN,
  445. &hLevel,
  446. policyKey.GetKey ());
  447. ASSERT (bRVal);
  448. if ( bRVal )
  449. {
  450. SAFER_IDENTIFICATION_TYPES dwIdentificationType =
  451. m_pAuthzInfo->dwIdentificationType;
  452. m_pAuthzInfo->dwIdentificationType = (SAFER_IDENTIFICATION_TYPES) 0; // 0 will cause deletion
  453. bRVal = SaferSetLevelInformation(hLevel,
  454. SaferObjectSingleIdentification,
  455. m_pAuthzInfo,
  456. m_pAuthzInfo->cbStructSize);
  457. ASSERT (bRVal);
  458. if ( !bRVal )
  459. {
  460. DWORD dwErr = GetLastError ();
  461. _TRACE (0, L"Attempt to delete entry using SaferSetLevelInformation(SaferObjectSingleIdentification) failed: %d\n", dwErr);
  462. hr = HRESULT_FROM_WIN32 (dwErr);
  463. }
  464. m_pAuthzInfo->dwIdentificationType = dwIdentificationType; // restore type
  465. VERIFY (SaferCloseLevel(hLevel));
  466. }
  467. else
  468. {
  469. DWORD dwErr = GetLastError ();
  470. hr = HRESULT_FROM_WIN32 (dwErr);
  471. _TRACE (0, L"SaferCreateLevel(SAFER_SCOPEID_REGISTRY, 0x%x, SAFER_LEVEL_OPEN) failed: %d\n",
  472. m_dwOriginalLevelID, dwErr);
  473. }
  474. }
  475. if ( SUCCEEDED (hr) )
  476. {
  477. // If this is new, create and initialize a new info structure
  478. if ( !m_pAuthzInfo )
  479. {
  480. // generate guid
  481. GUID guid;
  482. hr = CoCreateGuid (&guid);
  483. if ( SUCCEEDED (hr) )
  484. {
  485. m_pAuthzInfo = (PSAFER_IDENTIFICATION_HEADER)
  486. ::LocalAlloc (LPTR, dwInBufferSize);
  487. if ( m_pAuthzInfo )
  488. {
  489. m_pAuthzInfo->cbStructSize = dwInBufferSize;
  490. memcpy (&m_pAuthzInfo->IdentificationGuid, &guid, sizeof (GUID));
  491. }
  492. else
  493. hr = E_OUTOFMEMORY;
  494. }
  495. }
  496. if ( SUCCEEDED (hr) )
  497. {
  498. switch (m_saferEntryType)
  499. {
  500. case SAFER_ENTRY_TYPE_PATH:
  501. {
  502. m_pAuthzInfo->dwIdentificationType = SaferIdentityTypeImageName;
  503. PSAFER_PATHNAME_IDENTIFICATION pNameEntry =
  504. reinterpret_cast<PSAFER_PATHNAME_IDENTIFICATION> (m_pAuthzInfo);
  505. ASSERT (pNameEntry->header.cbStructSize >=
  506. sizeof (SAFER_PATHNAME_IDENTIFICATION));
  507. wcsncpy (pNameEntry->Description, m_szDescription, SAFER_MAX_DESCRIPTION_SIZE-1);
  508. pNameEntry->ImageName = const_cast <PWCHAR>((PCWSTR) m_szPath);
  509. pNameEntry->dwSaferFlags = m_dwFlags;
  510. }
  511. break;
  512. case SAFER_ENTRY_TYPE_HASH:
  513. {
  514. m_pAuthzInfo->dwIdentificationType = SaferIdentityTypeImageHash;
  515. PSAFER_HASH_IDENTIFICATION pHashEntry =
  516. reinterpret_cast<PSAFER_HASH_IDENTIFICATION>(m_pAuthzInfo);
  517. ASSERT (pHashEntry->header.cbStructSize ==
  518. sizeof (SAFER_HASH_IDENTIFICATION));
  519. wcsncpy (pHashEntry->FriendlyName, m_szHashFriendlyName,
  520. SAFER_MAX_FRIENDLYNAME_SIZE-1);
  521. wcsncpy (pHashEntry->Description,
  522. m_szDescription,
  523. SAFER_MAX_DESCRIPTION_SIZE-1);
  524. pHashEntry->dwSaferFlags = m_dwFlags;
  525. memcpy (pHashEntry->ImageHash, m_rgbFileHash, SAFER_MAX_HASH_SIZE);
  526. pHashEntry->HashSize = m_cbFileHash;
  527. memcpy (&pHashEntry->ImageSize, &m_nHashFileSize, sizeof (__int64));
  528. pHashEntry->HashAlgorithm = m_hashAlgid;
  529. }
  530. break;
  531. case SAFER_ENTRY_TYPE_URLZONE:
  532. {
  533. m_pAuthzInfo->dwIdentificationType = SaferIdentityTypeUrlZone;
  534. PSAFER_URLZONE_IDENTIFICATION pURLEntry =
  535. reinterpret_cast <PSAFER_URLZONE_IDENTIFICATION> (m_pAuthzInfo);
  536. ASSERT (pURLEntry->header.cbStructSize ==
  537. sizeof (SAFER_URLZONE_IDENTIFICATION));
  538. pURLEntry->dwSaferFlags = m_dwFlags;
  539. pURLEntry->UrlZoneId = m_UrlZoneId;
  540. }
  541. break;
  542. }
  543. bRVal = SaferCreateLevel(SAFER_SCOPEID_REGISTRY,
  544. m_dwLevelID,
  545. SAFER_LEVEL_OPEN,
  546. &hLevel,
  547. policyKey.GetKey ());
  548. ASSERT (bRVal);
  549. if ( bRVal )
  550. {
  551. bRVal = SaferSetLevelInformation(hLevel,
  552. SaferObjectSingleIdentification,
  553. m_pAuthzInfo, m_pAuthzInfo->cbStructSize);
  554. if ( bRVal )
  555. {
  556. switch ( m_saferEntryType )
  557. {
  558. case SAFER_ENTRY_TYPE_HASH:
  559. m_szDisplayName = m_szHashFriendlyName;
  560. m_szDisplayName.Replace (pcszNEWLINE, L" ");
  561. break;
  562. case SAFER_ENTRY_TYPE_PATH:
  563. m_szDisplayName = m_szPath;
  564. break;
  565. case SAFER_ENTRY_TYPE_URLZONE:
  566. m_szDisplayName = GetURLZoneFriendlyName (m_UrlZoneId);
  567. break;
  568. default:
  569. ASSERT (0);
  570. break;
  571. }
  572. hr = PolicyChanged ();
  573. if ( SUCCEEDED (hr) )
  574. {
  575. m_dwOriginalLevelID = m_dwLevelID;
  576. }
  577. }
  578. else
  579. {
  580. DWORD dwErr = GetLastError ();
  581. _TRACE (0, L"SaferSetLevelInformation(SaferObjectSingleIdentification) failed: %d\n",
  582. dwErr);
  583. hr = HRESULT_FROM_WIN32 (dwErr);
  584. }
  585. VERIFY (SaferCloseLevel(hLevel));
  586. }
  587. else
  588. {
  589. DWORD dwErr = GetLastError ();
  590. hr = HRESULT_FROM_WIN32 (dwErr);
  591. _TRACE (0, L"SaferCreateLevel(AUTHZSCOPID_REGISTRY, 0x%x, SAFER_LEVEL_OPEN) failed: %d\n",
  592. m_dwLevelID, dwErr);
  593. }
  594. }
  595. }
  596. }
  597. }
  598. else
  599. hr = E_FAIL;
  600. _TRACE (-1, L"Leaving CSaferEntry::Save: 0x%x\n", hr);
  601. return hr;
  602. }
  603. HRESULT CSaferEntry::PolicyChanged()
  604. {
  605. _TRACE (1, L"Entering CSaferEntry::PolicyChanged\n");
  606. HRESULT hr = E_FAIL;
  607. if ( m_pGPEInformation )
  608. {
  609. hr = m_pGPEInformation->PolicyChanged (
  610. m_bIsComputer ? TRUE : FALSE,
  611. TRUE, &g_guidExtension, &g_guidSnapin);
  612. hr = m_pGPEInformation->PolicyChanged (
  613. m_bIsComputer ? TRUE : FALSE,
  614. TRUE, &g_guidRegExt, &g_guidSnapin);
  615. }
  616. _TRACE (-1, L"Leaving CSaferEntry::PolicyChanged\n");
  617. return hr;
  618. }
  619. void CSaferEntry::SetFlags(DWORD dwFlags)
  620. {
  621. m_dwFlags = dwFlags;
  622. }
  623. HRESULT CSaferEntry::GetFlags(DWORD &dwFlags)
  624. {
  625. HRESULT hr = S_OK;
  626. if ( m_pAuthzInfo )
  627. {
  628. switch (m_saferEntryType)
  629. {
  630. case SAFER_ENTRY_TYPE_PATH:
  631. {
  632. m_pAuthzInfo->dwIdentificationType = SaferIdentityTypeImageName;
  633. PSAFER_PATHNAME_IDENTIFICATION pNameEntry =
  634. reinterpret_cast<PSAFER_PATHNAME_IDENTIFICATION>(m_pAuthzInfo);
  635. ASSERT (pNameEntry->header.cbStructSize >=
  636. sizeof (SAFER_PATHNAME_IDENTIFICATION));
  637. dwFlags = pNameEntry->dwSaferFlags;
  638. }
  639. break;
  640. case SAFER_ENTRY_TYPE_HASH:
  641. {
  642. m_pAuthzInfo->dwIdentificationType = SaferIdentityTypeImageHash;
  643. PSAFER_HASH_IDENTIFICATION pHashEntry =
  644. reinterpret_cast<PSAFER_HASH_IDENTIFICATION>(m_pAuthzInfo);
  645. ASSERT (pHashEntry->header.cbStructSize ==
  646. sizeof (SAFER_HASH_IDENTIFICATION));
  647. dwFlags = pHashEntry->dwSaferFlags;
  648. }
  649. break;
  650. case SAFER_ENTRY_TYPE_URLZONE:
  651. {
  652. m_pAuthzInfo->dwIdentificationType = SaferIdentityTypeUrlZone;
  653. PSAFER_URLZONE_IDENTIFICATION pURLEntry =
  654. reinterpret_cast<PSAFER_URLZONE_IDENTIFICATION>(m_pAuthzInfo);
  655. ASSERT (pURLEntry->header.cbStructSize ==
  656. sizeof (SAFER_URLZONE_IDENTIFICATION));
  657. dwFlags = pURLEntry->dwSaferFlags;
  658. }
  659. break;
  660. default:
  661. hr = E_FAIL;
  662. break;
  663. }
  664. }
  665. else if ( m_pCertificate )
  666. {
  667. hr = E_NOTIMPL;
  668. }
  669. return hr;
  670. }
  671. HRESULT CSaferEntry::Delete(bool bCommit)
  672. {
  673. _TRACE (1, L"Entering CSaferEntry::Delete\n");
  674. HRESULT hr = S_OK;
  675. ASSERT (!m_bDeleted);
  676. if ( m_bDeleted )
  677. return E_FAIL;
  678. if ( m_pCertificate )
  679. {
  680. BOOL bRVal = m_pCertificate->DeleteFromStore (bCommit);
  681. if ( bRVal )
  682. {
  683. m_bDeleted = true;
  684. }
  685. else
  686. {
  687. DWORD dwErr = GetLastError ();
  688. hr = HRESULT_FROM_WIN32 (dwErr);
  689. }
  690. }
  691. else if ( m_pGPEInformation )
  692. {
  693. BOOL bRVal = TRUE;
  694. CPolicyKey policyKey (m_pGPEInformation,
  695. SAFER_HKLM_REGBASE,
  696. m_bIsComputer);
  697. hr = SetRegistryScope (policyKey.GetKey (), m_bIsComputer);
  698. if ( SUCCEEDED (hr) )
  699. {
  700. DWORD dwInBufferSize = 0;
  701. switch (m_saferEntryType)
  702. {
  703. case SAFER_ENTRY_TYPE_PATH:
  704. dwInBufferSize = sizeof (SAFER_PATHNAME_IDENTIFICATION);
  705. break;
  706. case SAFER_ENTRY_TYPE_HASH:
  707. dwInBufferSize = sizeof (SAFER_HASH_IDENTIFICATION);
  708. break;
  709. case SAFER_ENTRY_TYPE_URLZONE:
  710. dwInBufferSize = sizeof (SAFER_URLZONE_IDENTIFICATION);
  711. break;
  712. default:
  713. ASSERT (0);
  714. break;
  715. }
  716. SAFER_LEVEL_HANDLE hLevel = 0;
  717. if ( m_pAuthzInfo )
  718. {
  719. bRVal = SaferCreateLevel(SAFER_SCOPEID_REGISTRY,
  720. m_dwOriginalLevelID,
  721. SAFER_LEVEL_OPEN,
  722. &hLevel,
  723. policyKey.GetKey ());
  724. ASSERT (bRVal);
  725. if ( bRVal )
  726. {
  727. SAFER_IDENTIFICATION_TYPES dwIdentificationType =
  728. m_pAuthzInfo->dwIdentificationType;
  729. m_pAuthzInfo->dwIdentificationType = (SAFER_IDENTIFICATION_TYPES) 0; // 0 will cause deletion
  730. bRVal = SaferSetLevelInformation(hLevel,
  731. SaferObjectSingleIdentification,
  732. m_pAuthzInfo,
  733. m_pAuthzInfo->cbStructSize);
  734. ASSERT (bRVal);
  735. if ( bRVal )
  736. {
  737. m_bDeleted = true;
  738. if ( bCommit )
  739. {
  740. hr = m_pGPEInformation->PolicyChanged (
  741. m_bIsComputer ? TRUE : FALSE,
  742. TRUE, &g_guidExtension, &g_guidSnapin);
  743. hr = m_pGPEInformation->PolicyChanged (
  744. m_bIsComputer ? TRUE : FALSE,
  745. TRUE, &g_guidRegExt, &g_guidSnapin);
  746. }
  747. }
  748. else
  749. {
  750. DWORD dwErr = GetLastError ();
  751. _TRACE (0, L"Attempt to delete entry using SaferSetLevelInformation(SaferObjectSingleIdentification) failed: %d\n", dwErr);
  752. hr = HRESULT_FROM_WIN32 (dwErr);
  753. }
  754. m_pAuthzInfo->dwIdentificationType = dwIdentificationType;
  755. VERIFY (SaferCloseLevel(hLevel)); // restore type
  756. }
  757. else
  758. {
  759. DWORD dwErr = GetLastError ();
  760. hr = HRESULT_FROM_WIN32 (dwErr);
  761. _TRACE (0, L"SaferCreateLevel(AUTHZSCOPID_REGISTRY, 0x%x, SAFER_LEVEL_OPEN) failed: %d\n",
  762. m_dwOriginalLevelID, dwErr);
  763. }
  764. }
  765. }
  766. }
  767. else
  768. hr = E_FAIL;
  769. _TRACE (-1, L"Leaving CSaferEntry::Delete: 0x%x\n", hr);
  770. return hr;
  771. }
  772. HRESULT CSaferEntry::GetHash(BYTE rgbFileHash[], DWORD& cbFileHash, __int64& nFileSize, ALG_ID& algId) const
  773. {
  774. HRESULT hr = S_OK;
  775. if ( m_pAuthzInfo )
  776. {
  777. if ( SAFER_ENTRY_TYPE_HASH == m_saferEntryType )
  778. {
  779. PSAFER_HASH_IDENTIFICATION pHashEntry =
  780. reinterpret_cast<PSAFER_HASH_IDENTIFICATION>(m_pAuthzInfo);
  781. ASSERT (pHashEntry->header.cbStructSize ==
  782. sizeof (SAFER_HASH_IDENTIFICATION));
  783. memcpy (rgbFileHash, pHashEntry->ImageHash, SAFER_MAX_HASH_SIZE);
  784. cbFileHash = pHashEntry->HashSize;
  785. memcpy (&nFileSize, &pHashEntry->ImageSize, sizeof (__int64));
  786. algId = pHashEntry->HashAlgorithm;
  787. }
  788. else
  789. hr = E_NOTIMPL;
  790. }
  791. else
  792. hr = E_FAIL;
  793. return hr;
  794. }
  795. HRESULT CSaferEntry::SetHash (
  796. BYTE rgbFileHash[],
  797. DWORD cbFileHash,
  798. __int64 nFileSize,
  799. ALG_ID hashAlgid)
  800. {
  801. ASSERT (cbFileHash <= SAFER_MAX_HASH_SIZE);
  802. if ( cbFileHash > SAFER_MAX_HASH_SIZE )
  803. return E_FAIL;
  804. ASSERT (rgbFileHash);
  805. if ( !rgbFileHash )
  806. return E_POINTER;
  807. m_nHashFileSize = nFileSize;
  808. m_cbFileHash = cbFileHash;
  809. ::ZeroMemory (m_rgbFileHash, SAFER_MAX_HASH_SIZE);
  810. memcpy (m_rgbFileHash, rgbFileHash, cbFileHash);
  811. m_hashAlgid = hashAlgid;
  812. return S_OK;
  813. }
  814. DWORD CSaferEntry::GetURLZoneID() const
  815. {
  816. return m_UrlZoneId;
  817. }
  818. void CSaferEntry::SetURLZoneID(DWORD dwURLZoneID)
  819. {
  820. m_UrlZoneId = dwURLZoneID;
  821. }
  822. CString CSaferEntry::GetHashFriendlyName()
  823. {
  824. CString szFriendlyName;
  825. if ( m_szHashFriendlyName.IsEmpty () )
  826. {
  827. if ( m_pAuthzInfo )
  828. {
  829. if ( SaferIdentityTypeImageHash == m_pAuthzInfo->dwIdentificationType )
  830. {
  831. PSAFER_HASH_IDENTIFICATION pHashEntry =
  832. (PSAFER_HASH_IDENTIFICATION) m_pAuthzInfo;
  833. ASSERT (pHashEntry->header.cbStructSize ==
  834. sizeof (SAFER_HASH_IDENTIFICATION));
  835. m_szHashFriendlyName = pHashEntry->FriendlyName;
  836. }
  837. }
  838. }
  839. return m_szHashFriendlyName;
  840. }
  841. void CSaferEntry::SetHashFriendlyName(const CString &szFriendlyName)
  842. {
  843. m_szHashFriendlyName = szFriendlyName;
  844. }
  845. int CSaferEntry::CompareLastModified (const CSaferEntry& saferEntry) const
  846. {
  847. int compVal = 0;
  848. FILETIME thisFt;
  849. FILETIME inFt;
  850. if ( m_pAuthzInfo )
  851. thisFt = m_pAuthzInfo->lastModified;
  852. else if ( m_pCertificate )
  853. {
  854. if ( FAILED (m_pCertificate->GetLastModifiedFileTime (thisFt)) )
  855. return 0;
  856. }
  857. else
  858. {
  859. ASSERT (0);
  860. return 0;
  861. }
  862. if ( saferEntry.m_pAuthzInfo )
  863. inFt = saferEntry.m_pAuthzInfo->lastModified;
  864. else if ( saferEntry.m_pCertificate )
  865. {
  866. if ( FAILED (saferEntry.m_pCertificate->GetLastModifiedFileTime (inFt)) )
  867. return 0;
  868. }
  869. else
  870. {
  871. ASSERT (0);
  872. return 0;
  873. }
  874. compVal = ::CompareFileTime (&thisFt, &inFt);
  875. return compVal;
  876. }
  877. CString CSaferEntry::GetRSOPRegistryKey () const
  878. {
  879. CString szRegistryKey;
  880. if ( m_pCertificate )
  881. {
  882. if ( SAFER_LEVELID_FULLYTRUSTED == m_dwLevelID )
  883. szRegistryKey = CERT_TRUST_PUB_SAFER_GROUP_POLICY_TRUSTED_PUBLISHER_STORE_REGPATH;
  884. else
  885. szRegistryKey = CERT_TRUST_PUB_SAFER_GROUP_POLICY_DISALLOWED_STORE_REGPATH;
  886. szRegistryKey += STR_REGKEY_CERTIFICATES;
  887. szRegistryKey += L"\\";
  888. //szRegistryKey += m_pCertificate->GetMD5Hash ();
  889. szRegistryKey += m_pCertificate->GetSHAHash ();
  890. }
  891. else
  892. szRegistryKey = m_szRSOPRegistryKey;
  893. ASSERT (!szRegistryKey.IsEmpty ());
  894. return szRegistryKey;
  895. }
  896. void CSaferEntry::Refresh()
  897. {
  898. _TRACE (1, L"Entering CSaferEntry::Refresh ()\n");
  899. if ( m_pAuthzInfo )
  900. {
  901. if ( m_pGPEInformation )
  902. {
  903. SAFER_LEVEL_HANDLE hLevel = 0;
  904. CPolicyKey policyKey (m_pGPEInformation,
  905. SAFER_HKLM_REGBASE,
  906. m_bIsComputer);
  907. BOOL bRVal = SaferCreateLevel(SAFER_SCOPEID_REGISTRY,
  908. m_dwLevelID,
  909. SAFER_LEVEL_OPEN,
  910. &hLevel,
  911. policyKey.GetKey ());
  912. if ( bRVal )
  913. {
  914. DWORD dwBufferSize = sizeof (SAFER_IDENTIFICATION_HEADER);
  915. bRVal = SaferGetLevelInformation (hLevel,
  916. SaferObjectSingleIdentification,
  917. m_pAuthzInfo,
  918. dwBufferSize,
  919. &dwBufferSize);
  920. if ( !bRVal && ERROR_INSUFFICIENT_BUFFER == GetLastError () )
  921. {
  922. PBYTE pBytes = (PBYTE) LocalAlloc (LPTR, dwBufferSize);
  923. if ( pBytes )
  924. {
  925. PSAFER_IDENTIFICATION_HEADER pCommon = (PSAFER_IDENTIFICATION_HEADER) pBytes;
  926. pCommon->cbStructSize = dwBufferSize;
  927. memcpy (&pCommon->IdentificationGuid, &m_pAuthzInfo->IdentificationGuid, sizeof (GUID));
  928. bRVal = SaferGetLevelInformation (hLevel,
  929. SaferObjectSingleIdentification,
  930. pBytes,
  931. dwBufferSize,
  932. &dwBufferSize);
  933. ASSERT (bRVal);
  934. if ( bRVal )
  935. {
  936. LocalFree (m_pAuthzInfo);
  937. m_pAuthzInfo = (PSAFER_IDENTIFICATION_HEADER) pBytes;
  938. }
  939. else
  940. {
  941. _TRACE (0, L"SaferGetLevelInformation () failed: %d\n", GetLastError ());
  942. }
  943. }
  944. }
  945. VERIFY (SaferCloseLevel(hLevel));
  946. }
  947. else
  948. {
  949. _TRACE (0, L"SaferCreateLevel() failed: %d\n", GetLastError ());
  950. }
  951. }
  952. else
  953. {
  954. // Is RSOP
  955. }
  956. }
  957. _TRACE (-1, L"Leaving CSaferEntry::Refresh ()\n");
  958. }