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 | |
parent | 6517da4563a47fb370f35c082ae709215f5d0b28 (diff) | |
download | coreclr-1f75aecd267e4d2d322ce6a812a34d6a34cae1f9.tar.gz coreclr-1f75aecd267e4d2d322ce6a812a34d6a34cae1f9.tar.bz2 coreclr-1f75aecd267e4d2d322ce6a812a34d6a34cae1f9.zip |
Remove always undefined FEATURE_CAS_POLICY
42 files changed, 1 insertions, 5856 deletions
diff --git a/src/dlls/mscorrc/mscorrc.rc b/src/dlls/mscorrc/mscorrc.rc index 3352256612..3489cd9ccf 100644 --- a/src/dlls/mscorrc/mscorrc.rc +++ b/src/dlls/mscorrc/mscorrc.rc @@ -1536,10 +1536,6 @@ BEGIN IDS_TYPE_INHERITANCE_RULES_VIOLATED "Inheritance security rules violated by type: '%1'. Derived types must either match the security accessibility of the base type or be less accessible. If the base class has a non-transparent default constructor, the derived class must also have a default constructor, and the method inheritance rules apply across those two methods." IDS_METHOD_INHERITANCE_RULES_VIOLATED "Inheritance security rules violated while overriding member: '%1'. Security accessibility of the overriding method must match the security accessibility of the method being overriden." IDS_CRITICAL_METHOD_ACCESS_DENIED "Attempt to access method %1 in violation of security transparency rules failed." -#ifdef FEATURE_CAS_POLICY - IDS_E_LOADFROM_REMOTE_SOURCE "An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information." - IDS_E_LOADFROM_REMOTE_SOURCE_MOTW "An attempt was made to load an assembly that was downloaded from a network location, which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this assembly is trusted, either remove the Zone marker from it or enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information." -#endif // FEATURE_CAS_POLICY IDS_CRITICAL_TYPE_ACCESS_DENIED "Attempt to access type %1 in violation of security transparency rules failed." IDS_APPLICATION_ASSEMBLY_EXEC_DENIED "Application assemblies cannot be directly executed: %1" IDS_REFLECTION_METHOD_ACCESS_DENIED "Application code cannot access %1 using Reflection." 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) |