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

  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;
  18.     using System.Threading;
  19.     using System.Security.Util;
  20.     using System.Collections;
  21.     using System.Runtime.CompilerServices;
  22.     using System.Security.Permissions;
  23.     using System.Reflection;
  24.     using System.Globalization;
  25.     using System.Security.Policy;
  26.     using System.Runtime.Versioning;
  27.    
  28.     // Used in DemandInternal, to remember the result of previous demands
  29.     // KEEP IN SYNC WITH DEFINITIONS IN SECURITYPOLICY.H
  30.     [Serializable()]
  31.     internal enum PermissionType
  32.     {
  33.         // special flags
  34.         SecurityUnmngdCodeAccess = 0,
  35.         SecuritySkipVerification = 1,
  36.         ReflectionTypeInfo = 2,
  37.         SecurityAssert = 3,
  38.         ReflectionMemberAccess = 4,
  39.         SecuritySerialization = 5,
  40.         ReflectionEmit = 6,
  41.         FullTrust = 7,
  42.         SecurityBindingRedirects = 8,
  43.        
  44.         // special permissions
  45.         UIPermission = 9,
  46.         EnvironmentPermission = 10,
  47.         FileDialogPermission = 11,
  48.         FileIOPermission = 12,
  49.         ReflectionPermission = 13,
  50.         SecurityPermission = 14,
  51.        
  52.         // additional special flags
  53.         SecurityControlEvidence = 16,
  54.         SecurityControlPrincipal = 17
  55.     }
  56.    
  57.     internal class CodeAccessSecurityEngine
  58.     {
  59.        
  60.         static internal SecurityPermission AssertPermission;
  61.         static internal PermissionToken AssertPermissionToken;
  62.        
  63.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  64.         static internal extern void SpecialDemand(PermissionType whatPermission, ref StackCrawlMark stackMark);
  65.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  66.         static internal extern bool DoesFullTrustMeanFullTrust();
  67.        
  68.         [System.Diagnostics.Conditional("_DEBUG")]
  69.         [ResourceExposure(ResourceScope.None)]
  70.         [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
  71.         private static void DEBUG_OUT(string str)
  72.         {
  73.             #if _DEBUG
  74.             if (debug) {
  75.                 if (to_file) {
  76.                     System.Text.StringBuilder sb = new System.Text.StringBuilder();
  77.                     sb.Append(str);
  78.                     sb.Append((char)13);
  79.                     sb.Append((char)10);
  80.                     PolicyManager._DebugOut(file, sb.ToString());
  81.                 }
  82.                 else
  83.                     Console.WriteLine(str);
  84.             }
  85.             #endif
  86.         }
  87.        
  88.         #if _DEBUG
  89.         private static bool debug = false;
  90.         private static readonly bool to_file = false;
  91.         private const string file = "d:\\foo\\debug.txt";
  92.         #endif
  93.        
  94.         private CodeAccessSecurityEngine()
  95.         {
  96.         }
  97.         // static default constructor. This will be called before any of the static members are accessed.
  98.         static CodeAccessSecurityEngine()
  99.         {
  100.             AssertPermission = new SecurityPermission(SecurityPermissionFlag.Assertion);
  101.             AssertPermissionToken = PermissionToken.GetToken(AssertPermission);
  102.         }
  103.        
  104.         private static void ThrowSecurityException(Assembly asm, PermissionSet granted, PermissionSet refused, RuntimeMethodHandle rmh, SecurityAction action, object demand, IPermission permThatFailed)
  105.         {
  106.             AssemblyName asmName = null;
  107.             Evidence asmEvidence = null;
  108.             if (asm != null) {
  109.                 // Assert here because reflection will check grants and if we fail the check,
  110.                 // there will be an infinite recursion that overflows the stack.
  111.                 PermissionSet.s_fullTrust.Assert();
  112.                 asmName = asm.GetName();
  113.                 if (asm != Assembly.GetExecutingAssembly())
  114.                     // this condition is to avoid having to marshal mscorlib's evidence (which is always in teh default domain) to the current domain
  115.                     asmEvidence = asm.Evidence;
  116.             }
  117.             throw SecurityException.MakeSecurityException(asmName, asmEvidence, granted, refused, rmh, action, demand, permThatFailed);
  118.         }
  119.        
  120.         private static void ThrowSecurityException(object assemblyOrString, PermissionSet granted, PermissionSet refused, RuntimeMethodHandle rmh, SecurityAction action, object demand, IPermission permThatFailed)
  121.         {
  122.             BCLDebug.Assert((assemblyOrString == null || assemblyOrString is Assembly || assemblyOrString is string), "Must pass in an Assembly object or String object here");
  123.            
  124.             if (assemblyOrString == null || assemblyOrString is Assembly)
  125.                 ThrowSecurityException((Assembly)assemblyOrString, granted, refused, rmh, action, demand, permThatFailed);
  126.             else {
  127.                 AssemblyName asmName = new AssemblyName((string)assemblyOrString);
  128.                 throw SecurityException.MakeSecurityException(asmName, null, granted, refused, rmh, action, demand, permThatFailed);
  129.             }
  130.         }
  131.        
  132.         private static void LazyCheckSetHelper(PermissionSet demands, IntPtr asmSecDesc, RuntimeMethodHandle rmh, Assembly assembly, SecurityAction action)
  133.         {
  134.             if (demands.CanUnrestrictedOverride())
  135.                 return;
  136.            
  137.             PermissionSet grants;
  138.             PermissionSet refused;
  139.            
  140.             _GetGrantedPermissionSet(asmSecDesc, out grants, out refused);
  141.            
  142.             CheckSetHelper(grants, refused, demands, rmh, (object)assembly, action, true);
  143.         }
  144.        
  145.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  146.         static internal extern void _GetGrantedPermissionSet(IntPtr secDesc, out PermissionSet grants, out PermissionSet refused);
  147.        
  148.         static internal void CheckSetHelper(CompressedStack cs, PermissionSet grants, PermissionSet refused, PermissionSet demands, RuntimeMethodHandle rmh, Assembly asm, SecurityAction action)
  149.         {
  150.             if (cs != null)
  151.                 cs.CheckSetDemand(demands, rmh);
  152.             else
  153.                 CheckSetHelper(grants, refused, demands, rmh, (object)asm, action, true);
  154.         }
  155.        
  156.         static internal bool CheckSetHelper(PermissionSet grants, PermissionSet refused, PermissionSet demands, RuntimeMethodHandle rmh, object assemblyOrString, SecurityAction action, bool throwException)
  157.         {
  158.            
  159.             BCLDebug.Assert(demands != null, "Should not reach here with a null demand set");
  160.             #if _DEBUG
  161.             if (debug) {
  162.                 DEBUG_OUT("Granted: ");
  163.                 DEBUG_OUT(grants.ToXml().ToString());
  164.                 DEBUG_OUT("Refused: ");
  165.                 DEBUG_OUT(refused != null ? refused.ToXml().ToString() : "<null>");
  166.                 DEBUG_OUT("Demanded: ");
  167.                 DEBUG_OUT(demands != null ? demands.ToXml().ToString() : "<null>");
  168.             }
  169.             #endif
  170.            
  171.             IPermission permThatFailed = null;
  172.             if (grants != null)
  173.                 grants.CheckDecoded(demands);
  174.             if (refused != null)
  175.                 refused.CheckDecoded(demands);
  176.            
  177.             bool bThreadSecurity = SecurityManager._SetThreadSecurity(false);
  178.            
  179.             try {
  180.                
  181.                 // Check grant set
  182.                 if (!demands.CheckDemand(grants, out permThatFailed)) {
  183.                     if (throwException)
  184.                         ThrowSecurityException(assemblyOrString, grants, refused, rmh, action, demands, permThatFailed);
  185.                     else
  186.                         return false;
  187.                 }
  188.                
  189.                 // Check refused set
  190.                 if (!demands.CheckDeny(refused, out permThatFailed)) {
  191.                     if (throwException)
  192.                         ThrowSecurityException(assemblyOrString, grants, refused, rmh, action, demands, permThatFailed);
  193.                     else
  194.                         return false;
  195.                 }
  196.             }
  197.             catch (SecurityException) {
  198.                 throw;
  199.             }
  200.             catch (Exception) {
  201.                 // Any exception besides a security exception in this code means that
  202.                 // a permission was unable to properly handle what we asked of it.
  203.                 // We will define this to mean that the demand failed.
  204.                 if (throwException)
  205.                     ThrowSecurityException(assemblyOrString, grants, refused, rmh, action, demands, permThatFailed);
  206.                 else
  207.                     return false;
  208.             }
  209.             catch {
  210.                 return false;
  211.             }
  212.             finally {
  213.                 if (bThreadSecurity)
  214.                     SecurityManager._SetThreadSecurity(true);
  215.             }
  216.             return true;
  217.         }
  218.        
  219.         static internal void CheckHelper(CompressedStack cs, PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandle rmh, Assembly asm, SecurityAction action)
  220.         {
  221.             if (cs != null)
  222.                 cs.CheckDemand(demand, permToken, rmh);
  223.             else
  224.                 CheckHelper(grantedSet, refusedSet, demand, permToken, rmh, (object)asm, action, true);
  225.         }
  226.        
  227.         static internal bool CheckHelper(PermissionSet grantedSet, PermissionSet refusedSet, CodeAccessPermission demand, PermissionToken permToken, RuntimeMethodHandle rmh, object assemblyOrString, SecurityAction action, bool throwException)
  228.         {
  229.             // We should never get here with a null demand
  230.             BCLDebug.Assert(demand != null, "Should not reach here with a null demand");
  231.            
  232.             #if _DEBUG
  233.             if (debug) {
  234.                 DEBUG_OUT("Granted: ");
  235.                 DEBUG_OUT(grantedSet.ToXml().ToString());
  236.                 DEBUG_OUT("Refused: ");
  237.                 DEBUG_OUT(refusedSet != null ? refusedSet.ToXml().ToString() : "<null>");
  238.                 DEBUG_OUT("Demanded: ");
  239.                 DEBUG_OUT(demand.ToString());
  240.             }
  241.             #endif
  242.            
  243.             if (permToken == null)
  244.                 permToken = PermissionToken.GetToken(demand);
  245.            
  246.             if (grantedSet != null)
  247.                 grantedSet.CheckDecoded(permToken.m_index);
  248.             if (refusedSet != null)
  249.                 refusedSet.CheckDecoded(permToken.m_index);
  250.            
  251.             // If PermissionSet is null, then module does not have Permissions... Fail check.
  252.            
  253.             bool bThreadSecurity = SecurityManager._SetThreadSecurity(false);
  254.            
  255.             try {
  256.                 if (grantedSet == null) {
  257.                     if (throwException)
  258.                         ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand);
  259.                     else
  260.                         return false;
  261.                 }
  262.                
  263.                 else if (!grantedSet.IsUnrestricted() || !demand.CanUnrestrictedOverride()) {
  264.                     // If we aren't unrestricted, there is a refused set, or our permission is not of the unrestricted
  265.                     // variety, we need to do the proper callback.
  266.                    
  267.                     BCLDebug.Assert(demand != null, "demand != null");
  268.                    
  269.                     // Find the permission of matching type in the permission set.
  270.                    
  271.                     CodeAccessPermission grantedPerm = (CodeAccessPermission)grantedSet.GetPermission(permToken);
  272.                    
  273.                     // Make sure the demand has been granted
  274.                     if (!demand.CheckDemand(grantedPerm)) {
  275.                         if (throwException)
  276.                             ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand);
  277.                         else
  278.                             return false;
  279.                     }
  280.                 }
  281.                
  282.                 // Make the sure the permission is not refused.
  283.                
  284.                 if (refusedSet != null) {
  285.                     CodeAccessPermission refusedPerm = (CodeAccessPermission)refusedSet.GetPermission(permToken);
  286.                     if (refusedPerm != null) {
  287.                         if (!refusedPerm.CheckDeny(demand)) {
  288.                             #if _DEBUG
  289.                             if (debug)
  290.                                 DEBUG_OUT("Permission found in refused set");
  291.                             #endif
  292.                             if (throwException)
  293.                                 ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand);
  294.                             else
  295.                                 return false;
  296.                            
  297.                         }
  298.                     }
  299.                    
  300.                     if (refusedSet.IsUnrestricted() && demand.CanUnrestrictedOverride()) {
  301.                         if (throwException)
  302.                             ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand);
  303.                         else
  304.                             return false;
  305.                     }
  306.                 }
  307.             }
  308.             catch (SecurityException) {
  309.                 throw;
  310.             }
  311.             catch (Exception) {
  312.                 // Any exception besides a security exception in this code means that
  313.                 // a permission was unable to properly handle what we asked of it.
  314.                 // We will define this to mean that the demand failed.
  315.                 if (throwException)
  316.                     ThrowSecurityException(assemblyOrString, grantedSet, refusedSet, rmh, action, demand, demand);
  317.                 else
  318.                     return false;
  319.             }
  320.             catch {
  321.                 return false;
  322.             }
  323.             finally {
  324.                 if (bThreadSecurity)
  325.                     SecurityManager._SetThreadSecurity(true);
  326.             }
  327.            
  328.             DEBUG_OUT("Check passed");
  329.             return true;
  330.         }
  331.        
  332.        
  333.         static internal void GetZoneAndOriginHelper(CompressedStack cs, PermissionSet grantSet, PermissionSet refusedSet, ArrayList zoneList, ArrayList originList)
  334.         {
  335.             if (cs != null)
  336.                 cs.GetZoneAndOrigin(zoneList, originList, PermissionToken.GetToken(typeof(ZoneIdentityPermission)), PermissionToken.GetToken(typeof(UrlIdentityPermission)));
  337.             else {
  338.                 ZoneIdentityPermission zone = (ZoneIdentityPermission)grantSet.GetPermission(typeof(ZoneIdentityPermission));
  339.                 UrlIdentityPermission url = (UrlIdentityPermission)grantSet.GetPermission(typeof(UrlIdentityPermission));
  340.                
  341.                 if (zone != null)
  342.                     zoneList.Add(zone.SecurityZone);
  343.                
  344.                 if (url != null)
  345.                     originList.Add(url.Url);
  346.             }
  347.         }
  348.        
  349.         static internal void GetZoneAndOrigin(ref StackCrawlMark mark, out ArrayList zone, out ArrayList origin)
  350.         {
  351.             zone = new ArrayList();
  352.             origin = new ArrayList();
  353.            
  354.             GetZoneAndOriginInternal(zone, origin, ref mark);
  355.         }
  356.        
  357.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  358.         private static extern void GetZoneAndOriginInternal(ArrayList zoneList, ArrayList originList, ref StackCrawlMark stackMark);
  359.        
  360.         static internal void CheckAssembly(Assembly asm, CodeAccessPermission demand)
  361.         {
  362.             BCLDebug.Assert(asm != null, "Must pass in a good assembly");
  363.             BCLDebug.Assert(demand != null, "Must pass in a good demand");
  364.             if (SecurityManager._IsSecurityOn()) {
  365.                 PermissionSet granted;
  366.                 PermissionSet refused;
  367.                 asm.nGetGrantSet(out granted, out refused);
  368.                 CheckHelper(granted, refused, demand, PermissionToken.GetToken(demand), RuntimeMethodHandle.EmptyHandle, asm, SecurityAction.Demand, true);
  369.             }
  370.         }
  371.        
  372.         // Check - Used to initiate a code-access security check.
  373.         // This method invokes a stack walk after skipping to the frame
  374.         // referenced by stackMark.
  375.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  376.         private static extern void Check(object demand, ref StackCrawlMark stackMark, bool isPermSet);
  377.        
  378.        
  379.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  380.         static internal extern bool QuickCheckForAllDemands();
  381.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  382.         static internal extern bool AllDomainsHomogeneousWithNoStackModifiers();
  383.        
  384.         static internal void Check(CodeAccessPermission cap, ref StackCrawlMark stackMark)
  385.         {
  386.             Check(cap, ref stackMark, false);
  387.         }
  388.        
  389.        
  390.         static internal void Check(PermissionSet permSet, ref StackCrawlMark stackMark)
  391.         {
  392.             Check(permSet, ref stackMark, true);
  393.         }
  394.        
  395.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  396.         static internal extern FrameSecurityDescriptor CheckNReturnSO(PermissionToken permToken, CodeAccessPermission demand, ref StackCrawlMark stackMark, int unrestrictedOverride, int create);
  397.        
  398.         static internal void Assert(CodeAccessPermission cap, ref StackCrawlMark stackMark)
  399.         {
  400.             // Make sure the caller of assert has the permission to assert
  401.             //WARNING: The placement of the call here is just right to check
  402.             // the appropriate frame.
  403.            
  404.             // Note: if the "AssertPermission" is not a permission that implements IUnrestrictedPermission
  405.             // you need to change the last parameter to a zero.
  406.             BCLDebug.Assert(AssertPermissionToken != null && AssertPermission != null, "Assert Permission not setup correctly");
  407.             FrameSecurityDescriptor secObj = CheckNReturnSO(AssertPermissionToken, AssertPermission, ref stackMark, 1, 1);
  408.             if (secObj == null) {
  409.                 if (SecurityManager._IsSecurityOn())
  410.                     // Security: REQ_SQ flag is missing. Bad compiler ?
  411.                     // This can happen when you create delegates over functions that need the REQ_SQ
  412.                     throw new ExecutionEngineException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
  413.             }
  414.             else {
  415.                 if (secObj.HasImperativeAsserts())
  416.                     throw new SecurityException(Environment.GetResourceString("Security_MustRevertOverride"));
  417.                
  418.                 secObj.SetAssert(cap);
  419.             }
  420.         }
  421.        
  422.         static internal void Deny(CodeAccessPermission cap, ref StackCrawlMark stackMark)
  423.         {
  424.             FrameSecurityDescriptor secObj = SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
  425.             if (secObj == null) {
  426.                 if (SecurityManager._IsSecurityOn())
  427.                     // Security: REQ_SQ flag is missing. Bad compiler ?
  428.                     // This can happen when you create delegates over functions that need the REQ_SQ
  429.                     throw new ExecutionEngineException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
  430.             }
  431.             else {
  432.                 if (secObj.HasImperativeDenials())
  433.                     throw new SecurityException(Environment.GetResourceString("Security_MustRevertOverride"));
  434.                
  435.                 secObj.SetDeny(cap);
  436.             }
  437.         }
  438.        
  439.         static internal void PermitOnly(CodeAccessPermission cap, ref StackCrawlMark stackMark)
  440.         {
  441.             FrameSecurityDescriptor secObj = SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
  442.             if (secObj == null) {
  443.                 if (SecurityManager._IsSecurityOn())
  444.                     // Security: REQ_SQ flag is missing. Bad compiler ?
  445.                     // This can happen when you create delegates over functions that need the REQ_SQ
  446.                     throw new ExecutionEngineException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
  447.             }
  448.             else {
  449.                 if (secObj.HasImperativeRestrictions())
  450.                     throw new SecurityException(Environment.GetResourceString("Security_MustRevertOverride"));
  451.                
  452.                 secObj.SetPermitOnly(cap);
  453.             }
  454.         }
  455.        
  456.         // Update the PLS used for optimization in the AppDomain: called from the VM
  457.         private static PermissionListSet UpdateAppDomainPLS(PermissionListSet adPLS, PermissionSet grantedPerms, PermissionSet refusedPerms)
  458.         {
  459.             if (adPLS == null) {
  460.                 adPLS = new PermissionListSet();
  461.                 adPLS.UpdateDomainPLS(grantedPerms, refusedPerms);
  462.                 return adPLS;
  463.             }
  464.             else {
  465.                 PermissionListSet newPLS = new PermissionListSet();
  466.                 newPLS.UpdateDomainPLS(adPLS);
  467.                 newPLS.UpdateDomainPLS(grantedPerms, refusedPerms);
  468.                 return newPLS;
  469.             }
  470.         }
  471.     }
  472. }

Developer Fusion