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.

1173 lines
39 KiB

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