diff options
author | danmosemsft <danmose@microsoft.com> | 2017-02-10 21:08:47 -0800 |
---|---|---|
committer | danmosemsft <danmose@microsoft.com> | 2017-02-10 21:36:09 -0800 |
commit | 1f75aecd267e4d2d322ce6a812a34d6a34cae1f9 (patch) | |
tree | f0b162c6ab8b4bf5fee43ae6191c6d4b47165e8a /src/vm | |
parent | 6517da4563a47fb370f35c082ae709215f5d0b28 (diff) | |
download | coreclr-1f75aecd267e4d2d322ce6a812a34d6a34cae1f9.tar.gz coreclr-1f75aecd267e4d2d322ce6a812a34d6a34cae1f9.tar.bz2 coreclr-1f75aecd267e4d2d322ce6a812a34d6a34cae1f9.zip |
Remove always undefined FEATURE_CAS_POLICY
Diffstat (limited to 'src/vm')
41 files changed, 1 insertions, 5852 deletions
diff --git a/src/vm/appdomainnative.cpp b/src/vm/appdomainnative.cpp index 02e96e2286..fd3897e7a4 100644 --- a/src/vm/appdomainnative.cpp +++ b/src/vm/appdomainnative.cpp @@ -280,12 +280,6 @@ void QCALLTYPE AppDomainNative::SetupDomainSecurity(QCall::AppDomainHandle pDoma } } -#ifdef FEATURE_CAS_POLICY - if (gc.orEvidence != NULL) - { - pSecDesc->SetEvidence(gc.orEvidence); - } -#endif // FEATURE_CAS_POLICY // We need to downgrade sharing level if the AppDomain is homogeneous and not fully trusted, or the // AppDomain is in legacy mode. Effectively, we need to be sure that all assemblies loaded into the @@ -859,39 +853,6 @@ void QCALLTYPE AppDomainNative::SetSecurityHomogeneousFlag(QCall::AppDomainHandl END_QCALL; } -#ifdef FEATURE_CAS_POLICY - -// static -void QCALLTYPE AppDomainNative::SetLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - IApplicationSecurityDescriptor *pAppSecDesc = adhTarget->GetSecurityDescriptor(); - pAppSecDesc->SetLegacyCasPolicyEnabled(); - - END_QCALL; -} - -// static -BOOL QCALLTYPE AppDomainNative::IsLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget) -{ - QCALL_CONTRACT; - - BOOL fLegacyCasPolicy = FALSE; - - BEGIN_QCALL; - - IApplicationSecurityDescriptor *pAppSecDesc = adhTarget->GetSecurityDescriptor(); - fLegacyCasPolicy = !!pAppSecDesc->IsLegacyCasPolicyEnabled(); - - END_QCALL; - - return fLegacyCasPolicy; -} - -#endif // FEATURE_CAS_POLICY FCIMPL1(Object*, AppDomainNative::GetFriendlyName, AppDomainBaseObject* refThisUNSAFE) diff --git a/src/vm/appdomainnative.hpp b/src/vm/appdomainnative.hpp index 6825fcfac6..964c3604c6 100644 --- a/src/vm/appdomainnative.hpp +++ b/src/vm/appdomainnative.hpp @@ -119,13 +119,6 @@ public: void QCALLTYPE SetSecurityHomogeneousFlag(QCall::AppDomainHandle adhTarget, BOOL fRuntimeSuppliedHomgenousGrantSet); -#ifdef FEATURE_CAS_POLICY - static - void QCALLTYPE SetLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget); - - static - BOOL QCALLTYPE IsLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget); -#endif // FEATURE_CAS_POLICY #ifdef FEATURE_APPDOMAINMANAGER_INITOPTIONS diff --git a/src/vm/assembly.cpp b/src/vm/assembly.cpp index 59f9947ef0..e71fffc326 100644 --- a/src/vm/assembly.cpp +++ b/src/vm/assembly.cpp @@ -801,17 +801,6 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs // should inherit the grant set of the creation assembly. if (loadSecurity.m_pAdditionalEvidence == NULL) { -#ifdef FEATURE_CAS_POLICY - // If we're going to inherit the grant set of an anonymously hosted dynamic method, it will be - // full trust/transparent. In that case, we should demand full trust. - if(args->securityContextSource == kCurrentAssembly && - pCallerAssembly != NULL && - pCallersDomain != NULL && - pCallerAssembly->GetDomainAssembly(pCallersDomain) == pCallersDomain->GetAnonymouslyHostedDynamicMethodsAssembly()) - { - loadSecurity.m_fPropagatingAnonymouslyHostedDynamicMethodGrant = true; - } -#endif // FEATURE_CAS_POLICY loadSecurity.m_pGrantSet = &gc.granted; loadSecurity.m_pRefusedSet = &gc.denied; @@ -875,33 +864,11 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs pAssem->m_dwDynamicAssemblyAccess = args->access; -#ifdef FEATURE_CAS_POLICY - // If a legacy assembly is emitting an assembly, then we implicitly add the legacy attribute. If the legacy - // assembly is also in partial trust, we implicitly make the emitted assembly transparent. - ModuleSecurityDescriptor *pEmittingMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pCallerAssembly); - if (pEmittingMSD->GetSecurityRuleSet() == SecurityRuleSet_Level1) - { - IAssemblySecurityDescriptor *pCallerSecDesc = pCallerAssembly->GetSecurityDescriptor(pCallersDomain); - if (!pCallerSecDesc->IsFullyTrusted()) - { - args->flags = kTransparentAssembly; - } - } - - // If the code emitting the dynamic assembly is transparent and it is attempting to emit a non-transparent - // assembly, then we need to do a demand for the grant set of the emitting assembly (which should also be - // is the grant set of the dynamic assembly). - if (Security::IsMethodTransparent(pmdEmitter) && !(args->flags & kTransparentAssembly)) - { - Security::DemandGrantSet(pCallerAssembly->GetSecurityDescriptor(pCallersDomain)); - } -#else // FEATURE_CORECLR // Making the dynamic assembly opportunistically critical in full trust CoreCLR and transparent otherwise. if (!GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted()) { args->flags = kTransparentAssembly; } -#endif //!FEATURE_CORECLR // Fake up a module security descriptor for the assembly. TokenSecurityDescriptorFlags tokenFlags = TokenSecurityDescriptorFlags_None; diff --git a/src/vm/assemblynative.cpp b/src/vm/assemblynative.cpp index f372bcb349..3a4176882a 100644 --- a/src/vm/assemblynative.cpp +++ b/src/vm/assemblynative.cpp @@ -347,35 +347,6 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs if (pCallersAssembly == NULL) { pCallersAssembly = SystemDomain::System()->SystemAssembly(); } else { -#ifdef FEATURE_CAS_POLICY - // If no evidence was provided to the Assembly.Load(byte[]) call, - // we want to inherit the evidence from the security context source - if (fPropagateIdentity) { - ISecurityDescriptor *pSecDesc = NULL; - if (securityContextSource == kCurrentAppDomain) { - pSecDesc = pCallersDomain->GetSecurityDescriptor(); - } - else { - _ASSERTE(securityContextSource == kCurrentAssembly); - pSecDesc = pCallersAssembly->GetSecurityDescriptor(pCallersDomain); - } - - ENTER_DOMAIN_PTR(pSecDesc->GetDomain(),ADV_RUNNINGIN) - { - gc.orefSecurity = pSecDesc->GetEvidence(); - } - END_DOMAIN_TRANSITION; - - // Caller may be in another appdomain context, in which case we'll - // need to marshal/unmarshal the evidence across. -#ifdef FEATURE_REMOTING // should not happenwithout remoting - if (pCallersDomain != GetAppDomain()) - gc.orefSecurity = AppDomainHelper::CrossContextCopyFrom(pCallersDomain->GetId(), &gc.orefSecurity); -#else - _ASSERTE(pCallersDomain == GetAppDomain()); -#endif - } -#endif // FEATURE_CAS_POLICY } if ((COUNT_T)uAssemblyLength !=uAssemblyLength) // overflow @@ -409,35 +380,9 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs { DWORD dwSpecialFlags = 0; -#ifdef FEATURE_CAS_POLICY - if (securityContextSource == kCurrentAssembly) - { - IAssemblySecurityDescriptor *pCallersSecDesc = pCallersAssembly->GetSecurityDescriptor(pCallersDomain); - gc.granted = pCallersSecDesc->GetGrantedPermissionSet( &(gc.denied)); - dwSpecialFlags = pCallersSecDesc->GetSpecialFlags(); - - // If we're going to inherit the grant set of an anonymously hosted dynamic method, it will be - // full trust/transparent. In that case, we should demand full trust. - if(pCallersAssembly != NULL && pCallersDomain != NULL && pCallersAssembly->GetDomainAssembly(pCallersDomain) == pCallersDomain->GetAnonymouslyHostedDynamicMethodsAssembly()) - { - loadSecurity.m_fPropagatingAnonymouslyHostedDynamicMethodGrant = true; - } - } - else -#endif // FEATURE_CAS_POLICY { IApplicationSecurityDescriptor *pDomainSecDesc = pCallersDomain->GetSecurityDescriptor(); -#ifdef FEATURE_CAS_POLICY - // We only want to propigate the identity of homogenous domains, since heterogenous domains tend - // to be fully trusted even if they are housing partially trusted code - which could lead to an - // elevation of privilege if we allow the grant set to be pushed to assemblies partially trusted - // code is loading. - if (!pDomainSecDesc->IsHomogeneous()) - { - COMPlusThrow(kNotSupportedException, W("NotSupported_SecurityContextSourceAppDomainInHeterogenous")); - } -#endif // FEATURE_CAS_POLICY gc.granted = pDomainSecDesc->GetGrantedPermissionSet(); @@ -2445,23 +2390,6 @@ INT64 QCALLTYPE AssemblyNative::GetHostContext(QCall::AssemblyHandle pAssembly) } #endif // FEATURE_FUSION -#ifdef FEATURE_CAS_POLICY -BOOL QCALLTYPE AssemblyNative::IsStrongNameVerified(QCall::AssemblyHandle pAssembly) -{ - QCALL_CONTRACT; - - BOOL fStrongNameVerified = FALSE; - - BEGIN_QCALL; - - PEFile *pPEFile = pAssembly->GetFile(); - fStrongNameVerified = pPEFile->IsStrongNameVerified(); - - END_QCALL; - - return fStrongNameVerified; -} -#endif // FEATURE_CAS_POLICY #ifdef FEATURE_APPX /*static*/ diff --git a/src/vm/assemblynative.hpp b/src/vm/assemblynative.hpp index a92198cb32..ece8100e95 100644 --- a/src/vm/assemblynative.hpp +++ b/src/vm/assemblynative.hpp @@ -167,10 +167,6 @@ public: static INT64 QCALLTYPE GetHostContext(QCall::AssemblyHandle pAssembly); -#ifdef FEATURE_CAS_POLICY - static - BOOL QCALLTYPE IsStrongNameVerified(QCall::AssemblyHandle pAssembly); -#endif // FEATURE_CAS_POLICY // // AssemblyBuilder FCALLs diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp index 1fc086d3a4..20c2d41ea2 100644 --- a/src/vm/ceemain.cpp +++ b/src/vm/ceemain.cpp @@ -1608,7 +1608,7 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) ETW::EnumerationLog::ProcessShutdown(); } -#if defined(FEATURE_CAS_POLICY) || defined(FEATURE_COMINTEROP) +#if defined(FEATURE_COMINTEROP) // Get the current thread. Thread * pThisThread = GetThread(); #endif @@ -1808,15 +1808,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) // because we are shutting down. CONTRACT_VIOLATION(ModeViolation); -#ifdef FEATURE_CAS_POLICY - // Save the security policy cache as necessary. - if (!g_fProcessDetach || pThisThread != NULL) - { - // If process shutdown has started, it is not safe to create Thread object which is needed - // by the following call. - Security::SaveCache(); - } -#endif #ifdef FEATURE_COMINTEROP // We need to call CoUninitialize in part one to ensure orderly shutdown of COM dlls. if (!g_fFastExitProcess) diff --git a/src/vm/comdelegate.cpp b/src/vm/comdelegate.cpp index ae65afcde0..f0799add07 100644 --- a/src/vm/comdelegate.cpp +++ b/src/vm/comdelegate.cpp @@ -2529,38 +2529,7 @@ BOOL COMDelegate::NeedsSecureDelegate(MethodDesc* pCreatorMethod, AppDomain *pCr } CONTRACTL_END; -#ifndef FEATURE_CAS_POLICY return FALSE; -#else - if (pCreatorMethod) - { - Assembly* pTargetAssembly = pTargetMD->GetAssembly(); - Assembly* pCreatorAssembly = pCreatorMethod->GetAssembly(); - if (pCreatorAssembly != pTargetAssembly) - { - // We don't need secure delegate is everything in the AppDomain is full trust. - if (!pCreatorDomain->GetSecurityDescriptor()->DomainMayContainPartialTrustCode()) - return FALSE; - - IAssemblySecurityDescriptor *pCreatorAsd = pCreatorAssembly->GetSecurityDescriptor(pCreatorDomain); - - // We should also create secure delegates for anonymously hosted dynamic methods which - // are themselves full trust (although transparent) yet can be created from partial trust. - if (!pCreatorAsd->IsFullyTrusted() || - pCreatorAssembly->GetDomainAssembly(pCreatorDomain) == pCreatorDomain->GetAnonymouslyHostedDynamicMethodsAssembly()) - { - return TRUE; - } - - // Note that if we begin to support using an NGEN image which is not fully trusted, we may need - // to force on secure delegates as the grant set of the image may not match between NGEN time - // and runtime. - } - } - - return FALSE; - -#endif // FEATURE_CAS_POLICY } BOOL COMDelegate::NeedsWrapperDelegate(MethodDesc* pTargetMD) @@ -2902,9 +2871,6 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD) } CONTRACTL_END; -#ifdef FEATURE_CAS_POLICY -#error GetSecureInvoke not implemented -#else MethodTable * pDelegateMT = pMD->GetMethodTable(); DelegateEEClass* delegateEEClass = (DelegateEEClass*) pDelegateMT->GetClass(); Stub *pStub = delegateEEClass->m_pSecureDelegateInvokeStub; @@ -2960,7 +2926,6 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD) } return pStub->GetEntryPoint(); -#endif } #else // FEATURE_STUBS_AS_IL PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD) diff --git a/src/vm/commodule.cpp b/src/vm/commodule.cpp index bb6da1d5e7..e3a7e3dbdd 100644 --- a/src/vm/commodule.cpp +++ b/src/vm/commodule.cpp @@ -1169,60 +1169,6 @@ Object* GetTypesInner(Module* pModule) RETURN(OBJECTREFToObject(refArrClasses)); } -#if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY) -//+-------------------------------------------------------------------------- -// -// Member: COMModule::GetSignerCertificate() -// -// Synopsis: Gets the certificate with which the module was signed. -// -// Effects: Creates an X509Certificate and returns it. -// -// Arguments: None. -// -// Returns: OBJECTREF to an X509Certificate object containing the -// signer certificate. -// -//--------------------------------------------------------------------------- - -void QCALLTYPE COMModule::GetSignerCertificate(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retData) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - PCOR_TRUST pCorTrust = NULL; - IAssemblySecurityDescriptor* pSecDesc = NULL; - PBYTE pbSigner = NULL; - DWORD cbSigner = 0; - - // ******** Get the security descriptor ******** - - // Get a pointer to the module security descriptor - pSecDesc = pModule->GetSecurityDescriptor(); - _ASSERTE(pSecDesc); - - // ******** Get COR_TRUST info from module security descriptor ******** - if (FAILED(pSecDesc->LoadSignature(&pCorTrust))) - { - COMPlusThrow(kArgumentNullException, W("InvalidOperation_MetaDataError")); - } - - if( pCorTrust ) - { - // Get a pointer to the signer certificate information in the COR_TRUST - pbSigner = pCorTrust->pbSigner; - cbSigner = pCorTrust->cbSigner; - - if( pbSigner && cbSigner ) - { - retData.SetByteArray(pbSigner, cbSigner); - } - } - - END_QCALL; -} -#endif // #if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY) FCIMPL1(FC_BOOL_RET, COMModule::IsResource, ReflectModuleBaseObject* pModuleUNSAFE) { diff --git a/src/vm/commodule.h b/src/vm/commodule.h index b3598abf5a..4ec82e7cd8 100644 --- a/src/vm/commodule.h +++ b/src/vm/commodule.h @@ -103,11 +103,6 @@ public: static mdString QCALLTYPE GetStringConstant(QCall::ModuleHandle pModule, LPCWSTR pwzValue, INT32 iLength); -#if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY) - /*X509Certificate*/ - static - void QCALLTYPE GetSignerCertificate(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retData); -#endif // #if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY) static void QCALLTYPE SetModuleName(QCall::ModuleHandle pModule, LPCWSTR wszModuleName); diff --git a/src/vm/customattribute.cpp b/src/vm/customattribute.cpp index a83815f8bf..5b679548db 100644 --- a/src/vm/customattribute.cpp +++ b/src/vm/customattribute.cpp @@ -906,93 +906,6 @@ FCIMPL5(VOID, COMCustomAttribute::ParseAttributeUsageAttribute, PVOID pData, ULO } FCIMPLEND -#ifdef FEATURE_CAS_POLICY -FCIMPL4(VOID, COMCustomAttribute::GetSecurityAttributes, ReflectModuleBaseObject *pModuleUNSAFE, DWORD tkToken, CLR_BOOL fAssembly, PTRARRAYREF* ppArray) -{ - FCALL_CONTRACT; - - OBJECTREF throwable = NULL; - REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE); - - if(refModule == NULL) - FCThrowResVoid(kArgumentNullException, W("Arg_InvalidHandle")); - - Module *pModule = refModule->GetModule(); - - HELPER_METHOD_FRAME_BEGIN_2(throwable, refModule); - { - IMDInternalImport* pScope = pModule->GetMDImport(); - - DWORD action; - - CORSEC_ATTRSET_ARRAY aAttrset; - DWORD dwCount = 0; - for(action = 1; action <= dclMaximumValue; action++) - { - // We cannot use IsAssemblyDclAction(action) != fAssembly because CLR_BOOL is defined - // as BYTE in PAL so it might contain a value other than 0 or 1. - if (IsNGenOnlyDclAction(action) || IsAssemblyDclAction(action) == !fAssembly) - continue; - - HENUMInternalHolder hEnum(pScope); - if (!hEnum.EnumPermissionSetsInit(tkToken, (CorDeclSecurity)action)) - continue; - - mdPermission tkPerm; - BYTE* pbBlob; - ULONG cbBlob; - DWORD dwAction; - - while (pScope->EnumNext(&hEnum, &tkPerm)) - { - IfFailThrow(pScope->GetPermissionSetProps( - tkPerm, - &dwAction, - (void const **)&pbBlob, - &cbBlob)); - - CORSEC_ATTRSET* pAttrSet = &*aAttrset.Append(); - IfFailThrow(BlobToAttributeSet(pbBlob, cbBlob, pAttrSet, dwAction)); - - dwCount += pAttrSet->dwAttrCount; - } - } - - *ppArray = (PTRARRAYREF)AllocateObjectArray(dwCount, g_pObjectClass); - - CQuickBytes qb; - - COUNT_T c = 0; - for (COUNT_T i = 0; i < aAttrset.GetCount(); i ++) - { - CORSEC_ATTRSET& attrset = aAttrset[i]; - OBJECTREF* attrArray = (OBJECTREF*)qb.AllocThrows(attrset.dwAttrCount * sizeof(OBJECTREF)); - memset(attrArray, 0, attrset.dwAttrCount * sizeof(OBJECTREF)); - { - // Convert to a managed array of attribute objects - DWORD dwErrorIndex; - HRESULT hr = E_FAIL; - GCPROTECT_ARRAY_BEGIN(*attrArray, attrset.dwAttrCount); - // This is very tricky. - // We have a GCFrame local here. The local goes out of scope beyond for loop. The stack location of the local - // is then reused by other variables, and the content in GCFrame may be changed. But the Frame is still chained - // on our Thread object. - // If exception is thrown before we pop our frame chain, we will have corrupted frame chain. - hr = SecurityAttributes::AttributeSetToManaged(attrArray, &attrset, &throwable, &dwErrorIndex, true); - GCPROTECT_END(); - if (FAILED(hr)) - COMPlusThrowHR(hr); - - for (COUNT_T j = 0; j < attrset.dwAttrCount; j ++) - (*ppArray)->SetAt(c++, attrArray[j]); - } - - } - } - HELPER_METHOD_FRAME_END(); -} -FCIMPLEND -#endif // FEATURE_CAS_POLICY FCIMPL7(void, COMCustomAttribute::GetPropertyOrFieldData, ReflectModuleBaseObject *pModuleUNSAFE, BYTE** ppBlobStart, BYTE* pBlobEnd, STRINGREF* pName, CLR_BOOL* pbIsProperty, OBJECTREF* pType, OBJECTREF* value) { diff --git a/src/vm/domainfile.cpp b/src/vm/domainfile.cpp index b482dafcbf..e66ebaef8b 100644 --- a/src/vm/domainfile.cpp +++ b/src/vm/domainfile.cpp @@ -1641,76 +1641,6 @@ DomainAssembly::DomainAssembly(AppDomain *pDomain, PEFile *pFile, AssemblyLoadSe if (pLoadSecurity != NULL) { -#ifdef FEATURE_CAS_POLICY - // If this assembly had a file name specified, we aren't allowed to load from remote sources and we - // aren't in CAS policy mode (which sandboxes remote assemblies automatically), then we need to do a - // check on this assembly's zone of origin when creating it. - if (pLoadSecurity->m_fCheckLoadFromRemoteSource && - !pLoadSecurity->m_fSuppressSecurityChecks && - !m_pDomain->GetSecurityDescriptor()->AllowsLoadsFromRemoteSources() && - !pFile->IsIntrospectionOnly()) - { - SString strCodeBase; - BYTE pbUniqueID[MAX_SIZE_SECURITY_ID]; - DWORD cbUniqueID = COUNTOF(pbUniqueID); - SecZone dwZone = NoZone; - - GetSecurityIdentity(strCodeBase, - &dwZone, - 0, - pbUniqueID, - &cbUniqueID); - - // Since loads from remote sources are not enabled for this assembly, we only want to allow the - // load if any of the following conditions apply: - // - // * The load is coming off the local machine - // * The load is coming from the intranet or a trusted site, and the code base is UNC. (ie, - // don't allow HTTP loads off the local intranet - - bool safeLoad = false; - if (dwZone == LocalMachine) - { - safeLoad = true; - } - else if (dwZone == Intranet || dwZone == Trusted) - { - if (UrlIsFileUrl(strCodeBase.GetUnicode())) - { - safeLoad = true; - } - else if (PathIsUNC(strCodeBase.GetUnicode())) - { - safeLoad = true; - } - } - - if (!safeLoad) - { - // We've tried to load an assembly from a location where it would have been sandboxed in legacy - // CAS situations, but the application hasn't indicated that this is a safe thing to do. In - // order to prevent accidental security holes by silently loading assemblies in full trust that - // an application expected to be sandboxed, we'll throw an exception instead. - // - // Since this exception can commonly occur with if the file is physically located on the - // hard drive, but has the mark of the web on it we'll also try to detect this mark and - // provide a customized error message if we find it. We do that by re-evaluating the - // assembly's zone with the NOSAVEDFILECHECK flag, which ignores the mark of the web, and if - // that comes back as MyComputer we flag the assembly as having the mark of the web on it. - SecZone dwNoMotwZone = NoZone; - GetSecurityIdentity(strCodeBase, &dwNoMotwZone, MUTZ_NOSAVEDFILECHECK, pbUniqueID, &cbUniqueID); - - if (dwNoMotwZone == LocalMachine) - { - COMPlusThrow(kNotSupportedException, IDS_E_LOADFROM_REMOTE_SOURCE_MOTW); - } - else - { - COMPlusThrow(kNotSupportedException, IDS_E_LOADFROM_REMOTE_SOURCE); - } - } - } -#endif // FEATURE_CAS_POLICY if (GetFile()->IsSourceGAC()) { @@ -1745,22 +1675,6 @@ DomainAssembly::DomainAssembly(AppDomain *pDomain, PEFile *pFile, AssemblyLoadSe { GCX_COOP(); -#ifdef FEATURE_CAS_POLICY - if (pLoadSecurity->m_pAdditionalEvidence != NULL) - { - if(*pLoadSecurity->m_pAdditionalEvidence != NULL) - { - pSecurityDescriptorHolder->SetAdditionalEvidence(*pLoadSecurity->m_pAdditionalEvidence); - } - } - else if (pLoadSecurity->m_pEvidence != NULL) - { - if (*pLoadSecurity->m_pEvidence != NULL) - { - pSecurityDescriptorHolder->SetEvidence(*pLoadSecurity->m_pEvidence); - } - } -#endif // FEATURE_CAS_POLICY // If the assembly being loaded already knows its grant set (for instnace, it's being pushed // from the loading assembly), then we can set that up now as well @@ -1768,15 +1682,6 @@ DomainAssembly::DomainAssembly(AppDomain *pDomain, PEFile *pFile, AssemblyLoadSe { _ASSERTE(pLoadSecurity->m_pGrantSet != NULL); -#ifdef FEATURE_CAS_POLICY - // The permissions from an anonymously hosted dynamic method are fulltrust/transparent, - // so ensure we have full trust to pass that on to the new assembly - if(pLoadSecurity->m_fPropagatingAnonymouslyHostedDynamicMethodGrant && - !CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_Security_DisableAnonymouslyHostedDynamicMethodCreatorSecurityCheck)) - { - Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST); - } -#endif // FEATURE_CAS_POLICY pSecurityDescriptorHolder->PropagatePermissionSet( *pLoadSecurity->m_pGrantSet, @@ -3264,45 +3169,7 @@ BOOL DomainAssembly::CheckZapSecurity(PEImage *pNativeImage) } #endif // FEATURE_PREJIT -#ifdef FEATURE_CAS_POLICY -void DomainAssembly::InitializeSecurityManager() -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - GetFile()->InitializeSecurityManager(); -} -#endif // FEATURE_CAS_POLICY - -#ifdef FEATURE_CAS_POLICY -// Returns security information for the assembly based on the codebase -void DomainAssembly::GetSecurityIdentity(SString &codebase, - SecZone *pdwZone, - DWORD dwFlags, - BYTE *pbUniqueID, - DWORD *pcbUniqueID) -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - MODE_ANY; - PRECONDITION(CheckPointer(pdwZone)); - PRECONDITION(CheckPointer(pbUniqueID)); - PRECONDITION(CheckPointer(pcbUniqueID)); - } - CONTRACTL_END; - - GetFile()->GetSecurityIdentity(codebase, pdwZone, dwFlags, pbUniqueID, pcbUniqueID); -} -#endif // FEATURE_CAS_POLICY #ifdef FEATURE_FUSION IAssemblyBindingClosure* DomainAssembly::GetAssemblyBindingClosure(WALK_LEVEL level) diff --git a/src/vm/domainfile.h b/src/vm/domainfile.h index 55a0907a0b..a468c0a7d9 100644 --- a/src/vm/domainfile.h +++ b/src/vm/domainfile.h @@ -810,11 +810,6 @@ private: ULONG HashIdentity(); private: -#ifdef FEATURE_CAS_POLICY - // Pulls in URLMON's security manager. It is used to translate a codebase - // into a zone and site - void InitializeSecurityManager(); -#endif // FEATURE_CAS_POLICY BOOL ShouldLoadDomainNeutral(); BOOL ShouldLoadDomainNeutralHelper(); diff --git a/src/vm/hostexecutioncontext.cpp b/src/vm/hostexecutioncontext.cpp index 2d9f16a6f1..40eaae2a9f 100644 --- a/src/vm/hostexecutioncontext.cpp +++ b/src/vm/hostexecutioncontext.cpp @@ -5,226 +5,4 @@ #include "common.h" -#ifdef FEATURE_CAS_POLICY - -#include "hostexecutioncontext.h" -#include "corhost.h" -#include "security.h" - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES -IHostSecurityContext *HostExecutionContextManager::m_pRestrictedHostContext = NULL; -#endif // FEATURE_INCLUDE_ALL_INTERFACES - -// initialize HostRestrictedContext -void HostExecutionContextManager::InitializeRestrictedContext() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - SO_TOLERANT; - } - CONTRACTL_END; - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - _ASSERTE(m_pRestrictedHostContext == NULL); - - IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager(); - if (pSM) - { - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - pSM->GetSecurityContext(eRestrictedContext, &m_pRestrictedHostContext); - END_SO_TOLERANT_CODE_CALLING_HOST; - } -#endif // FEATURE_INCLUDE_ALL_INTERFACES -} -// notify the Host to SetRestrictedContext -void HostExecutionContextManager::SetHostRestrictedContext() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - if(m_pRestrictedHostContext != NULL) - { - IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager(); - if (pSM) - { - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - pSM->SetSecurityContext(eRestrictedContext, m_pRestrictedHostContext); - END_SO_TOLERANT_CODE_CALLING_HOST; - } - } -#endif // FEATURE_INCLUDE_ALL_INTERFACES -} - -FCIMPL0(FC_BOOL_RET, HostExecutionContextManager::HostPresent) -{ - FCALL_CONTRACT; - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - FC_RETURN_BOOL(CorHost2::GetHostSecurityManager() != NULL); -#else // !FEATURE_INCLUDE_ALL_INTERFACES - FC_RETURN_BOOL(FALSE); -#endif // FEATURE_INCLUDE_ALL_INTERFACES -} -FCIMPLEND - -FCIMPL1(HRESULT, HostExecutionContextManager::ReleaseSecurityContext, LPVOID handle) -{ - CONTRACTL { - FCALL_CHECK; - PRECONDITION(CheckPointer(handle)); - } CONTRACTL_END; - - HELPER_METHOD_FRAME_BEGIN_RET_NOPOLL(); - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager(); - if (pSM) - { - // get the IUnknown pointer from handle - IHostSecurityContext* pSecurityContext = (IHostSecurityContext*)handle; - // null out the IUnknown pointer in the handle - //hTokenSAFE->SetHandle((void*)NULL); - // release the IUnknown pointer if it is non null - if (pSecurityContext != NULL) - { - pSecurityContext->Release(); - } - } -#endif // FEATURE_INCLUDE_ALL_INTERFACES - - HELPER_METHOD_FRAME_END(); - return S_OK; - -} -FCIMPLEND - -FCIMPL1(HRESULT, HostExecutionContextManager::CaptureSecurityContext, SafeHandle* hTokenUNSAFE) -{ - CONTRACTL { - FCALL_CHECK; - PRECONDITION(CheckPointer(hTokenUNSAFE)); - } CONTRACTL_END; - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostSecurityContext* pCurrentHostSecurityContext = NULL; - IHostSecurityContext* pCapturedSecurityContext = NULL; -#endif // FEATURE_INCLUDE_ALL_INTERFACES - - HRESULT hr = S_OK; - SAFEHANDLE hTokenSAFE = (SAFEHANDLE) hTokenUNSAFE; - HELPER_METHOD_FRAME_BEGIN_RET_1(hTokenSAFE); - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager(); - if (pSM) - { - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - hr = pSM->GetSecurityContext(eCurrentContext, &pCurrentHostSecurityContext); - END_SO_TOLERANT_CODE_CALLING_HOST; - if (hr == S_OK) - { - if(pCurrentHostSecurityContext != NULL) - { - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - hr = pCurrentHostSecurityContext->Capture(&pCapturedSecurityContext); - END_SO_TOLERANT_CODE_CALLING_HOST; - hTokenSAFE->SetHandle((void*)pCapturedSecurityContext); - SafeRelease(pCurrentHostSecurityContext); - } - } - } -#endif // FEATURE_INCLUDE_ALL_INTERFACES - - if (FAILED(hr)) - COMPlusThrowHR(hr); - - HELPER_METHOD_FRAME_END(); - return hr; - -} -FCIMPLEND - -FCIMPL2(HRESULT, HostExecutionContextManager::CloneSecurityContext, SafeHandle* hTokenUNSAFE, SafeHandle* hTokenClonedUNSAFE) -{ - CONTRACTL { - FCALL_CHECK; - PRECONDITION(CheckPointer(hTokenUNSAFE)); - PRECONDITION(CheckPointer(hTokenClonedUNSAFE)); - } CONTRACTL_END; - - SAFEHANDLE hTokenClonedSAFE = (SAFEHANDLE) hTokenClonedUNSAFE; - SAFEHANDLE hTokenSAFE = (SAFEHANDLE)hTokenUNSAFE; - - HELPER_METHOD_FRAME_BEGIN_RET_2(hTokenSAFE, hTokenClonedSAFE); - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager(); - if (pSM) - { - IHostSecurityContext* pSecurityContext = (IHostSecurityContext*)hTokenSAFE->GetHandle(); - if (pSecurityContext != NULL) - { - pSecurityContext->AddRef(); - hTokenClonedSAFE->SetHandle((void*)pSecurityContext); - } - } -#endif // FEATURE_INCLUDE_ALL_INTERFACES - - HELPER_METHOD_FRAME_END(); - return S_OK; -} -FCIMPLEND - -FCIMPL3(HRESULT, HostExecutionContextManager::SetSecurityContext, SafeHandle* hTokenUNSAFE, CLR_BOOL fReturnPrevious, SafeHandle* hTokenPreviousUNSAFE) -{ - CONTRACTL { - FCALL_CHECK; - PRECONDITION(CheckPointer(hTokenUNSAFE)); - } CONTRACTL_END; - - HRESULT hr = S_OK; - - SAFEHANDLE hTokenPreviousSAFE = (SAFEHANDLE) hTokenPreviousUNSAFE; - SAFEHANDLE hTokenSAFE = (SAFEHANDLE) hTokenUNSAFE; - - HELPER_METHOD_FRAME_BEGIN_RET_2(hTokenSAFE, hTokenPreviousSAFE); - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager(); - if (pSM) - { - if (fReturnPrevious) - { - IHostSecurityContext* pPreviousHostSecurityContext = NULL; - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - hr = pSM->GetSecurityContext(eCurrentContext, &pPreviousHostSecurityContext); - END_SO_TOLERANT_CODE_CALLING_HOST; - if (FAILED(hr)) - COMPlusThrowHR(hr); - // store the previous host context in the safe handle - hTokenPreviousSAFE->SetHandle((void*)pPreviousHostSecurityContext); - } - - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - hr = pSM->SetSecurityContext(eCurrentContext, (IHostSecurityContext*)hTokenSAFE->GetHandle()); - END_SO_TOLERANT_CODE_CALLING_HOST; - if (FAILED(hr)) - COMPlusThrowHR(hr); - } -#endif // FEATURE_INCLUDE_ALL_INTERFACES - - HELPER_METHOD_FRAME_END(); - return hr; -} -FCIMPLEND -#endif // #ifdef FEATURE_CAS_POLICY diff --git a/src/vm/hostexecutioncontext.h b/src/vm/hostexecutioncontext.h index 721c8953ad..b39d592e79 100644 --- a/src/vm/hostexecutioncontext.h +++ b/src/vm/hostexecutioncontext.h @@ -7,23 +7,5 @@ #ifndef __hostexecutioncontext_h__ #define __hostexecutioncontext_h__ -#ifdef FEATURE_CAS_POLICY - -class HostExecutionContextManager -{ -public: -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - static IHostSecurityContext* m_pRestrictedHostContext; -#endif // FEATURE_INCLUDE_ALL_INTERFACES - static void InitializeRestrictedContext(); - static void SetHostRestrictedContext(); - - static FCDECL0(FC_BOOL_RET, HostPresent); - static FCDECL1(HRESULT, ReleaseSecurityContext, LPVOID handle); - static FCDECL1(HRESULT, CaptureSecurityContext, SafeHandle* hTokenUNSAFE); - static FCDECL2(HRESULT, CloneSecurityContext, SafeHandle* hTokenUNSAFE, SafeHandle* hTokenClonedUNSAFE); - static FCDECL3(HRESULT, SetSecurityContext, SafeHandle* hTokenUNSAFE, CLR_BOOL fReturnPrevious, SafeHandle* hTokenPreviousUNSAFE); -}; -#endif // #ifdef FEATURE_CAS_POLICY #endif // __hostexecutioncontext_h__ diff --git a/src/vm/metasig.h b/src/vm/metasig.h index d317b421d6..9e5f767719 100644 --- a/src/vm/metasig.h +++ b/src/vm/metasig.h @@ -364,9 +364,6 @@ DEFINE_METASIG(SM(ArrByte_Bool_RetObj, a(b) F, j)) DEFINE_METASIG(SM(ArrByte_ArrByte_RefObj_RetObj, a(b) a(b) r(j), j)) DEFINE_METASIG_T(SM(PtrSByt_Int_Int_Encoding_RetStr, P(B) i i C(ENCODING), s)) DEFINE_METASIG_T(SM(Evidence_RetEvidence, C(EVIDENCE), C(EVIDENCE))) -#ifdef FEATURE_CAS_POLICY -DEFINE_METASIG_T(SM(PEFile_Evidence_RetEvidence, C(SAFE_PEFILE_HANDLE) C(EVIDENCE), C(EVIDENCE))) -#endif // FEATURE_CAS_POLICY DEFINE_METASIG_T(SM(Evidence_Asm_RetEvidence, C(EVIDENCE) C(ASSEMBLY), C(EVIDENCE))) DEFINE_METASIG_T(IM(Evidence_RetVoid, C(EVIDENCE), v)) @@ -401,9 +398,6 @@ DEFINE_METASIG(IM(RetBool, _, F)) DEFINE_METASIG(IM(RetArrByte, _, a(b))) DEFINE_METASIG_T(IM(RetArrParameterInfo, _, a(C(PARAMETER)))) DEFINE_METASIG_T(IM(RetCultureInfo, _, C(CULTURE_INFO))) -#ifdef FEATURE_CAS_POLICY -DEFINE_METASIG_T(IM(RetSecurityElement, _, C(SECURITY_ELEMENT))) -#endif // FEATURE_CAS_POLICY DEFINE_METASIG_T(SM(RetThread, _, C(THREAD))) diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp index 1c3deb5995..9fd5634f79 100644 --- a/src/vm/methodtable.cpp +++ b/src/vm/methodtable.cpp @@ -3965,10 +3965,6 @@ void MethodTable::CallFinalizer(Object *obj) return; } -#ifdef FEATURE_CAS_POLICY - // Notify the host to setup the restricted context before finalizing each object - HostExecutionContextManager::SetHostRestrictedContext(); -#endif // FEATURE_CAS_POLICY // Determine if the object has a critical or normal finalizer. BOOL fCriticalFinalizer = pMT->HasCriticalFinalizer(); diff --git a/src/vm/object.h b/src/vm/object.h index f6a8f9b1ab..c26011a733 100644 --- a/src/vm/object.h +++ b/src/vm/object.h @@ -2303,9 +2303,6 @@ class AppDomainBaseObject : public MarshalByRefObjectBaseObject #endif // FEATURE_EXCEPTION_NOTIFICATIONS AppDomain* m_pDomain; // Pointer to the BaseDomain Structure -#ifdef FEATURE_CAS_POLICY - INT32 m_iPrincipalPolicy; // Type of principal to create by default -#endif CLR_BOOL m_bHasSetPolicy; // SetDomainPolicy has been called for this domain CLR_BOOL m_bIsFastFullTrustDomain; // We know for sure that this is a homogeneous full trust domain. CLR_BOOL m_compatFlagsInitialized; diff --git a/src/vm/pefile.cpp b/src/vm/pefile.cpp index 4cc8859f98..09b4dcb7bd 100644 --- a/src/vm/pefile.cpp +++ b/src/vm/pefile.cpp @@ -41,9 +41,6 @@ #include "../binder/inc/coreclrbindercommon.h" #endif -#ifdef FEATURE_CAS_POLICY -#include <wintrust.h> -#endif #ifdef FEATURE_PREJIT #include "compile.h" @@ -88,12 +85,6 @@ PEFile::PEFile(PEImage *identity, BOOL fCheckAuthenticodeSignature/*=TRUE*/) : m_hash(NULL), m_flags(0), m_fStrongNameVerified(FALSE) -#ifdef FEATURE_CAS_POLICY - ,m_certificate(NULL), - m_fCheckedCertificate(FALSE) - ,m_pSecurityManager(NULL) - ,m_securityManagerLock(CrstPEFileSecurityManager) -#endif // FEATURE_CAS_POLICY ,m_pHostAssembly(nullptr) #if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) ,m_pFallbackLoadContextBinder(nullptr) @@ -122,12 +113,6 @@ PEFile::PEFile(PEImage *identity, BOOL fCheckAuthenticodeSignature/*=TRUE*/) : } -#ifdef FEATURE_CAS_POLICY - if (fCheckAuthenticodeSignature) - { - CheckAuthenticodeSignature(); - } -#endif // FEATURE_CAS_POLICY } @@ -164,14 +149,6 @@ PEFile::~PEFile() m_identity->Release(); if (m_pMetadataLock) delete m_pMetadataLock; -#ifdef FEATURE_CAS_POLICY - if (m_pSecurityManager) { - m_pSecurityManager->Release(); - m_pSecurityManager = NULL; - } - if (m_certificate && !g_pCertificateCache->Contains(m_certificate)) - CoTaskMemFree(m_certificate); -#endif // FEATURE_CAS_POLICY if (m_pHostAssembly != NULL) { @@ -835,86 +812,6 @@ void PEFile::GetCodeBaseOrName(SString &result) result.SetUTF8(GetSimpleName()); } -#ifdef FEATURE_CAS_POLICY - -// Returns security information for the assembly based on the codebase -void PEFile::GetSecurityIdentity(SString &codebase, SecZone *pdwZone, DWORD dwFlags, BYTE *pbUniqueID, DWORD *pcbUniqueID) -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - MODE_ANY; - PRECONDITION(CheckPointer(pdwZone)); - PRECONDITION(CheckPointer(pbUniqueID)); - PRECONDITION(CheckPointer(pcbUniqueID)); - } - CONTRACTL_END; - - if (IsAssembly()) - { - ((PEAssembly*)this)->GetCodeBase(codebase); - } - else if (m_identity != NULL && !m_identity->GetPath().IsEmpty()) - { - codebase.Set(W("file:///")); - codebase.Append(m_identity->GetPath()); - } - else - { - _ASSERTE( !"Unable to determine security identity" ); - } - - GCX_PREEMP(); - - if(!codebase.IsEmpty()) - { - *pdwZone = NoZone; - - InitializeSecurityManager(); - - // We have a class name, return a class factory for it - _ASSERTE(sizeof(SecZone) == sizeof(DWORD)); - IfFailThrow(m_pSecurityManager->MapUrlToZone(codebase, - reinterpret_cast<DWORD *>(pdwZone), - dwFlags)); - - if (*pdwZone>=NumZones) - IfFailThrow(SecurityPolicy::ApplyCustomZoneOverride(pdwZone)); - - IfFailThrow(m_pSecurityManager->GetSecurityId(codebase, - pbUniqueID, - pcbUniqueID, - 0)); - } -} - -void PEFile::InitializeSecurityManager() -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - CAN_TAKE_LOCK; - MODE_PREEMPTIVE; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - HRESULT hr = S_OK; - if(m_pSecurityManager == NULL) - { - CrstHolder holder(&m_securityManagerLock); - if (m_pSecurityManager == NULL) - { - IfFailThrow(CoInternetCreateSecurityManager(NULL, - &m_pSecurityManager, - 0)); - } - } -} - -#endif // FEATURE_CAS_POLICY // ------------------------------------------------------------ // Checks @@ -1287,153 +1184,6 @@ void PEFile::ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData/*= } } -#ifdef FEATURE_CAS_POLICY - -void PEFile::CheckAuthenticodeSignature() -{ - CONTRACTL - { - INSTANCE_CHECK; - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - // Check any security signature in the header. - - // This publisher data can potentially be cached and passed back in via - // PEAssembly::CreateDelayed. - // - // HOWEVER - even if we cache it, the certificate still may need to be verified at - // load time. The only real caching can be done when the COR_TRUST certificate is - // ABSENT. - // - // (In the case where it is present, we could still theoretically - // cache the certificate and re-verify it and at least avoid touching the image - // again, however this path is not implemented yet, so this is TBD if we decide - // it is an important case to optimize for.) - - if (!HasSecurityDirectory()) - { - LOG((LF_SECURITY, LL_INFO1000, "No certificates found in module\n")); - } - else if(g_pConfig->GeneratePublisherEvidence()) - { - // <TODO>@todo: Just because we don't have a file path, doesn't mean we can't have a certicate (does it?)</TODO> - if (!GetPath().IsEmpty()) - { - GCX_PREEMP(); - - // Ignore any errors here - if we fail to validate a certificate, we just don't - // include it as evidence. - - DWORD size; - CoTaskNewHolder<COR_TRUST> pCor = NULL; - // Failing to find a signature is OK. - LPWSTR pFileName = (LPWSTR) GetPath().GetUnicode(); - DWORD dwAuthFlags = COR_NOUI|COR_NOPOLICY; - - HRESULT hr = ::GetPublisher(pFileName, - NULL, - dwAuthFlags, - &pCor, - &size); - - - if( SUCCEEDED(hr) ) { - DWORD index = 0; - EnumCertificateAdditionFlags dwFlags = g_pCertificateCache->AddEntry(pCor, &index); - switch (dwFlags) { - case CacheSaturated: - pCor.SuppressRelease(); - m_certificate = pCor.GetValue(); - break; - - case Success: - pCor.SuppressRelease(); - // falling through - case AlreadyExists: - m_certificate = g_pCertificateCache->GetEntry(index); - _ASSERTE(m_certificate); - break; - } - } - } - } - else - { - LOG((LF_SECURITY, LL_INFO1000, "Assembly has an Authenticode signature, but Publisher evidence has been disabled.\n")); - } - - m_fCheckedCertificate = TRUE; -} - -HRESULT STDMETHODCALLTYPE -GetPublisher(__in __in_z IN LPWSTR pwsFileName, // File name, this is required even with the handle - IN HANDLE hFile, // Optional file name - IN DWORD dwFlags, // COR_NOUI or COR_NOPOLICY - OUT PCOR_TRUST *pInfo, // Returns a PCOR_TRUST (Use FreeM) - OUT DWORD *dwInfo) // Size of pInfo. -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - GUID gV2 = COREE_POLICY_PROVIDER; - COR_POLICY_PROVIDER sCorPolicy; - - WINTRUST_DATA sWTD; - WINTRUST_FILE_INFO sWTFI; - - // Set up the COR trust provider - memset(&sCorPolicy, 0, sizeof(COR_POLICY_PROVIDER)); - sCorPolicy.cbSize = sizeof(COR_POLICY_PROVIDER); - - // Set up the winverify provider structures - memset(&sWTD, 0x00, sizeof(WINTRUST_DATA)); - memset(&sWTFI, 0x00, sizeof(WINTRUST_FILE_INFO)); - - sWTFI.cbStruct = sizeof(WINTRUST_FILE_INFO); - sWTFI.hFile = hFile; - sWTFI.pcwszFilePath = pwsFileName; - - sWTD.cbStruct = sizeof(WINTRUST_DATA); - sWTD.pPolicyCallbackData = &sCorPolicy; // Add in the cor trust information!! - if (dwFlags & COR_NOUI) - { - sWTD.dwUIChoice = WTD_UI_NONE; // No bad UI is overridden in COR TRUST provider - } - else - { - sWTD.dwUIChoice = WTD_UI_ALL; // No bad UI is overridden in COR TRUST provider - } - sWTD.dwUnionChoice = WTD_CHOICE_FILE; - sWTD.pFile = &sWTFI; - - // Set the policies for the VM (we have stolen VMBased and use it like a flag) - if (dwFlags != 0) - sCorPolicy.VMBased = dwFlags; - - LeaveRuntimeHolder holder((size_t)WinVerifyTrust); - - // WinVerifyTrust calls mscorsecimpl.dll to do the policy check - hr = WinVerifyTrust(GetFocus(), &gV2, &sWTD); - - *pInfo = sCorPolicy.pbCorTrust; - *dwInfo = sCorPolicy.cbCorTrust; - - return hr; -} // GetPublisher - -#endif // FEATURE_CAS_POLICY // ------------------------------------------------------------ // PE file access @@ -2489,39 +2239,6 @@ ULONG PEFile::GetILImageTimeDateStamp() return GetLoadedIL()->GetTimeDateStamp(); } -#ifdef FEATURE_CAS_POLICY - -//--------------------------------------------------------------------------------------- -// -// Get a SafePEFileHandle for this PEFile -// - -SAFEHANDLE PEFile::GetSafeHandle() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - SAFEHANDLE objSafeHandle = NULL; - - GCPROTECT_BEGIN(objSafeHandle); - - objSafeHandle = (SAFEHANDLE)AllocateObject(MscorlibBinder::GetClass(CLASS__SAFE_PEFILE_HANDLE)); - CallDefaultConstructor(objSafeHandle); - - this->AddRef(); - objSafeHandle->SetHandle(this); - - GCPROTECT_END(); - - return objSafeHandle; -} - -#endif // FEATURE_CAS_POLICY // ================================================================================ // PEAssembly class - a PEFile which represents an assembly diff --git a/src/vm/pefile.h b/src/vm/pefile.h index 7bb13a7977..60a9a36e07 100644 --- a/src/vm/pefile.h +++ b/src/vm/pefile.h @@ -288,9 +288,6 @@ public: LPCSTR GetLocale(); DWORD GetFlags(); HRESULT GetFlagsNoTrigger(DWORD * pdwFlags); -#ifdef FEATURE_CAS_POLICY - COR_TRUST *GetAuthenticodeSignature(); -#endif // ------------------------------------------------------------ // PE file access // ------------------------------------------------------------ @@ -344,9 +341,6 @@ public: ULONG GetILImageTimeDateStamp(); -#ifdef FEATURE_CAS_POLICY - SAFEHANDLE GetSafeHandle(); -#endif // FEATURE_CAS_POLICY // ------------------------------------------------------------ // Image memory access @@ -517,10 +511,6 @@ protected: void ConvertMDInternalToReadWrite(); void ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData=FALSE); -#ifdef FEATURE_CAS_POLICY - // Check the Authenticode signature of a PE file - void CheckAuthenticodeSignature(); -#endif // FEATURE_CAS_POLICY friend class Module; #ifdef FEATURE_PREJIT @@ -574,12 +564,6 @@ protected: SBuffer *m_hash; // cached SHA1 hash value int m_flags; BOOL m_fStrongNameVerified; -#ifdef FEATURE_CAS_POLICY - COR_TRUST *m_certificate; - BOOL m_fCheckedCertificate; - IInternetSecurityManager *m_pSecurityManager; - Crst m_securityManagerLock; -#endif // FEATURE_CAS_POLICY #ifdef DEBUGGING_SUPPORTED #ifdef FEATURE_PREJIT diff --git a/src/vm/pefile.inl b/src/vm/pefile.inl index 76040e3551..da70cc2a74 100644 --- a/src/vm/pefile.inl +++ b/src/vm/pefile.inl @@ -1808,25 +1808,6 @@ inline HRESULT PEFile::GetFlagsNoTrigger(DWORD * pdwFlags) return GetPersistentMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, NULL, pdwFlags); } -#ifdef FEATURE_CAS_POLICY -inline COR_TRUST *PEFile::GetAuthenticodeSignature() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } - CONTRACTL_END; - - if (!m_fCheckedCertificate && HasSecurityDirectory()) - { - CheckAuthenticodeSignature(); - } - - return m_certificate; -} -#endif // ------------------------------------------------------------ // Hash support @@ -1887,57 +1868,6 @@ inline BOOL PEAssembly::IsFullySigned() } -#ifdef FEATURE_CAS_POLICY -//--------------------------------------------------------------------------------------- -// -// Verify the Authenticode and strong name signatures of an assembly during the assembly -// load code path. To verify the strong name signature outside of assembly load, use the -// VefifyStrongName method instead. -// -// If the applicaiton is using strong name bypass, then this method may not cause a real -// strong name verification, delaying the assembly's strong name load until we know that -// the verification is required. If the assembly must be forced to have its strong name -// verified, then the VerifyStrongName method should also be chosen. -// -// See code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass -// - -inline void PEAssembly::DoLoadSignatureChecks() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; // Fusion uses crsts on AddRef/Release - MODE_ANY; - } - CONTRACTL_END; - - ETWOnStartup(SecurityCatchCall_V1, SecurityCatchCallEnd_V1); - - // If this isn't mscorlib or a dynamic assembly, verify the Authenticode signature. - if (IsSystem() || IsDynamic()) - { - // If it was a dynamic module (or mscorlib), then we don't want to be doing module hash checks on it - m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS; - } - - // Check strong name signature. We only want to do this now if the application is not using the strong - // name bypass feature. Otherwise we'll delay strong name verification until we figure out how trusted - // the assembly is. - // - // For more information see code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass - - // Make sure m_pMDImport is initialized as we need to call VerifyStrongName which calls GetFlags - // BypassTrustedAppStrongNames = false is a relatively uncommon scenario so we need to make sure - // the initialization order is always correct and we don't miss this uncommon case - _ASSERTE(GetMDImport()); - - if (!g_pConfig->BypassTrustedAppStrongNames()) - { - VerifyStrongName(); - } -} -#endif // FEATURE_CAS_POLICY // ------------------------------------------------------------ // Metadata access diff --git a/src/vm/rexcep.h b/src/vm/rexcep.h index 2089c27172..77ff4e75f1 100644 --- a/src/vm/rexcep.h +++ b/src/vm/rexcep.h @@ -304,10 +304,6 @@ DEFINE_EXCEPTION(g_SystemNS, UnauthorizedAccessException, true, C DEFINE_EXCEPTION(g_SecurityNS, VerificationException, false, COR_E_VERIFICATION) -#ifdef FEATURE_CAS_POLICY -DEFINE_EXCEPTION(g_PolicyNS, PolicyException, true, CORSEC_E_POLICY_EXCEPTION, CORSEC_E_NO_EXEC_PERM, CORSEC_E_MIN_GRANT_FAIL) -DEFINE_EXCEPTION(g_SecurityNS, XmlSyntaxException, false, CORSEC_E_XMLSYNTAX) -#endif // FEATURE_CAS_POLICY DEFINE_EXCEPTION(g_InteropNS, COMException, false, E_FAIL) DEFINE_EXCEPTION(g_InteropNS, ExternalException, false, E_FAIL) diff --git a/src/vm/security.h b/src/vm/security.h index 2f91e66aba..9eb7ccd85a 100644 --- a/src/vm/security.h +++ b/src/vm/security.h @@ -68,10 +68,6 @@ namespace Security inline void SaveCache(); // Policy -#ifdef FEATURE_CAS_POLICY - inline bool IsProcessWideLegacyCasPolicyEnabled(); - inline bool CanLoadFromRemoteSources(); -#endif // FEATURE_CAS_POLICY BOOL IsTransparencyEnforcementEnabled(); @@ -129,17 +125,8 @@ namespace Security // other CAS Actions inline void Demand(SecurityStackWalkType eType, OBJECTREF demand) ; -#ifdef FEATURE_CAS_POLICY - inline void DemandGrantSet(IAssemblySecurityDescriptor *psdAssembly); -#endif // FEATURE_CAS_POLICY inline void DemandSet(SecurityStackWalkType eType, OBJECTREF demand) ; inline void DemandSet(SecurityStackWalkType eType, PsetCacheEntry *pPCE, DWORD dwAction) ; -#ifdef FEATURE_CAS_POLICY - inline void ReflectionTargetDemand(DWORD dwPermission, IAssemblySecurityDescriptor *psdTarget); - inline void ReflectionTargetDemand(DWORD dwPermission, - IAssemblySecurityDescriptor *psdTarget, - DynamicResolver * pAccessContext); -#endif // FEATURE_CAS_POLICY inline void SpecialDemand(SecurityStackWalkType eType, DWORD whatPermission) ; inline void InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand); @@ -243,11 +230,6 @@ public: virtual void Resolve() = 0; virtual BOOL IsResolved() const = 0; -#ifdef FEATURE_CAS_POLICY - virtual OBJECTREF GetEvidence() = 0; - virtual BOOL IsEvidenceComputed() const = 0; - virtual void SetEvidence(OBJECTREF evidence) = 0; -#endif // FEATURE_CAS_POLICY virtual OBJECTREF GetGrantedPermissionSet(OBJECTREF* RefusedPermissions = NULL) = 0; #endif // !DACCESS_COMPILE @@ -284,11 +266,6 @@ public: // or if unmanaged code access is allowed at this time virtual DWORD GetDomainWideSpecialFlag() const = 0; -#ifdef FEATURE_CAS_POLICY - virtual void SetLegacyCasPolicyEnabled() = 0; - virtual BOOL IsLegacyCasPolicyEnabled() = 0; - virtual BOOL AllowsLoadsFromRemoteSources() = 0; -#endif // FEATURE_CAS_POLICY #endif // !DACCESS_COMPILE }; @@ -312,14 +289,6 @@ public: virtual void ResolvePolicy(ISharedSecurityDescriptor *pSharedDesc, BOOL fShouldSkipPolicyResolution) = 0; -#ifdef FEATURE_CAS_POLICY - virtual HRESULT LoadSignature( COR_TRUST **ppSignature = NULL) = 0; - - virtual void SetAdditionalEvidence(OBJECTREF evidence) = 0; - virtual BOOL HasAdditionalEvidence() = 0; - virtual OBJECTREF GetAdditionalEvidence() = 0; - virtual void SetEvidenceFromPEFile(IPEFileSecurityDescriptor *pPEFileSecDesc) = 0; -#endif // FEATURE_CAS_POLICY virtual void PropagatePermissionSet(OBJECTREF GrantedPermissionSet, OBJECTREF DeniedPermissionSet, DWORD dwSpecialFlags) = 0; diff --git a/src/vm/security.inl b/src/vm/security.inl index 0d5bf24019..ca2693890e 100644 --- a/src/vm/security.inl +++ b/src/vm/security.inl @@ -25,59 +25,10 @@ inline void Security::Stop() WRAPPER_NO_CONTRACT; SecurityPolicy::Stop(); } -#ifdef FEATURE_CAS_POLICY -inline void Security::SaveCache() -{ - WRAPPER_NO_CONTRACT; - SecurityPolicy::SaveCache(); -} -#endif // ---------------------------------------- // SecurityPolicy // ---------------------------------------- -#ifdef FEATURE_CAS_POLICY - -//--------------------------------------------------------------------------------------- -// -// Determine if the entire process is running with CAS policy enabled for legacy -// compatibility. If this value is false, the CLR does not apply any security policy. -// Instead, it defers to a host if one is present or grants assemblies full trust. -// - -inline bool Security::IsProcessWideLegacyCasPolicyEnabled() -{ - LIMITED_METHOD_CONTRACT; - - // APPX precludes the use of legacy CAS policy - if (AppX::IsAppXProcess()) - { - return false; - } - - return CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Security_LegacyCasPolicy) || - CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Security_NetFx40LegacySecurityPolicy); -} - -//--------------------------------------------------------------------------------------- -// -// In pre-v4 versions of the CLR, doing a LoadFrom for a file in a remote location would -// implicitly sandbox that assembly. If CAS policy is disabled, then these applications -// will suddenly be granting full trust to assemblies they expected to be sandboxed. In -// order to prevent this, these LoadFroms are disabled unless the application has explcitly -// configured itself to allow them. -// -// This method returns the a value that indicates if the application has indicated that it -// is safe to LoadFrom remote locations and that the CLR should not block these loads. -// - -inline bool Security::CanLoadFromRemoteSources() -{ - WRAPPER_NO_CONTRACT; - return !!CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Security_LoadFromRemoteSources); -} - -#endif // FEATURE_CAS_POLICY inline BOOL Security::CanCallUnmanagedCode(Module *pModule) { @@ -173,17 +124,11 @@ inline LinktimeCheckReason Security::GetLinktimeCheckReason(MethodDesc *pMD, inline void Security::CheckLinkDemandAgainstAppDomain(MethodDesc *pMD) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityDeclarative::CheckLinkDemandAgainstAppDomain(pMD); -#endif } inline void Security::LinktimeCheckMethod(Assembly *pCaller, MethodDesc *pCallee) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityDeclarative::LinktimeCheckMethod(pCaller, pCallee); -#endif } inline void Security::ClassInheritanceCheck(MethodTable *pClass, MethodTable *pParent) @@ -201,18 +146,12 @@ inline void Security::MethodInheritanceCheck(MethodDesc *pMethod, MethodDesc *pP inline void Security::DoDeclarativeActions(MethodDesc *pMD, DeclActionInfo *pActions, LPVOID pSecObj, MethodSecurityDescriptor *pMSD) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityDeclarative::DoDeclarativeActions(pMD, pActions, pSecObj, pMSD); -#endif } #ifndef DACCESS_COMPILE inline void Security::CheckNonCasDemand(OBJECTREF *prefDemand) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityDeclarative::CheckNonCasDemand(prefDemand); -#endif } #endif // #ifndef DACCESS_COMPILE @@ -236,18 +175,8 @@ inline BOOL Security::MethodIsVisibleOutsideItsAssembly(DWORD dwMethodAttr, DWOR inline void Security::Demand(SecurityStackWalkType eType, OBJECTREF demand) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityStackWalk::Demand(eType, demand); -#endif } -#ifdef FEATURE_CAS_POLICY -inline void Security::DemandGrantSet(IAssemblySecurityDescriptor *psdAssembly) -{ - WRAPPER_NO_CONTRACT; - SecurityStackWalk::DemandGrantSet(static_cast<AssemblySecurityDescriptor*>(psdAssembly)); -} -#endif // FEATURE_CAS_POLICY inline void Security::DemandSet(SecurityStackWalkType eType, OBJECTREF demand) { @@ -258,65 +187,32 @@ inline void Security::DemandSet(SecurityStackWalkType eType, OBJECTREF demand) MODE_COOPERATIVE; } CONTRACTL_END; -#ifdef FEATURE_CAS_POLICY - SecurityStackWalk::DemandSet(eType, demand); -#endif } inline void Security::DemandSet(SecurityStackWalkType eType, PsetCacheEntry *pPCE, DWORD dwAction) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityStackWalk::DemandSet(eType, pPCE, dwAction); -#endif } -#ifdef FEATURE_CAS_POLICY -inline void Security::ReflectionTargetDemand(DWORD dwPermission, IAssemblySecurityDescriptor *psdTarget) -{ - WRAPPER_NO_CONTRACT; - SecurityStackWalk::ReflectionTargetDemand(dwPermission, static_cast<AssemblySecurityDescriptor*>(psdTarget)); -} - -inline void Security::ReflectionTargetDemand(DWORD dwPermission, - IAssemblySecurityDescriptor *psdTarget, - DynamicResolver * pAccessContext) -{ - WRAPPER_NO_CONTRACT; - SecurityStackWalk::ReflectionTargetDemand(dwPermission, static_cast<AssemblySecurityDescriptor*>(psdTarget), pAccessContext); -} -#endif // FEATURE_CAS_POLICY inline void Security::SpecialDemand(SecurityStackWalkType eType, DWORD whatPermission) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityStackWalk::SpecialDemand(eType, whatPermission); -#endif } inline void Security::InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityDeclarative::InheritanceLinkDemandCheck(pTargetAssembly, pMDLinkDemand); -#endif } inline void Security::FullTrustInheritanceDemand(Assembly *pTargetAssembly) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityDeclarative::FullTrustInheritanceDemand(pTargetAssembly); -#endif } inline void Security::FullTrustLinkDemand(Assembly *pTargetAssembly) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CAS_POLICY - SecurityDeclarative::FullTrustLinkDemand(pTargetAssembly); -#endif } #ifdef FEATURE_COMPRESSEDSTACK @@ -601,34 +497,7 @@ FORCEINLINE BOOL SecurityStackWalk::HasFlagsOrFullyTrustedIgnoreMode (DWORD flag } CONTRACTL_END; -#ifndef FEATURE_CAS_POLICY return TRUE; -#else - // either the desired flag (often 0) or fully trusted will do - flags |= (1<<SECURITY_FULL_TRUST); - - // in order for us to use the threadwide state it has to be the case that there have been no - // overrides since the evaluation (e.g. no denies) We keep the state up-to-date by updating - // it whenever a new AppDomainStackEntry is pushed on the AppDomainStack attached to the thread. - // When we evaluate the demand, we always intersect the current thread state with the AppDomain - // wide flags, which are updated anytime a new Assembly is loaded into that domain. - // - // note if the flag is clear we still might be able to satisfy the demand if we do the full - // stackwalk. - // - // this code is very perf sensitive, do not make changes here without running - // a lot of interop and declarative security benchmarks - // - // it's important that we be able to do these checks without having to touch objects - // other than the thread itself -- that's where a big part of the speed comes from - // L1 cache misses are at a premium on this code path -- never mind L2... - // main memory is right out :) - - Thread* pThread = GetThread(); - return ((pThread->GetOverridesCount() == 0) && - pThread->CheckThreadWideSpecialFlag(flags) && - static_cast<ApplicationSecurityDescriptor*>(pThread->GetDomain()->GetSecurityDescriptor())->CheckDomainWideSpecialFlag(flags)); -#endif } // Returns true if everyone is fully trusted or has the indicated flags AND we're not in legacy CAS mode diff --git a/src/vm/securityattributes.h b/src/vm/securityattributes.h index 5bcff51ec9..8408309b0a 100644 --- a/src/vm/securityattributes.h +++ b/src/vm/securityattributes.h @@ -38,22 +38,12 @@ namespace SecurityAttributes // Creates a new permission set OBJECTREF CreatePermissionSet(BOOL fTrusted); -#ifdef FEATURE_CAS_POLICY - // Takes two PermissionSets (referenced by index) and merges them (unions or intersects - // depending on fIntersect) and returns the index of the merged PermissionSet - PsetCacheEntry* MergePermissionSets(IN PsetCacheEntry *pPCE1, IN PsetCacheEntry *pPCE2, IN bool fIntersect, IN DWORD dwAction); -#endif // FEATURE_CAS_POLICY // Uses new to create the byte array that is returned. void CopyByteArrayToEncoding(IN U1ARRAYREF* pArray, OUT PBYTE* pbData, OUT DWORD* cbData); -#ifdef FEATURE_CAS_POLICY - void EncodePermissionSet(IN OBJECTREF* pRef, - OUT PBYTE* ppbData, - OUT DWORD* pcbData); -#endif // FEATURE_CAS_POLICY // Generic routine, use with encoding calls that // use the EncodePermission client data @@ -125,16 +115,6 @@ namespace SecurityAttributes void AttrArrayToPermissionSet(OBJECTREF* attrArray, bool fSerialize, DWORD attrCount, BYTE **ppbOutput, DWORD *pcbOutput, BYTE **ppbNonCasOutput, DWORD *pcbNonCasOutput, bool fAllowEmptyPermissionSet, OBJECTREF* pPermSet); void AttrSetBlobToPermissionSets(IN BYTE* pbRawPermissions, IN DWORD cbRawPermissions, OUT OBJECTREF* pObj, IN DWORD dwAction); -#ifdef FEATURE_CAS_POLICY - void XmlToPermissionSet(PBYTE pbXmlBlob, - DWORD cbXmlBlob, - OBJECTREF* pPermSet, - OBJECTREF* pEncoding, - PBYTE pbNonCasXmlBlob, - DWORD cbNonCasXmlBlob, - OBJECTREF* pNonCasPermSet, - OBJECTREF* pNonCasEncoding); -#endif // FEATURE_CAS_POLICY bool ActionAllowsNullPermissionSet(CorDeclSecurity action); diff --git a/src/vm/securityconfig.cpp b/src/vm/securityconfig.cpp index 9c7970db8c..747586d1c6 100644 --- a/src/vm/securityconfig.cpp +++ b/src/vm/securityconfig.cpp @@ -77,2105 +77,3 @@ #include "common.h" -#ifdef FEATURE_CAS_POLICY - -#include "securityconfig.h" - -// Header version of the cache file. -#define CONFIG_VERSION 2 -// This controls the maximum size of the cache file. -#define MAX_CACHEFILE_SIZE (1 << 20) - -#define SIZE_OF_ENTRY( X ) sizeof( CacheEntryHeader ) + X->header.keySize + X->header.dataSize -#define MAX_NUM_LENGTH 16 - -WCHAR* SecurityConfig::wcscatDWORD( __out_ecount(cchdst) __out_z WCHAR* dst, size_t cchdst, DWORD num ) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END - - _ASSERTE( SecurityConfig::dataLock_.OwnedByCurrentThread() ); - - static WCHAR buffer[MAX_NUM_LENGTH]; - - buffer[MAX_NUM_LENGTH-1] = W('\0'); - - size_t index = MAX_NUM_LENGTH-2; - - if (num == 0) - { - buffer[index--] = W('0'); - } - else - { - while (num != 0) - { - buffer[index--] = (WCHAR)(W('0') + (num % 10)); - num = num / 10; - } - } - - wcscat_s( dst, cchdst, buffer + index + 1 ); - - return dst; -} - -inline WCHAR * Wszdup(const WCHAR * str) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - size_t len = wcslen(str) + 1; - WCHAR * ret = new WCHAR[len]; - wcscpy_s(ret, len, str); - return ret; -} - -struct CacheHeader -{ - FILETIME dummyFileTime; - DWORD version; - FILETIME configFileTime; - DWORD isSecurityOn, quickCache; - SecurityConfig::RegistryExtensionsInfo registryExtensionsInfo; - DWORD numEntries, sizeConfig; - - CacheHeader() : isSecurityOn( (DWORD) -1 ), quickCache( 0 ), numEntries( 0 ), sizeConfig( 0 ) - { - WRAPPER_NO_CONTRACT; - memset( &this->configFileTime, 0, sizeof( configFileTime ) ); - dummyFileTime.dwLowDateTime = 1; - dummyFileTime.dwHighDateTime = 0; - version = CONFIG_VERSION; - memset(®istryExtensionsInfo, 0, sizeof(registryExtensionsInfo)); - _ASSERTE( IsValid() && "CacheHeader constructor should make it valid" ); - }; - - bool IsValid() - { - LIMITED_METHOD_CONTRACT; - return dummyFileTime.dwLowDateTime == 1 && - dummyFileTime.dwHighDateTime == 0 && - version == CONFIG_VERSION; - } -}; - -struct CacheEntryHeader -{ - DWORD numItemsInKey; - DWORD keySize; - DWORD dataSize; -}; - -struct CacheEntry -{ - CacheEntryHeader header; - BYTE* key; - BYTE* data; - DWORD cachePosition; - BOOL used; - - CacheEntry() : key( NULL ), data( NULL ), used( FALSE ) - { - LIMITED_METHOD_CONTRACT; - }; - - ~CacheEntry( void ) - { - WRAPPER_NO_CONTRACT; - delete [] key; - delete [] data; - } -}; - -struct Data -{ - enum State - { - None = 0x0, - UsingCacheFile = 0x1, - CopyCacheFile = 0x2, - CacheUpdated = 0x4, - UsingConfigFile = 0x10, - CacheExhausted = 0x20, - NewConfigFile = 0x40 - }; - - INT32 id; - WCHAR* configFileName; - WCHAR* cacheFileName; - WCHAR* cacheFileNameTemp; - - LPBYTE configData; - DWORD configDataSize; - FILETIME configFileTime; - FILETIME cacheFileTime; - CacheHeader header; - ArrayList* oldCacheEntries; - ArrayList* newCacheEntries; - State state; - DWORD cacheCurrentPosition; - HANDLE cache; - PBYTE configBuffer; - DWORD sizeConfig; - SecurityConfig::ConfigRetval initRetval; - DWORD newEntriesSize; - - Data( INT32 id ) - : id( id ), - configFileName( NULL ), - cacheFileName( NULL ), - configData( NULL ), - oldCacheEntries( new ArrayList ), - newCacheEntries( new ArrayList ), - state( Data::None ), - cache( INVALID_HANDLE_VALUE ), - configBuffer( NULL ), - newEntriesSize( 0 ) - { - LIMITED_METHOD_CONTRACT; - } - - Data( INT32 id, STRINGREF* configFile ) - : id( id ), - cacheFileName( NULL ), - configData( NULL ), - oldCacheEntries( new ArrayList ), - newCacheEntries( new ArrayList ), - state( Data::None ), - cache( INVALID_HANDLE_VALUE ), - configBuffer( NULL ), - newEntriesSize( 0 ) - { - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(*configFile != NULL); - } CONTRACTL_END; - - configFileName = Wszdup( (*configFile)->GetBuffer() ); - cacheFileName = NULL; - cacheFileNameTemp = NULL; - } - - Data( INT32 id, STRINGREF* configFile, STRINGREF* cacheFile ) - : id( id ), - configData( NULL ), - oldCacheEntries( new ArrayList ), - newCacheEntries( new ArrayList ), - state( Data::None ), - cache( INVALID_HANDLE_VALUE ), - configBuffer( NULL ), - newEntriesSize( 0 ) - { - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(*configFile != NULL); - } CONTRACTL_END; - - configFileName = Wszdup( (*configFile)->GetBuffer() ); - - if (cacheFile != NULL) - { - // Since temp cache files can stick around even after the process that - // created them, we want to make sure they are fairly unique (if they - // aren't, we'll just fail to save cache information, which is not good - // but it won't cause anyone to crash or anything). The unique name - // algorithm used here is to append the process id and tick count to - // the name of the cache file. - - cacheFileName = Wszdup( (*cacheFile)->GetBuffer() ); - size_t len = wcslen( cacheFileName ) + 1 + 2 * MAX_NUM_LENGTH; - cacheFileNameTemp = new WCHAR[len]; - wcscpy_s( cacheFileNameTemp, len, cacheFileName ); - wcscat_s( cacheFileNameTemp, len, W(".") ); - SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetCurrentProcessId() ); - wcscat_s( cacheFileNameTemp, len, W(".") ); - SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetTickCount() ); - } - else - { - cacheFileName = NULL; - cacheFileNameTemp = NULL; - } - } - - Data( INT32 id, const WCHAR* configFile, const WCHAR* cacheFile ) - : id( id ), - configData( NULL ), - oldCacheEntries( new ArrayList ), - newCacheEntries( new ArrayList ), - state( Data::None ), - cache( INVALID_HANDLE_VALUE ), - configBuffer( NULL ), - newEntriesSize( 0 ) - - { - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(*configFile != NULL); - } CONTRACTL_END; - - configFileName = Wszdup( configFile ); - - if (cacheFile != NULL) - { - cacheFileName = Wszdup( cacheFile ); - size_t len = wcslen( cacheFileName ) + 1 + 2 * MAX_NUM_LENGTH; - cacheFileNameTemp = new WCHAR[len]; - wcscpy_s( cacheFileNameTemp, len, cacheFileName ); - wcscat_s( cacheFileNameTemp, len, W(".") ); - SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetCurrentProcessId() ); - wcscat_s( cacheFileNameTemp, len, W(".") ); - SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetTickCount() ); - } - else - { - cacheFileName = NULL; - cacheFileNameTemp = NULL; - } - } - - void Reset( void ) - { - CONTRACTL { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - delete [] configBuffer; - configBuffer = NULL; - - if (cache != INVALID_HANDLE_VALUE) - { - CloseHandle( cache ); - cache = INVALID_HANDLE_VALUE; - } - - if (cacheFileNameTemp != NULL) - { - // Note: we don't check a return value here as the worst thing that - // happens is we leave a spurious cache file. - - WszDeleteFile( cacheFileNameTemp ); - } - - if (configData != NULL) - delete [] configData; - configData = NULL; - - DeleteAllEntries(); - header = CacheHeader(); - - oldCacheEntries = new ArrayList(); - newCacheEntries = new ArrayList(); - - } - - void Cleanup( void ) - { - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - if (cache != INVALID_HANDLE_VALUE) - { - CloseHandle( cache ); - cache = INVALID_HANDLE_VALUE; - } - - if (cacheFileNameTemp != NULL) - { - // Note: we don't check a return value here as the worst thing that - // happens is we leave a spurious cache file. - - WszDeleteFile( cacheFileNameTemp ); - } - } - - ~Data( void ) - { - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - Cleanup(); - delete [] configBuffer; - - delete [] configFileName; - delete [] cacheFileName; - delete [] cacheFileNameTemp; - - if (configData != NULL) - delete [] configData; - DeleteAllEntries(); - } - - void DeleteAllEntries( void ); -}; - -void Data::DeleteAllEntries( void ) -{ - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - ArrayList::Iterator iter; - - if (oldCacheEntries != NULL) - { - iter = oldCacheEntries->Iterate(); - - while (iter.Next()) - { - delete (CacheEntry*) iter.GetElement(); - } - - delete oldCacheEntries; - oldCacheEntries = NULL; - } - - if (newCacheEntries != NULL) - { - iter = newCacheEntries->Iterate(); - - while (iter.Next()) - { - delete (CacheEntry*) iter.GetElement(); - } - - delete newCacheEntries; - newCacheEntries = NULL; - } -} - -void* SecurityConfig::GetData( INT32 id ) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END - - ArrayList::Iterator iter = entries_.Iterate(); - - while (iter.Next()) - { - Data* data = (Data*)iter.GetElement(); - - if (data->id == id) - { - return data; - } - } - - return NULL; -} - -static BOOL CacheOutOfDate( FILETIME* configFileTime, __in_z WCHAR* configFileName, __in_z_opt WCHAR* cacheFileName ) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - } - CONTRACTL_END - - BOOL retval = TRUE; - BOOL deleteFile = FALSE; - - HandleHolder config(WszCreateFile( configFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )); - - if (config.GetValue() == INVALID_HANDLE_VALUE) - { - goto CLEANUP; - } - - // Get the last write time for both files. - - FILETIME newConfigTime; - - if (!GetFileTime( config.GetValue(), NULL, NULL, &newConfigTime )) - { - goto CLEANUP; - } - - if (CompareFileTime( configFileTime, &newConfigTime ) != 0) - { - // Cache is dated. Delete the cache. - deleteFile = TRUE; - goto CLEANUP; - } - - retval = FALSE; - -CLEANUP: - // Note: deleting this file is a perf optimization so that - // we don't have to do this file time comparison next time. - // Therefore, if it fails for some reason we just loss a - // little perf. - - if (deleteFile && cacheFileName != NULL) - WszDeleteFile( cacheFileName ); - - return retval; -} - -static BOOL CacheOutOfDate( FILETIME* cacheFileTime, HANDLE cache, __in_z_opt WCHAR* cacheFileName ) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - } - CONTRACTL_END - - BOOL retval = TRUE; - - // Get the last write time for both files. - - FILETIME newCacheTime; - - if (!GetFileTime( cache, NULL, NULL, &newCacheTime )) - { - goto CLEANUP; - } - - if (CompareFileTime( cacheFileTime, &newCacheTime ) != 0) - { - // Cache is dated. Delete the cache. - // Note: deleting this file is a perf optimization so that - // we don't have to do this file time comparison next time. - // Therefore, if it fails for some reason we just loss a - // little perf. - - if (cacheFileName != NULL) - { - CloseHandle( cache ); - WszDeleteFile( cacheFileName ); - } - goto CLEANUP; - } - - retval = FALSE; - -CLEANUP: - return retval; -} - -static BOOL CacheOutOfDate( FILETIME* configTime, FILETIME* cachedConfigTime ) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_PREEMPTIVE; - } - CONTRACTL_END - - DWORD result = CompareFileTime( configTime, cachedConfigTime ); - - return result != 0; -} - -static DWORD GetShareFlags() -{ - LIMITED_METHOD_CONTRACT; - - return FILE_SHARE_READ | FILE_SHARE_DELETE; -} - -static DWORD WriteFileData( HANDLE file, LPCBYTE data, DWORD size ) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END - - DWORD totalBytesWritten = 0; - DWORD bytesWritten; - - do - { - if (WriteFile( file, data, size - totalBytesWritten, &bytesWritten, NULL ) == 0) - { - return E_FAIL; - } - if (bytesWritten == 0) - { - return E_FAIL; - } - totalBytesWritten += bytesWritten; - } while (totalBytesWritten < size); - - return S_OK; -} - -// the data argument to this function can be a pointer to GC heap. -// We do ensure cooperative mode before we call this function using a pointer to GC heap, -// so we can't change GC mode inside this function. -// Greg will look into the ways to pin the object. - -static DWORD ReadFileData( HANDLE file, PBYTE data, DWORD size ) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END - - DWORD totalBytesRead = 0; - DWORD bytesRead; - do - { - if (ReadFile( file, data, size - totalBytesRead, &bytesRead, NULL ) == 0) - { - return E_FAIL; - } - - if (bytesRead == 0) - { - return E_FAIL; - } - - totalBytesRead += bytesRead; - - } while (totalBytesRead < size); - - return S_OK; -} - -SecurityConfig::ConfigRetval SecurityConfig::InitData( INT32 id, const WCHAR* configFileName, const WCHAR* cacheFileName ) -{ - STANDARD_VM_CONTRACT; - - Data* data = (Data*)GetData( id ); - if (data != NULL) - { - return data->initRetval; - } - - if (configFileName == NULL || wcslen( configFileName ) == 0) - { - return NoFile; - } - - { - CrstHolder ch( &dataLock_ ); - data = new (nothrow) Data( id, configFileName, cacheFileName ); - } - - if (data == NULL) - { - return NoFile; - } - - return InitData( data, TRUE ); -} - - -SecurityConfig::ConfigRetval SecurityConfig::InitData( void* configDataParam, BOOL addToList ) -{ - STANDARD_VM_CONTRACT; - - _ASSERTE( configDataParam != NULL ); - - Data* data = (Data*) configDataParam; - DWORD cacheSize; - DWORD configSize; - ConfigRetval retval = NoFile; - DWORD shareFlags; - - shareFlags = GetShareFlags(); - - // Crack open the config file. - - HandleHolder config(WszCreateFile( data->configFileName, GENERIC_READ, shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )); - if (config == INVALID_HANDLE_VALUE || !GetFileTime( config, NULL, NULL, &data->configFileTime )) - { - memset( &data->configFileTime, 0, sizeof( data->configFileTime ) ); - } - else - { - data->state = (Data::State)(Data::UsingConfigFile | data->state); - } - - // If we want a cache file, try to open that up. - // Note: we do not use a holder for data->cache because the new holder for data will - // delete the entire data structure which includes closing this handle as necessary. - - if (data->cacheFileName != NULL) - data->cache = WszCreateFile( data->cacheFileName, GENERIC_READ, shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - - if (data->cache == INVALID_HANDLE_VALUE) - { - goto READ_DATA; - } - - // Validate that the cache file is in a good form by checking - // that it is at least big enough to contain a header. - - cacheSize = SafeGetFileSize( data->cache, NULL ); - - if (cacheSize == 0xFFFFFFFF) - { - goto READ_DATA; - } - - if (cacheSize < sizeof( CacheHeader )) - { - goto READ_DATA; - } - - // Finally read the data from the file into the buffer. - - if (ReadFileData( data->cache, (BYTE*)&data->header, sizeof( CacheHeader ) ) != S_OK) - { - goto READ_DATA; - } - - if (!data->header.IsValid()) - { - goto READ_DATA; - } - - // Check to make sure the cache file and the config file - // match up by comparing the actual file time of the config - // file and the config file time stored in the cache file. - - if (CacheOutOfDate( &data->configFileTime, &data->header.configFileTime )) - { - goto READ_DATA; - } - - if (!GetFileTime( data->cache, NULL, NULL, &data->cacheFileTime )) - { - goto READ_DATA; - } - - // Set the file pointer to after both the header and config data (if any) so - // that we are ready to read cache entries. - - if (SetFilePointer( data->cache, sizeof( CacheHeader ) + data->header.sizeConfig, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - { - goto READ_DATA; - } - - data->cacheCurrentPosition = sizeof( CacheHeader ) + data->header.sizeConfig; - data->state = (Data::State)(Data::UsingCacheFile | Data::CopyCacheFile | data->state); - - retval = (ConfigRetval)(retval | CacheFile); - -READ_DATA: - // If we are not using the cache file but we successfully opened it, we need - // to close it now. In addition, we need to reset the cache information - // stored in the Data object to make sure there is no spill over. - - if (data->cache != INVALID_HANDLE_VALUE && (data->state & Data::UsingCacheFile) == 0) - { - CloseHandle( data->cache ); - data->header = CacheHeader(); - data->cache = INVALID_HANDLE_VALUE; - } - - if (config != INVALID_HANDLE_VALUE) - { - configSize = SafeGetFileSize( config, NULL ); - - if (configSize == 0xFFFFFFFF) - { - goto ADD_DATA; - } - - // Be paranoid and only use the cache file version if we find that it has the correct sized - // blob in it. - - if ((data->state & Data::UsingCacheFile) != 0 && configSize == data->header.sizeConfig) - { - goto ADD_DATA; - } - else - { - if (data->cache != INVALID_HANDLE_VALUE) - { - CloseHandle( data->cache ); - data->header = CacheHeader(); - data->cache = INVALID_HANDLE_VALUE; - data->state = (Data::State)(data->state & ~(Data::UsingCacheFile)); - } - - data->configData = new BYTE[configSize]; - if (ReadFileData( config, data->configData, configSize ) != S_OK) - { - goto ADD_DATA; - } - data->configDataSize = configSize; - } - retval = (ConfigRetval)(retval | ConfigFile); - } - -ADD_DATA: - { - CrstHolder ch(&dataLock_); - - if (addToList) - { - IfFailThrow(entries_.Append(data)); - } - } - - _ASSERTE( data ); - data->initRetval = retval; - - return retval; - -}; - -static CacheEntry* LoadNextEntry( HANDLE cache, Data* data ) -{ - STANDARD_VM_CONTRACT; - - if ((data->state & Data::CacheExhausted) != 0) - return NULL; - - NewHolder<CacheEntry> entry(new CacheEntry()); - - if (SetFilePointer( cache, data->cacheCurrentPosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - { - return NULL; - } - - if (ReadFileData( cache, (BYTE*)&entry.GetValue()->header, sizeof( CacheEntryHeader ) ) != S_OK) - { - return NULL; - } - - entry.GetValue()->cachePosition = data->cacheCurrentPosition + sizeof( entry.GetValue()->header ); - - data->cacheCurrentPosition += sizeof( entry.GetValue()->header ) + entry.GetValue()->header.keySize + entry.GetValue()->header.dataSize; - - if (SetFilePointer( cache, entry.GetValue()->header.keySize + entry->header.dataSize, NULL, FILE_CURRENT ) == INVALID_SET_FILE_POINTER) - { - return NULL; - } - - // We append a partially populated entry. CompareEntry is robust enough to handle this. - IfFailThrow(data->oldCacheEntries->Append( entry )); - - return entry.Extract(); -} - -static BOOL WriteEntry( HANDLE cache, CacheEntry* entry, HANDLE oldCache = NULL ) -{ - STANDARD_VM_CONTRACT; - - if (WriteFileData( cache, (BYTE*)&entry->header, sizeof( CacheEntryHeader ) ) != S_OK) - { - return FALSE; - } - - if (entry->key == NULL) - { - _ASSERTE (oldCache != NULL); - - // We were lazy in reading the entry. Read the key now. - entry->key = new BYTE[entry->header.keySize]; - - _ASSERTE (cache != INVALID_HANDLE_VALUE); - - if (SetFilePointer( oldCache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - return NULL; - - if (ReadFileData( oldCache, entry->key, entry->header.keySize ) != S_OK) - { - return NULL; - } - - entry->cachePosition += entry->header.keySize; - } - - _ASSERTE( entry->key != NULL ); - - if (entry->data == NULL) - { - _ASSERTE (oldCache != NULL); - - // We were lazy in reading the entry. Read the data also. - entry->data = new BYTE[entry->header.dataSize]; - - if (SetFilePointer( oldCache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - return NULL; - - if (ReadFileData( oldCache, entry->data, entry->header.dataSize ) != S_OK) - return NULL; - - entry->cachePosition += entry->header.dataSize; - } - - _ASSERT( entry->data != NULL ); - - if (WriteFileData( cache, entry->key, entry->header.keySize ) != S_OK) - { - return FALSE; - } - - if (WriteFileData( cache, entry->data, entry->header.dataSize ) != S_OK) - { - return FALSE; - } - - return TRUE; -} - -BOOL SecurityConfig::SaveCacheData( INT32 id ) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END - - GCX_PREEMP(); - - // Note: this function should only be called at EEShutdown time. - // This is because we need to close the current cache file in - // order to delete it. If it ever became necessary to do - // cache saves while a process we still executing managed code - // it should be possible to create a locking scheme for usage - // of the cache handle with very little reordering of the below - // (as it should always be possible for us to have a live copy of - // the file and yet still be making the swap). - - HandleHolder cache; - HandleHolder config; - CacheHeader header; - BOOL retval = FALSE; - BOOL fWriteSucceeded = FALSE; - DWORD numEntriesWritten = 0; - DWORD amountWritten = 0; - DWORD sizeConfig = 0; - NewHolder<BYTE> configBuffer; - BOOL useConfigData = FALSE; - - Data* data = (Data*)GetData( id ); - - // If there is not data by the id or there is no - // cache file name associated with the data, then fail. - - if (data == NULL || data->cacheFileName == NULL) - return FALSE; - - // If we haven't added anything new to the cache - // then just return success. - - if ((data->state & Data::CacheUpdated) == 0) - return TRUE; - - // If the config file has changed since the process started - // then our cache data is no longer valid. We'll just - // return success in this case. - - if ((data->state & Data::UsingConfigFile) != 0 && CacheOutOfDate( &data->configFileTime, data->configFileName, NULL )) - return TRUE; - - DWORD fileNameLength = (DWORD)wcslen( data->cacheFileName ); - - NewArrayHolder<WCHAR> newFileName(new WCHAR[fileNameLength + 5]); - - swprintf_s( newFileName.GetValue(), fileNameLength + 5, W("%s%s"), data->cacheFileName, W(".new") ); - - cache.Assign( WszCreateFile( newFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ) ); - - for (DWORD RetryCount = 0; RetryCount < 5; RetryCount++) - { - if (cache != INVALID_HANDLE_VALUE) - { - break; - } - else - { - DWORD error = GetLastError(); - - if (error == ERROR_PATH_NOT_FOUND) - { - // The directory does not exist, iterate through and try to create it. - - WCHAR* currentChar = newFileName; - - // Skip the first backslash - - while (*currentChar != W('\0')) - { - if (*currentChar == W('\\') || *currentChar == W('/')) - { - currentChar++; - break; - } - currentChar++; - } - - // Iterate through trying to create each subdirectory. - - while (*currentChar != W('\0')) - { - if (*currentChar == W('\\') || *currentChar == W('/')) - { - *currentChar = W('\0'); - - if (!WszCreateDirectory( newFileName, NULL )) - { - error = GetLastError(); - - if (error != ERROR_ACCESS_DENIED && error != ERROR_INVALID_NAME && error != ERROR_ALREADY_EXISTS) - { - goto CLEANUP; - } - } - - *currentChar = W('\\'); - } - currentChar++; - } - - // Try the file creation again - continue; - } - } - - // CreateFile failed. Sleep a little and retry, in case a - // virus scanner caused the creation to fail. - ClrSleepEx(10, FALSE); - } - - if (cache.GetValue() == INVALID_HANDLE_VALUE) - goto CLEANUP; - - // This code seems complicated only because of the - // number of cases that we are trying to handle. All we - // are trying to do is determine the amount of space to - // leave for the config information. - - // If we saved out a new config file during this run, use - // the config size stored in the Data object itself. - - if (data->configData != NULL) - { - useConfigData = TRUE; - } - - if ((data->state & Data::NewConfigFile) != 0) - { - sizeConfig = data->sizeConfig; - } - - // If we have a cache file, then use the size stored in the - // cache header. - - else if ((data->state & Data::UsingCacheFile) != 0) - { - sizeConfig = data->header.sizeConfig; - } - - // If we read in the config data, use the size of the - // managed byte array that it is stored in. - - else if (useConfigData) - { - sizeConfig = data->configDataSize; - } - - // Otherwise, check the config file itself to get the size. - - else - { - DWORD shareFlags; - - shareFlags = GetShareFlags(); - - config.Assign( WszCreateFile( data->configFileName, GENERIC_READ, shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) ); - - if (config == INVALID_HANDLE_VALUE) - { - sizeConfig = 0; - } - else - { - sizeConfig = SafeGetFileSize( config, NULL ); - - if (sizeConfig == 0xFFFFFFFF) - { - sizeConfig = 0; - } - } - } - - // First write the entries. - - if (SetFilePointer( cache, sizeof( CacheHeader ) + sizeConfig, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - { - goto CLEANUP; - } - - // We're going to write out the cache entries in a modified - // least recently used order, throwing out any that end up - // taking us past our hardcoded max file size. - - { - // First, write the entries from the cache file that were used. - // We do this because presumably these are system assemblies - // and other assemblies used by a number of applications. - - ArrayList::Iterator iter; - - if ((data->state & Data::UsingCacheFile) != 0) - { - iter = data->oldCacheEntries->Iterate(); - - while (iter.Next() && amountWritten < MAX_CACHEFILE_SIZE) - { - CacheEntry* currentEntry = (CacheEntry*)iter.GetElement(); - - if (currentEntry->used) - { - if(!WriteEntry( cache, currentEntry, data->cache )) - { - goto CLEANUP; - } - - amountWritten += SIZE_OF_ENTRY( currentEntry ); - numEntriesWritten++; - } - } - } - - // Second, write any new cache entries to the file. These are - // more likely to be assemblies specific to this app. - - iter = data->newCacheEntries->Iterate(); - - while (iter.Next() && amountWritten < MAX_CACHEFILE_SIZE) - { - CacheEntry* currentEntry = (CacheEntry*)iter.GetElement(); - - if (!WriteEntry( cache, currentEntry )) - { - goto CLEANUP; - } - - amountWritten += SIZE_OF_ENTRY( currentEntry ); - numEntriesWritten++; - } - - // Third, if we are using the cache file, write the old entries - // that were not used this time around. - - if ((data->state & Data::UsingCacheFile) != 0) - { - // First, write the ones that we already have partially loaded - - iter = data->oldCacheEntries->Iterate(); - - while (iter.Next() && amountWritten < MAX_CACHEFILE_SIZE) - { - CacheEntry* currentEntry = (CacheEntry*)iter.GetElement(); - - if (!currentEntry->used) - { - if(!WriteEntry( cache, currentEntry, data->cache )) - { - goto CLEANUP; - } - - amountWritten += SIZE_OF_ENTRY( currentEntry ); - numEntriesWritten++; - } - } - - while (amountWritten < MAX_CACHEFILE_SIZE) - { - CacheEntry* entry = LoadNextEntry( data->cache, data ); - - if (entry == NULL) - break; - - if (!WriteEntry( cache, entry, data->cache )) - { - goto CLEANUP; - } - - amountWritten += SIZE_OF_ENTRY( entry ); - numEntriesWritten++; - } - } - - fWriteSucceeded = TRUE; - } - - - if (!fWriteSucceeded) - { - CloseHandle( cache.GetValue() ); - cache.SuppressRelease(); - WszDeleteFile( newFileName ); - goto CLEANUP; - } - - // End with writing the header. - - header.configFileTime = data->configFileTime; - header.isSecurityOn = 1; - header.numEntries = numEntriesWritten; - header.quickCache = data->header.quickCache; - header.sizeConfig = sizeConfig; - - if (SetFilePointer( cache, 0, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - { - // Couldn't move to the beginning of the file - goto CLEANUP; - } - - if (WriteFileData( cache, (PBYTE)&header, sizeof( header ) ) != S_OK) - { - // Couldn't write header info. - goto CLEANUP; - } - - if (sizeConfig != 0) - { - if ((data->state & Data::NewConfigFile) != 0) - { - if (WriteFileData( cache, data->configBuffer, sizeConfig ) != S_OK) - { - goto CLEANUP; - } - } - else - { - if (data->configData != NULL) - { - if (WriteFileData( cache, data->configData, sizeConfig ) != S_OK) - { - goto CLEANUP; - } - } - else if ((data->state & Data::UsingCacheFile) != 0) - { - configBuffer.Assign( new BYTE[sizeConfig] ); - - if (SetFilePointer( data->cache, sizeof( CacheHeader ), NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - { - goto CLEANUP; - } - - if (ReadFileData( data->cache, configBuffer.GetValue(), sizeConfig ) != S_OK) - { - goto CLEANUP; - } - - if (WriteFileData( cache, configBuffer.GetValue(), sizeConfig ) != S_OK) - { - goto CLEANUP; - } - } - else - { - configBuffer.Assign( new BYTE[sizeConfig] ); - - if (SetFilePointer( config, 0, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - { - goto CLEANUP; - } - - if (ReadFileData( config, configBuffer.GetValue(), sizeConfig ) != S_OK) - { - goto CLEANUP; - } - - if (WriteFileData( cache, configBuffer.GetValue(), sizeConfig ) != S_OK) - { - goto CLEANUP; - } - } - } - } - - // Flush the file buffers to make sure - // we get full write through. - - FlushFileBuffers( cache.GetValue() ); - - CloseHandle( cache ); - cache.SuppressRelease(); - CloseHandle( data->cache ); - data->cache = INVALID_HANDLE_VALUE; - - // Move the existing file out of the way - // Note: use MoveFile because we know it will never cross - // device boundaries. - - // Note: the delete file can fail, but we can't really do anything - // if it does so just ignore any failures. - WszDeleteFile( data->cacheFileNameTemp ); - - // Try to move the existing cache file out of the way. However, if we can't - // then try to delete it. If it can't be deleted then just bail out. - if (!WszMoveFile( data->cacheFileName, data->cacheFileNameTemp ) && - (!Assembly::FileNotFound(HRESULT_FROM_WIN32(GetLastError()))) && - !WszDeleteFile( data->cacheFileName )) - { - if (!Assembly::FileNotFound(HRESULT_FROM_WIN32(GetLastError()))) - goto CLEANUP; - } - - // Move the new file into position - - if (!WszMoveFile( newFileName, data->cacheFileName )) - { - goto CLEANUP; - } - - retval = TRUE; - -CLEANUP: - if (retval) - cache.SuppressRelease(); - - return retval; - -} - -void QCALLTYPE SecurityConfig::ResetCacheData(INT32 id) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - Data* data = (Data*)GetData( id ); - - if (data != NULL) - { - CrstHolder ch(&dataLock_); - - data->DeleteAllEntries(); - - data->oldCacheEntries = new ArrayList; - data->newCacheEntries = new ArrayList; - - data->header = CacheHeader(); - data->state = (Data::State)(~(Data::CopyCacheFile | Data::UsingCacheFile) & data->state); - - HandleHolder config(WszCreateFile( data->configFileName, GENERIC_READ, GetShareFlags(), NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )); - - if (config.GetValue() != INVALID_HANDLE_VALUE) - { - VERIFY(GetFileTime( config, NULL, NULL, &data->configFileTime )); - VERIFY(GetFileTime( config, NULL, NULL, &data->header.configFileTime )); - } -} - - END_QCALL; -} - -HRESULT QCALLTYPE SecurityConfig::SaveDataByte(LPCWSTR wszConfigPath, LPCBYTE pbData, DWORD cbData) -{ - QCALL_CONTRACT; - - HRESULT retval = E_FAIL; - - BEGIN_QCALL; - - HandleHolder newFile(INVALID_HANDLE_VALUE); - - int RetryCount; - DWORD error = 0; - DWORD fileNameLength = (DWORD) wcslen(wszConfigPath); - - NewArrayHolder<WCHAR> newFileName(new WCHAR[fileNameLength + 5]); - NewArrayHolder<WCHAR> oldFileName(new WCHAR[fileNameLength + 5]); - - swprintf_s( newFileName.GetValue(), fileNameLength + 5, W("%s%s"), wszConfigPath, W(".new") ); - swprintf_s( oldFileName.GetValue(), fileNameLength + 5, W("%s%s"), wszConfigPath, W(".old") ); - - // Create the new file. - for (RetryCount = 0; RetryCount < 5; RetryCount++) { - newFile.Assign( WszCreateFile( newFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ) ); - - if (newFile != INVALID_HANDLE_VALUE) - break; - else - { - error = GetLastError(); - - if (error == ERROR_PATH_NOT_FOUND) - { - // The directory does not exist, iterate through and try to create it. - - WCHAR* currentChar = newFileName; - - // Skip the first backslash - - while (*currentChar != W('\0')) - { - if (*currentChar == W('\\') || *currentChar == W('/')) - { - currentChar++; - break; - } - currentChar++; - } - - // Iterate through trying to create each subdirectory. - - while (*currentChar != W('\0')) - { - if (*currentChar == W('\\') || *currentChar == W('/')) - { - *currentChar = W('\0'); - - if (!WszCreateDirectory( newFileName, NULL )) - { - error = GetLastError(); - - if (error != ERROR_ACCESS_DENIED && error != ERROR_ALREADY_EXISTS) - { - goto CLEANUP; - } - } - - *currentChar = W('\\'); - } - currentChar++; - } - - // Try the file creation again - continue; - } - } - - // CreateFile failed. Sleep a little and retry, in case a - // virus scanner caused the creation to fail. - ClrSleepEx(10, FALSE); - } - - if (newFile == INVALID_HANDLE_VALUE) { - goto CLEANUP; - } - - // Write the data into it. - if ((retval = WriteFileData(newFile.GetValue(), pbData, cbData)) != S_OK) - { - // Write failed, destroy the file and bail. - // Note: if the delete fails, we always do a CREATE_NEW - // for this file so that should take care of it. If not - // we'll fail to write out future cache files. - CloseHandle( newFile.GetValue() ); - newFile.SuppressRelease(); - WszDeleteFile( newFileName ); - goto CLEANUP; - } - - if (!FlushFileBuffers(newFile.GetValue())) - { - error = GetLastError(); - goto CLEANUP; - } - - CloseHandle( newFile.GetValue() ); - newFile.SuppressRelease(); - - // Move the existing file out of the way - if (!WszMoveFileEx( wszConfigPath, oldFileName, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED )) - { - // If move fails for a reason other than not being able to find the file, bail out. - // Also, if the old file didn't exist, we have no need to delete it. - HRESULT hrMove = HRESULT_FROM_WIN32(GetLastError()); - if (!Assembly::FileNotFound(hrMove)) - { - retval = hrMove; - WszDeleteFile(wszConfigPath); - goto CLEANUP; - } - } - - // Move the new file into position - - if (!WszMoveFileEx( newFileName, wszConfigPath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED )) - { - error = GetLastError(); - goto CLEANUP; - } - - retval = S_OK; - -CLEANUP: - if (retval == E_FAIL && error != 0) - retval = HRESULT_FROM_WIN32(error); - - END_QCALL; - - return retval; -} - -BOOL QCALLTYPE SecurityConfig::RecoverData(INT32 id) - { - QCALL_CONTRACT; - - BOOL retval = FALSE; - - BEGIN_QCALL; - - Data* data = (Data*)GetData( id ); - - if (data == NULL) - goto CLEANUP; - - { - DWORD fileNameLength = (DWORD)wcslen( data->configFileName ); - - NewArrayHolder<WCHAR> tempFileName(new WCHAR[fileNameLength + 10]); - NewArrayHolder<WCHAR> oldFileName(new WCHAR[fileNameLength + 5]); - - swprintf_s( tempFileName.GetValue(), fileNameLength + 10, W("%s%s"), data->configFileName, W(".old.temp") ); - swprintf_s( oldFileName.GetValue(), fileNameLength + 5, W("%s%s"), data->configFileName, W(".old") ); - - HandleHolder oldFile(WszCreateFile( oldFileName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )); - - if (oldFile.GetValue() == INVALID_HANDLE_VALUE) - { - goto CLEANUP; - } - - CloseHandle( oldFile ); - oldFile.SuppressRelease(); - - if (!WszMoveFile( data->configFileName, tempFileName )) - { - goto CLEANUP; - } - - if (!WszMoveFile( oldFileName, data->configFileName )) - { - goto CLEANUP; - } - - if (!WszMoveFile( tempFileName, oldFileName )) - { - goto CLEANUP; - } - } - - // We need to do some work to reset the unmanaged data object - // so that the managed side of things behaves like you'd expect. - // This basically means cleaning up the open resources and - // doing the work to init on a different set of files. - - data->Reset(); - InitData( data, FALSE ); - - retval = TRUE; - -CLEANUP: - END_QCALL; - - return retval; -} - -BOOL SecurityConfig::GetQuickCacheEntry( INT32 id, QuickCacheEntryType type ) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END - - // - // If there is no config file for this level, then we'll assume the default - // security policy is in effect. This could happen for example if there is - // user profile loaded or if the config file is not present. - // - - Data* data = (Data*)GetData( id ); - if (data == NULL || ((data->state & Data::UsingConfigFile) == 0)) - return (type == FullTrustZoneMyComputer); // MyComputer gets FT by default. - - if ((data->state & Data::UsingCacheFile) == 0) - return FALSE; - - return (data->header.quickCache & type); -} - -void QCALLTYPE SecurityConfig::SetQuickCache(INT32 id, QuickCacheEntryType type) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - Data* data = (Data*)GetData( id ); - - if (data != NULL && (DWORD) type != data->header.quickCache) - { - CrstHolder ch(&dataLock_); - - data->state = (Data::State)(Data::CacheUpdated | data->state); - data->header.quickCache = type; - } - - END_QCALL; -} - -static HANDLE OpenCacheFile( Data* data ) -{ - STANDARD_VM_CONTRACT; - - CrstHolder ch(&SecurityConfig::dataLock_); - - if (data->cache != INVALID_HANDLE_VALUE) - return data->cache; - - _ASSERTE( FALSE && "This case should never happen" ); - - data->cache = WszCreateFile( data->cacheFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); - if (data->cache == INVALID_HANDLE_VALUE) - return NULL; - - // Check whether the cache has changed since we first looked at it. - // If it has but the config file hasn't, then we need to start fresh. - // However, if the config file has changed then we have to ignore it. - - if (CacheOutOfDate( &data->cacheFileTime, data->cache, NULL )) - { - if (CacheOutOfDate( &data->configFileTime, data->configFileName, NULL )) - return NULL; - - if (ReadFileData( data->cache, (BYTE*)&data->header, sizeof( CacheHeader ) ) != S_OK) - return NULL; - - data->cacheCurrentPosition = sizeof( CacheHeader ); - - if (data->oldCacheEntries != NULL) - { - ArrayList::Iterator iter = data->oldCacheEntries->Iterate(); - while (iter.Next()) - { - delete (CacheEntry*)iter.GetElement(); - } - delete data->oldCacheEntries; - data->oldCacheEntries = new ArrayList(); - } - } - - return data->cache; -} - -static BYTE* CompareEntry( CacheEntry* entry, DWORD numEvidence, DWORD evidenceSize, LPCBYTE evidenceBlock, HANDLE cache, DWORD* size) -{ - STANDARD_VM_CONTRACT; - - _ASSERTE (entry); - - if (entry->header.numItemsInKey == numEvidence && - entry->header.keySize == evidenceSize) - { - if (entry->key == NULL) - { - // We were lazy in reading the entry. Read the key now. - entry->key = new BYTE[entry->header.keySize]; - - _ASSERTE (cache != INVALID_HANDLE_VALUE); - - if (SetFilePointer( cache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - return NULL; - - if (ReadFileData( cache, entry->key, entry->header.keySize ) != S_OK) - return NULL; - - entry->cachePosition += entry->header.keySize; - } - - _ASSERTE (entry->key); - - if (memcmp( entry->key, evidenceBlock, entry->header.keySize ) == 0) - { - if (entry->data == NULL) - { - // We were lazy in reading the entry. Read the data also. - entry->data = new BYTE[entry->header.dataSize]; - - if (SetFilePointer( cache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - return NULL; - - if (ReadFileData( cache, entry->data, entry->header.dataSize ) != S_OK) - return NULL; - - entry->cachePosition += entry->header.dataSize; - } - - entry->used = TRUE; - *size = entry->header.dataSize; - - return entry->data; - } - } - return NULL; -} - -BOOL QCALLTYPE SecurityConfig::GetCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, QCall::ObjectHandleOnStack retPolicy) -{ - QCALL_CONTRACT; - - BOOL success = FALSE; - - BEGIN_QCALL; - - HANDLE cache = INVALID_HANDLE_VALUE; - - BYTE* retval = NULL; - DWORD size = (DWORD) -1; - - Data* data = (Data*)GetData( id ); - - if (data == NULL) - { - goto CLEANUP; - } - - { - - ArrayList::Iterator iter; - - if ((data->state & Data::UsingCacheFile) == 0) - { - // We know we don't have anything in the config file, so - // let's just look through the new entries to make sure we - // aren't getting any repeats. - - // Then try the existing new entries - - iter = data->newCacheEntries->Iterate(); - - while (iter.Next()) - { - // newCacheEntries do not need the cache file so pass in NULL. - retval = CompareEntry( (CacheEntry*)iter.GetElement(), numEvidence, cbEvidence, pEvidence, NULL, &size ); - - if (retval != NULL) - { - success = TRUE; - goto CLEANUP; - } - } - - goto CLEANUP; - } - - // Its possible that the old entries were not read in completely - // so we keep the cache file open before iterating through the - // old entries. - - cache = OpenCacheFile( data ); - - if ( cache == NULL ) - { - goto CLEANUP; - } - - // First, iterator over the old entries - - { - CrstHolder ch(&dataLock_); - - iter = data->oldCacheEntries->Iterate(); - while (iter.Next()) - { - retval = CompareEntry( (CacheEntry*)iter.GetElement(), numEvidence, cbEvidence, pEvidence, cache, &size ); - if (retval != NULL) - { - success = TRUE; - goto CLEANUP; - } - } - - // LockHolder goes out of scope here - } - - // Then try the existing new entries - iter = data->newCacheEntries->Iterate(); - while (iter.Next()) - { - // newCacheEntries do not need the cache file so pass in NULL. - retval = CompareEntry( (CacheEntry*)iter.GetElement(), numEvidence, cbEvidence, pEvidence, NULL, &size ); - if (retval != NULL) - { - success = TRUE; - goto CLEANUP; - } - } - - // Finally, try loading existing entries from the file - - { - CrstHolder ch(&dataLock_); - - if (SetFilePointer( cache, data->cacheCurrentPosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER) - { - goto CLEANUP; - } - - do - { - CacheEntry* entry = LoadNextEntry( cache, data ); - if (entry == NULL) - { - data->state = (Data::State)(Data::CacheExhausted | data->state); - break; - } - - retval = CompareEntry( entry, numEvidence, cbEvidence, pEvidence, cache, &size ); - if (retval != NULL) - { - success = TRUE; - break; - } - } while (TRUE); - - // LockHolder goes out of scope here - } - } - -CLEANUP: - if (success && retval != NULL) - { - _ASSERTE( size != (DWORD) -1 ); - retPolicy.SetByteArray(retval, size); - } - - END_QCALL; - - return success; -} - -void QCALLTYPE SecurityConfig::AddCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, LPCBYTE pPolicy, DWORD cbPolicy) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - Data* data = (Data*)GetData( id ); - - DWORD sizeOfEntry = 0; - NewHolder<CacheEntry> entry; - - if (data == NULL) - { - goto lExit; - } - - // In order to limit how large a long running app can become, - // we limit the total memory held by the new cache entries list. - // For now this limit corresponds with how large the max cache file - // can be. - - sizeOfEntry = cbEvidence + cbPolicy + sizeof( CacheEntryHeader ); - - if (data->newEntriesSize + sizeOfEntry >= MAX_CACHEFILE_SIZE) - { - goto lExit; - } - - entry = new CacheEntry(); - - entry->header.numItemsInKey = numEvidence; - entry->header.keySize = cbEvidence; - entry->header.dataSize = cbPolicy; - - entry->key = new BYTE[entry->header.keySize]; - entry->data = new BYTE[entry->header.dataSize]; - - memcpyNoGCRefs(entry->key, pEvidence, cbEvidence); - memcpyNoGCRefs(entry->data, pPolicy, cbPolicy); - - { - CrstHolder ch(&dataLock_); - - // Check the size again to handle the race. - if (data->newEntriesSize + sizeOfEntry < MAX_CACHEFILE_SIZE) - { - data->state = (Data::State)(Data::CacheUpdated | data->state); - IfFailThrow(data->newCacheEntries->Append( entry.GetValue() )); - entry.SuppressRelease(); - data->newEntriesSize += sizeOfEntry; - } - } - -lExit: ; - - END_QCALL; -} - -ArrayListStatic SecurityConfig::entries_; -CrstStatic SecurityConfig::dataLock_; - -void SecurityConfig::Init( void ) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END - - dataLock_.Init(CrstSecurityPolicyCache); - entries_.Init(); -} - -void SecurityConfig::Cleanup( void ) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_ANY; - } - CONTRACTL_END - - ArrayList::Iterator iter = entries_.Iterate(); - - GCX_PREEMP(); - - CrstHolder ch(&dataLock_); - - while (iter.Next()) - { - ((Data*) iter.GetElement())->Cleanup(); - } -} - -void SecurityConfig::Delete( void ) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END - - ArrayList::Iterator iter = entries_.Iterate(); - - while (iter.Next()) - { - delete (Data*) iter.GetElement(); - } - - entries_.Destroy(); - dataLock_.Destroy(); -} - -void QCALLTYPE SecurityConfig::_GetMachineDirectory(QCall::StringHandleOnStack retDirectory) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - WCHAR machine[MAX_LONGPATH]; - - HRESULT hr = GetMachineDirectory(machine, MAX_LONGPATH); - if (FAILED(hr)) - ThrowHR(hr); - - retDirectory.Set(machine); - - END_QCALL; -} - -void QCALLTYPE SecurityConfig::_GetUserDirectory(QCall::StringHandleOnStack retDirectory) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - WCHAR user[MAX_LONGPATH]; - - BOOL result = GetUserDirectory(user, MAX_LONGPATH); - if (result) - retDirectory.Set(user); - - END_QCALL; -} - -HRESULT SecurityConfig::GetMachineDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount) -{ - STANDARD_VM_CONTRACT; - - HRESULT hr; - - DWORD length = (DWORD)bufferCount; - hr = GetInternalSystemDirectory(buffer, &length); - if (FAILED(hr)) - return hr; - - // Make sure we have enough buffer to concat the string. - // Note the length including the terminating zero. - if((bufferCount - wcslen(buffer) - 1) < wcslen(W("config\\"))) - return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - - wcscat_s(buffer, bufferCount, W("config\\")); - - return S_OK; -} - -BOOL SecurityConfig::GetVIUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount) -{ - STANDARD_VM_CONTRACT; - - WCHAR scratchBuffer[MAX_LONGPATH]; - BOOL retval = FALSE; - - DWORD size = MAX_LONGPATH; - - if (!GetUserDir(buffer, bufferCount, TRUE)) - goto CLEANUP; - - wcscpy_s( scratchBuffer, COUNTOF(scratchBuffer), W("\\Microsoft\\CLR Security Config\\") ); - - if (bufferCount < wcslen( buffer ) + wcslen( scratchBuffer ) + 1) - { - goto CLEANUP; - } - - wcscat_s( buffer, bufferCount, scratchBuffer ); - - retval = TRUE; - -CLEANUP: - return retval; -} - -BOOL SecurityConfig::GetUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount) -{ - STANDARD_VM_CONTRACT; - - StackSString ssScratchBuffer; - BOOL retval = FALSE; - - WCHAR* wszScratchBuffer = ssScratchBuffer.OpenUnicodeBuffer( (COUNT_T)bufferCount ); - retval = GetVIUserDirectory(wszScratchBuffer, bufferCount); - ssScratchBuffer.CloseBuffer( (COUNT_T)wcslen( wszScratchBuffer ) ); - - if (!retval) - return retval; - - ssScratchBuffer.Append( W("v") ); - ssScratchBuffer.Append( VER_PRODUCTVERSION_NO_QFE_STR_L ); - ssScratchBuffer.Append( W("\\") ); - -#ifdef _WIN64 - ssScratchBuffer.Append( W("64bit\\") ); -#endif // _WIN64 - - if (ssScratchBuffer.GetCount() + 1 > bufferCount) - return FALSE; - - wcscpy_s( buffer, bufferCount, ssScratchBuffer.GetUnicode() ); - - return TRUE; -} - -BOOL QCALLTYPE SecurityConfig::WriteToEventLog(LPCWSTR wszMessage) -{ - QCALL_CONTRACT; - - BOOL retVal = FALSE; - - BEGIN_QCALL; - - retVal = ReportEventCLR( - EVENTLOG_WARNING_TYPE, // event type - 0, // category - (DWORD)1000, // event identifier - NULL, // no user security identifier - &StackSString(wszMessage)); // message to log - - END_QCALL - - return retVal; -} - -#ifdef _DEBUG -HRESULT QCALLTYPE SecurityConfig::DebugOut(LPCWSTR wszFileName, LPCWSTR wszMessage) -{ - HRESULT retVal = E_FAIL; - - QCALL_CONTRACT; - - BEGIN_QCALL; - - HandleHolder file(WszCreateFile( wszFileName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL )); - - if (file == INVALID_HANDLE_VALUE) - { - goto lExit; - } - - SetFilePointer( file, 0, NULL, FILE_END ); - - DWORD cbMessage; - DWORD cbWritten; - - cbMessage = (DWORD)wcslen(wszMessage) * sizeof(WCHAR); - if (!WriteFile( file, wszMessage, cbMessage, &cbWritten, NULL )) - { - goto lExit; - } - - if (cbMessage != cbWritten) - { - goto lExit; - } - - retVal = S_OK; - -lExit: ; - END_QCALL; - - return retVal; -} -#endif - -#endif // FEATURE_CAS_POLICY diff --git a/src/vm/securityconfig.h b/src/vm/securityconfig.h index e7517c517e..2090f26a02 100644 --- a/src/vm/securityconfig.h +++ b/src/vm/securityconfig.h @@ -12,111 +12,4 @@ #ifndef _COMSecurityConfig_H_ #define _COMSecurityConfig_H_ -#ifdef FEATURE_CAS_POLICY - -#include "qcall.h" - -class SecurityConfig -{ -friend struct CacheHeader; - -private: - // These structures can be removed in the next SxS runtime version when we won't have to potentially read - // config files generated by an in-place runtime that used to include them in the header. - enum RegistryExtensionsAccessStatus { - Unknown = 0, - NoExtensions = 1, - AccessFailure = 2, - AccessSuccess = 3 - }; - - struct RegistryExtensionsInfo { - RegistryExtensionsAccessStatus eStatus; - FILETIME ftLastWriteTime; - }; - -public: - // Duplicated in System.Security.Util.Config.cs - enum ConfigId - { - None = 0, - MachinePolicyLevel = 1, - UserPolicyLevel = 2, - EnterprisePolicyLevel = 3, - }; - - // Duplicated in System.Security.Util.Config.cs - enum QuickCacheEntryType - { - FullTrustZoneMyComputer = 0x1000000, - FullTrustZoneIntranet = 0x2000000, - FullTrustZoneInternet = 0x4000000, - FullTrustZoneTrusted = 0x8000000, - FullTrustZoneUntrusted = 0x10000000, - FullTrustAll = 0x20000000, - }; - - // Duplicated in System.Security.Util.Config.cs - enum ConfigRetval - { - NoFile = 0, - ConfigFile = 1, - CacheFile = 2 - }; - - static ConfigRetval InitData( INT32 id, const WCHAR* configFileName, const WCHAR* cacheFileName ); - static ConfigRetval InitData( void* configData, BOOL addToList ); - - static BOOL SaveCacheData( INT32 id ); - - static - void QCALLTYPE ResetCacheData(INT32 id); - - static - HRESULT QCALLTYPE SaveDataByte(LPCWSTR wszConfigPath, LPCBYTE pbData, DWORD cbData); - - static - BOOL QCALLTYPE RecoverData(INT32 id); - - static - void QCALLTYPE SetQuickCache(INT32 id, QuickCacheEntryType type); - - static - BOOL QCALLTYPE GetCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, QCall::ObjectHandleOnStack retPolicy); - - static - void QCALLTYPE AddCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, LPCBYTE pPolicy, DWORD cbPolicy); - - static - void QCALLTYPE _GetMachineDirectory(QCall::StringHandleOnStack retDirectory); - - static - void QCALLTYPE _GetUserDirectory(QCall::StringHandleOnStack retDirectory); - - static HRESULT GetMachineDirectory (__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount); - static BOOL GetUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount); - static BOOL GetVIUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount); - - static - BOOL QCALLTYPE WriteToEventLog(LPCWSTR wszMessage); - -#ifdef _DEBUG - static - HRESULT QCALLTYPE DebugOut(LPCWSTR wszFileName, LPCWSTR wszMessage); -#endif - - static void Init( void ); - static void Cleanup( void ); - static void Delete( void ); - - static BOOL GetQuickCacheEntry( INT32 id, QuickCacheEntryType type ); - - static void* GetData( INT32 id ); - - static ArrayListStatic entries_; - static CrstStatic dataLock_; - - static WCHAR* wcscatDWORD( __out_ecount(cchdst) __out_z WCHAR* dst, size_t cchdst, DWORD num ); -}; -#endif // FEATURE_CAS_POLICY #endif diff --git a/src/vm/securitydeclarative.cpp b/src/vm/securitydeclarative.cpp index 3fd96d56dc..1d0f5c34f7 100644 --- a/src/vm/securitydeclarative.cpp +++ b/src/vm/securitydeclarative.cpp @@ -198,19 +198,11 @@ void SecurityDeclarative::AddDeclAction(CorDeclSecurity action, PsetCacheEntry * break; case DS_UNION: -#ifdef FEATURE_CAS_POLICY - LinkNewDeclAction(ppActionList, action, SecurityAttributes::MergePermissionSets(pClassPCE, pMethodPCE, false, action), pMeth); -#else // FEATURE_CAS_POLICY _ASSERTE(!"Declarative permission sets may not be unioned together in CoreCLR. Are you attempting to have a declarative demand or deny on both a method and its enclosing class?"); -#endif // FEATURE_CAS_POLICY break; case DS_INTERSECT: -#ifdef FEATURE_CAS_POLICY - LinkNewDeclAction(ppActionList, action, SecurityAttributes::MergePermissionSets(pClassPCE, pMethodPCE, true, action), pMeth); -#else // FEATURE_CAS_POLICY _ASSERTE(!"Declarative permission sets may not be intersected in CoreCLR. Are you attempting to have a declarative permit only on both a method and its enclosing class?"); -#endif // FEATURE_CAS_POLICY break; case DS_APPLY_METHOD_THEN_CLASS: @@ -591,37 +583,6 @@ void SecurityDeclarative::MethodInheritanceCheck(MethodDesc *pMethod, MethodDesc //----------------------------------------------------------------------------- -#ifdef FEATURE_CAS_POLICY -void DECLSPEC_NORETURN SecurityDeclarative::ThrowHPException(EApiCategories protectedCategories, EApiCategories demandedCategories) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - - OBJECTREF hpException = NULL; - GCPROTECT_BEGIN(hpException); - - MethodTable* pMT = MscorlibBinder::GetClass(CLASS__HOST_PROTECTION_EXCEPTION); - hpException = (OBJECTREF) AllocateObject(pMT); - - - MethodDescCallSite ctor(METHOD__HOST_PROTECTION_EXCEPTION__CTOR); - - ARG_SLOT arg[3] = { - ObjToArgSlot(hpException), - protectedCategories, - demandedCategories - }; - ctor.Call(arg); - - COMPlusThrow(hpException); - - GCPROTECT_END(); -} -#endif // FEATURE_CAS_POLICY @@ -642,17 +603,6 @@ void SecurityDeclarative::RetrieveLinktimeDemands(MethodDesc *pMD, INJECT_FAULT(COMPlusThrowOM();); } CONTRACTL_END; -#ifdef FEATURE_CAS_POLICY - MethodTable * pMT = pMD->GetMethodTable(); - - // Class level first. - if (pMT->GetClass()->RequiresLinktimeCheck()) - *pClassCas = TypeSecurityDescriptor::GetLinktimePermissions(pMT, pClassNonCas); - - // Then the method level. - if (IsMdHasSecurity(pMD->GetAttrs())) - *pMethodCas = MethodSecurityDescriptor::GetLinktimePermissions(pMD, pMethodNonCas); -#endif } // @@ -801,659 +751,5 @@ LinktimeCheckReason SecurityDeclarative::GetLinktimeCheckReason(MethodDesc *pMD, return reason; } -#ifdef FEATURE_CAS_POLICY -// Issue an inheritance demand against the target assembly - -// static -void SecurityDeclarative::InheritanceDemand(Assembly *pTargetAssembly, OBJECTREF refDemand) -{ - CONTRACTL - { - THROWS; - MODE_COOPERATIVE; - GC_TRIGGERS; - PRECONDITION(CheckPointer(pTargetAssembly)); - PRECONDITION(refDemand != NULL); - } - CONTRACTL_END; - - struct - { - OBJECTREF refDemand; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - gc.refDemand = refDemand; - - GCPROTECT_BEGIN(gc); - - IAssemblySecurityDescriptor *pTargetASD = pTargetAssembly->GetSecurityDescriptor(); - SecurityStackWalk::LinkOrInheritanceCheck(pTargetASD, - gc.refDemand, - pTargetAssembly, - dclInheritanceCheck); - GCPROTECT_END(); -} - -// static -void SecurityDeclarative::InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand) -{ - CONTRACTL - { - STANDARD_VM_CHECK; - PRECONDITION(CheckPointer(pTargetAssembly)); - PRECONDITION(CheckPointer(pMDLinkDemand)); - } - CONTRACTL_END; - - GCX_COOP(); - struct - { - OBJECTREF refClassCas; - OBJECTREF refClassNonCas; - OBJECTREF refMethodCas; - OBJECTREF refMethodNonCas; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - - Security::RetrieveLinktimeDemands(pMDLinkDemand, - &gc.refClassCas, - &gc.refClassNonCas, - &gc.refMethodCas, - &gc.refMethodNonCas); - - if (gc.refClassCas != NULL) - { - InheritanceDemand(pTargetAssembly, gc.refClassCas); - } - - if (gc.refMethodCas != NULL) - { - InheritanceDemand(pTargetAssembly, gc.refMethodCas); - } - - GCPROTECT_END(); -} - -// Issue a FullTrust inheritance demand against the target assembly - -// static -void SecurityDeclarative::FullTrustInheritanceDemand(Assembly *pTargetAssembly) -{ - CONTRACTL - { - STANDARD_VM_CHECK; - PRECONDITION(CheckPointer(pTargetAssembly)); - } - CONTRACTL_END; - - GCX_COOP(); - - struct - { - OBJECTREF refFullTrust; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - - gc.refFullTrust = Security::CreatePermissionSet(TRUE); - InheritanceDemand(pTargetAssembly, gc.refFullTrust); - - GCPROTECT_END(); -} - -// Issue a FullTrust link demand against the target assembly - -// static -void SecurityDeclarative::FullTrustLinkDemand(Assembly *pTargetAssembly) -{ - CONTRACTL - { - THROWS; - MODE_COOPERATIVE; - GC_TRIGGERS; - PRECONDITION(CheckPointer(pTargetAssembly)); - } - CONTRACTL_END; - - struct - { - OBJECTREF refFullTrust; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - - gc.refFullTrust = Security::CreatePermissionSet(TRUE); - IAssemblySecurityDescriptor *pTargetASD = pTargetAssembly->GetSecurityDescriptor(); - SecurityStackWalk::LinkOrInheritanceCheck(pTargetASD, - gc.refFullTrust, - pTargetAssembly, - dclLinktimeCheck); - GCPROTECT_END(); -} - -// Used by interop to simulate the effect of link demands when the caller is -// in fact script constrained by an appdomain setup by IE. -void SecurityDeclarative::CheckLinkDemandAgainstAppDomain(MethodDesc *pMD) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - - if (!pMD->RequiresLinktimeCheck()) - return; - - // Find the outermost (closest to caller) appdomain. This - // represents the domain in which the unmanaged caller is - // considered to "live" (or, at least, be constrained by). - AppDomain *pDomain = GetThread()->GetInitialDomain(); - - // The link check is only performed if this app domain has - // security permissions associated with it, which will be - // the case for all IE scripting callers that have got this - // far because we automatically reported our managed classes - // as "safe for scripting". - // - // We also can't do the check if the AppDomain isn't fully - // setup yet, since we might not have a domain grant set. - // This is acceptable, since the only code that should run - // during AppDomain creation is fully trusted. - IApplicationSecurityDescriptor *pSecDesc = pDomain->GetSecurityDescriptor(); - if (pSecDesc == NULL || pSecDesc->IsInitializationInProgress() || pSecDesc->IsDefaultAppDomain()) - return; - - struct _gc - { - OBJECTREF refGrant; - OBJECTREF refRefused; - OBJECTREF refClassNonCasDemands; - OBJECTREF refClassCasDemands; - OBJECTREF refMethodNonCasDemands; - OBJECTREF refMethodCasDemands; - OBJECTREF refAssembly; - } gc; - ZeroMemory(&gc, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - - - // Fetch link demand sets from all the places in metadata where we might - // find them (class and method). These might be split into CAS and non-CAS - // sets as well. - SecurityDeclarative::RetrieveLinktimeDemands(pMD, - &gc.refClassCasDemands, - &gc.refClassNonCasDemands, - &gc.refMethodCasDemands, - &gc.refMethodNonCasDemands); - - // Check CAS link demands. - bool fGotGrantSet = false; - if (gc.refClassCasDemands != NULL || gc.refMethodCasDemands != NULL) - { - // Get grant (and possibly denied) sets from the app - // domain. - gc.refGrant = pSecDesc->GetGrantedPermissionSet(NULL); - fGotGrantSet = true; - gc.refAssembly = pMD->GetAssembly()->GetExposedObject(); - - if (gc.refClassCasDemands != NULL) - SecurityStackWalk::CheckSetHelper(&gc.refClassCasDemands, - &gc.refGrant, - &gc.refRefused, - pDomain, - pMD, - &gc.refAssembly, - dclLinktimeCheck); - - if (gc.refMethodCasDemands != NULL) - SecurityStackWalk::CheckSetHelper(&gc.refMethodCasDemands, - &gc.refGrant, - &gc.refRefused, - pDomain, - pMD, - &gc.refAssembly, - dclLinktimeCheck); - - } - - // Non-CAS demands are not applied against a grant - // set, they're standalone. - if (gc.refClassNonCasDemands != NULL) - CheckNonCasDemand(&gc.refClassNonCasDemands); - - if (gc.refMethodNonCasDemands != NULL) - CheckNonCasDemand(&gc.refMethodNonCasDemands); - - - GCPROTECT_END(); -} - - - - - - - - - - - - - - - - - - - - - - - - - -//----------------------------------------------------------------------------- -// -// -// CODE FOR PERFORMING RUN-TIME CHECKS -// -// -//----------------------------------------------------------------------------- - -void SecurityDeclarative::EnsureAssertAllowed(MethodDesc *pMeth, MethodSecurityDescriptor *pMSD) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - PRECONDITION(CheckPointer(pMeth)); - PRECONDITION(pMSD == NULL || pMSD->GetMethod() == pMeth); - } CONTRACTL_END; - - // Check if this Assembly has permission to assert - if (pMSD == NULL || !pMSD->CanAssert()) // early out if we have an MSD and we already have checked this permission - { - Module* pModule = pMeth->GetModule(); - PREFIX_ASSUME_MSG(pModule != NULL, "Should be a Module pointer here"); - - if (!Security::CanAssert(pModule)) - SecurityPolicy::ThrowSecurityException(g_SecurityPermissionClassName, SPFLAGSASSERTION); - } - - // Check if the Method is allowed to assert based on transparent/critical classification - if (!SecurityTransparent::IsAllowedToAssert(pMeth) && Security::IsTransparencyEnforcementEnabled()) - { -#ifdef _DEBUG - if (g_pConfig->LogTransparencyErrors()) - { - SecurityTransparent::LogTransparencyError(pMeth, "Transparent method using a security assert"); - } -#endif // _DEBUG - // if assembly is transparent fail the ASSERT operations - COMPlusThrow(kInvalidOperationException, W("InvalidOperation_AssertTransparentCode")); - } - - return; -} - -void SecurityDeclarative::InvokeDeclarativeActions (MethodDesc *pMeth, DeclActionInfo *pActions, MethodSecurityDescriptor *pMSD) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - - OBJECTREF refPermSet = NULL; - ARG_SLOT arg = 0; - - // If we get a real PermissionSet, then invoke the action. - switch (pActions->dwDeclAction) - { - case DECLSEC_DEMANDS: - SecurityStackWalk::DemandSet(SSWT_DECLARATIVE_DEMAND, pActions->pPCE, dclDemand); - break; - - case DECLSEC_ASSERTIONS: - EnsureAssertAllowed(pMeth, pMSD); - GetThread()->IncrementAssertCount(); - break; - - case DECLSEC_DENIALS: - case DECLSEC_PERMITONLY: - GetThread()->IncrementOverridesCount(); - break; - - case DECLSEC_NONCAS_DEMANDS: - refPermSet = pActions->pPCE->CreateManagedPsetObject (dclNonCasDemand); - if (refPermSet == NULL) - break; - if(!((PERMISSIONSETREF)refPermSet)->CheckedForNonCas() ||((PERMISSIONSETREF)refPermSet)->ContainsNonCas()) - { - GCPROTECT_BEGIN(refPermSet); - MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, &refPermSet); - - arg = ObjToArgSlot(refPermSet); - demand.Call(&arg); - GCPROTECT_END(); - } - break; - - default: - _ASSERTE(!"Unknown action requested in InvokeDeclarativeActions"); - break; - - } // switch -} - - -// -// CODE FOR PERFORMING RUN-TIME CHECKS -// -extern LPVOID GetSecurityObjectForFrameInternal(StackCrawlMark *stackMark, INT32 create, OBJECTREF *pRefSecDesc); - -namespace -{ - inline void UpdateFrameSecurityObj(DWORD dwAction, OBJECTREF *refPermSet, OBJECTREF * pSecObj) - { - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - - GetSecurityObjectForFrameInternal(NULL, true, pSecObj); - - FRAMESECDESCREF fsdRef = (FRAMESECDESCREF)*pSecObj; - switch (dwAction) - { - // currently we require declarative security to store the data in both the fields in the FSD - case dclAssert: - fsdRef->SetDeclarativeAssertions(*refPermSet); - { - PERMISSIONSETREF psRef = (PERMISSIONSETREF)*refPermSet; - if (psRef != NULL && psRef->IsUnrestricted()) - fsdRef->SetAssertFT(TRUE); - } - break; - - case dclDeny: - fsdRef->SetDeclarativeDenials(*refPermSet); - break; - - case dclPermitOnly: - fsdRef->SetDeclarativeRestrictions(*refPermSet); - break; - - default: - _ASSERTE(0 && "Unreached, add code to handle if reached here..."); - break; - } - } -} - -void SecurityDeclarative::InvokeDeclarativeStackModifiers(MethodDesc * pMeth, DeclActionInfo * pActions, OBJECTREF * pSecObj) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - - OBJECTREF refPermSet = NULL; - - // If we get a real PermissionSet, then invoke the action. - switch (pActions->dwDeclAction) - { - case DECLSEC_DEMANDS: - case DECLSEC_NONCAS_DEMANDS: - // Nothing to do for demands - break; - - case DECLSEC_ASSERTIONS: - refPermSet = pActions->pPCE->CreateManagedPsetObject (dclAssert); - if (refPermSet == NULL) - break; - GCPROTECT_BEGIN(refPermSet); - // Now update the frame security object - UpdateFrameSecurityObj(dclAssert, &refPermSet, pSecObj); - GCPROTECT_END(); - break; - - case DECLSEC_DENIALS: - // Update the frame security object - refPermSet = pActions->pPCE->CreateManagedPsetObject (dclDeny); - - if (refPermSet == NULL) - break; - - GCPROTECT_BEGIN(refPermSet); - -#ifdef FEATURE_CAS_POLICY - // Deny is only valid if we're in legacy CAS mode - IApplicationSecurityDescriptor *pSecDesc = GetAppDomain()->GetSecurityDescriptor(); - if (!pSecDesc->IsLegacyCasPolicyEnabled()) - { - COMPlusThrow(kNotSupportedException, W("NotSupported_CasDeny")); - } -#endif // FEATURE_CAS_POLICY - - UpdateFrameSecurityObj(dclDeny, &refPermSet, pSecObj); - - GCPROTECT_END(); - break; - - case DECLSEC_PERMITONLY: - // Update the frame security object - refPermSet = pActions->pPCE->CreateManagedPsetObject (dclPermitOnly); - - if (refPermSet == NULL) - break; - GCPROTECT_BEGIN(refPermSet); - UpdateFrameSecurityObj(dclPermitOnly, &refPermSet, pSecObj); - GCPROTECT_END(); - break; - - - default: - _ASSERTE(!"Unknown action requested in InvokeDeclarativeStackModifiers"); - break; - - } // switch -} - -void SecurityDeclarative::DoDeclarativeActions(MethodDesc *pMeth, DeclActionInfo *pActions, LPVOID pSecObj, MethodSecurityDescriptor *pMSD) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - -#ifndef FEATURE_CAS_POLICY - // In the CoreCLR, we don't support CAS actions outside mscorlib. - // However, we do have to expose certain types in mscorlib due to compiler requirements - // (c# compiler requires us to expose SecurityPermission/SecurityAction etc so that it can - // insert a RequestMinimum for SkipVerification). - // This means that code outside mscorlib could construct IL that has declarative security - // in it. This is not a security issue - even if they try to create IL that asserts for - // permissions they don't have, it's not going to work for the same reasons it didn't in the desktop. - // However, we could have bugs like DDB 120109 where they can cause Demands to fail etc. - // So for goodness, we're not going to do any runtime declarative work on assemblies other than mscorlib. - if (!pMeth->GetModule()->IsSystem()) - { - // Non-mscorlib code reached... exit - return; - } -#endif //!FEATURE_CAS_POLICY - - - // --------------------------------------------------------------------------- // - // D E C L A R A T I V E S E C U R I T Y D E M A N D S // - // --------------------------------------------------------------------------- // - // The frame is now fully formed, arguments have been copied into place, - // and synchronization monitors have been entered if necessary. At this - // point, we are prepared for something to throw an exception, so we may - // check for declarative security demands and execute them. We need a - // well-formed frame and synchronization domain to accept security excep- - // tions thrown by the SecurityManager. We MAY need argument values in - // the frame so that the arguments may be finalized if security throws an - // exception across them (unknown). - if (pActions != NULL && pActions->dwDeclAction == DECLSEC_UNMNGD_ACCESS_DEMAND && - pActions->pNext == NULL) - { - /* We special-case the security check on single pinvoke/interop calls - so we can avoid setting up the GCFrame */ - - SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE); - return; - } - else - { -#ifdef FEATURE_COMPRESSEDSTACK - // If this is an anonymously hosted dynamic method, there aren't any direct modifiers, but if it has a compressed stack that - // might have modifiers, mark that there are modifiers so we make sure to do a stack walk - if(SecurityStackWalk::MethodIsAnonymouslyHostedDynamicMethodWithCSToEvaluate(pMeth)) - { - // We don't know how many asserts or overrides might be in the compressed stack, - // but we just need to increment the counters to ensure optimizations don't skip CS evaluation - GetThread()->IncrementAssertCount(); - GetThread()->IncrementOverridesCount(); - } -#endif // FEATURE_COMPRESSEDSTACK - - for (/**/; pActions; pActions = pActions->pNext) - { - if (pActions->dwDeclAction == DECLSEC_UNMNGD_ACCESS_DEMAND) - { - SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE); - } - else - { - InvokeDeclarativeActions(pMeth, pActions, pMSD); - } - } - - } -} -void SecurityDeclarative::DoDeclarativeStackModifiers(MethodDesc *pMeth, AppDomain* pAppDomain, LPVOID pSecObj) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - -#ifndef FEATURE_CAS_POLICY - // In the CoreCLR, we don't support CAS actions outside mscorlib. - // However, we do have to expose certain types in mscorlib due to compiler requirements - // (c# compiler requires us to expose SecurityPermission/SecurityAction etc so that it can - // insert a RequestMinimum for SkipVerification). - // This means that code outside mscorlib could construct IL that has declarative security - // in it. This is not a security issue - even if they try to create IL that asserts for - // permissions they don't have, it's not going to work for the same reasons it didn't in the desktop. - // However, we could have bugs like DDB 120109 where they can cause Demands to fail etc. - // So for goodness, we're not going to do any runtime declarative work on assemblies other than mscorlib. - if (!pMeth->GetModule()->IsSystem()) - { - // Non-mscorlib code reached... exit - return; - } -#endif //!FEATURE_CAS_POLICY - - - AppDomain* pCurrentDomain = GetAppDomain(); - - if (pCurrentDomain != pAppDomain) - { - ENTER_DOMAIN_PTR(pAppDomain, ADV_RUNNINGIN) - { - DoDeclarativeStackModifiersInternal(pMeth, pSecObj); - } - END_DOMAIN_TRANSITION; - } - else - { - DoDeclarativeStackModifiersInternal(pMeth, pSecObj); - } - } - -void SecurityDeclarative::DoDeclarativeStackModifiersInternal(MethodDesc *pMeth, LPVOID pSecObj) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - - Object** ppSecObject = (Object**) pSecObj; - _ASSERTE(pMeth->IsInterceptedForDeclSecurity() && !pMeth->IsInterceptedForDeclSecurityCASDemandsOnly()); - - MethodSecurityDescriptor MDSecDesc(pMeth); - MethodSecurityDescriptor::LookupOrCreateMethodSecurityDescriptor(&MDSecDesc); - DeclActionInfo* pActions = MDSecDesc.GetRuntimeDeclActionInfo(); - - OBJECTREF fsdRef = ObjectToOBJECTREF(*ppSecObject); - GCPROTECT_BEGIN(fsdRef); - - for (/**/; pActions; pActions = pActions->pNext) - { - InvokeDeclarativeStackModifiers(pMeth, pActions, &fsdRef); - } - // If we had just NON-CAS demands, we'd come here but not create an FSD. - if (fsdRef != NULL) - { - ((FRAMESECDESCREF)(fsdRef))->SetDeclSecComputed(TRUE); - - if (*ppSecObject == NULL) - { - // we came in with a NULL FSD and the FSD got created here...so we need to copy it back - // If we had come in with a non-NULL FSD, that would have been updated and this (shallow/pointer) copy - // would not be necessary - *ppSecObject = OBJECTREFToObject(fsdRef); - } -} - - GCPROTECT_END(); -} - - -void SecurityDeclarative::CheckNonCasDemand(OBJECTREF *prefDemand) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(IsProtectedByGCFrame (prefDemand)); - } CONTRACTL_END; - - if(((PERMISSIONSETREF)*prefDemand)->CheckedForNonCas()) - { - if(!((PERMISSIONSETREF)*prefDemand)->ContainsNonCas()) - return; - } - MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, prefDemand); - ARG_SLOT arg = ObjToArgSlot(*prefDemand); - demand.Call(&arg); -} - -#endif // FEATURE_CAS_POLICY #endif // CROSSGEN_COMPILE diff --git a/src/vm/securitydeclarative.h b/src/vm/securitydeclarative.h index f2b6b1fecd..9874148326 100644 --- a/src/vm/securitydeclarative.h +++ b/src/vm/securitydeclarative.h @@ -152,9 +152,6 @@ namespace SecurityDeclarative inline BOOL ClassIsVisibleOutsideItsAssembly(DWORD dwClassAttr, BOOL fIsGlobalClass); -#ifdef FEATURE_CAS_POLICY - void DECLSPEC_NORETURN ThrowHPException(EApiCategories protectedCategories, EApiCategories demandedCategories); -#endif // FEATURE_CAS_POLICY // Add a declarative action and PermissionSet index to the linked list void AddDeclAction(CorDeclSecurity action, PsetCacheEntry *pClassPCE, PsetCacheEntry *pMethodPCE, DeclActionInfo** ppActionList, MethodDesc *pMeth); diff --git a/src/vm/securitydeclarativecache.cpp b/src/vm/securitydeclarativecache.cpp index dcfc1e0c4d..202c016459 100644 --- a/src/vm/securitydeclarativecache.cpp +++ b/src/vm/securitydeclarativecache.cpp @@ -75,65 +75,7 @@ OBJECTREF PsetCacheEntry::CreateManagedPsetObject(DWORD dwAction, bool createEmp MODE_COOPERATIVE; } CONTRACTL_END; -#ifdef FEATURE_CAS_POLICY - OBJECTREF orRet; - - orRet = GetManagedPsetObject(); - if (orRet != NULL) { - return orRet; - } - - if (!createEmptySet && m_fEmptyPermissionSet) { - return NULL; - } - - struct _gc { - OBJECTREF pset; - OBJECTREF encoding; - OBJECTREF nonCasPset; - OBJECTREF orNonCasPset; - OBJECTREF orNonCasEncoding; - } gc; - memset(&gc, 0, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - - if ( (m_pKey->m_cbPset > 0) && (m_pKey->m_pbPset[0] == LAZY_DECL_SEC_FLAG) ) { - - SecurityAttributes::AttrSetBlobToPermissionSets(m_pKey->m_pbPset, - m_pKey->m_cbPset, - &gc.pset, - dwAction); - - } else { - - SecurityAttributes::XmlToPermissionSet(m_pKey->m_pbPset, - m_pKey->m_cbPset, - &gc.pset, - &gc.encoding, - NULL, - 0, - &gc.orNonCasPset, - &gc.orNonCasEncoding); - } - - StoreFirstObjectInHandle(m_handle, gc.pset); - - if (gc.pset == NULL) - m_fEmptyPermissionSet = true; - - GCPROTECT_END(); - - // - // Some other thread may have won the race, and stored away a different - // object in the handle. - // - - orRet = GetManagedPsetObject(); - return orRet; -#else return NULL; -#endif } #endif // CROSSGEN_COMPILE diff --git a/src/vm/securitydescriptor.cpp b/src/vm/securitydescriptor.cpp index d8af752e2e..2ff1823bb5 100644 --- a/src/vm/securitydescriptor.cpp +++ b/src/vm/securitydescriptor.cpp @@ -56,65 +56,9 @@ OBJECTREF SecurityDescriptor::GetGrantedPermissionSet(OBJECTREF* pRefusedPermiss // // Returns TRUE if the given zone has the given special permission. // -#ifdef FEATURE_CAS_POLICY -BOOL SecurityDescriptor::CheckQuickCache(SecurityConfig::QuickCacheEntryType all, DWORD dwZone) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled()); - PRECONDITION(SecurityPolicy::s_fPolicyInitialized); - } CONTRACTL_END; - - static const SecurityConfig::QuickCacheEntryType zoneTable[] = - { - SecurityConfig::FullTrustZoneMyComputer, - SecurityConfig::FullTrustZoneIntranet, - SecurityConfig::FullTrustZoneTrusted, - SecurityConfig::FullTrustZoneInternet, - SecurityConfig::FullTrustZoneUntrusted - }; - - // If an additional evidence was provided, then perform the normal - // policy resolution. This is true for all AppDomains and also for - // assemblies loaded with a specific additional evidence. Note that - // for the default AppDomain, the policy resolution code paths short - // circuits the parsing of the security XML files by granting FullTrust - // to the default AppDomain. - - if (m_hAdditionalEvidence != NULL) - return FALSE; - - BOOL fMachine = SecurityConfig::GetQuickCacheEntry(SecurityConfig::MachinePolicyLevel, all); - BOOL fUser = SecurityConfig::GetQuickCacheEntry(SecurityConfig::UserPolicyLevel, all); - BOOL fEnterprise = SecurityConfig::GetQuickCacheEntry(SecurityConfig::EnterprisePolicyLevel, all); - - if (fMachine && fUser && fEnterprise) - return TRUE; - - // If we can't match for all, try for our zone. - if (dwZone == 0xFFFFFFFF) - return FALSE; - - fMachine = SecurityConfig::GetQuickCacheEntry(SecurityConfig::MachinePolicyLevel, zoneTable[dwZone]); - fUser = SecurityConfig::GetQuickCacheEntry(SecurityConfig::UserPolicyLevel, zoneTable[dwZone]); - fEnterprise = SecurityConfig::GetQuickCacheEntry(SecurityConfig::EnterprisePolicyLevel, zoneTable[dwZone]); - - return (fMachine && fUser && fEnterprise); -} -#endif // FEATURE_CAS_POLICY #endif // DACCESS_COMPILE -#ifdef FEATURE_CAS_POLICY -BOOL SecurityDescriptor::IsEvidenceComputed() const -{ - LIMITED_METHOD_CONTRACT; - return m_fEvidenceComputed; -} -#endif //FEATURE_CAS_POLICY // // This method will return TRUE if this object is fully trusted. @@ -179,25 +123,6 @@ void SecurityDescriptor::SetGrantedPermissionSet(OBJECTREF GrantedPermissionSet, } -#ifdef FEATURE_CAS_POLICY -void SecurityDescriptor::SetEvidence(OBJECTREF evidence) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(evidence != NULL); - } - CONTRACTL_END; - - if (evidence != NULL) - { - StoreObjectInLazyHandle(m_hAdditionalEvidence, evidence, m_pLoaderAllocator); - SetEvidenceComputed(); - } -} -#endif // FEATURE_CAS_POLICY #endif // !DACCESS_COMPILE AppDomain* SecurityDescriptor::GetDomain() const @@ -208,67 +133,6 @@ AppDomain* SecurityDescriptor::GetDomain() const #ifndef DACCESS_COMPILE -#ifdef FEATURE_CAS_POLICY - -//--------------------------------------------------------------------------------------- -// -// Build an evidence collection which can generate evidence about a PEFile -// -// Arguments: -// pPEFile - PEFile the evidence collection will generate evidence for -// objHostSuppliedEvidence - additional evidence to merge into the collection supplied by the host -// -// Return Value: -// Evidence collection which targets this PEFile -// -// Notes: -// Calls System.Security.Policy.PEFileEvidenceFactory.CreateSecurityIdentity -// - -// static -OBJECTREF PEFileSecurityDescriptor::BuildEvidence(PEFile *pPEFile, const OBJECTREF& objHostSuppliedEvidence) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pPEFile)); - } - CONTRACTL_END; - - struct - { - SAFEHANDLE objPEFile; - OBJECTREF objHostSuppliedEvidence; - OBJECTREF objEvidence; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - BEGIN_SO_INTOLERANT_CODE(GetThread()); - - gc.objPEFile = pPEFile->GetSafeHandle(); - gc.objHostSuppliedEvidence = objHostSuppliedEvidence; - - MethodDescCallSite createSecurityIdentity(METHOD__PEFILE_EVIDENCE_FACTORY__CREATE_SECURITY_IDENTITY); - - ARG_SLOT args[] = - { - ObjToArgSlot(gc.objPEFile), - ObjToArgSlot(gc.objHostSuppliedEvidence) - }; - - gc.objEvidence = createSecurityIdentity.Call_RetOBJECTREF(args); - - END_SO_INTOLERANT_CODE; - GCPROTECT_END(); - - return gc.objEvidence; -} - -#endif // FEATURE_CAS_POLICY #endif // !DACCESS_COMPILE diff --git a/src/vm/securitydescriptor.h b/src/vm/securitydescriptor.h index 26e46633dc..a4d6b309ef 100644 --- a/src/vm/securitydescriptor.h +++ b/src/vm/securitydescriptor.h @@ -68,9 +68,6 @@ inline void StoreObjectInLazyHandle(LOADERHANDLE& handle, OBJECTREF ref, LoaderA class SecurityDescriptor { protected: -#ifdef FEATURE_CAS_POLICY - LOADERHANDLE m_hAdditionalEvidence; // Evidence Object -#endif // FEATURE_CAS_POLICY // The unmanaged DomainAssembly object DomainAssembly *m_pAssem; @@ -82,9 +79,6 @@ protected: AppDomain* m_pAppDomain; BOOL m_fSDResolved; -#ifdef FEATURE_CAS_POLICY - BOOL m_fEvidenceComputed; -#endif // FEATURE_CAS_POLICY DWORD m_dwSpecialFlags; LoaderAllocator *m_pLoaderAllocator; @@ -102,15 +96,6 @@ public: AppDomain* GetDomain() const; BOOL CanCallUnmanagedCode() const; -#ifdef FEATURE_CAS_POLICY - -#ifndef DACCESS_COMPILE - void SetEvidence(OBJECTREF evidence); - BOOL CheckQuickCache(SecurityConfig::QuickCacheEntryType all, DWORD dwZone); -#endif // FEATURE_CAS_POLICY - BOOL IsEvidenceComputed() const; - inline void SetEvidenceComputed(); -#endif // FEATURE_CAS_POLICY #ifndef DACCESS_COMPILE void SetGrantedPermissionSet(OBJECTREF GrantedPermissionSet, @@ -156,12 +141,6 @@ public: virtual BOOL IsResolved() const { return SecurityDescriptor::IsResolved(); } -#ifdef FEATURE_CAS_POLICY - virtual BOOL IsEvidenceComputed() const { return SecurityDescriptor::IsEvidenceComputed(); } -#ifndef DACCESS_COMPILE - virtual void SetEvidence(OBJECTREF evidence) { SecurityDescriptor::SetEvidence(evidence); } -#endif // DACCESS_COMPILE -#endif // FEATURE_CAS_POLICY #ifndef DACCESS_COMPILE virtual OBJECTREF GetGrantedPermissionSet(OBJECTREF* RefusedPermissions = NULL) { return SecurityDescriptor::GetGrantedPermissionSet(RefusedPermissions); } diff --git a/src/vm/securitydescriptor.inl b/src/vm/securitydescriptor.inl index 8351389ef4..f894831db6 100644 --- a/src/vm/securitydescriptor.inl +++ b/src/vm/securitydescriptor.inl @@ -38,16 +38,10 @@ inline SecurityDescriptor::SecurityDescriptor(AppDomain *pAppDomain, DomainAssembly *pAssembly, PEFile* pPEFile, LoaderAllocator *pLoaderAllocator) : -#ifdef FEATURE_CAS_POLICY - m_hAdditionalEvidence(NULL), -#endif // FEATURE_CAS_POLICY m_pAssem(pAssembly), m_pPEFile(pPEFile), m_pAppDomain(pAppDomain), m_fSDResolved(FALSE), -#ifdef FEATURE_CAS_POLICY - m_fEvidenceComputed(FALSE), -#endif // FEATURE_CAS_POLICY m_dwSpecialFlags(0), m_pLoaderAllocator(pLoaderAllocator) #ifndef CROSSGEN_COMPILE @@ -59,14 +53,6 @@ inline SecurityDescriptor::SecurityDescriptor(AppDomain *pAppDomain, } #endif // !DACCESS_COMPILE -#ifdef FEATURE_CAS_POLICY -inline void SecurityDescriptor::SetEvidenceComputed() -{ - LIMITED_METHOD_CONTRACT; - m_fEvidenceComputed = TRUE; -} - -#endif // FEATURE_CAS_POLICY // Checks for one of the special security flags such as FullTrust or UnmanagedCode FORCEINLINE BOOL SecurityDescriptor::CheckSpecialFlag (DWORD flags) const diff --git a/src/vm/securitydescriptorappdomain.h b/src/vm/securitydescriptorappdomain.h index b3f862b69d..432e0e391f 100644 --- a/src/vm/securitydescriptorappdomain.h +++ b/src/vm/securitydescriptorappdomain.h @@ -76,9 +76,6 @@ private: // exists on the AppDomain. (In the managed world: AppDomain._SecurityIdentity != null) BOOL m_fHomogeneous; // This AppDomain has an ApplicationTrust BOOL m_fRuntimeSuppliedHomogenousGrantSet; // This AppDomain is homogenous only because the v4 CLR defaults to creating homogenous domains, and would not have been homogenous in v2 -#ifdef FEATURE_CAS_POLICY - BOOL m_fLegacyCasPolicy; // This AppDomain is using legacy CAS policy -#endif // FEATURE_CAS_POLICY DWORD m_dwHostSecurityManagerFlags; // Flags indicating what decisions the host wants to participate in. BOOL m_fContainsAnyRefusedPermissions; @@ -125,20 +122,12 @@ public: inline void SetHomogeneousFlag(BOOL fRuntimeSuppliedHomogenousGrantSet); virtual BOOL IsHomogeneous() const; -#ifdef FEATURE_CAS_POLICY - virtual BOOL IsLegacyCasPolicyEnabled(); - virtual void SetLegacyCasPolicyEnabled(); -#endif // FEATURE_CAS_POLICY virtual BOOL ContainsAnyRefusedPermissions(); // Should the HSM be consulted for security decisions in this AppDomain. virtual BOOL CallHostSecurityManager(); -#ifdef FEATURE_CAS_POLICY - // Does the domain's HSM need to be consulted for assemblies loaded into the domain - inline BOOL CallHostSecurityManagerForAssemblies(); -#endif // FEATURE_CAS_POLICY // Initialize the PLS on the AppDomain. void InitializePLS(); @@ -157,12 +146,6 @@ public: inline BOOL CheckDomainWideSpecialFlag(DWORD flags) const; virtual DWORD GetDomainWideSpecialFlag() const; -#ifdef FEATURE_CAS_POLICY - virtual OBJECTREF GetEvidence(); - DWORD GetZone(); - - virtual BOOL AllowsLoadsFromRemoteSources(); -#endif // FEATURE_CAS_POLICY virtual BOOL DomainMayContainPartialTrustCode(); diff --git a/src/vm/securitydescriptorappdomain.inl b/src/vm/securitydescriptorappdomain.inl index 13fccf3b79..f3fdde2b12 100644 --- a/src/vm/securitydescriptorappdomain.inl +++ b/src/vm/securitydescriptorappdomain.inl @@ -21,9 +21,6 @@ inline ApplicationSecurityDescriptor::ApplicationSecurityDescriptor(AppDomain *p m_fIsDefaultAppdomainEvidence(FALSE), m_fHomogeneous(FALSE), m_fRuntimeSuppliedHomogenousGrantSet(FALSE), -#ifdef FEATURE_CAS_POLICY - m_fLegacyCasPolicy(Security::IsProcessWideLegacyCasPolicyEnabled()), -#endif // FEATURE_CAS_POLICY m_dwHostSecurityManagerFlags(HOST_NONE), m_fContainsAnyRefusedPermissions(FALSE), m_fIsPreResolved(FALSE), @@ -76,34 +73,6 @@ inline void ApplicationSecurityDescriptor::SetHomogeneousFlag(BOOL fRuntimeSuppl m_fRuntimeSuppliedHomogenousGrantSet = fRuntimeSuppliedHomogenousGrantSet; } -#ifdef FEATURE_CAS_POLICY - -// Does the domain's HSM need to be consulted for assemblies loaded into the domain -inline BOOL ApplicationSecurityDescriptor::CallHostSecurityManagerForAssemblies() -{ - LIMITED_METHOD_CONTRACT; - - // We always need to call the HSM if it wants to specify the assembly's grant set - if (m_dwHostSecurityManagerFlags & HOST_RESOLVE_POLICY) - { - return TRUE; - } - - // In legacy CAS mode, we also need to call the HSM if it wants to supply evidence or if we have an - // AppDomain policy level - if (IsLegacyCasPolicyEnabled()) - { - if ((m_dwHostSecurityManagerFlags & HOST_ASM_EVIDENCE) || - (m_dwHostSecurityManagerFlags & HOST_POLICY_LEVEL)) - { - return TRUE; - } - } - - return FALSE; -} - -#endif // FEATURE_CAS_POLICY #endif // #ifndef DACCESS_COMPILE diff --git a/src/vm/securitydescriptorassembly.cpp b/src/vm/securitydescriptorassembly.cpp index be9e70e5aa..383d62c3e3 100644 --- a/src/vm/securitydescriptorassembly.cpp +++ b/src/vm/securitydescriptorassembly.cpp @@ -15,14 +15,6 @@ AssemblySecurityDescriptor::AssemblySecurityDescriptor(AppDomain *pDomain, Domai m_dwNumPassedDemands(0), m_pSignature(NULL), m_pSharedSecDesc(NULL), -#ifdef FEATURE_CAS_POLICY - m_hRequiredPermissionSet(NULL), - m_hOptionalPermissionSet(NULL), - m_hDeniedPermissionSet(NULL), - m_fAdditionalEvidence(FALSE), - m_fIsSignatureLoaded(FALSE), - m_fAssemblyRequestsComputed(FALSE), -#endif m_fMicrosoftPlatform(FALSE), m_fAllowSkipVerificationInFullTrust(TRUE) { @@ -151,48 +143,6 @@ BOOL AssemblySecurityDescriptor::QuickIsFullyTrusted() if (IsSystem()) return TRUE; -#ifdef FEATURE_CAS_POLICY - - // NGEN is always done in full trust - if (m_pAppDomain->IsCompilationDomain()) - { - return TRUE; - } - - // If the assembly is in the GAC then it gets FullTrust. - if (m_pAssem->GetFile()->IsSourceGAC()) - return TRUE; - - // quickly detect if we've got a request refused or a request optional. - if (m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled()) - { - ReleaseHolder<IMDInternalImport> pImport(m_pAssem->GetFile()->GetMDImportWithRef()); - if (SecurityAttributes::RestrictiveRequestsInAssembly(pImport)) - return FALSE; - } - - // Check if we need to call the HostSecurityManager. - ApplicationSecurityDescriptor* pAppSecDesc = static_cast<ApplicationSecurityDescriptor*>(m_pAppDomain->GetSecurityDescriptor()); - if (pAppSecDesc->CallHostSecurityManagerForAssemblies()) - return FALSE; - - // - If the AppDomain is homogeneous, we currently simply detect the FT case - // - Not having CAS on implies full trust. We can get here if we're still in the process of setting up - // the AppDomain and the CLR hasn't yet setup the homogenous flag. - // - Otherwise, check the quick cache - if (pAppSecDesc->IsHomogeneous()) - { - return m_pAppDomain->GetSecurityDescriptor()->IsFullyTrusted(); - } - else if (!m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled()) - { - return TRUE; - } - else if (CheckQuickCache(SecurityConfig::FullTrustAll, GetZone())) - { - return TRUE; - } -#endif // See if we've already determined that the assembly is FT // in another AppDomain, in case this is a shared assembly. @@ -231,115 +181,6 @@ void AssemblySecurityDescriptor::PropagatePermissionSet(OBJECTREF GrantedPermiss Resolve(); } -#ifdef FEATURE_CAS_POLICY -//----------------------------------------------------------------------------------------------------------- -// -// Use the evidence already generated for this assembly's PEFile as the evidence for the assembly -// -// Arguments: -// pPEFileSecDesc - PEFile security descriptor contining the already generated evidence -// -void AssemblySecurityDescriptor::SetEvidenceFromPEFile(IPEFileSecurityDescriptor *pPEFileSecDesc) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(CheckPointer(pPEFileSecDesc)); - PRECONDITION(GetPEFile()->Equals(static_cast<PEFileSecurityDescriptor*>(pPEFileSecDesc)->GetPEFile())); - } - CONTRACTL_END; - - // If we couldn't determine the assembly was fully trusted without first generating evidence for it, - // then we cannot reuse the PEFile's evidence. In that case we'll just use what we've generated for the - // assembly, and discard the PEFile's version. - if (!IsEvidenceComputed()) - { - struct - { - OBJECTREF objPEFileEvidence; - OBJECTREF objEvidence; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - - gc.objPEFileEvidence = pPEFileSecDesc->GetEvidence(); - gc.objEvidence = UpgradePEFileEvidenceToAssemblyEvidence(gc.objPEFileEvidence); - SetEvidence(gc.objEvidence); - - GCPROTECT_END(); - } -} - -//--------------------------------------------------------------------------------------- -// -// Get the evidence collection for this Assembly -// -// -OBJECTREF AssemblySecurityDescriptor::GetEvidence() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(m_pAppDomain == GetAppDomain()); - INJECT_FAULT(COMPlusThrowOM();); - } - CONTRACTL_END; - - // If we already have evidence, then just return that - if (IsEvidenceComputed()) - return ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator); - - struct - { - OBJECTREF objHostProvidedEvidence; - OBJECTREF objPEFileEvidence; - OBJECTREF objEvidence; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - BEGIN_SO_INTOLERANT_CODE(GetThread()); - - gc.objHostProvidedEvidence = ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator); - -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - { - _ASSERTE(gc.objPEFileEvidence == NULL || GetAppDomain() == gc.objPEFileEvidence->GetAppDomain()); - _ASSERTE(gc.objHostProvidedEvidence == NULL || GetAppDomain() == gc.objHostProvidedEvidence->GetAppDomain()); - } -#endif // CHECK_APP_DOMAIN_LEAKS - - // - // First get an evidence collection which targets our PEFile, then upgrade it to use this assembly as a - // target. We create a new Evidence for the PEFile here, which means that any evidence that PEFile may - // have already had is not used in this upgrade. If an existing PEFileSecurityDescriptor exists for the - // PEFile, then that should be upgraded directly, rather than going through this code path. - // - - gc.objPEFileEvidence = PEFileSecurityDescriptor::BuildEvidence(m_pPEFile, gc.objHostProvidedEvidence); - gc.objEvidence = UpgradePEFileEvidenceToAssemblyEvidence(gc.objPEFileEvidence); - SetEvidence(gc.objEvidence); - -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - _ASSERTE(gc.objEvidence == NULL || GetAppDomain() == gc.objEvidence->GetAppDomain()); -#endif // CHECK_APP_DOMAIN_LEAKS - - END_SO_INTOLERANT_CODE; - - GCPROTECT_END(); - - return gc.objEvidence; -} -#endif // FEATURE_CAS_POLICY #endif // !DACCESS_COMPILE BOOL AssemblySecurityDescriptor::IsSystem() @@ -369,36 +210,6 @@ void AssemblySecurityDescriptor::Resolve() pSharedSecDesc->Resolve(this); } -#ifdef FEATURE_CAS_POLICY -// This routine is called when we have determined that it that there is no SECURITY reason -// to verify an image, but we may want to do so anyway to insure that 3rd parties don't -// accidentally ship delay signed dlls because the application happens to be full trust. -// -static bool DontNeedToFlagAccidentalDelaySigning(PEAssembly* assem) -{ - WRAPPER_NO_CONTRACT; - - // If the file has a native image, then either it is strongly named and can be considered - // fully signed (see additional comments in code:PEAssembly::IsFullySigned), or it is not - // strong named and thus can't be delay signed. Either way no check is needed. - // If the file fully signed, then people did not accidentally forget, so no check is needed - if (assem->HasNativeImage() || assem->IsFullySigned()) - return true; - - // If mscorlib itself is not signed, this is not an offical CLR, you don't need to - // to do the checking in this case either because 3rd parties should not be running this way. - // This is useful because otherwise when we run perf runs on normal CLR lab builds we don't - // measure the performance that we get for a offical runtime (since official runtimes will - // be signed). - PEAssembly* mscorlib = SystemDomain::SystemFile(); - if (!mscorlib->HasNativeImage()) - return false; - if ((mscorlib->GetLoadedNative()->GetNativeHeader()->COR20Flags & COMIMAGE_FLAGS_STRONGNAMESIGNED) == 0) - return true; - - return false; -} -#endif // FEATURE_CAS_POLICY void AssemblySecurityDescriptor::ResolveWorker() { @@ -463,27 +274,6 @@ void AssemblySecurityDescriptor::ResolvePolicy(ISharedSecurityDescriptor *pShare __dcimf.Pop(); } -#ifdef FEATURE_CAS_POLICY -DWORD AssemblySecurityDescriptor::GetZone() -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - PRECONDITION(m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled()); - } CONTRACTL_END; - - StackSString codebase; - SecZone dwZone = NoZone; - BYTE rbUniqueID[MAX_SIZE_SECURITY_ID]; - DWORD cbUniqueID = sizeof(rbUniqueID); - - m_pAssem->GetSecurityIdentity(codebase, &dwZone, 0, rbUniqueID, &cbUniqueID); - return dwZone; -} -#endif // FEATURE_CAS_POLICY Assembly* AssemblySecurityDescriptor::GetAssembly() { @@ -498,120 +288,6 @@ BOOL AssemblySecurityDescriptor::CanSkipPolicyResolution() } -#ifdef FEATURE_CAS_POLICY -//----------------------------------------------------------------------------------------------------------- -// -// Upgrade the evidence used for resolving a PEFile to be targeted at the Assembly the PEFile represents -// -// Arguments: -// objPEFileEvidence - -// -// Notes: -// During CLR startup we may need to resolve policy against a PEFile before we have the associated -// Assembly. Once we have the Assembly we don't want to recompute potenially expensive evidence, so this -// method can be used to upgrade the evidence who's target was the PEFile to target the assembly instead. -// -// Will call into System.Reflection.Assembly.UpgradeSecurityIdentity -// - -OBJECTREF AssemblySecurityDescriptor::UpgradePEFileEvidenceToAssemblyEvidence(const OBJECTREF& objPEFileEvidence) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(objPEFileEvidence != NULL); - } - CONTRACTL_END; - - struct - { - OBJECTREF objAssembly; - OBJECTREF objEvidence; - OBJECTREF objUpgradedEvidence; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - - gc.objAssembly = m_pAssem->GetExposedAssemblyObject(); - gc.objEvidence = objPEFileEvidence; - - MethodDescCallSite upgradeSecurityIdentity(METHOD__ASSEMBLY_EVIDENCE_FACTORY__UPGRADE_SECURITY_IDENTITY); - - ARG_SLOT args[] = - { - ObjToArgSlot(gc.objEvidence), - ObjToArgSlot(gc.objAssembly) - }; - - gc.objUpgradedEvidence = upgradeSecurityIdentity.Call_RetOBJECTREF(args); - - GCPROTECT_END(); - - return gc.objUpgradedEvidence; -} - -HRESULT AssemblySecurityDescriptor::LoadSignature(COR_TRUST **ppSignature) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END; - - if (IsSignatureLoaded()) - { - if (ppSignature) - { - *ppSignature = m_pSignature; - } - - return S_OK; - } - - GCX_PREEMP(); - m_pSignature = m_pAssem->GetFile()->GetAuthenticodeSignature(); - - SetSignatureLoaded(); - - if (ppSignature) - { - *ppSignature = m_pSignature; - } - - return S_OK; -} - -void AssemblySecurityDescriptor::SetAdditionalEvidence(OBJECTREF evidence) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - StoreObjectInLazyHandle(m_hAdditionalEvidence, evidence, m_pLoaderAllocator); - m_fAdditionalEvidence = TRUE; -} - -BOOL AssemblySecurityDescriptor::HasAdditionalEvidence() -{ - LIMITED_METHOD_CONTRACT; - return m_fAdditionalEvidence; -} - -OBJECTREF AssemblySecurityDescriptor::GetAdditionalEvidence() -{ - WRAPPER_NO_CONTRACT; - return ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator); -} -#endif // FEATURE_CAS_POLICY // Check to make sure that security will allow this assembly to load. Throw an exception if the assembly diff --git a/src/vm/securitydescriptorassembly.h b/src/vm/securitydescriptorassembly.h index 68023d670b..d414de033d 100644 --- a/src/vm/securitydescriptorassembly.h +++ b/src/vm/securitydescriptorassembly.h @@ -65,15 +65,6 @@ private: COR_TRUST *m_pSignature; // Contains the publisher, requested permission SharedSecurityDescriptor *m_pSharedSecDesc; // Shared state for assemblies loaded into multiple appdomains -#ifdef FEATURE_CAS_POLICY - LOADERHANDLE m_hRequiredPermissionSet; // Required Requested Permissions - LOADERHANDLE m_hOptionalPermissionSet; // Optional Requested Permissions - LOADERHANDLE m_hDeniedPermissionSet; // Denied Permissions - - BOOL m_fAdditionalEvidence; - BOOL m_fIsSignatureLoaded; - BOOL m_fAssemblyRequestsComputed; -#endif // FEATURE_CAS_POLICY BOOL m_fMicrosoftPlatform; BOOL m_fAllowSkipVerificationInFullTrust; @@ -108,20 +99,6 @@ public: virtual void PropagatePermissionSet(OBJECTREF GrantedPermissionSet, OBJECTREF DeniedPermissionSet, DWORD dwSpecialFlags); #endif // !DACCESS_COMPILE -#ifdef FEATURE_CAS_POLICY - virtual HRESULT LoadSignature(COR_TRUST **ppSignature = NULL); - virtual OBJECTREF GetEvidence(); - DWORD GetZone(); - - OBJECTREF GetRequestedPermissionSet(OBJECTREF *pOptionalPermissionSet, OBJECTREF *pDeniedPermissionSet); - -#ifndef DACCESS_COMPILE - virtual void SetAdditionalEvidence(OBJECTREF evidence); - virtual BOOL HasAdditionalEvidence(); - virtual OBJECTREF GetAdditionalEvidence(); - virtual void SetEvidenceFromPEFile(IPEFileSecurityDescriptor *pPEFileSecDesc); -#endif // !DACCESS_COMPILE -#endif // FEATURE_CAS_POLICY virtual void CheckAllowAssemblyLoad(); @@ -132,11 +109,6 @@ private: void ResolveWorker(); -#ifdef FEATURE_CAS_POLICY - inline BOOL IsAssemblyRequestsComputed(); - inline BOOL IsSignatureLoaded(); - inline void SetSignatureLoaded(); -#endif #endif // #ifndef DACCESS_COMPILE diff --git a/src/vm/securitydescriptorassembly.inl b/src/vm/securitydescriptorassembly.inl index b923100b0a..e12a6c5963 100644 --- a/src/vm/securitydescriptorassembly.inl +++ b/src/vm/securitydescriptorassembly.inl @@ -35,27 +35,6 @@ inline void AssemblySecurityDescriptor::TryCachePassedDemand(PsetCacheEntry *pCa m_arrPassedLinktimeDemands[m_dwNumPassedDemands++] = pCasDemands; } -#ifdef FEATURE_CAS_POLICY - -inline BOOL AssemblySecurityDescriptor::IsAssemblyRequestsComputed() -{ - LIMITED_METHOD_CONTRACT; - return m_fAssemblyRequestsComputed; -} - -inline BOOL AssemblySecurityDescriptor::IsSignatureLoaded() -{ - LIMITED_METHOD_CONTRACT; - return m_fIsSignatureLoaded; -} - -inline void AssemblySecurityDescriptor::SetSignatureLoaded() -{ - LIMITED_METHOD_CONTRACT; - m_fIsSignatureLoaded = TRUE; -} - -#endif // FEATURE_CAS_POLICY #endif // !DACCESS_COMPILE diff --git a/src/vm/securitymeta.cpp b/src/vm/securitymeta.cpp index dcb2eb765f..8bff148516 100644 --- a/src/vm/securitymeta.cpp +++ b/src/vm/securitymeta.cpp @@ -905,117 +905,6 @@ TypeSecurityDescriptor* TypeSecurityDescriptor::GetTypeSecurityDescriptor(Method return pTypeSecurityDesc; } -#if !defined(CROSSGEN_COMPILE) && defined(FEATURE_CAS_POLICY) -HRESULT TokenDeclActionInfo::GetDeclaredPermissionsWithCache( - IN CorDeclSecurity action, - OUT OBJECTREF *pDeclaredPermissions, - OUT PsetCacheEntry **pPCE) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - HRESULT hr = S_OK; - DWORD dwActionFlag = DclToFlag((CorDeclSecurity)action); - - PsetCacheEntry *ptempPCE=NULL; - TokenDeclActionInfo* pCurrentAction = this; - for (; - pCurrentAction; - pCurrentAction = pCurrentAction->pNext) - { - if (pCurrentAction->dwDeclAction == dwActionFlag) - { - ptempPCE = pCurrentAction->pPCE; - break; - } - } - if (pDeclaredPermissions && pCurrentAction) - { - *pDeclaredPermissions = ptempPCE->CreateManagedPsetObject (action); - } - if (pPCE && pCurrentAction) - { - *pPCE = ptempPCE; - } - - return hr; -} - -OBJECTREF TokenDeclActionInfo::GetLinktimePermissions(OBJECTREF *prefNonCasDemands) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - OBJECTREF refCasDemands = NULL; - GCPROTECT_BEGIN(refCasDemands); - - GetDeclaredPermissionsWithCache( - dclLinktimeCheck, - &refCasDemands, NULL); - - TokenDeclActionInfo::GetDeclaredPermissionsWithCache( - dclNonCasLinkDemand, - prefNonCasDemands, NULL); - - GCPROTECT_END(); - return refCasDemands; -} - -void TokenDeclActionInfo::InvokeLinktimeChecks(Assembly* pCaller) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - INJECT_FAULT(COMPlusThrowOM();); - PRECONDITION(CheckPointer(pCaller)); - } - CONTRACTL_END; - -#ifdef FEATURE_MULTICOREJIT - - // Reset the flag to allow managed code to be called in multicore JIT background thread from this routine - ThreadStateNCStackHolder holder(-1, Thread::TSNC_CallingManagedCodeDisabled); - -#endif - - struct gc - { - OBJECTREF refNonCasDemands; - OBJECTREF refCasDemands; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - - // CAS LinkDemands - GetDeclaredPermissionsWithCache(dclLinktimeCheck, - &gc.refCasDemands, - NULL); - - if (gc.refCasDemands != NULL) - { - SecurityStackWalk::LinkOrInheritanceCheck(pCaller->GetSecurityDescriptor(), gc.refCasDemands, pCaller, dclLinktimeCheck); - } - - // NON CAS LinkDEMANDS (we shouldn't support this). - GetDeclaredPermissionsWithCache(dclNonCasLinkDemand, - &gc.refNonCasDemands, - NULL); - - GCPROTECT_END(); -} -#endif // !CROSSGEN_COMPILE && FEATURE_CAS_POLICY void TypeSecurityDescriptor::ComputeCriticalTransparentInfo() { diff --git a/src/vm/securitypolicy.cpp b/src/vm/securitypolicy.cpp index 03910a2311..8a2423bb06 100644 --- a/src/vm/securitypolicy.cpp +++ b/src/vm/securitypolicy.cpp @@ -30,66 +30,6 @@ void SecurityProperties::operator delete(void *pMem) // No action required } -#ifdef FEATURE_CAS_POLICY - -// static -CrstStatic SecurityPolicy::s_crstPolicyInit; - -// static -bool SecurityPolicy::s_fPolicyInitialized = false; - -void SecurityPolicy::InitPolicyConfig() -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - - GCX_PREEMP(); - - CrstHolder initializePolicy(&s_crstPolicyInit); - - if (!s_fPolicyInitialized) - { - // Note: These buffers should be at least as big as the longest possible - // string that will be placed into them by the code below. - const size_t cchcache = MAX_LONGPATH + sizeof( W("defaultusersecurity.config.cch") ) / sizeof( WCHAR ) + 1; - const size_t cchconfig = MAX_LONGPATH + sizeof( W("defaultusersecurity.config.cch") ) / sizeof( WCHAR ) + 1; - NewArrayHolder<WCHAR> cache(new WCHAR[cchcache]); - NewArrayHolder<WCHAR> config(new WCHAR[cchconfig]); - - HRESULT hr = SecurityConfig::GetMachineDirectory(config, MAX_LONGPATH); - if (FAILED(hr)) - ThrowHR(hr); - - wcscat_s( config, cchconfig, W("security.config") ); - wcscpy_s( cache, cchcache, config ); - wcscat_s( cache, cchcache, W(".cch") ); - SecurityConfig::InitData( SecurityConfig::MachinePolicyLevel, config, cache ); - - hr = SecurityConfig::GetMachineDirectory(config, MAX_LONGPATH); - if (FAILED(hr)) - ThrowHR(hr); - - wcscat_s( config, cchconfig, W("enterprisesec.config") ); - wcscpy_s( cache, cchcache, config ); - wcscat_s( cache, cchcache, W(".cch") ); - SecurityConfig::InitData( SecurityConfig::EnterprisePolicyLevel, config, cache ); - - BOOL result = SecurityConfig::GetUserDirectory(config, MAX_LONGPATH); - if (result) { - wcscat_s( config, cchconfig, W("security.config") ); - wcscpy_s( cache, cchcache, config ); - wcscat_s( cache, cchcache, W(".cch") ); - SecurityConfig::InitData( SecurityConfig::UserPolicyLevel, config, cache ); - } - - s_fPolicyInitialized = true; - } -} -#endif // FEATURE_CAS_POLICY void SecurityPolicy::Start() { @@ -109,18 +49,6 @@ void SecurityPolicy::Start() _ASSERTE(URLZONE_UNTRUSTED == Untrusted); #endif // !FEATURE_PAL -#ifdef FEATURE_CAS_POLICY - s_crstPolicyInit.Init(CrstSecurityPolicyInit); - - SecurityConfig::Init(); - - if (Security::IsProcessWideLegacyCasPolicyEnabled()) - { - SecurityPolicy::InitPolicyConfig(); - } - - g_pCertificateCache = new CertificateCache(); -#endif // FEATURE_CAS_POLICY } void SecurityPolicy::Stop() @@ -134,50 +62,6 @@ void SecurityPolicy::Stop() } -#ifdef FEATURE_CAS_POLICY -void SecurityPolicy::SaveCache() -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_ANY; - INJECT_FAULT(COMPlusThrowOM();); - } CONTRACTL_END; - - Thread *pThread = GetThread(); - if (pThread == NULL) - { - BOOL fRet = FALSE; - EX_TRY - { - // If CLR is hosted, a host can deny a thread during SetupThread call. - if (IsShutdownSpecialThread()) - { - SetupInternalThread(); - } - else - { - SetupThread(); - } - } - EX_CATCH - { - fRet = TRUE; - } - EX_END_CATCH(SwallowAllExceptions); - if (fRet) - { - return; - } - } - - SecurityConfig::SaveCacheData( SecurityConfig::MachinePolicyLevel ); - SecurityConfig::SaveCacheData( SecurityConfig::UserPolicyLevel ); - SecurityConfig::SaveCacheData( SecurityConfig::EnterprisePolicyLevel ); - - SecurityConfig::Cleanup(); -} -#endif void QCALLTYPE SecurityPolicy::GetGrantedPermissions(QCall::ObjectHandleOnStack retGranted, QCall::ObjectHandleOnStack retDenied, QCall::StackCrawlMarkHandle stackmark) { @@ -228,58 +112,6 @@ void SecurityPolicy::CreateSecurityException(__in_z const char *szDemandClass, D MethodTable * pMT = MscorlibBinder::GetClass(CLASS__SECURITY_EXCEPTION); -#ifdef FEATURE_CAS_POLICY - MethodTable * pMTSecPerm = MscorlibBinder::GetClass(CLASS__SECURITY_PERMISSION); - - struct _gc { - STRINGREF strDemandClass; - OBJECTREF secPerm; - STRINGREF strPermState; - OBJECTREF secPermType; - OBJECTREF secElement; - } gc; - memset(&gc, 0, sizeof(gc)); - - GCPROTECT_BEGIN(gc); - - gc.strDemandClass = StringObject::NewString(wszDemandClass); - if (gc.strDemandClass == NULL) COMPlusThrowOM(); - // Get the type seen by reflection - gc.secPermType = pMTSecPerm->GetManagedClassObject(); - // Allocate the security exception object - *pThrowable = AllocateObject(pMT); - // Allocate the security permission object - gc.secPerm = AllocateObject(pMTSecPerm); - - // Call the construtor with the correct flag - MethodDescCallSite ctor(METHOD__SECURITY_PERMISSION__CTOR); - ARG_SLOT arg3[2] = { - ObjToArgSlot(gc.secPerm), - (ARG_SLOT)dwFlags - }; - ctor.Call(arg3); - - // Now, get the ToXml method - MethodDescCallSite toXML(METHOD__SECURITY_PERMISSION__TOXML, &gc.secPerm); - ARG_SLOT arg4 = ObjToArgSlot(gc.secPerm); - gc.secElement = toXML.Call_RetOBJECTREF(&arg4); - - MethodDescCallSite toString(METHOD__SECURITY_ELEMENT__TO_STRING, &gc.secElement); - ARG_SLOT arg5 = ObjToArgSlot(gc.secElement); - gc.strPermState = toString.Call_RetSTRINGREF(&arg5); - - MethodDescCallSite exceptionCtor(METHOD__SECURITY_EXCEPTION__CTOR); - - ARG_SLOT arg6[4] = { - ObjToArgSlot(*pThrowable), - ObjToArgSlot(gc.strDemandClass), - ObjToArgSlot(gc.secPermType), - ObjToArgSlot(gc.strPermState), - }; - exceptionCtor.Call(arg6); - - GCPROTECT_END(); -#else // FEATURE_CAS_POLICY UNREFERENCED_PARAMETER(szDemandClass); UNREFERENCED_PARAMETER(dwFlags); @@ -288,7 +120,6 @@ void SecurityPolicy::CreateSecurityException(__in_z const char *szDemandClass, D *pThrowable = AllocateObject(pMT); CallDefaultConstructor(*pThrowable); -#endif // FEATURE_CAS_POLICY } DECLSPEC_NORETURN void SecurityPolicy::ThrowSecurityException(__in_z const char *szDemandClass, DWORD dwFlags) @@ -315,137 +146,6 @@ DECLSPEC_NORETURN void SecurityPolicy::ThrowSecurityException(__in_z const char GCPROTECT_END(); } -#ifdef FEATURE_CAS_POLICY -//----------------------------------------------------------------------------------------- -// -// Fire an ETW event to indicate that an evidence object has been generated for an assembly -// -// Arguments: -// type - Type of evidence that was generated -// pPEFile - PEFile for the assembly the evidence was for -// - -// static -void SecurityPolicy::TraceEvidenceGeneration(EvidenceType type, PEFile *pPEFile) -{ - CONTRACTL - { - STANDARD_VM_CHECK; - PRECONDITION(CheckPointer(pPEFile)); - PRECONDITION(type >= kAssemblySupplied && type <= kZone); - } - CONTRACTL_END; - - const SString& strPath = pPEFile->GetILimage()->GetPath(); - FireEtwEvidenceGenerated(type, - GetThread()->GetDomain()->GetId().m_dwId, - strPath.IsEmpty() ? W("") : strPath.GetUnicode(), - GetClrInstanceId()); -} - -// Called if CAS policy is not enabled, but we either have a host or a simple sandbox domain which will -// determine the grant set of some evidence. -OBJECTREF SecurityPolicy::ResolveGrantSet(OBJECTREF evidence, DWORD *pdwSpecialFlags, BOOL fCheckExecutionPermission) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(!GetAppDomain()->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled()); - PRECONDITION(CheckPointer(pdwSpecialFlags)); - } - CONTRACTL_END; - - struct - { - OBJECTREF evidence; - OBJECTREF grantSet; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - gc.evidence = evidence; - - GCPROTECT_BEGIN(gc); - - MethodDescCallSite resolve(METHOD__SECURITY_ENGINE__RESOLVE_GRANT_SET); - - ARG_SLOT args[3]; - args[0] = ObjToArgSlot(gc.evidence); - args[1] = PtrToArgSlot(pdwSpecialFlags); - args[2] = BoolToArgSlot(fCheckExecutionPermission); - - gc.grantSet = resolve.Call_RetOBJECTREF(args); - - GCPROTECT_END(); - - return gc.grantSet; -} - -// Resolve legacy CAS policy -OBJECTREF SecurityPolicy::ResolveCasPolicy(OBJECTREF evidence, - OBJECTREF reqdPset, - OBJECTREF optPset, - OBJECTREF denyPset, - OBJECTREF* grantdenied, - DWORD* dwSpecialFlags, - BOOL checkExecutionPermission) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - INJECT_FAULT(COMPlusThrowOM();); - PRECONDITION(GetAppDomain()->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled()); - PRECONDITION(SecurityPolicy::s_fPolicyInitialized); - PRECONDITION(CheckPointer(dwSpecialFlags)); - } CONTRACTL_END; - - - OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED); - - // If we got here, then we are going to do at least one security - // check. Make sure security is initialized. - - struct _gc { - OBJECTREF reqdPset; // Required Requested Permissions - OBJECTREF optPset; // Optional Requested Permissions - OBJECTREF denyPset; // Denied Permissions - OBJECTREF evidence; // Object containing evidence - OBJECTREF refRetVal; - } gc; - ZeroMemory(&gc, sizeof(gc)); - gc.evidence = evidence; - gc.reqdPset = reqdPset; - gc.denyPset = denyPset; - gc.optPset = optPset; - - GCPROTECT_BEGIN(gc); - - MethodDescCallSite resolvePolicy(METHOD__SECURITY_MANAGER__RESOLVE_CAS_POLICY); - - ARG_SLOT args[7]; - args[0] = ObjToArgSlot(gc.evidence); - args[1] = ObjToArgSlot(gc.reqdPset); - args[2] = ObjToArgSlot(gc.optPset); - args[3] = ObjToArgSlot(gc.denyPset); - args[4] = PtrToArgSlot(grantdenied); - args[5] = PtrToArgSlot(dwSpecialFlags); - args[6] = BoolToArgSlot(checkExecutionPermission); - - { - // Elevate thread's allowed loading level. This can cause load failures if assemblies loaded from this point on require - // any assemblies currently being loaded. - OVERRIDE_LOAD_LEVEL_LIMIT(FILE_ACTIVE); - // call policy resolution routine in managed code - gc.refRetVal = resolvePolicy.Call_RetOBJECTREF(args); - } - - GCPROTECT_END(); - return gc.refRetVal; -} -#endif // FEATURE_CAS_POLICY #endif // CROSSGEN_COMPILE @@ -501,139 +201,6 @@ BOOL SecurityPolicy::CanCallUnmanagedCode(Module *pModule) #ifndef CROSSGEN_COMPILE -#ifdef FEATURE_CAS_POLICY -SecZone QCALLTYPE SecurityPolicy::CreateFromUrl(LPCWSTR wszUrl) -{ - QCALL_CONTRACT; - - SecZone dwZone = NoZone; - - BEGIN_QCALL; - - if (wszUrl != NULL) - { - dwZone = SecurityPolicy::MapUrlToZone(wszUrl); - } - - END_QCALL; - - return dwZone; -} - -HRESULT -GetSecurityPolicyRegKey( - __out WCHAR **ppszSecurityPolicy) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - INJECT_FAULT(return E_OUTOFMEMORY); - } - CONTRACTL_END; - - DWORD dwLen = 0; - - HRESULT hr = g_pCLRRuntime->GetVersionString(NULL, &dwLen); - if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) - return hr; - - size_t bufSize = _countof(FRAMEWORK_REGISTRY_KEY_W) + 1 + dwLen + _countof(KEY_COM_SECURITY_POLICY); - NewArrayHolder<WCHAR> key(new(nothrow) WCHAR[bufSize]); - if (key == NULL) - return E_OUTOFMEMORY; - wcscpy_s(key, bufSize, FRAMEWORK_REGISTRY_KEY_W W("\\")); - - hr = g_pCLRRuntime->GetVersionString(key + NumItems(FRAMEWORK_REGISTRY_KEY_W), &dwLen); - if (FAILED(hr)) - return hr; - - size_t offset = _countof(FRAMEWORK_REGISTRY_KEY_W)+dwLen-1; - wcscpy_s(key + offset, bufSize - offset, KEY_COM_SECURITY_POLICY); - key.SuppressRelease(); - *ppszSecurityPolicy = key; - return S_OK; -} // GetSecurityPolicyRegKey - -HRESULT SecurityPolicy::ApplyCustomZoneOverride(SecZone *pdwZone) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - PRECONDITION(*pdwZone >= NumZones); - INJECT_FAULT(return E_OUTOFMEMORY); - } - CONTRACTL_END; - - NewArrayHolder<WCHAR> key(NULL); - HRESULT hr = GetSecurityPolicyRegKey(&key); - if (FAILED(hr)) - return hr; - if (REGUTIL::GetLong(KEY_COM_SECURITY_ZONEOVERRIDE, 0, key, HKEY_POLICY_ROOT) == 1) - *pdwZone=Internet; - return S_OK; -} // ApplyCustomZoneOverride - -//--------------------------------------------------------------------------------------- -// -// Determine which security zone a URL belongs to -// -// Arguments: -// wszUrl - URL to get zone information about -// -// Return Value: -// Security zone the URL belongs to -// -// Notes: -// If the runtime cannot map the URL, we'll return NoZone. A mapping to a zone that the VM doesn't -// know about will cause us to check the TreatCustomZonesAsInternetZone registry key and potentially -// map it back to the Internet zone. -// - -// static -SecZone SecurityPolicy::MapUrlToZone(__in_z LPCWSTR wszUrl) -{ - CONTRACTL - { - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(wszUrl != NULL); - } - CONTRACTL_END; - - SecZone dwZone = NoZone; - - ReleaseHolder<IInternetSecurityManager> securityManager = NULL; - HRESULT hr = CoInternetCreateSecurityManager(NULL, &securityManager, 0); - - if (SUCCEEDED(hr)) - { - _ASSERTE(sizeof(SecZone) == sizeof(DWORD)); - hr = securityManager->MapUrlToZone(wszUrl, reinterpret_cast<DWORD *>(&dwZone), 0); - - if (SUCCEEDED(hr)) - { - // if this is a custom zone, see if the user wants us to map it back to the Internet zone - if (dwZone >= NumZones) - { - SecZone dwMappedZone = dwZone; - hr = ApplyCustomZoneOverride(&dwMappedZone); - if (SUCCEEDED(hr)) - { - dwZone = dwMappedZone; - } - } - } - else - { - dwZone = NoZone; - } - } - - return dwZone; -} -#endif //FEATURE_CAS_POLICY BOOL QCALLTYPE SecurityPolicy::IsLocalDrive(LPCWSTR wszPath) { @@ -792,100 +359,6 @@ void QCALLTYPE SecurityPolicy::GetDeviceName(LPCWSTR wszDriveLetter, QCall::Stri } -#ifdef FEATURE_CAS_POLICY - -// -// Fire the ETW event that signals that a specific type of evidence has been created -// -// Arguments: -// pPEFile - PEFile the evidence was generated for -// type - type of evidence generated -// - -// static -void QCALLTYPE SecurityPolicy::FireEvidenceGeneratedEvent(PEFile *pPEFile, - EvidenceType type) -{ - CONTRACTL - { - QCALL_CHECK; - PRECONDITION(CheckPointer(pPEFile)); - } - CONTRACTL_END; - - BEGIN_QCALL; - - TraceEvidenceGeneration(type, pPEFile); - - END_QCALL; -} - -// static - -void QCALLTYPE SecurityPolicy::GetEvidence(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retEvidence) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - IAssemblySecurityDescriptor *pSecDesc = pAssembly->GetSecurityDescriptor(); - - _ASSERTE(pSecDesc->GetDomain() == GetAppDomain()); - - GCX_COOP(); - if (pSecDesc->IsEvidenceComputed()) - retEvidence.Set(pSecDesc->GetAdditionalEvidence()); - else - retEvidence.Set(pSecDesc->GetEvidence()); - - END_QCALL; -} - -//--------------------------------------------------------------------------------------- -// -// Determine if an evidence collection has a delay generated strong name evidence object -// which was used during the process of demand evaluation. -// -// Arguments: -// orEvidence - evidence collection to examine -// -// Return Value: -// true if orEvidence contains unverified strong name evidence which has been used to generate a grant, -// false if orEvidence does not contain strong name evidence or that evidence was verified / not used -// - -// static -BOOL SecurityPolicy::WasStrongNameEvidenceUsed(OBJECTREF orEvidence) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - // If we don't have any evidence, then there isn't any strong name evidence, and therefore it couldn't - // have been used. - if (orEvidence == NULL) - { - return FALSE; - } - - BOOL fStrongNameEvidenceWasUsed = FALSE; - - GCPROTECT_BEGIN(orEvidence); - - MethodDescCallSite wasSnEvidenceUsed(METHOD__EVIDENCE__WAS_STRONGNAME_EVIDENCE_USED); - - ARG_SLOT args[] = { ObjToArgSlot(orEvidence) }; - fStrongNameEvidenceWasUsed = !!wasSnEvidenceUsed.Call_RetBool(args); - - GCPROTECT_END(); - - return fStrongNameEvidenceWasUsed; -} -#endif // FEATURE_CAS_POLICY FCIMPL0(void, SecurityPolicy::IncrementOverridesCount) { @@ -923,240 +396,6 @@ FCIMPL0(void, SecurityPolicy::DecrementAssertCount) } FCIMPLEND -#ifdef FEATURE_CAS_POLICY -// -// Evidence QCalls -// - -//--------------------------------------------------------------------------------------- -// -// Get the assembly level permission requests -// -// Arguments: -// pAssembly - Assembly to get the declarative security of -// retMinimumPermissions - [out] RequestMinimum set of the assembly -// retOptionalPermissions - [out] RequestOptional set of the assembly -// retRefusedPermissions - [out] RequestRefuse set of the assembly -// - -// static -void QCALLTYPE SecurityPolicy::GetAssemblyPermissionRequests(QCall::AssemblyHandle pAssembly, - QCall::ObjectHandleOnStack retMinimumPermissions, - QCall::ObjectHandleOnStack retOptionalPermissions, - QCall::ObjectHandleOnStack retRefusedPermissions) -{ - QCALL_CONTRACT; - - BEGIN_QCALL; - - - TraceEvidenceGeneration(kPermissionRequest, pAssembly->GetFile()); - AssemblySecurityDescriptor *pSecurityDescriptor = static_cast<AssemblySecurityDescriptor*>(pAssembly->GetSecurityDescriptor()); - - _ASSERTE(pSecurityDescriptor->GetDomain()->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled()); - - struct - { - OBJECTREF objMinimumPermissions; - OBJECTREF objOptionalPermissions; - OBJECTREF objRefusedPermissions; - } - gc; - ZeroMemory(&gc, sizeof(gc)); - - GCX_COOP(); - GCPROTECT_BEGIN(gc); - - gc.objMinimumPermissions = pSecurityDescriptor->GetRequestedPermissionSet(&gc.objOptionalPermissions, - &gc.objRefusedPermissions); - - retMinimumPermissions.Set(gc.objMinimumPermissions); - retOptionalPermissions.Set(gc.objOptionalPermissions); - retRefusedPermissions.Set(gc.objRefusedPermissions); - - GCPROTECT_END(); - - END_QCALL; -} - -//--------------------------------------------------------------------------------------- -// -// Get the serialized evidence stream from an assembly -// -// Arguments: -// pPEFile - PEFile to load the evidence stream from -// retSerializedEvidence - [out] contents of the serialized evidence -// - -// static -void QCALLTYPE SecurityPolicy::GetAssemblySuppliedEvidence(PEFile *pPEFile, - QCall::ObjectHandleOnStack retSerializedEvidence) -{ - CONTRACTL - { - QCALL_CHECK; - PRECONDITION(CheckPointer(pPEFile)); - } - CONTRACTL_END; - - BEGIN_QCALL; - - DWORD cbResource; - BYTE *pbResource; - - // Load the resource from the PE file. We do not need to free this memory, since we're getting a direct - // pointer into the PE contents rather than a buffer. - TraceEvidenceGeneration(kAssemblySupplied, pPEFile); - BOOL fFoundSerializedEvidence = pPEFile->GetResource("Security.Evidence", - &cbResource, - &pbResource, - NULL, - NULL, - NULL, - NULL, - FALSE, - TRUE, - NULL, - NULL); - - if (fFoundSerializedEvidence) - { - retSerializedEvidence.SetByteArray(pbResource, cbResource); - } - - END_QCALL; -} - -//--------------------------------------------------------------------------------------- -// -// Get the zone and URL that the PEFile was loaded from -// -// Arguments: -// pPEFile - PEFile to load the evidence stream from -// pZone - [out] SecurityZone the file was loaded from -// retUrl - [out] URL the file was loaded from - -// static -void QCALLTYPE SecurityPolicy::GetLocationEvidence(PEFile *pPEFile, - SecZone *pZone, - QCall::StringHandleOnStack retUrl) -{ - CONTRACTL - { - QCALL_CHECK; - PRECONDITION(CheckPointer(pPEFile)); - } - CONTRACTL_END; - - BEGIN_QCALL; - - StackSString ssCodeBase; - BYTE pbUniqueID[MAX_SIZE_SECURITY_ID]; - DWORD cbUniqueID = COUNTOF(pbUniqueID); - - // The location information is used to create Site, Url, and Zone evidence so fire all three events - TraceEvidenceGeneration(kSite, pPEFile); - TraceEvidenceGeneration(kUrl, pPEFile); - TraceEvidenceGeneration(kZone, pPEFile); - - pPEFile->GetSecurityIdentity(ssCodeBase, pZone, 0, pbUniqueID, &cbUniqueID); - - retUrl.Set(ssCodeBase); - - END_QCALL; -} - -//--------------------------------------------------------------------------------------- -// -// Get the X.509 certificate that the PE file's Authenticode signature was created with -// -// Arguments: -// pPEFile - PEFile to load the evidence stream from -// retCertificate - [out] certificate that signed the file - -// static -void QCALLTYPE SecurityPolicy::GetPublisherCertificate(PEFile *pPEFile, - QCall::ObjectHandleOnStack retCertificate) -{ - CONTRACTL - { - QCALL_CHECK; - PRECONDITION(CheckPointer(pPEFile)); - } - CONTRACTL_END; - - BEGIN_QCALL; - - TraceEvidenceGeneration(kPublisher, pPEFile); - COR_TRUST *pAuthenticodeSignature = pPEFile->GetAuthenticodeSignature(); - if (pAuthenticodeSignature != NULL && pAuthenticodeSignature->pbSigner != NULL) - { - retCertificate.SetByteArray(pAuthenticodeSignature->pbSigner, pAuthenticodeSignature->cbSigner); - } - - END_QCALL; -} - -//--------------------------------------------------------------------------------------- -// -// Get the components of an assembly's strong name to generate strong name evidence with -// -// Arguments: -// pAssembly - assembly to get the strong name of -// retPublicKeyBlob - [out] public component of the key the assembly is signed with -// retSimpleName - [out] simple name of the file -// piMajorVersion - [out] major version -// piMinorVersion - [out] minor version -// piBuild - [out] build -// piRevision - [out] revision -// -// Notes: -// retPublicKeyBlob will be null for a simply named assembly -// - -// static -void QCALLTYPE SecurityPolicy::GetStrongNameInformation(QCall::AssemblyHandle pAssembly, - QCall::ObjectHandleOnStack retPublicKeyBlob, - QCall::StringHandleOnStack retSimpleName, - USHORT *piMajorVersion, - USHORT *piMinorVersion, - USHORT *piBuild, - USHORT *piRevision) -{ - CONTRACTL - { - QCALL_CHECK; - PRECONDITION(CheckPointer(piMajorVersion)); - PRECONDITION(CheckPointer(piMinorVersion)); - PRECONDITION(CheckPointer(piBuild)); - PRECONDITION(CheckPointer(piRevision)); - } - CONTRACTL_END; - - BEGIN_QCALL; - - PEAssembly *pPEAssembly = pAssembly->GetFile(); - TraceEvidenceGeneration(kStrongName, pPEAssembly); - - DWORD cbPublicKey; - const BYTE *pbPublicKey = reinterpret_cast<const BYTE*>(pPEAssembly->GetPublicKey(&cbPublicKey)); - - if (pbPublicKey != NULL && cbPublicKey > 0) - { - pPEAssembly->GetVersion(piMajorVersion, piMinorVersion, piBuild, piRevision); - retPublicKeyBlob.SetByteArray(pbPublicKey, cbPublicKey); - retSimpleName.Set(pPEAssembly->GetSimpleName()); - } - else - { - GCX_COOP(); - retPublicKeyBlob.Set(NULL); - } - - END_QCALL; -} - -#endif // FEATURE_CAS_POLICY #ifdef FEATURE_FUSION static void GetFusionNameFromAssemblyQualifiedTypeName(LPCWSTR pAssemblyQualifedTypeName, IAssemblyName ** ppFusionName) diff --git a/src/vm/securitypolicy.h b/src/vm/securitypolicy.h index 3166f7fd24..90b41324ad 100644 --- a/src/vm/securitypolicy.h +++ b/src/vm/securitypolicy.h @@ -77,9 +77,6 @@ namespace SecurityPolicy #endif // #ifdef FEATURE_IMPERSONATION FCDECL0(FC_BOOL_RET, IsDefaultThreadSecurityInfo); -#ifdef FEATURE_CAS_POLICY - SecZone QCALLTYPE CreateFromUrl(LPCWSTR wszUrl); -#endif // FEATURE_CAS_POLICY void QCALLTYPE _GetLongPathName(LPCWSTR wszPath, QCall::StringHandleOnStack retLongPath); BOOL QCALLTYPE IsLocalDrive(LPCWSTR wszPath); @@ -94,35 +91,6 @@ namespace SecurityPolicy FCDECL0(VOID, DecrementAssertCount); -#ifdef FEATURE_CAS_POLICY - // - // Evidence QCalls - // - -//public: - void QCALLTYPE FireEvidenceGeneratedEvent(PEFile *pPEFile, EvidenceType type); - - void QCALLTYPE GetEvidence(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retEvidence); - - void QCALLTYPE GetAssemblyPermissionRequests(QCall::AssemblyHandle pAssembly, - QCall::ObjectHandleOnStack retMinimumPermissions, - QCall::ObjectHandleOnStack retOptionalPermissions, - QCall::ObjectHandleOnStack retRefusedPermissions); - - void QCALLTYPE GetAssemblySuppliedEvidence(PEFile *pPEFile, QCall::ObjectHandleOnStack retSerializedEvidence); - - void QCALLTYPE GetLocationEvidence(PEFile *pPEFile, SecZone *pZone, QCall::StringHandleOnStack retUrl); - - void QCALLTYPE GetPublisherCertificate(PEFile *pPEFile, QCall::ObjectHandleOnStack retCertificate); - - void QCALLTYPE GetStrongNameInformation(QCall::AssemblyHandle pAssembly, - QCall::ObjectHandleOnStack retPublicKeyBlob, - QCall::StringHandleOnStack retSimpleName, - USHORT *piMajorVersion, - USHORT *piMinorVersion, - USHORT *piBuild, - USHORT *piRevision); -#endif // FEATURE_CAS_POLICY //private: // ----------------------------------------------------------- @@ -139,12 +107,6 @@ namespace SecurityPolicy // <currently unused> @TODO: shouldn't EEShutDownHelper call this? void Stop(); -#ifdef FEATURE_CAS_POLICY - // Saves security cache data - // Callers: - // EEShutDownHelper - void SaveCache(); -#endif // ----------------------------------------------------------- @@ -166,41 +128,9 @@ namespace SecurityPolicy BOOL CanSkipVerification(DomainAssembly * pAssembly); -#ifdef FEATURE_CAS_POLICY - void TraceEvidenceGeneration(EvidenceType type, PEFile *pPEFile); - - // Map a URL to a zone, applying any user supplied policy - SecZone MapUrlToZone(__in_z LPCWSTR wszUrl); - - // Apply user supplied policy to a zone - HRESULT ApplyCustomZoneOverride(SecZone *pdwZone); - - // Determine what the grant set of an assembly is - OBJECTREF ResolveGrantSet(OBJECTREF evidence, OUT DWORD *pdwSpecialFlags, BOOL fcheckExecutionPermission); - - // Resolve legacy CAS policy on the assembly - // Callers: - // SecurityDescriptor::ResolveWorker - OBJECTREF ResolveCasPolicy(OBJECTREF evidence, - OBJECTREF reqdPset, - OBJECTREF optPset, - OBJECTREF denyPset, - OBJECTREF* grantdenied, - DWORD* pdwSpecialFlags, - BOOL checkExecutionPermission); - - // Load the policy config/cache files at EE startup - void InitPolicyConfig(); - - BOOL WasStrongNameEvidenceUsed(OBJECTREF evidence); -#endif // Like WszGetLongPathName, but it works with nonexistant files too size_t GetLongPathNameHelper( const WCHAR* wszShortPath, SString& wszBuffer); -#ifdef FEATURE_CAS_POLICY - extern CrstStatic s_crstPolicyInit; - extern bool s_fPolicyInitialized; -#endif // FEATURE_CAS_POLICY } struct SharedPermissionObjects diff --git a/src/vm/securitytransparentassembly.cpp b/src/vm/securitytransparentassembly.cpp index c1823fc034..f9ac18cd62 100644 --- a/src/vm/securitytransparentassembly.cpp +++ b/src/vm/securitytransparentassembly.cpp @@ -233,20 +233,6 @@ static void ConvertCriticalMethodToLinkDemand(MethodDesc *pCallerMD) } CONTRACTL_END; -#if !defined(CROSSGEN_COMPILE) && defined(FEATURE_CAS_POLICY) - if (NingenEnabled()) - return; - - GCX_COOP(); - - OBJECTREF permSet = NULL; - GCPROTECT_BEGIN(permSet); - - Security::GetPermissionInstance(&permSet, SECURITY_FULL_TRUST); - Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet); - - GCPROTECT_END(); -#endif // !CROSSGEN_COMPILE && FEATURE_CAS_POLICY } // static @@ -620,44 +606,6 @@ VOID SecurityTransparent::PerformTransparencyChecksForLoadByteArray(MethodDesc* } CONTRACTL_END -#ifdef FEATURE_CAS_POLICY - GCX_COOP(); - // check to see if the method that does the Load(byte[] ) is transparent - if (IsMethodTransparent(pCallerMD)) - { - Assembly* pLoadedAssembly = pLoadedSecDesc->GetAssembly(); - // check to see if the byte[] being loaded is critical, i.e. not Transparent - if (!ModuleSecurityDescriptor::IsMarkedTransparent(pLoadedAssembly)) - { - // if transparent code loads a byte[] that is critical, need to inject appropriate demands - if (pLoadedSecDesc->IsFullyTrusted()) // if the loaded code is full-trust - { - // do a full-demand for Full-Trust - OBJECTREF permSet = NULL; - GCPROTECT_BEGIN(permSet); - Security::GetPermissionInstance(&permSet, SECURITY_FULL_TRUST); - Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet); - GCPROTECT_END();// do a full-demand for Full-Trust - } - else - { - // otherwise inject a Demand for permissions being granted? - struct _localGC { - OBJECTREF granted; - OBJECTREF denied; - } localGC; - ZeroMemory(&localGC, sizeof(localGC)); - - GCPROTECT_BEGIN(localGC); - { - localGC.granted = pLoadedSecDesc->GetGrantedPermissionSet(&(localGC.denied)); - Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, localGC.granted); - } - GCPROTECT_END(); - } - } - } -#endif // FEATURE_CAS_POLICY } static void ConvertLinkDemandToFullDemand(MethodDesc* pCallerMD, MethodDesc* pCalleeMD) |