From 4b11dc566a5bbfa1378d6266525c281b028abcc8 Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Fri, 10 Feb 2017 20:35:12 +0900 Subject: Imported Upstream version 1.0.0.9910 --- src/mscorlib/src/System/Security/PermissionSet.cs | 1605 --------------------- 1 file changed, 1605 deletions(-) delete mode 100644 src/mscorlib/src/System/Security/PermissionSet.cs (limited to 'src/mscorlib/src/System/Security/PermissionSet.cs') diff --git a/src/mscorlib/src/System/Security/PermissionSet.cs b/src/mscorlib/src/System/Security/PermissionSet.cs deleted file mode 100644 index 11ca02a81e..0000000000 --- a/src/mscorlib/src/System/Security/PermissionSet.cs +++ /dev/null @@ -1,1605 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -// - -namespace System.Security { - using System; - using System.Threading; - using System.Security.Util; - using System.Collections; - using System.IO; - using System.Security.Permissions; - using System.Runtime.CompilerServices; - using System.Security.Policy; -#if FEATURE_SERIALIZATION - using System.Runtime.Serialization.Formatters.Binary; -#endif // FEATURE_SERIALIZATION - using BindingFlags = System.Reflection.BindingFlags; - using System.Runtime.Serialization; - using System.Text; - using System.Globalization; - using System.Runtime.Versioning; - using System.Diagnostics; - using System.Diagnostics.Contracts; - - [Serializable] - internal enum SpecialPermissionSetFlag - { - // These also appear in clr/src/vm/permset.h - Regular = 0, - NoSet = 1, - EmptySet = 2, - SkipVerification = 3 - } - -#if FEATURE_SERIALIZATION - [Serializable] -#endif - [System.Runtime.InteropServices.ComVisible(true)] - public class PermissionSet : ISecurityEncodable, ICollection, IStackWalk -#if FEATURE_SERIALIZATION - , IDeserializationCallback -#endif - { -#if _DEBUG - internal static readonly bool debug; -#endif - - [System.Diagnostics.Conditional( "_DEBUG" )] - private static void DEBUG_WRITE(String str) { - #if _DEBUG - if (debug) Console.WriteLine(str); - #endif - } - - [System.Diagnostics.Conditional( "_DEBUG" )] - private static void DEBUG_COND_WRITE(bool exp, String str) - { - #if _DEBUG - if (debug && (exp)) Console.WriteLine(str); - #endif - } - - [System.Diagnostics.Conditional( "_DEBUG" )] - private static void DEBUG_PRINTSTACK(Exception e) - { - #if _DEBUG - if (debug) Console.WriteLine((e).StackTrace); - #endif - } - - // These members are accessed from EE using their hardcoded offset. - // Please update the PermissionSetObject in object.h if you make any changes - // to the fields here. !dumpobj will show the field layout - - // First the fields that are serialized x-appdomain (for perf reasons) - private bool m_Unrestricted; - [OptionalField(VersionAdded = 2)] - private bool m_allPermissionsDecoded = false; - - [OptionalField(VersionAdded = 2)] - internal TokenBasedSet m_permSet = null; - - // This is a workaround so that SQL can operate under default policy without actually - // granting permissions in assemblies that they disallow. - - [OptionalField(VersionAdded = 2)] - private bool m_ignoreTypeLoadFailures = false; - - // This field will be populated only for non X-AD scenarios where we create a XML-ised string of the PermissionSet - [OptionalField(VersionAdded = 2)] - private String m_serializedPermissionSet; - - [NonSerialized] private bool m_CheckedForNonCas; - [NonSerialized] private bool m_ContainsCas; - [NonSerialized] private bool m_ContainsNonCas; - - // only used during non X-AD serialization to save the m_permSet value (which we dont want serialized) - [NonSerialized] private TokenBasedSet m_permSetSaved; - - // Following 4 fields are used only for serialization compat purposes: DO NOT USE THESE EVER! -#pragma warning disable 169 - private bool readableonly; - private TokenBasedSet m_unrestrictedPermSet; - private TokenBasedSet m_normalPermSet; - - [OptionalField(VersionAdded = 2)] - private bool m_canUnrestrictedOverride; -#pragma warning restore 169 - // END: Serialization-only fields - - internal static readonly PermissionSet s_fullTrust = new PermissionSet( true ); - -#if _DEBUG - [OnSerialized] - private void OnSerialized(StreamingContext context) - { - Debug.Assert(false, "PermissionSet does not support serialization on CoreCLR"); - } -#endif // _DEBUG - - internal PermissionSet() - { - Reset(); - m_Unrestricted = true; - } - - internal PermissionSet(bool fUnrestricted) - : this() - { - SetUnrestricted(fUnrestricted); - } - - public PermissionSet(PermissionState state) - : this() - { - if (state == PermissionState.Unrestricted) - { - SetUnrestricted( true ); - } - else if (state == PermissionState.None) - { - SetUnrestricted( false ); - } - else - { - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionState")); - } - } - - public PermissionSet(PermissionSet permSet) - : this() - { - if (permSet == null) - { - Reset(); - return; - } - - m_Unrestricted = permSet.m_Unrestricted; - m_CheckedForNonCas = permSet.m_CheckedForNonCas; - m_ContainsCas = permSet.m_ContainsCas; - m_ContainsNonCas = permSet.m_ContainsNonCas; - m_ignoreTypeLoadFailures = permSet.m_ignoreTypeLoadFailures; - - if (permSet.m_permSet != null) - { - m_permSet = new TokenBasedSet(permSet.m_permSet); - - // now deep copy all permissions in set - for (int i = m_permSet.GetStartingIndex(); i <= m_permSet.GetMaxUsedIndex(); i++) - { - Object obj = m_permSet.GetItem(i); - IPermission perm = obj as IPermission; - - if (perm != null) - { - m_permSet.SetItem(i, perm.Copy()); - } - } - } - } - - public virtual void CopyTo(Array array, int index) - { - if (array == null) - throw new ArgumentNullException( nameof(array) ); - Contract.EndContractBlock(); - - PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this); - - while (enumerator.MoveNext()) - { - array.SetValue(enumerator.Current , index++ ); - } - } - - - // private constructor that doesn't create any token based sets - private PermissionSet( Object trash, Object junk ) - { - m_Unrestricted = false; - } - - - // Returns an object appropriate for synchronizing access to this - // Array. - public virtual Object SyncRoot - { get { return this; } } - - // Is this Array synchronized (i.e., thread-safe)? If you want a synchronized - // collection, you can use SyncRoot as an object to synchronize your - // collection with. You could also call GetSynchronized() - // to get a synchronized wrapper around the Array. - public virtual bool IsSynchronized - { get { return false; } } - - // Is this Collection ReadOnly? - public virtual bool IsReadOnly - { get {return false; } } - - // Reinitializes all state in PermissionSet - DO NOT null-out m_serializedPermissionSet - internal void Reset() - { - m_Unrestricted = false; - m_allPermissionsDecoded = true; - m_permSet = null; - - m_ignoreTypeLoadFailures = false; - - m_CheckedForNonCas = false; - m_ContainsCas = false; - m_ContainsNonCas = false; - m_permSetSaved = null; - - - } - - internal void CheckSet() - { - if (this.m_permSet == null) - this.m_permSet = new TokenBasedSet(); - } - - public bool IsEmpty() - { - if (m_Unrestricted) - return false; - - if (m_permSet == null || m_permSet.FastIsEmpty()) - return true; - - PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this); - - while (enumerator.MoveNext()) - { - IPermission perm = (IPermission)enumerator.Current; - - if (!perm.IsSubsetOf( null )) - { - return false; - } - } - - return true; - } - - internal bool FastIsEmpty() - { - if (m_Unrestricted) - return false; - - if (m_permSet == null || m_permSet.FastIsEmpty()) - return true; - - return false; - } - - public virtual int Count - { - get - { - int count = 0; - - if (m_permSet != null) - count += m_permSet.GetCount(); - - return count; - } - } - - internal IPermission GetPermission(int index) - { - if (m_permSet == null) - return null; - Object obj = m_permSet.GetItem( index ); - if (obj == null) - return null; - return obj as IPermission; - } - - internal IPermission GetPermission(PermissionToken permToken) - { - if (permToken == null) - return null; - - return GetPermission( permToken.m_index ); - } - - internal IPermission GetPermission( IPermission perm ) - { - if (perm == null) - return null; - - return GetPermission(PermissionToken.GetToken( perm )); - } - - public IPermission SetPermission(IPermission perm) - { - return SetPermissionImpl(perm); - } - - // SetPermission overwrites a permission in a permissionset. - protected virtual IPermission SetPermissionImpl(IPermission perm) - { - // can't get token if perm is null - if (perm == null) - return null; - - PermissionToken permToken = PermissionToken.GetToken(perm); - - if ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0) - { - // SetPermission Makes the Permission "Restricted" - m_Unrestricted = false; - } - - CheckSet(); - - IPermission currPerm = GetPermission( permToken.m_index ); - - m_CheckedForNonCas = false; - - // Should we copy here? - m_permSet.SetItem( permToken.m_index, perm ); - return perm; - } - - public IPermission AddPermission(IPermission perm) - { - return AddPermissionImpl(perm); - } - - protected virtual IPermission AddPermissionImpl(IPermission perm) - { - // can't get token if perm is null - if (perm == null) - return null; - - m_CheckedForNonCas = false; - - // If the permission set is unrestricted, then return an unrestricted instance - // of perm. - - PermissionToken permToken = PermissionToken.GetToken(perm); - - if (this.IsUnrestricted() && ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0)) - { - Type perm_type = perm.GetType(); - Object[] objs = new Object[1]; - objs[0] = PermissionState.Unrestricted; - return (IPermission) Activator.CreateInstance(perm_type, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, objs, null ); - } - - CheckSet(); - IPermission currPerm = GetPermission(permToken.m_index); - - // If a Permission exists in this slot, then union it with perm - // Otherwise, just add perm. - - if (currPerm != null) { - IPermission ip_union = currPerm.Union(perm); - m_permSet.SetItem( permToken.m_index, ip_union ); - return ip_union; - } else { - // Should we copy here? - m_permSet.SetItem( permToken.m_index, perm ); - return perm; - } - - } - - private IPermission RemovePermission( int index ) - { - IPermission perm = GetPermission(index); - if (perm == null) - return null; - return (IPermission)m_permSet.RemoveItem( index ); // this cast is safe because the call to GetPermission will guarantee it is an IPermission - } - - // Make this internal soon. - internal void SetUnrestricted(bool unrestricted) - { - m_Unrestricted = unrestricted; - if (unrestricted) - { - // if this is to be an unrestricted permset, null the m_permSet member - m_permSet = null; - } - } - - public bool IsUnrestricted() - { - return m_Unrestricted; - } - - internal enum IsSubsetOfType - { - Normal, - CheckDemand, - CheckPermitOnly, - CheckAssertion, - } - - internal bool IsSubsetOfHelper(PermissionSet target, IsSubsetOfType type, out IPermission firstPermThatFailed, bool ignoreNonCas) - { - #if _DEBUG - if (debug) - DEBUG_WRITE("IsSubsetOf\n" + - "Other:\n" + - (target == null ? "" : target.ToString()) + - "\nMe:\n" + - ToString()); - #endif - - firstPermThatFailed = null; - if (target == null || target.FastIsEmpty()) - { - if(this.IsEmpty()) - return true; - else - { - firstPermThatFailed = GetFirstPerm(); - return false; - } - } - else if (this.IsUnrestricted() && !target.IsUnrestricted()) - return false; - else if (this.m_permSet == null) - return true; - else - { - target.CheckSet(); - - for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i) - { - IPermission thisPerm = this.GetPermission(i); - if (thisPerm == null || thisPerm.IsSubsetOf(null)) - continue; - - IPermission targetPerm = target.GetPermission(i); -#if _DEBUG - PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); - Debug.Assert(targetPerm == null || (token.m_type & PermissionTokenType.DontKnow) == 0, "Token not properly initialized"); -#endif - - if (target.m_Unrestricted) - continue; - - // targetPerm can be null here, but that is fine since it thisPerm is a subset - // of empty/null then we can continue in the loop. - CodeAccessPermission cap = thisPerm as CodeAccessPermission; - if(cap == null) - { - if (!ignoreNonCas && !thisPerm.IsSubsetOf( targetPerm )) - { - firstPermThatFailed = thisPerm; - return false; - } - } - else - { - firstPermThatFailed = thisPerm; - switch(type) - { - case IsSubsetOfType.Normal: - if (!thisPerm.IsSubsetOf( targetPerm )) - return false; - break; - case IsSubsetOfType.CheckDemand: - if (!cap.CheckDemand( (CodeAccessPermission)targetPerm )) - return false; - break; - case IsSubsetOfType.CheckPermitOnly: - if (!cap.CheckPermitOnly( (CodeAccessPermission)targetPerm )) - return false; - break; - case IsSubsetOfType.CheckAssertion: - if (!cap.CheckAssert( (CodeAccessPermission)targetPerm )) - return false; - break; - } - firstPermThatFailed = null; - } - } - } - - return true; - } - - public bool IsSubsetOf(PermissionSet target) - { - IPermission perm; - return IsSubsetOfHelper(target, IsSubsetOfType.Normal, out perm, false); - } - - internal bool CheckDemand(PermissionSet target, out IPermission firstPermThatFailed) - { - return IsSubsetOfHelper(target, IsSubsetOfType.CheckDemand, out firstPermThatFailed, true); - } - - internal bool CheckPermitOnly(PermissionSet target, out IPermission firstPermThatFailed) - { - return IsSubsetOfHelper(target, IsSubsetOfType.CheckPermitOnly, out firstPermThatFailed, true); - } - - internal bool CheckAssertion(PermissionSet target) - { - IPermission perm; - return IsSubsetOfHelper(target, IsSubsetOfType.CheckAssertion, out perm, true); - } - - internal bool CheckDeny(PermissionSet deniedSet, out IPermission firstPermThatFailed) - { - firstPermThatFailed = null; - if (deniedSet == null || deniedSet.FastIsEmpty() || this.FastIsEmpty()) - return true; - - if(this.m_Unrestricted && deniedSet.m_Unrestricted) - return false; - - CodeAccessPermission permThis, permThat; - PermissionSetEnumeratorInternal enumThis = new PermissionSetEnumeratorInternal(this); - - while (enumThis.MoveNext()) - { - permThis = enumThis.Current as CodeAccessPermission; - if(permThis == null || permThis.IsSubsetOf(null)) - continue; // ignore non-CAS permissions in the grant set. - if (deniedSet.m_Unrestricted) - { - firstPermThatFailed = permThis; - return false; - } - permThat = (CodeAccessPermission)deniedSet.GetPermission(enumThis.GetCurrentIndex()); - if (!permThis.CheckDeny(permThat)) - { - firstPermThatFailed = permThis; - return false; - } - } - if(this.m_Unrestricted) - { - PermissionSetEnumeratorInternal enumThat = new PermissionSetEnumeratorInternal(deniedSet); - while (enumThat.MoveNext()) - { - if(enumThat.Current is IPermission) - return false; - } - } - return true; - } - - internal void CheckDecoded( CodeAccessPermission demandedPerm, PermissionToken tokenDemandedPerm ) - { - Debug.Assert( demandedPerm != null, "Expected non-null value" ); - - if (this.m_allPermissionsDecoded || this.m_permSet == null) - return; - - if (tokenDemandedPerm == null) - tokenDemandedPerm = PermissionToken.GetToken( demandedPerm ); - - Debug.Assert( tokenDemandedPerm != null, "Unable to find token for demanded permission" ); - - CheckDecoded( tokenDemandedPerm.m_index ); - } - - internal void CheckDecoded( int index ) - { - if (this.m_allPermissionsDecoded || this.m_permSet == null) - return; - - GetPermission(index); - } - - internal void CheckDecoded(PermissionSet demandedSet) - { - Debug.Assert(demandedSet != null, "Expected non-null value"); - - if (this.m_allPermissionsDecoded || this.m_permSet == null) - return; - - PermissionSetEnumeratorInternal enumerator = demandedSet.GetEnumeratorInternal(); - - while (enumerator.MoveNext()) - { - CheckDecoded(enumerator.GetCurrentIndex()); - } - } - - internal void InplaceIntersect( PermissionSet other ) - { - Exception savedException = null; - - m_CheckedForNonCas = false; - - if (this == other) - return; - - if (other == null || other.FastIsEmpty()) - { - // If the other is empty or null, make this empty. - Reset(); - return; - } - - if (this.FastIsEmpty()) - return; - - int maxMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex(); - int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex(); - - if (this.IsUnrestricted() && maxMax < otherMax) - { - maxMax = otherMax; - this.CheckSet(); - } - - if (other.IsUnrestricted()) - { - other.CheckSet(); - } - - for (int i = 0; i <= maxMax; ++i) - { - Object thisObj = this.m_permSet.GetItem( i ); - IPermission thisPerm = thisObj as IPermission; - - Object otherObj = other.m_permSet.GetItem( i ); - IPermission otherPerm = otherObj as IPermission; - - if (thisObj == null && otherObj == null) - continue; - - if (thisObj == null) - { - // There is no object in , so intersection is empty except for IUnrestrictedPermissions - if (this.IsUnrestricted()) - { - { - PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); - if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) - { - this.m_permSet.SetItem( i, otherPerm.Copy() ); - Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); - } - } - } - } - else if (otherObj == null) - { - if (other.IsUnrestricted()) - { - { - PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); - if ((token.m_type & PermissionTokenType.IUnrestricted) == 0) - this.m_permSet.SetItem( i, null ); - } - } - else - { - this.m_permSet.SetItem( i, null ); - } - } - else - { - try - { - IPermission intersectPerm; - if (thisPerm == null) - intersectPerm = otherPerm; - else if(otherPerm == null) - intersectPerm = thisPerm; - else - intersectPerm = thisPerm.Intersect( otherPerm ); - this.m_permSet.SetItem( i, intersectPerm ); - } - catch (Exception e) - { - if (savedException == null) - savedException = e; - } - } - } - - this.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted; - - if (savedException != null) - throw savedException; - } - - public PermissionSet Intersect(PermissionSet other) - { - if (other == null || other.FastIsEmpty() || this.FastIsEmpty()) - { - return null; - } - - int thisMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex(); - int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex(); - int minMax = thisMax < otherMax ? thisMax : otherMax; - - if (this.IsUnrestricted() && minMax < otherMax) - { - minMax = otherMax; - this.CheckSet(); - } - - if (other.IsUnrestricted() && minMax < thisMax) - { - minMax = thisMax; - other.CheckSet(); - } - - PermissionSet pset = new PermissionSet( false ); - - if (minMax > -1) - { - pset.m_permSet = new TokenBasedSet(); - } - - for (int i = 0; i <= minMax; ++i) - { - Object thisObj = this.m_permSet.GetItem( i ); - IPermission thisPerm = thisObj as IPermission; - Object otherObj = other.m_permSet.GetItem( i ); - IPermission otherPerm = otherObj as IPermission; - - if (thisObj == null && otherObj == null) - continue; - - if (thisObj == null) - { - if (this.m_Unrestricted) - { - if (otherPerm != null) - { - PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); - if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) - { - pset.m_permSet.SetItem( i, otherPerm.Copy() ); - Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); - } - } - } - } - else if (otherObj == null) - { - if (other.m_Unrestricted) - { - if (thisPerm != null) - { - PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); - if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) - { - pset.m_permSet.SetItem( i, thisPerm.Copy() ); - Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); - } - } - } - } - else - { - IPermission intersectPerm; - if (thisPerm == null) - intersectPerm = otherPerm; - else if(otherPerm == null) - intersectPerm = thisPerm; - else - intersectPerm = thisPerm.Intersect( otherPerm ); - pset.m_permSet.SetItem( i, intersectPerm ); - Debug.Assert( intersectPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); - } - } - - pset.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted; - if (pset.FastIsEmpty()) - return null; - else - return pset; - } - - internal void InplaceUnion( PermissionSet other ) - { - // Unions the "other" PermissionSet into this one. It can be optimized to do less copies than - // need be done by the traditional union (and we don't have to create a new PermissionSet). - - if (this == other) - return; - - // Quick out conditions, union doesn't change this PermissionSet - if (other == null || other.FastIsEmpty()) - return; - - m_CheckedForNonCas = false; - - this.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted; - - if (this.m_Unrestricted) - { - // if the result of Union is unrestricted permset, null the m_permSet member - this.m_permSet = null; - return; - } - - - // If we reach here, result of Union is not unrestricted - // We have to union "normal" permission no matter what now. - int maxMax = -1; - if (other.m_permSet != null) - { - maxMax = other.m_permSet.GetMaxUsedIndex(); - this.CheckSet(); - } - // Save exceptions until the end - Exception savedException = null; - - for (int i = 0; i <= maxMax; ++i) - { - Object thisObj = this.m_permSet.GetItem( i ); - IPermission thisPerm = thisObj as IPermission; - - Object otherObj = other.m_permSet.GetItem( i ); - IPermission otherPerm = otherObj as IPermission; - - if (thisObj == null && otherObj == null) - continue; - - if (thisObj == null) - { - if (otherPerm != null) - { - PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); - if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !this.m_Unrestricted) - { - this.m_permSet.SetItem( i, otherPerm.Copy() ); - } - } - } - else if (otherObj == null) - { - continue; - } - else - { - try - { - IPermission unionPerm; - if(thisPerm == null) - unionPerm = otherPerm; - else if(otherPerm == null) - unionPerm = thisPerm; - else - unionPerm = thisPerm.Union( otherPerm ); - this.m_permSet.SetItem( i, unionPerm ); - } - catch (Exception e) - { - if (savedException == null) - savedException = e; - } - } - } - - if (savedException != null) - throw savedException; - } - - public PermissionSet Union(PermissionSet other) - { - // if other is null or empty, return a clone of myself - if (other == null || other.FastIsEmpty()) - { - return this.Copy(); - } - - if (this.FastIsEmpty()) - { - return other.Copy(); - } - - int maxMax = -1; - - PermissionSet pset = new PermissionSet(); - pset.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted; - if (pset.m_Unrestricted) - { - // if the result of Union is unrestricted permset, just return - return pset; - } - - // degenerate case where we look at both this.m_permSet and other.m_permSet - this.CheckSet(); - other.CheckSet(); - maxMax = this.m_permSet.GetMaxUsedIndex() > other.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : other.m_permSet.GetMaxUsedIndex(); - pset.m_permSet = new TokenBasedSet(); - - - - for (int i = 0; i <= maxMax; ++i) - { - Object thisObj = this.m_permSet.GetItem( i ); - IPermission thisPerm = thisObj as IPermission; - - Object otherObj = other.m_permSet.GetItem( i ); - IPermission otherPerm = otherObj as IPermission; - - if (thisObj == null && otherObj == null) - continue; - - if (thisObj == null) - { - if (otherPerm != null) - { - PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); - if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted) - { - pset.m_permSet.SetItem( i, otherPerm.Copy() ); - Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); - } - } - } - else if (otherObj == null) - { - if (thisPerm != null) - { - PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); - if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted) - { - pset.m_permSet.SetItem( i, thisPerm.Copy() ); - Debug.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); - } - } - } - else - { - IPermission unionPerm; - if(thisPerm == null) - unionPerm = otherPerm; - else if(otherPerm == null) - unionPerm = thisPerm; - else - unionPerm = thisPerm.Union( otherPerm ); - pset.m_permSet.SetItem( i, unionPerm ); - Debug.Assert( unionPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); - } - } - - return pset; - } - - // Treating the current permission set as a grant set, and the input set as - // a set of permissions to be denied, try to cancel out as many permissions - // from both sets as possible. For a first cut, any granted permission that - // is a safe subset of the corresponding denied permission can result in - // that permission being removed from both sides. - - internal void MergeDeniedSet(PermissionSet denied) - { - if (denied == null || denied.FastIsEmpty() || this.FastIsEmpty()) - return; - - m_CheckedForNonCas = false; - - // Check for the unrestricted case: FastIsEmpty() will return false if the PSet is unrestricted, but has no items - if (this.m_permSet == null || denied.m_permSet == null) - return; //nothing can be removed - - int maxIndex = denied.m_permSet.GetMaxUsedIndex() > this.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : denied.m_permSet.GetMaxUsedIndex(); - for (int i = 0; i <= maxIndex; ++i) { - IPermission deniedPerm = denied.m_permSet.GetItem(i) as IPermission; - if (deniedPerm == null) - continue; - - IPermission thisPerm = this.m_permSet.GetItem(i) as IPermission; - - if (thisPerm == null && !this.m_Unrestricted) { - denied.m_permSet.SetItem(i, null); - continue; - } - - if (thisPerm != null && deniedPerm != null) { - if (thisPerm.IsSubsetOf(deniedPerm)) { - this.m_permSet.SetItem(i, null); - denied.m_permSet.SetItem(i, null); - } - } - } - } - - // Returns true if perm is contained in this - internal bool Contains(IPermission perm) - { - if (perm == null) - return true; - if (m_Unrestricted) - return true; - if (FastIsEmpty()) - return false; - - PermissionToken token = PermissionToken.GetToken(perm); - Object thisObj = this.m_permSet.GetItem( token.m_index ); - if (thisObj == null) - return perm.IsSubsetOf( null ); - - IPermission thisPerm = GetPermission(token.m_index); - if (thisPerm != null) - return perm.IsSubsetOf( thisPerm ); - else - return perm.IsSubsetOf( null ); - } - - [System.Runtime.InteropServices.ComVisible(false)] - public override bool Equals( Object obj ) - { - // Note: this method is designed to accept both PermissionSet and NamedPermissionSets. - // It will compare them based on the values in the base type, thereby ignoring the - // name and description of the named permission set. - - PermissionSet other = obj as PermissionSet; - - if (other == null) - return false; - - if (this.m_Unrestricted != other.m_Unrestricted) - return false; - - CheckSet(); - other.CheckSet(); - - DecodeAllPermissions(); - other.DecodeAllPermissions(); - - int maxIndex = Math.Max( this.m_permSet.GetMaxUsedIndex(), other.m_permSet.GetMaxUsedIndex() ); - - for (int i = 0; i <= maxIndex; ++i) - { - IPermission thisPerm = (IPermission)this.m_permSet.GetItem( i ); - IPermission otherPerm = (IPermission)other.m_permSet.GetItem( i ); - - if (thisPerm == null && otherPerm == null) - { - continue; - } - else if (thisPerm == null) - { - if (!otherPerm.IsSubsetOf( null )) - return false; - } - else if (otherPerm == null) - { - if (!thisPerm.IsSubsetOf( null )) - return false; - } - else - { - if (!thisPerm.Equals( otherPerm )) - return false; - } - } - - return true; - } - - [System.Runtime.InteropServices.ComVisible(false)] - public override int GetHashCode() - { - int accumulator; - - accumulator = this.m_Unrestricted ? -1 : 0; - - if (this.m_permSet != null) - { - DecodeAllPermissions(); - - int maxIndex = this.m_permSet.GetMaxUsedIndex(); - - for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i) - { - IPermission perm = (IPermission)this.m_permSet.GetItem( i ); - if (perm != null) - { - accumulator = accumulator ^ perm.GetHashCode(); - } - } - } - - return accumulator; - } - - // Mark this method as requiring a security object on the caller's frame - // so the caller won't be inlined (which would mess up stack crawling). - [DynamicSecurityMethodAttribute()] - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public void Demand() - { - if (this.FastIsEmpty()) - return; // demanding the empty set always passes. - - ContainsNonCodeAccessPermissions(); - - if (m_ContainsCas) - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller; - CodeAccessSecurityEngine.Check(GetCasOnlySet(), ref stackMark); - } - if (m_ContainsNonCas) - { - DemandNonCAS(); - } - } - - internal void DemandNonCAS() - { - ContainsNonCodeAccessPermissions(); - - if (m_ContainsNonCas) - { - if (this.m_permSet != null) - { - CheckSet(); - for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i) - { - IPermission currPerm = GetPermission(i); - if (currPerm != null && !(currPerm is CodeAccessPermission)) - currPerm.Demand(); - } - } - } - } - - // Metadata for this method should be flaged with REQ_SQ so that - // EE can allocate space on the stack frame for FrameSecurityDescriptor - - [DynamicSecurityMethodAttribute()] - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public void Assert() - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - SecurityRuntime.Assert(this, ref stackMark); - } - - // Metadata for this method should be flaged with REQ_SQ so that - // EE can allocate space on the stack frame for FrameSecurityDescriptor - - [DynamicSecurityMethodAttribute()] - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - [Obsolete("Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] - public void Deny() - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - SecurityRuntime.Deny(this, ref stackMark); - } - - // Metadata for this method should be flaged with REQ_SQ so that - // EE can allocate space on the stack frame for FrameSecurityDescriptor - - [DynamicSecurityMethodAttribute()] - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public void PermitOnly() - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - SecurityRuntime.PermitOnly(this, ref stackMark); - } - - internal IPermission GetFirstPerm() - { - IEnumerator enumerator = GetEnumerator(); - if(!enumerator.MoveNext()) - return null; - return enumerator.Current as IPermission; - } - - // Returns a deep copy - public virtual PermissionSet Copy() - { - return new PermissionSet(this); - } - - internal PermissionSet CopyWithNoIdentityPermissions() - { - // Explicitly make a new PermissionSet, rather than copying, since we may have a - // ReadOnlyPermissionSet which cannot have identity permissions removed from it in a true copy. - return new PermissionSet(this); - } - - public IEnumerator GetEnumerator() - { - return GetEnumeratorImpl(); - } - - protected virtual IEnumerator GetEnumeratorImpl() - { - return new PermissionSetEnumerator(this); - } - - internal PermissionSetEnumeratorInternal GetEnumeratorInternal() - { - return new PermissionSetEnumeratorInternal(this); - } - - private void NormalizePermissionSet() - { - // This function guarantees that all the permissions are placed at - // the proper index within the token based sets. This becomes necessary - // since these indices are dynamically allocated based on usage order. - - PermissionSet permSetTemp = new PermissionSet(false); - - permSetTemp.m_Unrestricted = this.m_Unrestricted; - - // Move all the normal permissions to the new permission set - - if (this.m_permSet != null) - { - for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i) - { - Object obj = this.m_permSet.GetItem(i); - IPermission perm = obj as IPermission; - if (perm != null) - permSetTemp.SetPermission( perm ); - } - } - - this.m_permSet = permSetTemp.m_permSet; - } - - private void DecodeAllPermissions() - { - if (m_permSet == null) - { - m_allPermissionsDecoded = true; - return; - } - - int maxIndex = m_permSet.GetMaxUsedIndex(); - for (int i = 0; i <= maxIndex; ++i) - { - // GetPermission has the side-effect of decoding the permission in the slot - GetPermission(i); - } - - m_allPermissionsDecoded = true; - } - - internal void FilterHostProtectionPermissions(HostProtectionResource fullTrustOnly, HostProtectionResource inaccessible) - { - HostProtectionPermission.protectedResources = fullTrustOnly; - HostProtectionPermission hpp = (HostProtectionPermission)GetPermission(HostProtectionPermission.GetTokenIndex()); - if(hpp == null) - return; - - HostProtectionPermission newHpp = (HostProtectionPermission)hpp.Intersect(new HostProtectionPermission(fullTrustOnly)); - if (newHpp == null) - { - RemovePermission(HostProtectionPermission.GetTokenIndex()); - } - else if (newHpp.Resources != hpp.Resources) - { - SetPermission(newHpp); - } - } - - // Determines whether the permission set contains any non-code access - // security permissions. - public bool ContainsNonCodeAccessPermissions() - { - if (m_CheckedForNonCas) - return m_ContainsNonCas; - - lock (this) - { - if (m_CheckedForNonCas) - return m_ContainsNonCas; - - m_ContainsCas = false; - m_ContainsNonCas = false; - - if (IsUnrestricted()) - m_ContainsCas = true; - - if (this.m_permSet != null) - { - PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this); - - while (enumerator.MoveNext() && (!m_ContainsCas || !m_ContainsNonCas)) - { - IPermission perm = enumerator.Current as IPermission; - - if (perm != null) - { - if (perm is CodeAccessPermission) - m_ContainsCas = true; - else - m_ContainsNonCas = true; - } - } - } - - m_CheckedForNonCas = true; - } - - return m_ContainsNonCas; - } - - // Returns a permission set containing only CAS-permissions. If possible - // this is just the input set, otherwise a new set is allocated. - private PermissionSet GetCasOnlySet() - { - if (!m_ContainsNonCas) - return this; - - if (IsUnrestricted()) - return this; - - PermissionSet pset = new PermissionSet(false); - - PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this); - - while (enumerator.MoveNext()) - { - IPermission perm = (IPermission)enumerator.Current; - - if (perm is CodeAccessPermission) - pset.AddPermission(perm); - } - - pset.m_CheckedForNonCas = true; - pset.m_ContainsCas = !pset.IsEmpty(); - pset.m_ContainsNonCas = false; - - return pset; - } - - // Internal routine used by CreateSerialized to add a permission to the set - private static void MergePermission(IPermission perm, bool separateCasFromNonCas, ref PermissionSet casPset, ref PermissionSet nonCasPset) - { - Debug.Assert(casPset == null || !casPset.IsReadOnly); - Debug.Assert(nonCasPset == null || !nonCasPset.IsReadOnly); - - if (perm == null) - return; - - if (!separateCasFromNonCas || perm is CodeAccessPermission) - { - if(casPset == null) - casPset = new PermissionSet(false); - IPermission oldPerm = casPset.GetPermission(perm); - IPermission unionPerm = casPset.AddPermission(perm); - if (oldPerm != null && !oldPerm.IsSubsetOf( unionPerm )) - throw new NotSupportedException( Environment.GetResourceString( "NotSupported_DeclarativeUnion" ) ); - } - else - { - if(nonCasPset == null) - nonCasPset = new PermissionSet(false); - IPermission oldPerm = nonCasPset.GetPermission(perm); - IPermission unionPerm = nonCasPset.AddPermission( perm ); - if (oldPerm != null && !oldPerm.IsSubsetOf( unionPerm )) - throw new NotSupportedException( Environment.GetResourceString( "NotSupported_DeclarativeUnion" ) ); - } - } - - // Converts an array of SecurityAttributes to a PermissionSet - private static byte[] CreateSerialized(Object[] attrs, - bool serialize, - ref byte[] nonCasBlob, - out PermissionSet casPset, - HostProtectionResource fullTrustOnlyResources, - bool allowEmptyPermissionSets) - { - // Create two new (empty) sets. - casPset = null; - PermissionSet nonCasPset = null; - - // Most security attributes generate a single permission. The - // PermissionSetAttribute class generates an entire permission set we - // need to merge, however. - for (int i = 0; i < attrs.Length; i++) - { -#pragma warning disable 618 - Debug.Assert(i == 0 || ((SecurityAttribute)attrs[i]).m_action == ((SecurityAttribute)attrs[i - 1]).m_action, "Mixed SecurityActions"); -#pragma warning restore 618 - if (attrs[i] is PermissionSetAttribute) - { - PermissionSet pset = ((PermissionSetAttribute)attrs[i]).CreatePermissionSet(); - if (pset == null) - throw new ArgumentException( Environment.GetResourceString( "Argument_UnableToGeneratePermissionSet" ) ); - - PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(pset); - - while (enumerator.MoveNext()) - { - IPermission perm = (IPermission)enumerator.Current; - MergePermission(perm, serialize, ref casPset, ref nonCasPset); - } - - if(casPset == null) - casPset = new PermissionSet(false); - if (pset.IsUnrestricted()) - casPset.SetUnrestricted(true); - } - else - { -#pragma warning disable 618 - IPermission perm = ((SecurityAttribute)attrs[i]).CreatePermission(); -#pragma warning restore 618 - MergePermission(perm, serialize, ref casPset, ref nonCasPset); - } - } - Debug.Assert(serialize || nonCasPset == null, "We shouldn't separate nonCAS permissions unless fSerialize is true"); - - // - // Filter HostProtection permission. In the VM, some optimizations are done based upon these - // declarative permission sets being NULL if they do not exist. When filtering the permission - // set if we end up with an empty set, we can the permission set NULL rather than returning the - // empty set in order to enable those optimizations. - // - - if(casPset != null) - { - casPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None); - casPset.ContainsNonCodeAccessPermissions(); // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code - if (allowEmptyPermissionSets && casPset.IsEmpty()) - casPset = null; - } - if(nonCasPset != null) - { - nonCasPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None); - nonCasPset.ContainsNonCodeAccessPermissions(); // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code - if (allowEmptyPermissionSets && nonCasPset.IsEmpty()) - nonCasPset = null; - } - - Debug.Assert(!serialize, "Cannot serialize permission sets on CoreCLR"); - return null; - } - -#if FEATURE_SERIALIZATION - /// - void IDeserializationCallback.OnDeserialization(Object sender) - { - NormalizePermissionSet(); - m_CheckedForNonCas = false; - } -#endif - - [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable - public static void RevertAssert() - { - StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; - SecurityRuntime.RevertAssert(ref stackMark); - } - - internal static PermissionSet RemoveRefusedPermissionSet(PermissionSet assertSet, PermissionSet refusedSet, out bool bFailedToCompress) - { - Debug.Assert((assertSet == null || !assertSet.IsUnrestricted()), "Cannot be unrestricted here"); - PermissionSet retPs = null; - bFailedToCompress = false; - if (assertSet == null) - return null; - if (refusedSet != null) - { - if (refusedSet.IsUnrestricted()) - return null; // we're refusing everything...cannot assert anything now. - - PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(refusedSet); - while (enumerator.MoveNext()) - { - CodeAccessPermission refusedPerm = (CodeAccessPermission)enumerator.Current; - int i = enumerator.GetCurrentIndex(); - if (refusedPerm != null) - { - CodeAccessPermission perm - = (CodeAccessPermission)assertSet.GetPermission(i); - try - { - if (refusedPerm.Intersect(perm) != null) - { - if (refusedPerm.Equals(perm)) - { - if (retPs == null) - retPs = assertSet.Copy(); - - retPs.RemovePermission(i); - } - else - { - // Asserting a permission, part of which is already denied/refused - // cannot compress this assert - bFailedToCompress = true; - return assertSet; - } - } - } - catch (ArgumentException) - { - // Any exception during removing a refused set from assert set => we play it safe and not assert that perm - if (retPs == null) - retPs = assertSet.Copy(); - retPs.RemovePermission(i); - } - } - } - } - if (retPs != null) - return retPs; - return assertSet; - } - - internal static void RemoveAssertedPermissionSet(PermissionSet demandSet, PermissionSet assertSet, out PermissionSet alteredDemandSet) - { - Debug.Assert(!assertSet.IsUnrestricted(), "Cannot call this function if assertSet is unrestricted"); - alteredDemandSet = null; - - PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(demandSet); - while (enumerator.MoveNext()) - { - CodeAccessPermission demandDerm = (CodeAccessPermission)enumerator.Current; - int i = enumerator.GetCurrentIndex(); - if (demandDerm != null) - { - CodeAccessPermission assertPerm - = (CodeAccessPermission)assertSet.GetPermission(i); - try - { - if (demandDerm.CheckAssert(assertPerm)) - { - if (alteredDemandSet == null) - alteredDemandSet = demandSet.Copy(); - - alteredDemandSet.RemovePermission(i); - } - } - catch (ArgumentException) - { - } - } - } - return; - } - - internal static bool IsIntersectingAssertedPermissions(PermissionSet assertSet1, PermissionSet assertSet2) - { - bool isIntersecting = false; - if (assertSet1 != null && assertSet2 != null) - { - PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(assertSet2); - while (enumerator.MoveNext()) - { - CodeAccessPermission perm2 = (CodeAccessPermission)enumerator.Current; - int i = enumerator.GetCurrentIndex(); - if (perm2 != null) - { - CodeAccessPermission perm1 - = (CodeAccessPermission)assertSet1.GetPermission(i); - try - { - if (perm1 != null && !perm1.Equals(perm2)) - { - isIntersecting = true; // Same type of permission, but with different flags or something - cannot union them - } - } - catch (ArgumentException) - { - isIntersecting = true; //assume worst case - } - } - } - } - return isIntersecting; - - } - - // This is a workaround so that SQL can operate under default policy without actually - // granting permissions in assemblies that they disallow. - - internal bool IgnoreTypeLoadFailures - { - set { m_ignoreTypeLoadFailures = value; } - } - } -} -- cgit v1.2.3