1078 lines
38 KiB
C++
1078 lines
38 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997-2001.
|
|
//
|
|
// File: cmponent.cpp
|
|
//
|
|
// Contents: Implementation of CCertMgrComponent
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <gpedit.h>
|
|
#include "compdata.h" // CCertMgrComponentData
|
|
#include "cmponent.h" // CCertMgrComponent
|
|
#include "SaferLevel.h"
|
|
#include "SaferEntry.h"
|
|
#include "storeGPE.h"
|
|
#include "SaferUtil.h"
|
|
#include "PolicyKey.h"
|
|
|
|
#ifdef _DEBUG
|
|
#ifndef ALPHA
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
HKEY g_hkeyLastSaferRegistryScope = 0;
|
|
extern PCWSTR pcszNEWLINE;
|
|
|
|
|
|
HRESULT CCertMgrComponent::AddSaferLevels(
|
|
bool bIsComputer,
|
|
PCWSTR pszServerName,
|
|
HKEY hGroupPolicyKey)
|
|
{
|
|
_TRACE (1, L"Entering CCertMgrComponent::AddSaferLevels ()\n");
|
|
HRESULT hr = S_OK;
|
|
CWaitCursor cursor;
|
|
CCertMgrComponentData& dataRef = QueryComponentDataRef ();
|
|
|
|
if ( dataRef.m_pdwSaferLevels )
|
|
{
|
|
for (UINT nIndex = 0;
|
|
NO_MORE_SAFER_LEVELS != dataRef.m_pdwSaferLevels[nIndex] && SUCCEEDED (hr);
|
|
nIndex++)
|
|
{
|
|
CString szLevel;
|
|
|
|
switch (dataRef.m_pdwSaferLevels[nIndex])
|
|
{
|
|
case SAFER_LEVELID_FULLYTRUSTED:
|
|
case SAFER_LEVELID_CONSTRAINED:
|
|
case SAFER_LEVELID_DISALLOWED:
|
|
case SAFER_LEVELID_NORMALUSER:
|
|
case SAFER_LEVELID_UNTRUSTED:
|
|
szLevel = SaferGetLevelFriendlyName (dataRef.m_pdwSaferLevels[nIndex],
|
|
hGroupPolicyKey, bIsComputer);
|
|
hr = AddLevel (szLevel, dataRef.m_pdwSaferLevels[nIndex],
|
|
bIsComputer,
|
|
pszServerName);
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
_TRACE (0, L"Unexpected safer level while enumerating levels: 0x%x\n",
|
|
dataRef.m_pdwSaferLevels[nIndex]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::AddSaferLevels (): 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
HRESULT CCertMgrComponent::AddLevel (
|
|
const CString& szLevel,
|
|
DWORD dwLevel,
|
|
bool fIsMachine,
|
|
PCWSTR pszServerName)
|
|
{
|
|
_TRACE (1, L"Entering CCertMgrComponent::AddLevel ()\n");
|
|
HRESULT hr = S_OK;
|
|
CCertMgrComponentData& dataRef = QueryComponentDataRef ();
|
|
CCookie& rootCookie = dataRef.QueryBaseRootCookie ();
|
|
|
|
|
|
RESULTDATAITEM rdItem;
|
|
::ZeroMemory (&rdItem, sizeof (rdItem));
|
|
rdItem.mask = RDI_STR | RDI_PARAM | RDI_IMAGE;
|
|
rdItem.nCol = 0;
|
|
|
|
CSaferLevel* pNewLevel = new CSaferLevel (
|
|
dwLevel,
|
|
fIsMachine,
|
|
pszServerName,
|
|
szLevel,
|
|
dataRef.m_pGPEInformation,
|
|
fIsMachine ?
|
|
dataRef.m_rsopObjectArrayComputer :
|
|
dataRef.m_rsopObjectArrayUser);
|
|
if ( pNewLevel )
|
|
{
|
|
if ( pNewLevel->IsDefault () )
|
|
{
|
|
rdItem.nImage = iIconDefaultSaferLevel;
|
|
dataRef.m_dwDefaultSaferLevel = pNewLevel->GetLevel ();
|
|
}
|
|
else
|
|
rdItem.nImage = iIconSaferLevel;
|
|
rootCookie.m_listResultCookieBlocks.AddHead (pNewLevel);
|
|
rdItem.str = MMC_TEXTCALLBACK ;
|
|
rdItem.lParam = (LPARAM) pNewLevel;
|
|
pNewLevel->m_resultDataID = m_pResultData;
|
|
hr = m_pResultData->InsertItem (&rdItem);
|
|
if ( FAILED (hr) )
|
|
{
|
|
_TRACE (0, L"IResultData::InsertItem () failed: 0x%x\n", hr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::AddLevel () : 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertMgrComponent::SaferEnumerateEntries (
|
|
bool bIsComputer,
|
|
CSaferEntries* pSaferEntries)
|
|
{
|
|
if ( !pSaferEntries )
|
|
return E_POINTER;
|
|
|
|
_TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateEntries ()\n");
|
|
HRESULT hr = S_OK;
|
|
CCertMgrComponentData& dataRef = QueryComponentDataRef ();
|
|
|
|
if ( dataRef.m_pGPEInformation )
|
|
{
|
|
CPolicyKey policyKey (dataRef.m_pGPEInformation,
|
|
SAFER_HKLM_REGBASE,
|
|
bIsComputer);
|
|
hr = SetRegistryScope (policyKey.GetKey (), bIsComputer);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
hr = SaferEnumerateNonCertEntries (policyKey.GetKey (),
|
|
bIsComputer);
|
|
|
|
hr = SaferEnumerateCertEntries (
|
|
bIsComputer,
|
|
pSaferEntries);
|
|
}
|
|
}
|
|
else if ( dataRef.m_bIsRSOP )
|
|
{
|
|
hr = SaferEnumerateRSOPNonCertEntries (bIsComputer, pSaferEntries);
|
|
|
|
hr = SaferEnumerateCertEntries (bIsComputer,
|
|
pSaferEntries);
|
|
}
|
|
else
|
|
hr = E_UNEXPECTED;
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateEntries () : 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertMgrComponent::SaferEnumerateRSOPNonCertEntries (
|
|
bool bIsComputer,
|
|
CSaferEntries* pSaferEntries)
|
|
{
|
|
if ( !pSaferEntries )
|
|
return E_POINTER;
|
|
|
|
_TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateRSOPNonCertEntries\n");
|
|
HRESULT hr = S_OK;
|
|
int nIndex = 0;
|
|
CCertMgrComponentData& dataRef = QueryComponentDataRef ();
|
|
CString szKeyStart (SAFER_HKLM_REGBASE);
|
|
const CRSOPObjectArray* pObjectArray = bIsComputer ?
|
|
dataRef.GetRSOPObjectArrayComputer () : dataRef.GetRSOPObjectArrayUser ();
|
|
INT_PTR nUpperBound = pObjectArray->GetUpperBound ();
|
|
|
|
szKeyStart += L"\\";
|
|
szKeyStart += SAFER_CODEIDS_REGSUBKEY;
|
|
size_t nKeyStartLen = wcslen (szKeyStart);
|
|
|
|
// Skip the common text and get the level
|
|
long dwLevel = 0;
|
|
long dwPreviousLevel = 0;
|
|
CString szLevel;
|
|
CString szType; // hash, url, path
|
|
SAFER_ENTRY_TYPE type = SAFER_ENTRY_TYPE_UNKNOWN; // hash, url, path
|
|
SAFER_ENTRY_TYPE previousType = SAFER_ENTRY_TYPE_UNKNOWN;
|
|
CString szGUID;
|
|
GUID guid;
|
|
::ZeroMemory (&guid, sizeof (GUID));
|
|
bool bCreateNew = false;
|
|
PSAFER_IDENTIFICATION_HEADER pCaiCommon = 0;
|
|
CString szPreviousKey;
|
|
CString szKey;
|
|
CRSOPObject* pCurrObject = 0;
|
|
|
|
|
|
while ( nUpperBound >= nIndex )
|
|
{
|
|
if ( pCurrObject )
|
|
szPreviousKey = pCurrObject->GetRegistryKey ();
|
|
|
|
pCurrObject = pObjectArray->GetAt (nIndex);
|
|
if ( pCurrObject )
|
|
{
|
|
szKey = pCurrObject->GetRegistryKey ();
|
|
if ( !wcsncmp (szKey, szKeyStart, nKeyStartLen) )
|
|
{
|
|
szKey = szKey.Right ((int) (wcslen (szKey) - (nKeyStartLen + 1)));
|
|
|
|
if ( !szKey.IsEmpty () )
|
|
{
|
|
// get level
|
|
int nPos = szKey.Find (L'\\');
|
|
szLevel = szKey.Left (nPos);
|
|
dwPreviousLevel = dwLevel;
|
|
dwLevel = wcstol(szLevel, 0, 10);
|
|
szKey = szKey.Right ((int)(wcslen (szKey) - (nPos + 1)));
|
|
|
|
// get type
|
|
nPos = szKey.Find (L'\\');
|
|
szType = szKey.Left (nPos);
|
|
if ( SAFER_PATHS_REGSUBKEY == szType )
|
|
type = SAFER_ENTRY_TYPE_PATH;
|
|
else if ( SAFER_HASHMD5_REGSUBKEY == szType )
|
|
type = SAFER_ENTRY_TYPE_HASH;
|
|
else if ( SAFER_SOURCEURL_REGSUBKEY == szType )
|
|
type = SAFER_ENTRY_TYPE_URLZONE;
|
|
else
|
|
{
|
|
ASSERT (0);
|
|
}
|
|
|
|
if ( SAFER_ENTRY_TYPE_UNKNOWN == previousType )
|
|
previousType = type;
|
|
|
|
szKey = szKey.Right ((int) (wcslen (szKey) - (nPos + 1)));
|
|
|
|
// get guid
|
|
if ( szKey != szGUID )
|
|
{
|
|
szGUID = szKey;
|
|
if ( !GuidFromString (&guid, szGUID) )
|
|
continue;
|
|
|
|
bCreateNew = true;
|
|
}
|
|
else
|
|
bCreateNew = false;
|
|
|
|
if ( bCreateNew && pCaiCommon )
|
|
{
|
|
// If we were working on an old one, create the
|
|
// CSaferEntry with the available information and add
|
|
// it to the result pane
|
|
hr = SaferFinishEntryAndAdd (previousType, pCaiCommon,
|
|
bIsComputer, dwPreviousLevel, pSaferEntries,
|
|
szPreviousKey);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
pCaiCommon = 0;
|
|
}
|
|
else if ( E_OUTOFMEMORY == hr )
|
|
{
|
|
::LocalFree (pCaiCommon);
|
|
pCaiCommon = 0;
|
|
}
|
|
|
|
|
|
previousType = type;
|
|
}
|
|
|
|
switch (type)
|
|
{
|
|
case SAFER_ENTRY_TYPE_PATH:
|
|
if ( bCreateNew )
|
|
{
|
|
ASSERT (!pCaiCommon);
|
|
pCaiCommon = (PSAFER_IDENTIFICATION_HEADER)
|
|
::LocalAlloc (LPTR, sizeof (SAFER_PATHNAME_IDENTIFICATION));
|
|
if ( pCaiCommon )
|
|
{
|
|
((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->header.cbStructSize =
|
|
sizeof (SAFER_PATHNAME_IDENTIFICATION);
|
|
memcpy (&((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->header.IdentificationGuid,
|
|
&guid, sizeof (GUID));
|
|
((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->header.dwIdentificationType =
|
|
SaferIdentityTypeImageName;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
if ( SUCCEEDED (hr) && pCaiCommon )
|
|
{
|
|
if ( SAFER_IDS_DESCRIPTION_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
BSTR bstr = 0;
|
|
if ( SUCCEEDED (pCurrObject->GetBSTR (&bstr)) )
|
|
{
|
|
wcsncpy (((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->Description,
|
|
bstr,
|
|
SAFER_MAX_DESCRIPTION_SIZE);
|
|
SysFreeString (bstr);
|
|
}
|
|
}
|
|
else if ( SAFER_IDS_ITEMDATA_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
ASSERT ( MAX_PATH * sizeof (WCHAR) >= pCurrObject->GetBlobLength ());
|
|
((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->ImageName =
|
|
(PWCHAR) pCurrObject->GetBlob ();
|
|
}
|
|
else if ( SAFER_IDS_LASTMODIFIED_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
pCurrObject->GetFileTime (
|
|
((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->header.lastModified);
|
|
}
|
|
else if ( SAFER_IDS_SAFERFLAGS_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->dwSaferFlags =
|
|
pCurrObject->GetDWORDValue ();
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_HASH:
|
|
if ( bCreateNew )
|
|
{
|
|
ASSERT (!pCaiCommon);
|
|
pCaiCommon = (PSAFER_IDENTIFICATION_HEADER)
|
|
::LocalAlloc (LPTR, sizeof (SAFER_HASH_IDENTIFICATION));
|
|
if ( pCaiCommon )
|
|
{
|
|
((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->header.cbStructSize =
|
|
sizeof (SAFER_HASH_IDENTIFICATION);
|
|
memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->header.IdentificationGuid,
|
|
&guid, sizeof (GUID));
|
|
((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->header.dwIdentificationType =
|
|
SaferIdentityTypeImageHash;
|
|
// NTRAID# 424997 SAFER: File hash not displayed on hash rule property sheets in RSOP mode.
|
|
((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->HashSize = 16;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
if ( SUCCEEDED (hr) && pCaiCommon && !pCurrObject->GetValueName ().IsEmpty () )
|
|
{
|
|
if ( SAFER_IDS_ITEMDATA_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
ASSERT (SAFER_MAX_HASH_SIZE >= pCurrObject->GetBlobLength ());
|
|
memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->ImageHash,
|
|
pCurrObject->GetBlob (),
|
|
pCurrObject->GetBlobLength ());
|
|
}
|
|
else if ( SAFER_IDS_LASTMODIFIED_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
pCurrObject->GetFileTime (
|
|
((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->header.lastModified);
|
|
}
|
|
else if ( SAFER_IDS_SAFERFLAGS_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->dwSaferFlags =
|
|
pCurrObject->GetDWORDValue ();
|
|
}
|
|
else if ( SAFER_IDS_FRIENDLYNAME_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
BSTR bstr = 0;
|
|
if ( SUCCEEDED (pCurrObject->GetBSTR (&bstr)) )
|
|
{
|
|
wcsncpy (((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->FriendlyName,
|
|
bstr,
|
|
SAFER_MAX_FRIENDLYNAME_SIZE);
|
|
SysFreeString (bstr);
|
|
}
|
|
}
|
|
else if ( SAFER_IDS_HASHALG_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
ASSERT (sizeof (ALG_ID) == pCurrObject->GetBlobLength ()); memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->HashAlgorithm,
|
|
pCurrObject->GetBlob (),
|
|
pCurrObject->GetBlobLength ());
|
|
}
|
|
else if ( SAFER_IDS_ITEMSIZE_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
ASSERT (sizeof (LARGE_INTEGER) == pCurrObject->GetBlobLength ());
|
|
memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->ImageSize,
|
|
pCurrObject->GetBlob (),
|
|
pCurrObject->GetBlobLength ());
|
|
}
|
|
else if ( SAFER_IDS_DESCRIPTION_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
BSTR bstr = 0;
|
|
if ( SUCCEEDED (pCurrObject->GetBSTR (&bstr)) )
|
|
{
|
|
wcsncpy (((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->Description,
|
|
bstr,
|
|
SAFER_MAX_DESCRIPTION_SIZE);
|
|
SysFreeString (bstr);
|
|
}
|
|
}
|
|
else if ( SAFER_VALUE_NAME_HASH_SIZE == pCurrObject->GetValueName () )
|
|
{
|
|
ASSERT (sizeof (LARGE_INTEGER) == pCurrObject->GetBlobLength ());
|
|
memcpy (&((SAFER_HASH_IDENTIFICATION*)pCaiCommon)->HashSize,
|
|
pCurrObject->GetBlob (),
|
|
pCurrObject->GetBlobLength ());
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_URLZONE:
|
|
if ( bCreateNew )
|
|
{
|
|
ASSERT (!pCaiCommon);
|
|
pCaiCommon = (PSAFER_IDENTIFICATION_HEADER)
|
|
::LocalAlloc (LPTR, sizeof (SAFER_URLZONE_IDENTIFICATION));
|
|
if ( pCaiCommon )
|
|
{
|
|
((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->header.cbStructSize =
|
|
sizeof (SAFER_URLZONE_IDENTIFICATION);
|
|
memcpy (&((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->header.IdentificationGuid,
|
|
&guid, sizeof (GUID));
|
|
((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->header.dwIdentificationType =
|
|
SaferIdentityTypeUrlZone;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
if ( SUCCEEDED (hr) && pCaiCommon )
|
|
{
|
|
if ( SAFER_IDS_ITEMDATA_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
memcpy (&((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->UrlZoneId,
|
|
pCurrObject->GetBlob (),
|
|
pCurrObject->GetBlobLength ());
|
|
#if DBG
|
|
SAFER_URLZONE_IDENTIFICATION* pCaiUrlZone =
|
|
(SAFER_URLZONE_IDENTIFICATION*) pCaiCommon;
|
|
ASSERT (URLZONE_LOCAL_MACHINE == pCaiUrlZone->UrlZoneId ||
|
|
URLZONE_INTRANET == pCaiUrlZone->UrlZoneId ||
|
|
URLZONE_TRUSTED == pCaiUrlZone->UrlZoneId ||
|
|
URLZONE_INTERNET == pCaiUrlZone->UrlZoneId ||
|
|
URLZONE_UNTRUSTED == pCaiUrlZone->UrlZoneId);
|
|
#endif DBG
|
|
}
|
|
else if ( SAFER_IDS_LASTMODIFIED_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
pCurrObject->GetFileTime (
|
|
((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->header.lastModified);
|
|
}
|
|
else if ( SAFER_IDS_SAFERFLAGS_REGVALUE == pCurrObject->GetValueName () )
|
|
{
|
|
((SAFER_URLZONE_IDENTIFICATION*)pCaiCommon)->dwSaferFlags =
|
|
pCurrObject->GetDWORDValue ();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
nIndex++;
|
|
}
|
|
|
|
if ( pCaiCommon )
|
|
{
|
|
// If we were working on an old one, create the
|
|
// CSaferEntry with the available information and add
|
|
// it to the result pane
|
|
hr = SaferFinishEntryAndAdd (previousType, pCaiCommon,
|
|
bIsComputer, dwLevel, pSaferEntries,
|
|
szPreviousKey);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
pCaiCommon = 0;
|
|
}
|
|
else if ( E_OUTOFMEMORY == hr )
|
|
{
|
|
::LocalFree (pCaiCommon);
|
|
pCaiCommon = 0;
|
|
}
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateRSOPNonCertEntries: 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertMgrComponent::SaferFinishEntryAndAdd (SAFER_ENTRY_TYPE previousType,
|
|
PSAFER_IDENTIFICATION_HEADER pCaiCommon,
|
|
bool bIsComputer,
|
|
long dwLevel,
|
|
CSaferEntries* pSaferEntries,
|
|
const CString& szPreviousKey)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CString szSubjectName;
|
|
switch (previousType)
|
|
{
|
|
case SAFER_ENTRY_TYPE_PATH:
|
|
szSubjectName = ((SAFER_PATHNAME_IDENTIFICATION*)pCaiCommon)->ImageName;
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_HASH:
|
|
szSubjectName = ((PSAFER_HASH_IDENTIFICATION) (pCaiCommon))->FriendlyName;
|
|
szSubjectName.Replace (pcszNEWLINE, L" ");
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_URLZONE:
|
|
szSubjectName = GetURLZoneFriendlyName (
|
|
((SAFER_URLZONE_IDENTIFICATION*) pCaiCommon)->UrlZoneId);
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
ASSERT (pCaiCommon);
|
|
if ( pCaiCommon )
|
|
{
|
|
hr = InsertNewSaferEntry (
|
|
previousType,
|
|
bIsComputer,
|
|
szSubjectName,
|
|
pCaiCommon,
|
|
dwLevel,
|
|
pSaferEntries,
|
|
QueryComponentDataRef ().m_pGPEInformation,
|
|
0,
|
|
szPreviousKey);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertMgrComponent::InsertNewSaferEntry (
|
|
SAFER_ENTRY_TYPE type,
|
|
bool bIsComputer,
|
|
PCWSTR pwcszObjectName,
|
|
PSAFER_IDENTIFICATION_HEADER pCaiCommon,
|
|
DWORD dwLevel,
|
|
CSaferEntries* pSaferEntries,
|
|
IGPEInformation* pGPEInformation,
|
|
CCertificate* pCert,
|
|
PCWSTR pszRSOPRegistryKey)
|
|
{
|
|
_TRACE (1, L"Entering CCertMgrComponent::InsertNewSaferEntry (%s)\n", pwcszObjectName);
|
|
HRESULT hr = S_OK;
|
|
|
|
switch (type)
|
|
{
|
|
case SAFER_ENTRY_TYPE_PATH:
|
|
ASSERT (pCaiCommon &&
|
|
SaferIdentityTypeImageName == pCaiCommon->dwIdentificationType);
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_HASH:
|
|
ASSERT (pCaiCommon &&
|
|
SaferIdentityTypeImageHash == pCaiCommon->dwIdentificationType);
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_URLZONE:
|
|
ASSERT (pCaiCommon &&
|
|
SaferIdentityTypeUrlZone == pCaiCommon->dwIdentificationType);
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_CERT:
|
|
ASSERT (pCert);
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
CSaferEntry* pNewEntry = new CSaferEntry (
|
|
type,
|
|
bIsComputer,
|
|
L"",
|
|
pwcszObjectName,
|
|
pCaiCommon,
|
|
dwLevel,
|
|
pGPEInformation,
|
|
pCert,
|
|
pSaferEntries,
|
|
bIsComputer ? QueryComponentDataRef ().m_rsopObjectArrayComputer :
|
|
QueryComponentDataRef ().m_rsopObjectArrayUser,
|
|
pszRSOPRegistryKey);
|
|
if ( pNewEntry )
|
|
{
|
|
RESULTDATAITEM rdItem;
|
|
|
|
::ZeroMemory (&rdItem, sizeof (rdItem));
|
|
rdItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM;
|
|
switch (type)
|
|
{
|
|
case SAFER_ENTRY_TYPE_HASH:
|
|
rdItem.nImage = iIconSaferHashEntry;
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_PATH:
|
|
rdItem.nImage = iIconSaferNameEntry;
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_CERT:
|
|
rdItem.nImage = iIconSaferCertEntry;
|
|
break;
|
|
|
|
case SAFER_ENTRY_TYPE_URLZONE:
|
|
rdItem.nImage = iIconSaferURLEntry;
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
rdItem.nCol = 0;
|
|
rdItem.str = MMC_TEXTCALLBACK;
|
|
QueryComponentDataRef ().QueryBaseRootCookie ().m_listResultCookieBlocks.AddHead (pNewEntry);
|
|
rdItem.lParam = (LPARAM) pNewEntry;
|
|
pNewEntry->m_resultDataID = m_pResultData;
|
|
hr = m_pResultData->InsertItem (&rdItem);
|
|
if ( FAILED (hr) )
|
|
{
|
|
_TRACE (0, L"IResultData::InsertItem () failed: 0x%x\n", hr);
|
|
}
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::InsertNewSaferEntry (%s): 0x%x\n", pwcszObjectName, hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertMgrComponent::SaferEnumerateNonCertEntries (
|
|
HKEY hGroupPolicyKey,
|
|
bool bIsComputer)
|
|
{
|
|
_TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateNonCertEntries ()\n");
|
|
ASSERT (0 != g_hkeyLastSaferRegistryScope);
|
|
HRESULT hr = S_OK;
|
|
DWORD* pdwLevels = 0;
|
|
DWORD cbBuffer = 0;
|
|
|
|
SetRegistryScope (hGroupPolicyKey, bIsComputer);
|
|
BOOL bRVal = SaferGetPolicyInformation (
|
|
SAFER_SCOPEID_REGISTRY,
|
|
SaferPolicyLevelList,
|
|
cbBuffer,
|
|
pdwLevels,
|
|
&cbBuffer,
|
|
0);
|
|
if ( !bRVal && GetLastError () == ERROR_INSUFFICIENT_BUFFER )
|
|
{
|
|
DWORD nLevels = cbBuffer/sizeof (DWORD);
|
|
pdwLevels = new DWORD[nLevels];
|
|
if ( pdwLevels )
|
|
{
|
|
bRVal = SaferGetPolicyInformation (
|
|
SAFER_SCOPEID_REGISTRY,
|
|
SaferPolicyLevelList,
|
|
cbBuffer,
|
|
pdwLevels,
|
|
&cbBuffer,
|
|
0);
|
|
ASSERT (bRVal);
|
|
if ( bRVal )
|
|
{
|
|
for (DWORD dwIndex = 0; dwIndex < nLevels; dwIndex++)
|
|
{
|
|
hr = SaferEnumerateEntriesAtLevel (
|
|
bIsComputer,
|
|
hGroupPolicyKey,
|
|
pdwLevels[dwIndex]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
_TRACE (0, L"SaferGetPolicyInformation (SAFER_SCOPEID_REGISTRY, SaferPolicyLevelList) failed: %d\n",
|
|
dwErr);
|
|
}
|
|
delete [] pdwLevels;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else if ( !bRVal )
|
|
{
|
|
ASSERT (0);
|
|
DWORD dwErr = GetLastError ();
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
_TRACE (0, L"SaferGetPolicyInformation (SAFER_SCOPEID_REGISTRY, SaferPolicyLevelList) failed: %d\n",
|
|
dwErr);
|
|
}
|
|
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateNonCertEntries (): 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertMgrComponent::SaferEnumerateCertEntries (
|
|
bool bIsComputer,
|
|
CSaferEntries* pSaferEntries)
|
|
{
|
|
if ( !pSaferEntries )
|
|
return E_POINTER;
|
|
|
|
_TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateCertEntries ()\n");
|
|
HRESULT hr = S_OK;
|
|
CCertStore* pTrustedPublisherStore = 0;
|
|
hr = pSaferEntries->GetTrustedPublishersStore (&pTrustedPublisherStore);
|
|
if ( pTrustedPublisherStore )
|
|
{
|
|
hr = EnumSaferCertificates (
|
|
bIsComputer,
|
|
*pTrustedPublisherStore,
|
|
pSaferEntries);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
m_currResultNodeType = bIsComputer ?
|
|
CERTMGR_SAFER_COMPUTER_ENTRY : CERTMGR_SAFER_USER_ENTRY;
|
|
m_pResultData->Sort (m_nSelectedSaferEntryColumn, 0,
|
|
(long) m_currResultNodeType);
|
|
}
|
|
|
|
pTrustedPublisherStore->Release ();
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
CCertStore* pDisallowedStore = 0;
|
|
hr = pSaferEntries->GetDisallowedStore (&pDisallowedStore);
|
|
if ( pDisallowedStore )
|
|
{
|
|
hr = EnumSaferCertificates (
|
|
bIsComputer,
|
|
*pDisallowedStore,
|
|
pSaferEntries);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
m_currResultNodeType = bIsComputer ?
|
|
CERTMGR_SAFER_COMPUTER_ENTRY : CERTMGR_SAFER_USER_ENTRY;
|
|
m_pResultData->Sort (m_nSelectedSaferEntryColumn, 0,
|
|
(long) m_currResultNodeType);
|
|
}
|
|
|
|
pDisallowedStore->Release ();
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateCertEntries (): 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertMgrComponent::EnumSaferCertificates (
|
|
bool bIsComputer,
|
|
CCertStore& rCertStore,
|
|
CSaferEntries* pSaferEntries)
|
|
{
|
|
if ( !pSaferEntries )
|
|
return E_POINTER;
|
|
|
|
_TRACE (1, L"Entering CCertMgrComponent::EnumCertificates\n");
|
|
CWaitCursor cursor;
|
|
PCCERT_CONTEXT pCertContext = 0;
|
|
HRESULT hr = 0;
|
|
CCertificate* pCert = 0;
|
|
DWORD dwLevelID = SAFER_TRUSTED_PUBLISHER_STORE == rCertStore.GetStoreType () ?
|
|
SAFER_LEVELID_FULLYTRUSTED : SAFER_LEVELID_DISALLOWED;
|
|
|
|
// Iterate through the list of certificates in the system store,
|
|
// allocate new certificates with the CERT_CONTEXT returned,
|
|
// and store them in the certificate list.
|
|
while ( 1 )
|
|
{
|
|
pCertContext = rCertStore.EnumCertificates (pCertContext);
|
|
if ( !pCertContext )
|
|
break;
|
|
|
|
pCert =
|
|
new CCertificate (pCertContext, &rCertStore);
|
|
if ( pCert )
|
|
{
|
|
hr = InsertNewSaferEntry (SAFER_ENTRY_TYPE_CERT,
|
|
bIsComputer,
|
|
pCert->GetSubjectName (),
|
|
0,
|
|
dwLevelID,
|
|
pSaferEntries,
|
|
QueryComponentDataRef ().m_pGPEInformation,
|
|
pCert);
|
|
if ( FAILED (hr) )
|
|
break;
|
|
pCert->Release ();
|
|
}
|
|
else
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
}
|
|
rCertStore.Close ();
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::EnumCertificates: 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertMgrComponent::SaferEnumerateEntriesAtLevel (
|
|
bool bIsComputer,
|
|
HKEY hGroupPolicyKey,
|
|
DWORD dwLevel)
|
|
{
|
|
_TRACE (1, L"Entering CCertMgrComponent::SaferEnumerateEntriesAtLevel (%d)\n", dwLevel);
|
|
SetRegistryScope (hGroupPolicyKey, bIsComputer);
|
|
HRESULT hr = S_OK;
|
|
SAFER_LEVEL_HANDLE hLevel = 0;
|
|
BOOL bRVal = SaferCreateLevel (SAFER_SCOPEID_REGISTRY,
|
|
dwLevel,
|
|
SAFER_LEVEL_OPEN,
|
|
&hLevel,
|
|
hGroupPolicyKey);
|
|
ASSERT (bRVal);
|
|
if ( bRVal )
|
|
{
|
|
DWORD dwBufferSize = 0;
|
|
bRVal = SaferGetLevelInformation(hLevel,
|
|
SaferObjectAllIdentificationGuids,
|
|
0,
|
|
dwBufferSize,
|
|
&dwBufferSize);
|
|
if ( !bRVal && ERROR_INSUFFICIENT_BUFFER == GetLastError () )
|
|
{
|
|
DWORD nGuids = dwBufferSize/sizeof (GUID);
|
|
GUID* pGuids = new GUID[nGuids];
|
|
if ( pGuids )
|
|
{
|
|
bRVal = SaferGetLevelInformation(hLevel,
|
|
SaferObjectAllIdentificationGuids,
|
|
pGuids,
|
|
dwBufferSize,
|
|
&dwBufferSize);
|
|
ASSERT (bRVal);
|
|
if ( bRVal )
|
|
{
|
|
for (DWORD dwIndex = 0; dwIndex < nGuids; dwIndex++)
|
|
{
|
|
hr = SaferGetSingleEntry (bIsComputer, hLevel,
|
|
pGuids[dwIndex], dwLevel);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
_TRACE (0, L"SaferGetLevelInformation (SaferObjectAllIdentificationGuids) failed: %d\n",
|
|
dwErr);
|
|
}
|
|
delete [] pGuids;
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else if ( !bRVal )
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
ASSERT (ERROR_NOT_FOUND == dwErr);
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
_TRACE (0, L"SaferGetLevelInformation (SaferObjectAllIdentificationGuids) failed: %d\n",
|
|
dwErr);
|
|
}
|
|
|
|
VERIFY (SaferCloseLevel (hLevel));
|
|
}
|
|
else
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
_TRACE (0, L"SaferCreateLevel (SAFER_SCOPEID_REGISTRY, 0x%x, SAFER_LEVEL_OPEN) failed: %d\n",
|
|
dwLevel, dwErr);
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::SaferEnumerateEntriesAtLevel () : 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertMgrComponent::SaferGetSingleEntry(
|
|
bool bIsComputer,
|
|
SAFER_LEVEL_HANDLE hLevel,
|
|
GUID &rEntryGuid,
|
|
DWORD dwLevelID)
|
|
{
|
|
_TRACE (1, L"Entering CCertMgrComponent::SaferGetSingleEntry ()\n");
|
|
ASSERT (0 != g_hkeyLastSaferRegistryScope);
|
|
HRESULT hr = S_OK;
|
|
DWORD dwBufferSize = sizeof (SAFER_IDENTIFICATION_HEADER);
|
|
SAFER_IDENTIFICATION_HEADER caiCommon;
|
|
::ZeroMemory (&caiCommon, sizeof (SAFER_IDENTIFICATION_HEADER));
|
|
caiCommon.cbStructSize = dwBufferSize;
|
|
memcpy (&caiCommon.IdentificationGuid, &rEntryGuid, sizeof (GUID));
|
|
|
|
|
|
BOOL bRVal = SaferGetLevelInformation(hLevel,
|
|
SaferObjectSingleIdentification,
|
|
&caiCommon,
|
|
dwBufferSize,
|
|
&dwBufferSize);
|
|
if ( !bRVal && ERROR_INSUFFICIENT_BUFFER == GetLastError () )
|
|
{
|
|
PBYTE pBytes = (PBYTE) LocalAlloc (LPTR, dwBufferSize);
|
|
if ( pBytes )
|
|
{
|
|
SAFER_ENTRY_TYPE saferEntryType = SAFER_ENTRY_TYPE_UNKNOWN;
|
|
PSAFER_IDENTIFICATION_HEADER pCommon = (PSAFER_IDENTIFICATION_HEADER) pBytes;
|
|
pCommon->cbStructSize = dwBufferSize;
|
|
memcpy (&pCommon->IdentificationGuid, &rEntryGuid, sizeof (GUID));
|
|
|
|
bRVal = SaferGetLevelInformation(hLevel,
|
|
SaferObjectSingleIdentification,
|
|
pBytes,
|
|
dwBufferSize,
|
|
&dwBufferSize);
|
|
ASSERT (bRVal);
|
|
if ( bRVal )
|
|
{
|
|
CString szObjectName;
|
|
|
|
switch (pCommon->dwIdentificationType)
|
|
{
|
|
case SaferIdentityTypeImageName:
|
|
szObjectName = ((PSAFER_PATHNAME_IDENTIFICATION) (pCommon))->ImageName;
|
|
saferEntryType = SAFER_ENTRY_TYPE_PATH;
|
|
break;
|
|
|
|
case SaferIdentityTypeImageHash:
|
|
szObjectName = ((PSAFER_HASH_IDENTIFICATION) (pCommon))->FriendlyName;
|
|
|
|
// replace new-line characters with spaces
|
|
szObjectName.Replace (pcszNEWLINE, L" ");
|
|
saferEntryType = SAFER_ENTRY_TYPE_HASH;
|
|
break;
|
|
|
|
case SaferIdentityTypeUrlZone:
|
|
szObjectName = GetURLZoneFriendlyName (
|
|
((PSAFER_URLZONE_IDENTIFICATION) (pCommon))->UrlZoneId);
|
|
saferEntryType = SAFER_ENTRY_TYPE_URLZONE;
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
break;
|
|
}
|
|
|
|
hr = InsertNewSaferEntry (
|
|
saferEntryType,
|
|
bIsComputer,
|
|
szObjectName,
|
|
pCommon,
|
|
dwLevelID,
|
|
0,
|
|
QueryComponentDataRef ().m_pGPEInformation,
|
|
0);
|
|
if ( E_OUTOFMEMORY == hr )
|
|
::LocalFree (pBytes);
|
|
}
|
|
else
|
|
{
|
|
DWORD dwErr = GetLastError ();
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
_TRACE (0, L"SaferGetLevelInformation (SaferObjectSingleIdentification) failed: %d\n",
|
|
dwErr);
|
|
}
|
|
// pBytes is freed in ~CSaferEntry
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else if ( !bRVal )
|
|
{
|
|
ASSERT (0);
|
|
DWORD dwErr = GetLastError ();
|
|
hr = HRESULT_FROM_WIN32 (dwErr);
|
|
_TRACE (0, L"SaferGetLevelInformation (SaferObjectSingleIdentification) failed: %d\n",
|
|
dwErr);
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::SaferGetSingleEntry (): 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertMgrComponent::DeleteSaferEntryFromResultPane (
|
|
CSaferEntry * pSaferEntry,
|
|
LPDATAOBJECT pDataObject,
|
|
bool bDoCommit)
|
|
{
|
|
_TRACE (1, L"Entering CCertMgrComponent::DeleteSaferEntryFromResultPane\n");
|
|
HRESULT hr = S_OK;
|
|
hr = pSaferEntry->Delete (bDoCommit);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
HRESULTITEM itemID = 0;
|
|
hr = m_pResultData->FindItemByLParam ( (LPARAM) pSaferEntry, &itemID);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
hr = m_pResultData->DeleteItem (itemID, 0);
|
|
}
|
|
|
|
// If we can't succeed in removing this one item, then update the whole panel.
|
|
if ( !SUCCEEDED (hr) )
|
|
{
|
|
hr = m_pConsole->UpdateAllViews (pDataObject, 0, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CString text;
|
|
CString caption;
|
|
|
|
VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
|
|
text.FormatMessage (IDS_CANT_DELETE_SAFER_ENTRY, GetSystemMessage (hr));
|
|
int iRetVal = 0;
|
|
VERIFY (SUCCEEDED (m_pConsole->MessageBox (text, caption,
|
|
MB_OK, &iRetVal)));
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponent::DeleteSaferEntryFromResultPane: 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertMgrComponent::OnNotifyCanPasteOutOfProc (LPBOOL pbCanHandle)
|
|
{
|
|
if ( !pbCanHandle )
|
|
return E_POINTER;
|
|
|
|
CCertMgrComponentData& dataRef = QueryComponentDataRef ();
|
|
CLSID clsID;
|
|
if ( SUCCEEDED (dataRef.GetClassID (&clsID)) )
|
|
{
|
|
if ( CLSID_SaferWindowsExtension == clsID )
|
|
*pbCanHandle = TRUE;
|
|
}
|
|
|
|
return S_OK; // snapins should redefine this
|
|
}
|