// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // [....] // namespace System.Security { using System; using System.Threading; using System.Security.Util; using System.Collections; using System.Runtime.CompilerServices; using System.Security.Permissions; using System.Reflection; using System.Globalization; using System.Security.Policy; using System.Runtime.Versioning; using System.Diagnostics.Contracts; // Used in DemandInternal, to remember the result of previous demands // KEEP IN [....] WITH DEFINITIONS IN SECURITYPOLICY.H [Serializable] internal enum PermissionType { // special flags SecurityUnmngdCodeAccess = 0, SecuritySkipVerification = 1, ReflectionTypeInfo = 2, SecurityAssert = 3, ReflectionMemberAccess = 4, SecuritySerialization = 5, ReflectionRestrictedMemberAccess = 6, FullTrust = 7, SecurityBindingRedirects = 8, // special permissions UIPermission = 9, EnvironmentPermission = 10, FileDialogPermission = 11, FileIOPermission = 12, ReflectionPermission = 13, SecurityPermission = 14, // additional special flags SecurityControlEvidence = 16, SecurityControlPrincipal = 17 } internal static class CodeAccessSecurityEngine { internal static SecurityPermission AssertPermission; internal static PermissionToken AssertPermissionToken; [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void SpecialDemand(PermissionType whatPermission, ref StackCrawlMark stackMark); [System.Security.SecurityCritical] // auto-generated [System.Diagnostics.Conditional( "_DEBUG" )] [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] private static void DEBUG_OUT( String str ) { #if _DEBUG if (debug) { #if !FEATURE_CORECLR if (to_file) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append( str ); sb.Append ((char)13) ; sb.Append ((char)10) ; PolicyManager.DebugOut( file, sb.ToString() ); } else #endif Console.WriteLine( str ); } #endif } #if _DEBUG private static bool debug = false; #if !FEATURE_CORECLR private static readonly bool to_file = false; #endif private const String file = "d:\\foo\\debug.txt"; #endif // static default constructor. This will be called before any of the static members are accessed. static CodeAccessSecurityEngine() { #pragma warning disable 618 AssertPermission = new SecurityPermission(SecurityPermissionFlag.Assertion); #pragma warning restore 618 AssertPermissionToken = PermissionToken.GetToken(AssertPermission); } [System.Security.SecurityCritical] // auto-generated #pragma warning disable 618 private static void ThrowSecurityException(RuntimeAssembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed) #pragma warning restore 618 { AssemblyName asmName = null; Evidence asmEvidence = null; if (asm != null) { // Assert here because reflection will check grants and if we fail the check, // there will be an infinite recursion that overflows the stack. PermissionSet.s_fullTrust.Assert(); asmName = asm.GetName(); #if FEATURE_CAS_POLICY if(asm != Assembly.GetExecutingAssembly()) // this condition is to avoid having to marshal mscorlib's evidence (which is always in teh default domain) to the current domain asmEvidence = asm.Evidence; #endif // FEATURE_CAS_POLICY } throw SecurityException.MakeSecurityException(asmName, asmEvidence, granted, refused, rmh, action, demand, permThatFailed); } [System.Security.SecurityCritical] // auto-generated #pragma warning disable 618 private static void ThrowSecurityException(Object assemblyOrString, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed) #pragma warning restore 618 { Contract.Assert((assemblyOrString == null || assemblyOrString is RuntimeAssembly || assemblyOrString is String), "Must pass in an Assembly object or String object here"); if (assemblyOrString == null || assemblyOrString is RuntimeAssembly) ThrowSecurityException((RuntimeAssembly)assemblyOrString, granted, refused, rmh, action, demand, permThatFailed); else { AssemblyName asmName = new AssemblyName((String)assemblyOrString); throw SecurityException.MakeSecurityException(asmName, null, granted, refused, rmh, action, demand, permThatFailed); } } #if FEATURE_COMPRESSEDSTACK [System.Security.SecurityCritical] // auto-generated internal static void CheckSetHelper(CompressedStack cs, PermissionSet grants, PermissionSet refused, PermissionSet demands, RuntimeMethodHandleInternal rmh, RuntimeAssembly asm, SecurityAction action) { if (cs != null) cs.CheckSetDemand(demands, rmh); else CheckSetHelper(grants, refused, demands, rmh, (Object)asm, action, true); } #else // FEATURE_COMPRESSEDSTACK #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #endif #pragma warning disable 618 internal static void CheckSetHelper(Object notUsed, #pragma warning restore 618 PermissionSet grants, PermissionSet refused, PermissionSet demands, RuntimeMethodHandleInternal rmh, RuntimeAssembly asm, SecurityAction action) { // To reduce the amount of ifdef-code-churn, a dummy arg is used for the first parameter - instead of a CompressedStack object, // we use a System.Object that should always be null. If we tried to change the signature of the function, there will need to be // corresponding changes in VM (metasig.h, mscorlib.h, securitystackwalk.cpp, number of elements in the arg array, etc.) Contract.Assert(notUsed == null, "Should not reach here with a non-null first arg which is the CompressedStack"); CheckSetHelper(grants, refused, demands, rmh, (Object)asm, action, true); } #endif // FEATURE_COMPRESSEDSTACK [System.Security.SecurityCritical] // auto-generated #pragma warning disable 618 internal static bool CheckSetHelper(PermissionSet grants, #pragma warning restore 618 PermissionSet refused, PermissionSet demands, RuntimeMethodHandleInternal rmh, Object assemblyOrString, SecurityAction action, bool throwException) { Contract.Assert(demands != null, "Should not reach here with a null demand set"); #if _DEBUG && FEATURE_CAS_POLICY if (debug) { DEBUG_OUT("Granted: "); DEBUG_OUT(grants.ToXml().ToString()); DEBUG_OUT("Refused: "); DEBUG_OUT(refused != null ? refused.ToXml().ToString() : ""); DEBUG_OUT("Demanded: "); DEBUG_OUT(demands!=null ? demands.ToXml().ToString() : ""); } #endif // _DEBUG && FEATURE_CAS_POLICY IPermission permThatFailed = null; if (grants != null) grants.CheckDecoded(demands); if (refused != null) refused.CheckDecoded(demands); bool bThreadSecurity = SecurityManager._SetThreadSecurity(false); try { // Check grant set if (!demands.CheckDemand(grants, out permThatFailed)) { if (throwException) ThrowSecurityException(assemblyOrString, grants, refused, rmh, action, demands, permThatFailed); else return false; } // Check refused set if (!demands.CheckDeny(refused, out permThatFailed)) { if (throwException) ThrowSecurityException(assemblyOrString, grants, refused, rmh, action, demands, permThatFailed); else return false; } } catch (SecurityException) { throw; } catch (Exception) { // Any exception besides a security exception in this code means that // a permission was unable to properly handle what we asked of it. // We will define this to mean that the demand failed. if (throwException) ThrowSecurityException(assemblyOrString, grants, refused, rmh, action, demands, permThatFailed); else return false; } finally { if (bThreadSecurity) SecurityManager._SetThreadSecurity(true); } return true; } #if FEATURE_COMPRESSEDSTACK [System.Security.SecurityCritical] // auto-generated internal static void CheckHelper(CompressedStack cs, PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, RuntimeAssembly asm, SecurityAction action) { if (cs != null) cs.CheckDemand(demand, permToken, rmh); else CheckHelper(grantedSet, refusedSet, demand, permToken, rmh, (Object)asm, action, true); } #else // FEATURE_COMPRESSEDSTACK #if FEATURE_CORECLR [System.Security.SecurityCritical] // auto-generated #endif #pragma warning disable 618 internal static void CheckHelper(Object notUsed, #pragma warning restore 618 PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, RuntimeAssembly asm, SecurityAction action) { // To reduce the amount of ifdef-code-churn, a dummy arg is used for the first parameter - instead of a CompressedStack object, // we use a System.Object that should always be null. If we tried to change the signature of the function, there will need to be // corresponding changes in VM (metasig.h, mscorlib.h, securitystackwalk.cpp, number of elements in the arg array, etc.) Contract.Assert(notUsed == null, "Should not reach here with a non-null first arg which is the CompressedStack"); CheckHelper(grantedSet, refusedSet, demand, permToken, rmh, (Object)asm, action, true); } #endif // FEATURE_COMPRESSEDSTACK [System.Security.SecurityCritical] // auto-generated #pragma warning disable 618 internal static bool CheckHelper(PermissionSet grantedSet, #pragma warning restore 618 PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandleInternal rmh, Object assemblyOrString, SecurityAction action, bool throwException) { // We should never get here with a null demand Contract.Assert(demand != null, "Should not reach here with a null demand"); #if _DEBUG && FEATURE_CAS_POLICY if (debug) { DEBUG_OUT("Granted: "); DEBUG_OUT(grantedSet.ToXml().ToString()); DEBUG_OUT("Refused: "); DEBUG_OUT(refusedSet != null ? refusedSet.ToXml().ToString() : ""); DEBUG_OUT("Demanded: "); DEBUG_OUT(demand.ToString()); } #endif // _DEBUG && FEATURE_CAS_POLICY if (permToken == null) permToken = PermissionToken.GetToken(demand); if (grantedSet != null) grantedSet.CheckDecoded(permToken.m_index); if (refusedSet != null) refusedSet.CheckDecoded(permToken.m_index); // If PermissionSet is null, then module does not have Permissions... Fail check. bool bThreadSecurity = SecurityManager._SetThreadSecurity(false); try { if (grantedSet == null) { if (throwException) ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand); else return false; } else if (!grantedSet.IsUnrestricted()) { // If we aren't unrestricted, there is a refused set, or our permission is not of the unrestricted // variety, we need to do the proper callback. Contract.Assert(demand != null,"demand != null"); // Find the permission of matching type in the permission set. CodeAccessPermission grantedPerm = (CodeAccessPermission)grantedSet.GetPermission(permToken); // Make sure the demand has been granted if (!demand.CheckDemand( grantedPerm )) { if (throwException) ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand); else return false; } } // Make the sure the permission is not refused. if (refusedSet != null) { CodeAccessPermission refusedPerm = (CodeAccessPermission)refusedSet.GetPermission(permToken); if (refusedPerm != null) { if (!refusedPerm.CheckDeny(demand)) { #if _DEBUG if (debug) DEBUG_OUT( "Permission found in refused set" ); #endif if (throwException) ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand); else return false; } } if (refusedSet.IsUnrestricted()) { if (throwException) ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand); else return false; } } } catch (SecurityException) { throw; } catch (Exception) { // Any exception besides a security exception in this code means that // a permission was unable to properly handle what we asked of it. // We will define this to mean that the demand failed. if (throwException) ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand); else return false; } finally { if (bThreadSecurity) SecurityManager._SetThreadSecurity(true); } DEBUG_OUT( "Check passed" ); return true; } #if FEATURE_CAS_POLICY /// /// Demand for the grant set of an assembly /// /// /// Managed half of SecurityStackWalk::DemandGrantSet. /// [System.Security.SecurityCritical] // auto-generated private static void CheckGrantSetHelper(PermissionSet grantSet) { Contract.Assert(grantSet != null, "Missing grant set"); grantSet.CopyWithNoIdentityPermissions().Demand(); } /// /// Perform a security demand which succeeds if either a compatibilty permission is granted to the /// call stack, or restricted member access and the grant set of the target of the reflection /// operation is granted. /// /// compatibility permission to check /// grant set of the reflection target [System.Security.SecurityCritical] // auto-generated internal static void ReflectionTargetDemandHelper(PermissionType permission, PermissionSet targetGrant) { ReflectionTargetDemandHelper((int)permission, targetGrant); } /// /// Perform a security demand which succeeds if either a compatibilty permission is granted to the /// call stack, or restricted member access and the grant set of the target of the reflection /// operation is granted. /// /// /// Managed half of SecurityStackWalk::ReflectionTargetDemand. /// /// compatibility permission to check (See PermissionType) /// grant set of the reflection target [System.Security.SecurityCritical] // auto-generated [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable private static void ReflectionTargetDemandHelper(int permission, PermissionSet targetGrant) { // Capture a compressed stack so that we can make both permission checks without walking the stack // multiple times. StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; CompressedStack cs = CompressedStack.GetCompressedStack(ref stackMark); ReflectionTargetDemandHelper(permission, targetGrant, cs); } /// /// Perform a reflection target demand against a given access context /// /// /// Managed half of SecurityStackWalk::ReflectionTargetDemand /// /// compatibility permission to check (See PermissionType) /// grant set of the reflection target /// access context to do the demand against [System.Security.SecurityCritical] // auto-generated private static void ReflectionTargetDemandHelper(int permission, PermissionSet targetGrant, Resolver accessContext) { ReflectionTargetDemandHelper(permission, targetGrant, accessContext.GetSecurityContext()); } /// /// Perform a reflection target demand against a given compressed stack /// /// /// Managed half of SecurityStackWalk::ReflectionTargetDemand /// /// compatibility permission to check (See PermissionType) /// grant set of the reflection target /// compressed stack to do the demand against [System.Security.SecurityCritical] // auto-generated private static void ReflectionTargetDemandHelper(int permission, PermissionSet targetGrant, CompressedStack securityContext) { Contract.Assert(securityContext != null, "securityContext != null"); // We need to remove all identity permissions from the grant set of the target, otherwise the // disjunctive demand will fail unless we're reflecting on the same assembly. PermissionSet demandSet = null; if (targetGrant == null) { demandSet = new PermissionSet(PermissionState.Unrestricted); } else { demandSet = targetGrant.CopyWithNoIdentityPermissions(); demandSet.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)); } securityContext.DemandFlagsOrGrantSet((1 << (int)permission), demandSet); } [System.Security.SecurityCritical] // auto-generated internal static void GetZoneAndOriginHelper( CompressedStack cs, PermissionSet grantSet, PermissionSet refusedSet, ArrayList zoneList, ArrayList originList ) { if (cs != null) cs.GetZoneAndOrigin(zoneList, originList, PermissionToken.GetToken(typeof(ZoneIdentityPermission)), PermissionToken.GetToken(typeof(UrlIdentityPermission))); else { ZoneIdentityPermission zone = (ZoneIdentityPermission)grantSet.GetPermission( typeof( ZoneIdentityPermission ) ); UrlIdentityPermission url = (UrlIdentityPermission)grantSet.GetPermission( typeof( UrlIdentityPermission ) ); if (zone != null) zoneList.Add( zone.SecurityZone ); if (url != null) originList.Add( url.Url ); } } [System.Security.SecurityCritical] // auto-generated internal static void GetZoneAndOrigin( ref StackCrawlMark mark, out ArrayList zone, out ArrayList origin ) { zone = new ArrayList(); origin = new ArrayList(); GetZoneAndOriginInternal( zone, origin, ref mark); } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void GetZoneAndOriginInternal(ArrayList zoneList, ArrayList originList, ref StackCrawlMark stackMark); #endif // FEATURE_CAS_POLICY [System.Security.SecurityCritical] // auto-generated internal static void CheckAssembly(RuntimeAssembly asm, CodeAccessPermission demand ) { Contract.Assert( asm != null, "Must pass in a good assembly" ); Contract.Assert( demand != null, "Must pass in a good demand" ); PermissionSet granted, refused; asm.GetGrantSet( out granted, out refused ); #pragma warning disable 618 CheckHelper( granted, refused, demand, PermissionToken.GetToken(demand), RuntimeMethodHandleInternal.EmptyHandle, asm, SecurityAction.Demand, true ); #pragma warning restore 618 } // Check - Used to initiate a code-access security check. // This method invokes a stack walk after skipping to the frame // referenced by stackMark. [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern void Check (Object demand, ref StackCrawlMark stackMark, bool isPermSet); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool QuickCheckForAllDemands(); [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool AllDomainsHomogeneousWithNoStackModifiers(); [System.Security.SecurityCritical] // auto-generated internal static void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark) { Check(cap, ref stackMark, false); } [System.Security.SecurityCritical] // auto-generated internal static void Check(PermissionSet permSet, ref StackCrawlMark stackMark) { Check(permSet, ref stackMark, true); } [System.Security.SecurityCritical] // auto-generated [ResourceExposure(ResourceScope.None)] [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern FrameSecurityDescriptor CheckNReturnSO(PermissionToken permToken, CodeAccessPermission demand, ref StackCrawlMark stackMark, int create ); [System.Security.SecurityCritical] // auto-generated internal static void Assert(CodeAccessPermission cap, ref StackCrawlMark stackMark) { // Make sure the caller of assert has the permission to assert //WARNING: The placement of the call here is just right to check // the appropriate frame. // Note: if the "AssertPermission" is not a permission that implements IUnrestrictedPermission // you need to change the last parameter to a zero. Contract.Assert(AssertPermissionToken != null && AssertPermission != null, "Assert Permission not setup correctly"); FrameSecurityDescriptor secObj = CheckNReturnSO(AssertPermissionToken, AssertPermission, ref stackMark, 1 ); if (secObj == null) { // Security: REQ_SQ flag is missing. Bad compiler ? // This can happen when you create delegates over functions that need the REQ_SQ System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor")); } else { if (secObj.HasImperativeAsserts()) throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) ); secObj.SetAssert(cap); } } [System.Security.SecurityCritical] // auto-generated internal static void Deny(CodeAccessPermission cap, ref StackCrawlMark stackMark) { #if FEATURE_CAS_POLICY // Deny is only valid in legacy mode if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_CasDeny")); } #endif // FEATURE_CAS_POLICY FrameSecurityDescriptor secObj = SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true); if (secObj == null) { // Security: REQ_SQ flag is missing. Bad compiler ? // This can happen when you create delegates over functions that need the REQ_SQ System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor")); } else { if (secObj.HasImperativeDenials()) throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) ); secObj.SetDeny(cap); } } [System.Security.SecurityCritical] // auto-generated internal static void PermitOnly(CodeAccessPermission cap, ref StackCrawlMark stackMark) { FrameSecurityDescriptor secObj = SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true); if (secObj == null) { // Security: REQ_SQ flag is missing. Bad compiler ? // This can happen when you create delegates over functions that need the REQ_SQ System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor")); } else { if (secObj.HasImperativeRestrictions()) throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) ); secObj.SetPermitOnly(cap); } } #if FEATURE_CAS_POLICY // Called from the VM to do a pre-domain initialization check of the security state of the // AppDomain. This method looks at the state of the security of an AppDomain before it is // completely initialized - so the output of this method does not always match what will be true // when the domain is completely initialized. Instead, it is used to read what the input parameters // to the domain setup say about the domain. private static void PreResolve(out bool isFullyTrusted, out bool isHomogeneous) { // // There are three main cases: // 1. The AppDomain has an explict ApplicationTrust - we can use this to read the input state // of the AppDomain. // 2. The AppDomain is using legacy CAS policy - this means we can't tell much about the // domain itself without a full policy resolution. // 3. The domain is a standard v4+ AppDomain - these are always full trust and homogenous by // default. // // If the AppDomain is setup with an ApplicationTrust then it is always homogenous and we can // tell its grant set right from the ApplicaitonTrust ApplicationTrust domainTrust = AppDomain.CurrentDomain.SetupInformation.ApplicationTrust; if (domainTrust != null) { isFullyTrusted = domainTrust.DefaultGrantSet.PermissionSet.IsUnrestricted(); isHomogeneous = true; return; } // Otherwise, see if the domain is being configured on input to use legacy CAS policy if (CompatibilitySwitches.IsNetFx40LegacySecurityPolicy || AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled) { isFullyTrusted = false; isHomogeneous = false; return; } // If none of the above is true, then we must be a standard AppDomain isFullyTrusted = true; isHomogeneous = true; } // Called from the VM when either a HostSecurityManager or simple sandbox domain can determine the // grant set of an assembly private static PermissionSet ResolveGrantSet(Evidence evidence, out int specialFlags, bool checkExecutionPermission) { Contract.Assert(evidence != null); Contract.Assert(!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled); // This API does not do CAS policy resolution PermissionSet grantSet = null; if (!TryResolveGrantSet(evidence, out grantSet)) { // If we couldn't figure out a grant set from the domain or the host, then we treat the // assembly as fully trusted. grantSet = new PermissionSet(PermissionState.Unrestricted); } // Make sure the grant set includes the ability to execute code if that has been requested. if (checkExecutionPermission) { SecurityPermission executionPermission = new SecurityPermission(SecurityPermissionFlag.Execution); if (!grantSet.Contains(executionPermission)) { throw new PolicyException(Environment.GetResourceString("Policy_NoExecutionPermission"), System.__HResults.CORSEC_E_NO_EXEC_PERM); } } specialFlags = SecurityManager.GetSpecialFlags(grantSet, null); return grantSet; } // Consult the host and the current AppDomain if it is homogenous to determine what the grant set // of an assembly is. This API returns true if it was able to determine a grant set for the evidence, // false if it cannot and other policy needs to be applied. [SecuritySafeCritical] internal static bool TryResolveGrantSet(Evidence evidence, out PermissionSet grantSet) { Contract.Assert(evidence != null); HostSecurityManager securityManager = AppDomain.CurrentDomain.HostSecurityManager; // GAC assemblies always are fully trusted if (evidence.GetHostEvidence() != null) { grantSet = new PermissionSet(PermissionState.Unrestricted); return true; } // If the host wants to participate in policy resolution, then our next option is to ask it for // a grant set else if ((securityManager.Flags & HostSecurityManagerOptions.HostResolvePolicy) == HostSecurityManagerOptions.HostResolvePolicy) { PermissionSet hostGrantSet = securityManager.ResolvePolicy(evidence); if (hostGrantSet == null) { throw new PolicyException(Environment.GetResourceString("Policy_NullHostGrantSet", securityManager.GetType().FullName)); } // If we're in a homogenous domain, we don't want to allow the host to create multiple // levels of permissions within the domain. So, if we see the host return something other // than full trust or the homogenous grant set, we reject the grant set. if (AppDomain.CurrentDomain.IsHomogenous) { // Some hosts, such as ASP.NET, return Nothing as a way of saying that the assembly should // not be allowed to run in the AppDomain. Reject that with a specific // no-execution-allowed-here exception message, rather than the return value validation // exception message we'd hit below. if (hostGrantSet.IsEmpty()) { throw new PolicyException(Environment.GetResourceString("Policy_NoExecutionPermission")); } PermissionSet homogenousGrantSet = AppDomain.CurrentDomain.ApplicationTrust.DefaultGrantSet.PermissionSet; bool isValidGrantSet = hostGrantSet.IsUnrestricted() || (hostGrantSet.IsSubsetOf(homogenousGrantSet) && homogenousGrantSet.IsSubsetOf(hostGrantSet)); if (!isValidGrantSet) { throw new PolicyException(Environment.GetResourceString("Policy_GrantSetDoesNotMatchDomain", securityManager.GetType().FullName)); } } grantSet = hostGrantSet; return true; } // If we're in a homogenous domain, we can get the grant set directly from the application trust else if (AppDomain.CurrentDomain.IsHomogenous) { grantSet = AppDomain.CurrentDomain.GetHomogenousGrantSet(evidence); return true; } // Otherwise we have no way to figure out what the grant set is else { grantSet = null; return false; } } #endif // FEATURE_CAS_POLICY #if FEATURE_PLS // Update the PLS used for optimization in the AppDomain: called from the VM [System.Security.SecurityCritical] // auto-generated private static PermissionListSet UpdateAppDomainPLS(PermissionListSet adPLS, PermissionSet grantedPerms, PermissionSet refusedPerms) { if (adPLS == null) { adPLS = new PermissionListSet(); adPLS.UpdateDomainPLS(grantedPerms, refusedPerms); return adPLS; } else { PermissionListSet newPLS = new PermissionListSet(); newPLS.UpdateDomainPLS(adPLS); newPLS.UpdateDomainPLS(grantedPerms, refusedPerms); return newPLS; } } #endif //FEATURE_PLS } }