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

  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. /*=============================================================================
  16. **
  17. ** Class: PermissionSetTriple
  18. **
  19. ** Purpose: Container class for holding an AppDomain's Grantset and Refused sets.
  20. **          Also used for CompressedStacks which brings in the third PermissionSet.
  21. **          Hence, the name PermissionSetTriple.
  22. **
  23. =============================================================================*/
  24. namespace System.Security
  25. {
  26.     using IEnumerator = System.Collections.IEnumerator;
  27.     using System.Security;
  28.     using System.Security.Permissions;
  29.     using System.Runtime.InteropServices;
  30.    
  31.    
  32.     [Serializable()]
  33.     internal sealed class PermissionSetTriple
  34.     {
  35.         unsafe private static RuntimeMethodHandle s_emptyRMH = new RuntimeMethodHandle(null);
  36.         private static PermissionToken s_zoneToken;
  37.         private static PermissionToken s_urlToken;
  38.         internal PermissionSet AssertSet;
  39.         internal PermissionSet GrantSet;
  40.         internal PermissionSet RefusedSet;
  41.        
  42.         internal PermissionSetTriple()
  43.         {
  44.             Reset();
  45.         }
  46.         internal PermissionSetTriple(PermissionSetTriple triple)
  47.         {
  48.             this.AssertSet = triple.AssertSet;
  49.             this.GrantSet = triple.GrantSet;
  50.             this.RefusedSet = triple.RefusedSet;
  51.         }
  52.         internal void Reset()
  53.         {
  54.             AssertSet = null;
  55.             GrantSet = null;
  56.             RefusedSet = null;
  57.         }
  58.         internal bool IsEmpty()
  59.         {
  60.             return (AssertSet == null && GrantSet == null && RefusedSet == null);
  61.         }
  62.        
  63.         private PermissionToken ZoneToken {
  64.             get {
  65.                 if (s_zoneToken == null)
  66.                     s_zoneToken = PermissionToken.GetToken(typeof(ZoneIdentityPermission));
  67.                 return s_zoneToken;
  68.             }
  69.         }
  70.         private PermissionToken UrlToken {
  71.             get {
  72.                 if (s_urlToken == null)
  73.                     s_urlToken = PermissionToken.GetToken(typeof(UrlIdentityPermission));
  74.                 return s_urlToken;
  75.             }
  76.         }
  77.         internal bool Update(PermissionSetTriple psTriple, out PermissionSetTriple retTriple)
  78.         {
  79.             retTriple = null;
  80.             // Special case: unrestricted assert. Note: dcs.Assert.IsUnrestricted => dcs.Grant.IsUnrestricted
  81.             if (psTriple.AssertSet != null && psTriple.AssertSet.IsUnrestricted()) {
  82.                 return true;
  83.                 // stop construction
  84.             }
  85.             retTriple = UpdateAssert(psTriple.AssertSet);
  86.             UpdateGrant(psTriple.GrantSet);
  87.             UpdateRefused(psTriple.RefusedSet);
  88.             return false;
  89.         }
  90.        
  91.         internal PermissionSetTriple UpdateAssert(PermissionSet in_a)
  92.         {
  93.             PermissionSetTriple retTriple = null;
  94.             if (in_a != null) {
  95.                 BCLDebug.Assert((!in_a.IsUnrestricted()), "Cannot be unrestricted here");
  96.                 // if we're already asserting in_a, nothing to do
  97.                 if (in_a.IsSubsetOf(AssertSet))
  98.                     return null;
  99.                
  100.                 PermissionSet retPs;
  101.                 if (GrantSet != null)
  102.                     retPs = in_a.Intersect(GrantSet);
  103.                 // Restrict the assert to what we've already been granted
  104.                 else {
  105.                     GrantSet = new PermissionSet(true);
  106.                     retPs = in_a.Copy();
  107.                     // Currently unrestricted Grant: assert the whole assert set
  108.                 }
  109.                 bool bFailedToCompress;
  110.                 // removes anything that is already in the refused set from the assert set
  111.                 retPs = PermissionSet.RemoveRefusedPermissionSet(retPs, RefusedSet, out bFailedToCompress);
  112.                 if (!bFailedToCompress)
  113.                     bFailedToCompress = PermissionSet.IsIntersectingAssertedPermissions(retPs, AssertSet);
  114.                 if (bFailedToCompress) {
  115.                     retTriple = new PermissionSetTriple(this);
  116.                     this.Reset();
  117.                     this.GrantSet = retTriple.GrantSet.Copy();
  118.                 }
  119.                
  120.                 if (AssertSet == null)
  121.                     AssertSet = retPs;
  122.                 else
  123.                     AssertSet.InplaceUnion(retPs);
  124.                
  125.             }
  126.             return retTriple;
  127.         }
  128.         internal void UpdateGrant(PermissionSet in_g, out ZoneIdentityPermission z, out UrlIdentityPermission u)
  129.         {
  130.             z = null;
  131.             u = null;
  132.             if (in_g != null) {
  133.                 if (GrantSet == null)
  134.                     GrantSet = in_g.Copy();
  135.                 else
  136.                     GrantSet.InplaceIntersect(in_g);
  137.                
  138.                 z = (ZoneIdentityPermission)in_g.GetPermission(ZoneToken);
  139.                 u = (UrlIdentityPermission)in_g.GetPermission(UrlToken);
  140.             }
  141.         }
  142.        
  143.         internal void UpdateGrant(PermissionSet in_g)
  144.         {
  145.             if (in_g != null) {
  146.                 if (GrantSet == null)
  147.                     GrantSet = in_g.Copy();
  148.                 else
  149.                     GrantSet.InplaceIntersect(in_g);
  150.             }
  151.         }
  152.         internal void UpdateRefused(PermissionSet in_r)
  153.         {
  154.             if (in_r != null) {
  155.                 if (RefusedSet == null)
  156.                     RefusedSet = in_r.Copy();
  157.                 else
  158.                     RefusedSet.InplaceUnion(in_r);
  159.             }
  160.         }
  161.        
  162.        
  163.         static bool CheckAssert(PermissionSet pSet, CodeAccessPermission demand, PermissionToken permToken)
  164.         {
  165.             if (pSet != null) {
  166.                 pSet.CheckDecoded(demand, permToken);
  167.                
  168.                 CodeAccessPermission perm = (CodeAccessPermission)pSet.GetPermission(demand);
  169.                
  170.                 // If the assert set does contain the demanded permission, halt the stackwalk
  171.                
  172.                 try {
  173.                     if ((pSet.IsUnrestricted() && demand.CanUnrestrictedOverride()) || demand.CheckAssert(perm)) {
  174.                         return SecurityRuntime.StackHalt;
  175.                     }
  176.                 }
  177.                 catch (ArgumentException) {
  178.                 }
  179.             }
  180.             return SecurityRuntime.StackContinue;
  181.         }
  182.        
  183.         static bool CheckAssert(PermissionSet assertPset, PermissionSet demandSet, out PermissionSet newDemandSet)
  184.         {
  185.             newDemandSet = null;
  186.             if (assertPset != null) {
  187.                 assertPset.CheckDecoded(demandSet);
  188.                 // If this frame asserts a superset of the demand set we're done
  189.                
  190.                 if (demandSet.CheckAssertion(assertPset))
  191.                     return SecurityRuntime.StackHalt;
  192.                 PermissionSet.RemoveAssertedPermissionSet(demandSet, assertPset, out newDemandSet);
  193.             }
  194.             return SecurityRuntime.StackContinue;
  195.         }
  196.        
  197.        
  198.         internal bool CheckDemand(CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandle rmh)
  199.         {
  200.             if (CheckAssert(AssertSet, demand, permToken) == SecurityRuntime.StackHalt)
  201.                 return SecurityRuntime.StackHalt;
  202.            
  203.             CodeAccessSecurityEngine.CheckHelper(GrantSet, RefusedSet, demand, permToken, rmh, null, SecurityAction.Demand, true);
  204.            
  205.             return SecurityRuntime.StackContinue;
  206.         }
  207.         internal bool CheckSetDemand(PermissionSet demandSet, out PermissionSet alteredDemandset, RuntimeMethodHandle rmh)
  208.         {
  209.             alteredDemandset = null;
  210.            
  211.             if (CheckAssert(AssertSet, demandSet, out alteredDemandset) == SecurityRuntime.StackHalt)
  212.                 return SecurityRuntime.StackHalt;
  213.             if (alteredDemandset != null)
  214.                 demandSet = alteredDemandset;
  215.             // note that this does not modify demandSet external to this function.
  216.             CodeAccessSecurityEngine.CheckSetHelper(GrantSet, RefusedSet, demandSet, rmh, null, SecurityAction.Demand, true);
  217.            
  218.             return SecurityRuntime.StackContinue;
  219.            
  220.         }
  221.        
  222.         internal bool CheckDemandNoThrow(CodeAccessPermission demand, PermissionToken permToken)
  223.         {
  224.             BCLDebug.Assert(AssertSet == null, "AssertSet not null");
  225.            
  226.             return CodeAccessSecurityEngine.CheckHelper(GrantSet, RefusedSet, demand, permToken, s_emptyRMH, null, SecurityAction.Demand, false);
  227.         }
  228.         internal bool CheckSetDemandNoThrow(PermissionSet demandSet)
  229.         {
  230.             BCLDebug.Assert(AssertSet == null, "AssertSet not null");
  231.            
  232.             return CodeAccessSecurityEngine.CheckSetHelper(GrantSet, RefusedSet, demandSet, s_emptyRMH, null, SecurityAction.Demand, false);
  233.         }
  234.     }
  235. }

Developer Fusion