FrameSecurityDescriptor.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / clr / src / BCL / System / Security / FrameSecurityDescriptor.cs / 2 / FrameSecurityDescriptor.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
namespace System.Security {
    using System.Text; 
    using System.Runtime.CompilerServices; 
    using System.Threading;
    using System; 
    using System.Collections;
    using System.Security.Permissions;
    using System.Globalization;
    using System.Runtime.ConstrainedExecution; 
#if !FEATURE_PAL
    using Microsoft.Win32.SafeHandles; 
    using System.Security.Principal; 
#endif
     //FrameSecurityDescriptor.cs 
    //
    // Internal use only.
    // DO NOT DOCUMENT
    // 

    [Serializable()] 
    sealed internal class FrameSecurityDescriptor 
    {
 
      /* EE has native FrameSecurityDescriptorObject definition in object.h
              Make sure to update that structure as well, if you make any changes here.
      */
        private PermissionSet       m_asserttions;    // imperative assertts 
        private PermissionSet       m_denials;      // imperative denials
        private PermissionSet       m_restriction;      // imperative permitonlys 
        private PermissionSet       m_DeclarativeAssertions; 
        private PermissionSet       m_DeclarativeDenials;
        private PermissionSet       m_DeclarativeRestrictions; 

#if !FEATURE_PAL
        // if this frame contains a call to any WindowsIdentity.Impersonate(),
        // we save the previous SafeTokenHandles here (in the next two fields) 
        // Used during exceptionstackwalks to revert impersonation before calling filters
        [NonSerialized] 
        private SafeTokenHandle     m_callerToken; 
        [NonSerialized]
        private SafeTokenHandle     m_impToken; 
#endif

        private bool                m_AssertFT;
        private bool                m_asserttAllPossible; 
#pragma warning disable 169
        private bool                m_declSecComputed; // set from the VM to indicate that the declarative A/PO/D on this frame has been populated 
#pragma warning restore 169 

 

        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private static extern void IncrementOverridesCount();
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private static extern void DecrementOverridesCount();
        [MethodImplAttribute(MethodImplOptions.InternalCall)] 
        private static extern void IncrementAssertCount(); 
        [MethodImplAttribute(MethodImplOptions.InternalCall)]
        private static extern void DecrementAssertCount(); 


        // Default constructor.
        internal FrameSecurityDescriptor() 
        {
            //m_flags = 0; 
        } 
        //------------------------------------------------------------+
        // H E L P E R 
        //-----------------------------------------------------------+

        private PermissionSet CreateSingletonSet(IPermission perm)
        { 
            PermissionSet permSet = new PermissionSet(false);
            permSet.AddPermission(perm.Copy()); 
            return permSet; 
        }
 
        //-----------------------------------------------------------+
        // A S S E R T
        //-----------------------------------------------------------+
 
        internal bool HasImperativeAsserts()
        { 
         // we store declarative actions in both fields, so 
            return (m_asserttions != null);
        } 
        internal bool HasImperativeDenials()
        {
            // we store declarative actions in both fields, so
            return (m_denials != null); 
        }
        internal bool HasImperativeRestrictions() 
        { 
            // we store declarative actions in both fields, so
            return (m_restriction != null); 
        }
        internal void SetAssert(IPermission perm)
        {
            m_asserttions = CreateSingletonSet(perm); 
            IncrementAssertCount();
        } 
 
        internal void SetAssert(PermissionSet permSet)
        { 
            m_asserttions = permSet.Copy();
            m_AssertFT = m_AssertFT || (CodeAccessSecurityEngine.DoesFullTrustMeanFullTrust() && m_asserttions.IsUnrestricted());
            IncrementAssertCount();
        } 

        internal PermissionSet GetAssertions(bool fDeclarative) 
        { 
            return (fDeclarative) ? m_DeclarativeAssertions : m_asserttions;
        } 

        internal void SetAssertAllPossible()
        {
            m_asserttAllPossible = true; 
            IncrementAssertCount();
        } 
 
        internal bool GetAssertAllPossible()
        { 
            return m_asserttAllPossible;
        }

        //------------------------------------------------------------+ 
        // D E N Y
        //-----------------------------------------------------------+ 
 
        internal void SetDeny(IPermission perm)
        { 
            m_denials = CreateSingletonSet(perm);
            IncrementOverridesCount();

        } 

        internal void SetDeny(PermissionSet permSet) 
        { 
            m_denials = permSet.Copy();
            IncrementOverridesCount(); 
        }

        internal PermissionSet GetDenials(bool fDeclarative)
        { 
            return (fDeclarative) ? m_DeclarativeDenials: m_denials;
        } 
 
        //------------------------------------------------------------+
        // R E S T R I C T 
        //------------------------------------------------------------+

        internal void SetPermitOnly(IPermission perm)
        { 
            m_restriction  = CreateSingletonSet(perm);
            IncrementOverridesCount(); 
        } 

        internal void SetPermitOnly(PermissionSet permSet) 
        {
            // permSet must not be null
            m_restriction  = permSet.Copy();
            IncrementOverridesCount(); 
        }
 
        internal PermissionSet GetPermitOnly(bool fDeclarative) 
        {
 
            return (fDeclarative) ? m_DeclarativeRestrictions : m_restriction;
        }
#if !FEATURE_PAL
        //-----------------------------------------------------------+ 
        // SafeTokenHandle (Impersonation + EH purposes)
        //------------------------------------------------------------+ 
        internal void SetTokenHandles (SafeTokenHandle callerToken, SafeTokenHandle impToken) 
        {
            m_callerToken = callerToken; 
            m_impToken = impToken;
        }
#endif
        //-----------------------------------------------------------+ 
        // R E V E R T
        //-----------------------------------------------------------+ 
 
        internal void RevertAssert()
        { 
            if (m_asserttions != null)
            {
            m_asserttions = null;
                DecrementAssertCount(); 
            }
 
 
            if (m_DeclarativeAssertions != null)
            { 
                m_AssertFT = (CodeAccessSecurityEngine.DoesFullTrustMeanFullTrust() && m_DeclarativeAssertions.IsUnrestricted());;
             }
            else
                m_AssertFT = false; 
        }
 
        internal void RevertAssertAllPossible() 
        {
            if (m_asserttAllPossible) 
            {
            m_asserttAllPossible = false;
                DecrementAssertCount();
            } 
        }
 
        internal void RevertDeny() 
        {
            if (HasImperativeDenials()) 
            {
                DecrementOverridesCount();
                m_denials = null;
            } 
        }
 
        internal void RevertPermitOnly() 
        {
            if (HasImperativeRestrictions()) 
            {
                DecrementOverridesCount();
                m_restriction= null;;
            } 
        }
 
        internal void RevertAll() 
        {
            RevertAssert(); 
            RevertAssertAllPossible();
            RevertDeny();
            RevertPermitOnly();
        } 

 
        //-----------------------------------------------------------+ 
        // Demand Evaluation
        //------------------------------------------------------------+ 


        // This will get called when we hit a FSD while evaluating a demand on the call stack or compressedstack
        internal bool CheckDemand(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandle rmh) 
        {
            // imperative security 
            bool fContinue = CheckDemand2(demand, permToken, rmh, false); 
            if (fContinue == SecurityRuntime.StackContinue)
            { 
                // declarative security
                fContinue = CheckDemand2(demand, permToken, rmh, true);
            }
            return fContinue; 
        }
 
        internal bool CheckDemand2(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandle rmh, bool fDeclarative) 
        {
            PermissionSet permSet; 

            // If the demand is null, there is no need to continue
            BCLDebug.Assert(demand != null && !demand.CheckDemand(null), "Empty demands should have been filtered out by this point");
 
            // decode imperative
            if (GetPermitOnly(fDeclarative) != null) 
                GetPermitOnly(fDeclarative).CheckDecoded(demand, permToken); 

            if (GetDenials(fDeclarative) != null) 
                GetDenials(fDeclarative).CheckDecoded(demand, permToken);

            if (GetAssertions(fDeclarative) != null)
                GetAssertions(fDeclarative).CheckDecoded(demand, permToken); 

            // 
 
            bool bThreadSecurity = SecurityManager._SetThreadSecurity(false);
 
            // Check Reduction

            try
            { 
                permSet = GetPermitOnly(fDeclarative);
                if (permSet != null) 
                { 
                    CodeAccessPermission perm = (CodeAccessPermission)permSet.GetPermission(demand);
 
                    // If the permit only set does not contain the demanded permission, throw a security exception
                    if (perm == null)
                    {
                        if(!(permSet.IsUnrestricted() && demand.CanUnrestrictedOverride())) 
                            throw new SecurityException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), null, permSet, SecurityRuntime.GetMethodInfo(rmh), demand, demand);
                    } 
                    else 
                    {
                        bool bNeedToThrow = true; 

                        try
                        {
                            bNeedToThrow = !demand.CheckPermitOnly(perm); 
                        }
                        catch (ArgumentException) 
                        { 
                        }
 
                        if (bNeedToThrow)
                            throw new SecurityException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), null, permSet, SecurityRuntime.GetMethodInfo(rmh), demand, demand);
                    }
                } 

                // Check Denials 
 
                permSet = GetDenials(fDeclarative);
                if (permSet != null) 
                {
                    CodeAccessPermission perm = (CodeAccessPermission)permSet.GetPermission(demand);

                    // If an unrestricted set was denied and the demand implements IUnrestricted 
                    if (permSet.IsUnrestricted() && demand.CanUnrestrictedOverride())
                        throw new SecurityException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), permSet, null, SecurityRuntime.GetMethodInfo(rmh), demand, demand); 
 
                    // If the deny set does contain the demanded permission, throw a security exception
                    bool bNeedToThrow = true; 
                    try
                    {
                        bNeedToThrow = !demand.CheckDeny(perm);
                    } 
                    catch (ArgumentException)
                    { 
                    } 
                    if (bNeedToThrow)
                        throw new SecurityException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), permSet, null, SecurityRuntime.GetMethodInfo(rmh), demand, demand); 
                }

                if (GetAssertAllPossible())
                { 
                    return SecurityRuntime.StackHalt;
                } 
 
                permSet = GetAssertions(fDeclarative);
                // Check Assertions 
                if (permSet != null)
                {

                    CodeAccessPermission perm = (CodeAccessPermission)permSet.GetPermission(demand); 

                    // If the assertt set does contain the demanded permission, halt the stackwalk 
 
                    try
                    { 
                        if ((permSet.IsUnrestricted() && demand.CanUnrestrictedOverride()) || (demand.CheckAssert(perm)))
                        {
                            return SecurityRuntime.StackHalt;
                        } 
                    }
                    catch (ArgumentException) 
                    { 
                    }
                } 

            }
            finally
            { 
                if (bThreadSecurity)
                    SecurityManager._SetThreadSecurity(true); 
            } 

            return SecurityRuntime.StackContinue; 
        }

        internal bool CheckSetDemand(PermissionSet demandSet,
                                                                   out PermissionSet alteredDemandSet, 
                                                                   RuntimeMethodHandle rmh)
        { 
            // imperative security 
            PermissionSet altPset1 = null, altPset2 = null;
            bool fContinue = CheckSetDemand2(demandSet, out altPset1, rmh, false); 
            if (altPset1 != null)
            {
                demandSet = altPset1;
            } 

            if (fContinue == SecurityRuntime.StackContinue) 
            { 
                // declarative security
                fContinue = CheckSetDemand2(demandSet, out altPset2, rmh, true); 
            }
            // Return the most recent altered set
            // If both declarative and imperative assertts modified the demand set: return altPset2
            // Else if imperative assertts modified the demand set: return altPset1 
            // else no alteration: return null
            if (altPset2 != null) 
                alteredDemandSet = altPset2; 
            else if (altPset1 != null)
                alteredDemandSet = altPset1; 
            else
                alteredDemandSet = null;

            return fContinue; 
        }
 
        internal bool CheckSetDemand2(PermissionSet demandSet, 
                                                                   out PermissionSet alteredDemandSet,
                                                                   RuntimeMethodHandle rmh, bool fDeclarative) 
        {
            PermissionSet permSet;

            // In the common case we are not going to alter the demand set, so just to 
            // be safe we'll set it to null up front.
            alteredDemandSet = null; 
 
            // There's some oddness in here to deal with exceptions.  The general idea behind
            // this is that we need some way of dealing with custom permissions that may not 
            // handle all possible scenarios of Union(), Intersect(), and IsSubsetOf() properly
            // (they don't support it, throw null reference exceptions, etc.).

            // An empty demand always succeeds. 
            if (demandSet == null || demandSet.IsEmpty())
                return SecurityRuntime.StackHalt; 
 
            if (GetPermitOnly(fDeclarative) != null)
                GetPermitOnly(fDeclarative).CheckDecoded( demandSet ); 
            if (GetDenials(fDeclarative) != null)
                GetDenials(fDeclarative).CheckDecoded( demandSet );
            if (GetAssertions(fDeclarative) != null)
                GetAssertions(fDeclarative).CheckDecoded( demandSet ); 

 
            bool bThreadSecurity = SecurityManager._SetThreadSecurity(false); 

            try 
            {
                // In the case of permit only, we define an exception to be failure of the

 
                permSet = GetPermitOnly(fDeclarative);
                if (permSet != null) 
                { 
                    IPermission permFailed = null;
                    bool bNeedToThrow = true; 

                    try
                    {
                        bNeedToThrow = !demandSet.CheckPermitOnly(permSet, out permFailed); 
                    }
                    catch (ArgumentException) 
                    { 
                    }
                    if (bNeedToThrow) 
                        throw new SecurityException(Environment.GetResourceString("Security_GenericNoType"), null, permSet, SecurityRuntime.GetMethodInfo(rmh), demandSet, permFailed);
                }

                // In the case of denial, we define an exception to be failure of the 

 
                permSet = GetDenials(fDeclarative); 

 
                if (permSet != null)
                {
                    IPermission permFailed = null;
 
                    bool bNeedToThrow = true;
 
                    try 
                    {
                        bNeedToThrow = !demandSet.CheckDeny(permSet, out permFailed); 
                    }
                    catch (ArgumentException)
                    {
                    } 

                    if (bNeedToThrow) 
                        throw new SecurityException(Environment.GetResourceString("Security_GenericNoType"), permSet, null, SecurityRuntime.GetMethodInfo(rmh), demandSet, permFailed); 
                }
 
                // The assertt case is more complex.  Since assertts have the ability to "bleed through"
                // (where part of a demand is handled by an asserttion, but the rest is passed on to
                // continue the stackwalk), we need to be more careful in handling the "failure" case.
                // Therefore, if an exception is thrown in performing any operation, we make sure to keep 
                // that permission in the demand set thereby continuing the demand for that permission
                // walking down the stack. 
 
                if (GetAssertAllPossible())
                { 
                    return SecurityRuntime.StackHalt;
                }

                permSet = GetAssertions(fDeclarative); 
                if (permSet != null)
                { 
                    // If this frame assertts a superset of the demand set we're done 

                    if (demandSet.CheckAssertion( permSet )) 
                        return SecurityRuntime.StackHalt;

                    // Determine whether any of the demand set assertted.  We do this by
                    // copying the demand set and removing anything in it that is assertted. 

                    if (!permSet.IsUnrestricted()) 
                    { 
                        PermissionSet.RemoveAssertedPermissionSet(demandSet, permSet, out alteredDemandSet);
                    } 
                }

                        }
            finally 
            {
                if (bThreadSecurity) 
                    SecurityManager._SetThreadSecurity(true); 
            }
 
            return SecurityRuntime.StackContinue;
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK