The Labs \ Source Viewer \ SSCLI \ System.Security \ FrameSecurityDescriptor

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace System.Security
  16. {
  17.     using System.Text;
  18.     using System.Runtime.CompilerServices;
  19.     using System.Threading;
  20.     using System;
  21.     using System.Collections;
  22.     using System.Security.Permissions;
  23.     using System.Globalization;
  24.     using System.Runtime.ConstrainedExecution;
  25.     //FrameSecurityDescriptor.cs
  26.     //
  27.     // Internal use only.
  28.     // DO NOT DOCUMENT
  29.     //
  30.    
  31.     [Serializable()]
  32.     internal sealed class FrameSecurityDescriptor
  33.     {
  34.        
  35. /* EE has native FrameSecurityDescriptorObject definition in object.h
  36.             Make sure to update that structure as well, if you make any changes here.
  37.     */       
  38.         private PermissionSet m_assertions;
  39.         // imperative asserts
  40.         private PermissionSet m_denials;
  41.         // imperative denials
  42.         private PermissionSet m_restriction;
  43.         // imperative permitonlys
  44.         private PermissionSet m_DeclarativeAssertions;
  45.         private PermissionSet m_DeclarativeDenials;
  46.         private PermissionSet m_DeclarativeRestrictions;
  47.        
  48.        
  49.         private bool m_AssertFT;
  50.         private bool m_assertAllPossible;
  51.         #pragma warning disable 169
  52.         private bool m_declSecComputed;
  53.         // set from the VM to indicate that the declarative A/PO/D on this frame has been populated
  54.         #pragma warning restore 169
  55.        
  56.        
  57.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  58.         private static extern void IncrementOverridesCount();
  59.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  60.         private static extern void DecrementOverridesCount();
  61.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  62.         private static extern void IncrementAssertCount();
  63.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  64.         private static extern void DecrementAssertCount();
  65.        
  66.        
  67.         // Default constructor.
  68.         internal FrameSecurityDescriptor()
  69.         {
  70.             //m_flags = 0;
  71.         }
  72.         //-----------------------------------------------------------+
  73.         // H E L P E R
  74.         //-----------------------------------------------------------+
  75.        
  76.         private PermissionSet CreateSingletonSet(IPermission perm)
  77.         {
  78.             PermissionSet permSet = new PermissionSet(false);
  79.             permSet.AddPermission(perm.Copy());
  80.             return permSet;
  81.         }
  82.        
  83.         //-----------------------------------------------------------+
  84.         // A S S E R T
  85.         //-----------------------------------------------------------+
  86.        
  87.         internal bool HasImperativeAsserts()
  88.         {
  89.             // we store declarative actions in both fields, so check if they are different
  90.             return (m_assertions != null);
  91.         }
  92.         internal bool HasImperativeDenials()
  93.         {
  94.             // we store declarative actions in both fields, so check if they are different
  95.             return (m_denials != null);
  96.         }
  97.         internal bool HasImperativeRestrictions()
  98.         {
  99.             // we store declarative actions in both fields, so check if they are different
  100.             return (m_restriction != null);
  101.         }
  102.         internal void SetAssert(IPermission perm)
  103.         {
  104.             m_assertions = CreateSingletonSet(perm);
  105.             IncrementAssertCount();
  106.         }
  107.        
  108.         internal void SetAssert(PermissionSet permSet)
  109.         {
  110.             m_assertions = permSet.Copy();
  111.             m_AssertFT = m_AssertFT || (CodeAccessSecurityEngine.DoesFullTrustMeanFullTrust() && m_assertions.IsUnrestricted());
  112.             IncrementAssertCount();
  113.         }
  114.        
  115.         internal PermissionSet GetAssertions(bool fDeclarative)
  116.         {
  117.             return (fDeclarative) ? m_DeclarativeAssertions : m_assertions;
  118.         }
  119.        
  120.         internal void SetAssertAllPossible()
  121.         {
  122.             m_assertAllPossible = true;
  123.             IncrementAssertCount();
  124.         }
  125.        
  126.         internal bool GetAssertAllPossible()
  127.         {
  128.             return m_assertAllPossible;
  129.         }
  130.        
  131.         //-----------------------------------------------------------+
  132.         // D E N Y
  133.         //-----------------------------------------------------------+
  134.        
  135.         internal void SetDeny(IPermission perm)
  136.         {
  137.             m_denials = CreateSingletonSet(perm);
  138.             IncrementOverridesCount();
  139.            
  140.         }
  141.        
  142.         internal void SetDeny(PermissionSet permSet)
  143.         {
  144.             m_denials = permSet.Copy();
  145.             IncrementOverridesCount();
  146.         }
  147.        
  148.         internal PermissionSet GetDenials(bool fDeclarative)
  149.         {
  150.             return (fDeclarative) ? m_DeclarativeDenials : m_denials;
  151.         }
  152.        
  153.         //-----------------------------------------------------------+
  154.         // R E S T R I C T
  155.         //-----------------------------------------------------------+
  156.        
  157.         internal void SetPermitOnly(IPermission perm)
  158.         {
  159.             m_restriction = CreateSingletonSet(perm);
  160.             IncrementOverridesCount();
  161.         }
  162.        
  163.         internal void SetPermitOnly(PermissionSet permSet)
  164.         {
  165.             // permSet must not be null
  166.             m_restriction = permSet.Copy();
  167.             IncrementOverridesCount();
  168.         }
  169.        
  170.         internal PermissionSet GetPermitOnly(bool fDeclarative)
  171.         {
  172.            
  173.             return (fDeclarative) ? m_DeclarativeRestrictions : m_restriction;
  174.         }
  175.         //-----------------------------------------------------------+
  176.         // R E V E R T
  177.         //-----------------------------------------------------------+
  178.        
  179.         internal void RevertAssert()
  180.         {
  181.             if (m_assertions != null) {
  182.                 m_assertions = null;
  183.                 DecrementAssertCount();
  184.             }
  185.            
  186.            
  187.             if (m_DeclarativeAssertions != null) {
  188.                 m_AssertFT = (CodeAccessSecurityEngine.DoesFullTrustMeanFullTrust() && m_DeclarativeAssertions.IsUnrestricted());
  189.                 ;
  190.             }
  191.             else
  192.                 m_AssertFT = false;
  193.         }
  194.        
  195.         internal void RevertAssertAllPossible()
  196.         {
  197.             if (m_assertAllPossible) {
  198.                 m_assertAllPossible = false;
  199.                 DecrementAssertCount();
  200.             }
  201.         }
  202.        
  203.         internal void RevertDeny()
  204.         {
  205.             if (HasImperativeDenials()) {
  206.                 DecrementOverridesCount();
  207.                 m_denials = null;
  208.             }
  209.         }
  210.        
  211.         internal void RevertPermitOnly()
  212.         {
  213.             if (HasImperativeRestrictions()) {
  214.                 DecrementOverridesCount();
  215.                 m_restriction = null;
  216.                 ;
  217.             }
  218.         }
  219.        
  220.         internal void RevertAll()
  221.         {
  222.             RevertAssert();
  223.             RevertAssertAllPossible();
  224.             RevertDeny();
  225.             RevertPermitOnly();
  226.         }
  227.        
  228.        
  229.         //-----------------------------------------------------------+
  230.         // Demand Evaluation
  231.         //-----------------------------------------------------------+
  232.        
  233.        
  234.         // This will get called when we hit a FSD while evaluating a demand on the call stack or compressedstack
  235.         internal bool CheckDemand(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandle rmh)
  236.         {
  237.             // imperative security
  238.             bool fContinue = CheckDemand2(demand, permToken, rmh, false);
  239.             if (fContinue == SecurityRuntime.StackContinue) {
  240.                 // declarative security
  241.                 fContinue = CheckDemand2(demand, permToken, rmh, true);
  242.             }
  243.             return fContinue;
  244.         }
  245.        
  246.         internal bool CheckDemand2(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandle rmh, bool fDeclarative)
  247.         {
  248.             PermissionSet permSet;
  249.            
  250.             // If the demand is null, there is no need to continue
  251.             BCLDebug.Assert(demand != null && !demand.CheckDemand(null), "Empty demands should have been filtered out by this point");
  252.            
  253.             // decode imperative
  254.             if (GetPermitOnly(fDeclarative) != null)
  255.                 GetPermitOnly(fDeclarative).CheckDecoded(demand, permToken);
  256.            
  257.             if (GetDenials(fDeclarative) != null)
  258.                 GetDenials(fDeclarative).CheckDecoded(demand, permToken);
  259.            
  260.             if (GetAssertions(fDeclarative) != null)
  261.                 GetAssertions(fDeclarative).CheckDecoded(demand, permToken);
  262.            
  263.             // NOTE: See notes about exceptions and exception handling in FrameDescSetHelper
  264.            
  265.             bool bThreadSecurity = SecurityManager._SetThreadSecurity(false);
  266.            
  267.             // Check Reduction
  268.            
  269.             try {
  270.                 permSet = GetPermitOnly(fDeclarative);
  271.                 if (permSet != null) {
  272.                     CodeAccessPermission perm = (CodeAccessPermission)permSet.GetPermission(demand);
  273.                    
  274.                     // If the permit only set does not contain the demanded permission, throw a security exception
  275.                     if (perm == null) {
  276.                         if (!(permSet.IsUnrestricted() && demand.CanUnrestrictedOverride()))
  277.                             throw new SecurityException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), null, permSet, SecurityRuntime.GetMethodInfo(rmh), demand, demand);
  278.                     }
  279.                     else {
  280.                         bool bNeedToThrow = true;
  281.                        
  282.                         try {
  283.                             bNeedToThrow = !demand.CheckPermitOnly(perm);
  284.                         }
  285.                         catch (ArgumentException) {
  286.                         }
  287.                        
  288.                         if (bNeedToThrow)
  289.                             throw new SecurityException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), null, permSet, SecurityRuntime.GetMethodInfo(rmh), demand, demand);
  290.                     }
  291.                 }
  292.                
  293.                 // Check Denials
  294.                
  295.                 permSet = GetDenials(fDeclarative);
  296.                 if (permSet != null) {
  297.                     CodeAccessPermission perm = (CodeAccessPermission)permSet.GetPermission(demand);
  298.                    
  299.                     // If an unrestricted set was denied and the demand implements IUnrestricted
  300.                     if (permSet.IsUnrestricted() && demand.CanUnrestrictedOverride())
  301.                         throw new SecurityException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), permSet, null, SecurityRuntime.GetMethodInfo(rmh), demand, demand);
  302.                    
  303.                     // If the deny set does contain the demanded permission, throw a security exception
  304.                     bool bNeedToThrow = true;
  305.                     try {
  306.                         bNeedToThrow = !demand.CheckDeny(perm);
  307.                     }
  308.                     catch (ArgumentException) {
  309.                     }
  310.                     if (bNeedToThrow)
  311.                         throw new SecurityException(String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Security_Generic"), demand.GetType().AssemblyQualifiedName), permSet, null, SecurityRuntime.GetMethodInfo(rmh), demand, demand);
  312.                 }
  313.                
  314.                 if (GetAssertAllPossible()) {
  315.                     return SecurityRuntime.StackHalt;
  316.                 }
  317.                
  318.                 permSet = GetAssertions(fDeclarative);
  319.                 // Check Assertions
  320.                 if (permSet != null) {
  321.                    
  322.                     CodeAccessPermission perm = (CodeAccessPermission)permSet.GetPermission(demand);
  323.                    
  324.                     // If the assert set does contain the demanded permission, halt the stackwalk
  325.                    
  326.                     try {
  327.                         if ((permSet.IsUnrestricted() && demand.CanUnrestrictedOverride()) || (demand.CheckAssert(perm))) {
  328.                             return SecurityRuntime.StackHalt;
  329.                         }
  330.                     }
  331.                     catch (ArgumentException) {
  332.                     }
  333.                 }
  334.                
  335.             }
  336.             finally {
  337.                 if (bThreadSecurity)
  338.                     SecurityManager._SetThreadSecurity(true);
  339.             }
  340.            
  341.             return SecurityRuntime.StackContinue;
  342.         }
  343.        
  344.         internal bool CheckSetDemand(PermissionSet demandSet, out PermissionSet alteredDemandSet, RuntimeMethodHandle rmh)
  345.         {
  346.             // imperative security
  347.             PermissionSet altPset1 = null;
  348.             PermissionSet altPset2 = null;
  349.             bool fContinue = CheckSetDemand2(demandSet, out altPset1, rmh, false);
  350.             if (altPset1 != null) {
  351.                 demandSet = altPset1;
  352.             }
  353.            
  354.             if (fContinue == SecurityRuntime.StackContinue) {
  355.                 // declarative security
  356.                 fContinue = CheckSetDemand2(demandSet, out altPset2, rmh, true);
  357.             }
  358.             // Return the most recent altered set
  359.             // If both declarative and imperative asserts modified the demand set: return altPset2
  360.             // Else if imperative asserts modified the demand set: return altPset1
  361.             // else no alteration: return null
  362.             if (altPset2 != null)
  363.                 alteredDemandSet = altPset2;
  364.             else if (altPset1 != null)
  365.                 alteredDemandSet = altPset1;
  366.             else
  367.                 alteredDemandSet = null;
  368.            
  369.             return fContinue;
  370.         }
  371.        
  372.         internal bool CheckSetDemand2(PermissionSet demandSet, out PermissionSet alteredDemandSet, RuntimeMethodHandle rmh, bool fDeclarative)
  373.         {
  374.             PermissionSet permSet;
  375.            
  376.             // In the common case we are not going to alter the demand set, so just to
  377.             // be safe we'll set it to null up front.
  378.             alteredDemandSet = null;
  379.            
  380.             // There's some oddness in here to deal with exceptions. The general idea behind
  381.             // this is that we need some way of dealing with custom permissions that may not
  382.             // handle all possible scenarios of Union(), Intersect(), and IsSubsetOf() properly
  383.             // (they don't support it, throw null reference exceptions, etc.).
  384.            
  385.             // An empty demand always succeeds.
  386.             if (demandSet == null || demandSet.IsEmpty())
  387.                 return SecurityRuntime.StackHalt;
  388.            
  389.             if (GetPermitOnly(fDeclarative) != null)
  390.                 GetPermitOnly(fDeclarative).CheckDecoded(demandSet);
  391.             if (GetDenials(fDeclarative) != null)
  392.                 GetDenials(fDeclarative).CheckDecoded(demandSet);
  393.             if (GetAssertions(fDeclarative) != null)
  394.                 GetAssertions(fDeclarative).CheckDecoded(demandSet);
  395.            
  396.            
  397.             bool bThreadSecurity = SecurityManager._SetThreadSecurity(false);
  398.            
  399.             try {
  400.                 // In the case of permit only, we define an exception to be failure of the check
  401.                 // and therefore we throw a security exception.
  402.                
  403.                 permSet = GetPermitOnly(fDeclarative);
  404.                 if (permSet != null) {
  405.                     IPermission permFailed = null;
  406.                     bool bNeedToThrow = true;
  407.                    
  408.                     try {
  409.                         bNeedToThrow = !demandSet.CheckPermitOnly(permSet, out permFailed);
  410.                     }
  411.                     catch (ArgumentException) {
  412.                     }
  413.                     if (bNeedToThrow)
  414.                         throw new SecurityException(Environment.GetResourceString("Security_GenericNoType"), null, permSet, SecurityRuntime.GetMethodInfo(rmh), demandSet, permFailed);
  415.                 }
  416.                
  417.                 // In the case of denial, we define an exception to be failure of the check
  418.                 // and therefore we throw a security exception.
  419.                
  420.                 permSet = GetDenials(fDeclarative);
  421.                
  422.                
  423.                 if (permSet != null) {
  424.                     IPermission permFailed = null;
  425.                    
  426.                     bool bNeedToThrow = true;
  427.                    
  428.                     try {
  429.                         bNeedToThrow = !demandSet.CheckDeny(permSet, out permFailed);
  430.                     }
  431.                     catch (ArgumentException) {
  432.                     }
  433.                    
  434.                     if (bNeedToThrow)
  435.                         throw new SecurityException(Environment.GetResourceString("Security_GenericNoType"), permSet, null, SecurityRuntime.GetMethodInfo(rmh), demandSet, permFailed);
  436.                 }
  437.                
  438.                 // The assert case is more complex. Since asserts have the ability to "bleed through"
  439.                 // (where part of a demand is handled by an assertion, but the rest is passed on to
  440.                 // continue the stackwalk), we need to be more careful in handling the "failure" case.
  441.                 // Therefore, if an exception is thrown in performing any operation, we make sure to keep
  442.                 // that permission in the demand set thereby continuing the demand for that permission
  443.                 // walking down the stack.
  444.                
  445.                 if (GetAssertAllPossible()) {
  446.                     return SecurityRuntime.StackHalt;
  447.                 }
  448.                
  449.                 permSet = GetAssertions(fDeclarative);
  450.                 if (permSet != null) {
  451.                     // If this frame asserts a superset of the demand set we're done
  452.                    
  453.                     if (demandSet.CheckAssertion(permSet))
  454.                         return SecurityRuntime.StackHalt;
  455.                    
  456.                     // Determine whether any of the demand set asserted. We do this by
  457.                     // copying the demand set and removing anything in it that is asserted.
  458.                    
  459.                     if (!permSet.IsUnrestricted()) {
  460.                         PermissionSet.RemoveAssertedPermissionSet(demandSet, permSet, out alteredDemandSet);
  461.                     }
  462.                 }
  463.                
  464.             }
  465.             finally {
  466.                 if (bThreadSecurity)
  467.                     SecurityManager._SetThreadSecurity(true);
  468.             }
  469.            
  470.             return SecurityRuntime.StackContinue;
  471.         }
  472.     }
  473. }

Developer Fusion