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

  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.IO;
  18.     using System.Threading;
  19.     using System.Security;
  20.     using System.Security.Util;
  21.     using System.Security.Permissions;
  22.     using System.Collections;
  23.     using System.Text;
  24.     using System;
  25.     using IUnrestrictedPermission = System.Security.Permissions.IUnrestrictedPermission;
  26.    
  27.     [Serializable(), SecurityPermissionAttribute(SecurityAction.InheritanceDemand, ControlEvidence = true, ControlPolicy = true)]
  28.     [System.Runtime.InteropServices.ComVisible(true)]
  29.     public abstract class CodeAccessPermission : IPermission, ISecurityEncodable, IStackWalk
  30.     {
  31.         // Static methods for manipulation of stack
  32.         public static void RevertAssert()
  33.         {
  34.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  35.             SecurityRuntime.RevertAssert(ref stackMark);
  36.         }
  37.        
  38.         public static void RevertDeny()
  39.         {
  40.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  41.             SecurityRuntime.RevertDeny(ref stackMark);
  42.         }
  43.        
  44.         public static void RevertPermitOnly()
  45.         {
  46.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  47.             SecurityRuntime.RevertPermitOnly(ref stackMark);
  48.         }
  49.        
  50.         public static void RevertAll()
  51.         {
  52.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  53.             SecurityRuntime.RevertAll(ref stackMark);
  54.         }
  55.        
  56.         //
  57.         // Standard implementation of IPermission methods for
  58.         // code-access permissions.
  59.         //
  60.        
  61.         // Mark this method as requiring a security object on the caller's frame
  62.         // so the caller won't be inlined (which would mess up stack crawling).
  63.         [DynamicSecurityMethodAttribute()]
  64.         public void Demand()
  65.         {
  66.             if (!this.CheckDemand(null)) {
  67.                 StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller;
  68.                 CodeAccessSecurityEngine.Check(this, ref stackMark);
  69.             }
  70.         }
  71.        
  72.         [DynamicSecurityMethodAttribute()]
  73.         static internal void DemandInternal(PermissionType permissionType)
  74.         {
  75.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller;
  76.             CodeAccessSecurityEngine.SpecialDemand(permissionType, ref stackMark);
  77.         }
  78.        
  79.         // Metadata for this method should be flaged with REQ_SQ so that
  80.         // EE can allocate space on the stack frame for FrameSecurityDescriptor
  81.        
  82.         [DynamicSecurityMethodAttribute()]
  83.         public void Assert()
  84.         {
  85.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  86.             CodeAccessSecurityEngine.Assert(this, ref stackMark);
  87.         }
  88.        
  89.         [DynamicSecurityMethodAttribute()]
  90.         static internal void AssertAllPossible()
  91.         {
  92.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  93.             SecurityRuntime.AssertAllPossible(ref stackMark);
  94.         }
  95.        
  96.         // Metadata for this method should be flaged with REQ_SQ so that
  97.         // EE can allocate space on the stack frame for FrameSecurityDescriptor
  98.        
  99.         [DynamicSecurityMethodAttribute()]
  100.         public void Deny()
  101.         {
  102.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  103.             CodeAccessSecurityEngine.Deny(this, ref stackMark);
  104.         }
  105.        
  106.         // Metadata for this method should be flaged with REQ_SQ so that
  107.         // EE can allocate space on the stack frame for FrameSecurityDescriptor
  108.        
  109.         [DynamicSecurityMethodAttribute()]
  110.         public void PermitOnly()
  111.         {
  112.             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
  113.             CodeAccessSecurityEngine.PermitOnly(this, ref stackMark);
  114.         }
  115.        
  116.         // IPermission interfaces
  117.        
  118.         // We provide a default implementation of Union here.
  119.         // Any permission that doesn't provide its own representation
  120.         // of Union will get this one and trigger CompoundPermission
  121.         // We can take care of simple cases here...
  122.        
  123.         public virtual IPermission Union(IPermission other)
  124.         {
  125.             // The other guy could be null
  126.             if (other == null)
  127.                 return (this.Copy());
  128.            
  129.             // otherwise we don't support it.
  130.             throw new NotSupportedException(Environment.GetResourceString("NotSupported_SecurityPermissionUnion"));
  131.         }
  132.        
  133.         static internal SecurityElement CreatePermissionElement(IPermission perm, string permname)
  134.         {
  135.             SecurityElement root = new SecurityElement("IPermission");
  136.             XMLUtil.AddClassAttribute(root, perm.GetType(), permname);
  137.             // If you hit this assert then most likely you are trying to change the name of this class.
  138.             // This is ok as long as you change the hard coded string above and change the assert below.
  139.             BCLDebug.Assert(perm.GetType().FullName.Equals(permname), "Incorrect class name passed in! Was: " + permname + " Should be " + perm.GetType().FullName);
  140.            
  141.             root.AddAttribute("version", "1");
  142.             return root;
  143.         }
  144.        
  145.         static internal void ValidateElement(SecurityElement elem, IPermission perm)
  146.         {
  147.             if (elem == null)
  148.                 throw new ArgumentNullException("elem");
  149.            
  150.             if (!XMLUtil.IsPermissionElement(perm, elem))
  151.                 throw new ArgumentException(Environment.GetResourceString("Argument_NotAPermissionElement"));
  152.            
  153.             string version = elem.Attribute("version");
  154.            
  155.             if (version != null && !version.Equals("1"))
  156.                 throw new ArgumentException(Environment.GetResourceString("Argument_InvalidXMLBadVersion"));
  157.         }
  158.        
  159.         public abstract SecurityElement ToXml();
  160.         public abstract void FromXml(SecurityElement elem);
  161.        
  162.         //
  163.         // Unimplemented interface methods
  164.         // (as a reminder only)
  165.         //
  166.        
  167.         public override string ToString()
  168.         {
  169.             return ToXml().ToString();
  170.         }
  171.        
  172.         //
  173.         // HELPERS FOR IMPLEMENTING ABSTRACT METHODS
  174.         //
  175.        
  176.         //
  177.         // Protected helper
  178.         //
  179.        
  180.         internal bool VerifyType(IPermission perm)
  181.         {
  182.             // if perm is null, then obviously not of the same type
  183.             if ((perm == null) || (perm.GetType() != this.GetType())) {
  184.                 return (false);
  185.             }
  186.             else {
  187.                 return (true);
  188.             }
  189.         }
  190.        
  191.         // The IPermission Interface
  192.         public abstract IPermission Copy();
  193.         public abstract IPermission Intersect(IPermission target);
  194.         public abstract bool IsSubsetOf(IPermission target);
  195.        
  196.         [System.Runtime.InteropServices.ComVisible(false)]
  197.         public override bool Equals(object obj)
  198.         {
  199.             IPermission perm = obj as IPermission;
  200.             if (obj != null && perm == null)
  201.                 return false;
  202.             try {
  203.                 if (!this.IsSubsetOf(perm))
  204.                     return false;
  205.                 if (perm != null && !perm.IsSubsetOf(this))
  206.                     return false;
  207.             }
  208.             catch (ArgumentException) {
  209.                 // Any argument exception implies inequality
  210.                 // Note that we require a try/catch block here because we have to deal with
  211.                 // custom permissions that may throw exceptions indiscriminately.
  212.                 return false;
  213.             }
  214.             return true;
  215.         }
  216.        
  217.         [System.Runtime.InteropServices.ComVisible(false)]
  218.         public override int GetHashCode()
  219.         {
  220.             // This implementation is only to silence a compiler warning.
  221.             return base.GetHashCode();
  222.         }
  223.        
  224.        
  225.         internal bool CheckDemand(CodeAccessPermission grant)
  226.         {
  227.             BCLDebug.Assert(grant == null || grant.GetType().Equals(this.GetType()), "CheckDemand not defined for permissions of different type");
  228.             return IsSubsetOf(grant);
  229.         }
  230.        
  231.         internal bool CheckPermitOnly(CodeAccessPermission permitted)
  232.         {
  233.             BCLDebug.Assert(permitted == null || permitted.GetType().Equals(this.GetType()), "CheckPermitOnly not defined for permissions of different type");
  234.             return IsSubsetOf(permitted);
  235.         }
  236.        
  237.         internal bool CheckDeny(CodeAccessPermission denied)
  238.         {
  239.             BCLDebug.Assert(denied == null || denied.GetType().Equals(this.GetType()), "CheckDeny not defined for permissions of different type");
  240.             IPermission intersectPerm = Intersect(denied);
  241.             return (intersectPerm == null || intersectPerm.IsSubsetOf(null));
  242.         }
  243.        
  244.         internal bool CheckAssert(CodeAccessPermission asserted)
  245.         {
  246.             BCLDebug.Assert(asserted == null || asserted.GetType().Equals(this.GetType()), "CheckPermitOnly not defined for permissions of different type");
  247.             return IsSubsetOf(asserted);
  248.         }
  249.        
  250.         internal bool CanUnrestrictedOverride()
  251.         {
  252.             return CanUnrestrictedOverride(this);
  253.         }
  254.        
  255.         static internal bool CanUnrestrictedOverride(IPermission ip)
  256.         {
  257.             if (CodeAccessSecurityEngine.DoesFullTrustMeanFullTrust())
  258.                 return true;
  259.             if (ip is IUnrestrictedPermission)
  260.                 return true;
  261.             return false;
  262.         }
  263.     }
  264. }

Developer Fusion