2 // System.Security.SecurityManager.cs
5 // Nick Drochak(ndrochak@gol.com)
6 // Sebastien Pouliot <sebastien@ximian.com>
9 // Portions (C) 2004 Motus Technologies Inc. (http://www.motus.com)
10 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Globalization;
35 using System.Reflection;
36 using System.Runtime.CompilerServices;
37 using System.Runtime.InteropServices;
38 using System.Security.Permissions;
39 using System.Security.Policy;
44 namespace System.Security {
46 // Must match MonoDeclSecurityActions in /mono/metadata/reflection.h
47 internal struct RuntimeDeclSecurityActions {
48 public RuntimeDeclSecurityEntry cas;
49 public RuntimeDeclSecurityEntry noncas;
50 public RuntimeDeclSecurityEntry choice;
55 public static class SecurityManager {
57 public sealed class SecurityManager {
59 private SecurityManager ()
63 private static object _lockObject;
64 private static ArrayList _hierarchy;
65 private static IPermission _unmanagedCode;
66 private static Hashtable _declsecCache;
67 private static PolicyLevel _level;
69 static SecurityManager ()
72 // http://msdn.microsoft.com/library/en-us/dnaskdr/html/askgui06032003.asp?frame=true
73 _lockObject = new object ();
78 extern public static bool CheckExecutionRights {
79 [MethodImplAttribute (MethodImplOptions.InternalCall)]
82 [MethodImplAttribute (MethodImplOptions.InternalCall)]
83 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
87 extern public static bool SecurityEnabled {
88 [MethodImplAttribute (MethodImplOptions.InternalCall)]
91 [MethodImplAttribute (MethodImplOptions.InternalCall)]
92 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
99 // NOTE: This method doesn't show in the class library status page because
100 // it cannot be "found" with the StrongNameIdentityPermission for ECMA key.
102 [MonoTODO ("works for fulltrust (empty), documentation doesn't really make sense, type wise")]
103 [StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000")]
104 public static void GetZoneAndOrigin (out ArrayList zone, out ArrayList origin)
106 zone = new ArrayList ();
107 origin = new ArrayList ();
111 public static bool IsGranted (IPermission perm)
115 if (!SecurityEnabled)
119 // - Only check the caller (no stack walk required)
120 // - Not affected by overrides (like Assert, Deny and PermitOnly)
121 // - calls IsSubsetOf even for non CAS permissions
122 // (i.e. it does call Demand so any code there won't be executed)
124 // with 2.0 identity permission are unrestrictable
125 return IsGranted (Assembly.GetCallingAssembly (), perm);
127 if (perm is IUnrestrictedPermission)
128 return IsGranted (Assembly.GetCallingAssembly (), perm);
130 return IsGrantedRestricted (Assembly.GetCallingAssembly (), perm);
135 // only for permissions that do not implement IUnrestrictedPermission
136 internal static bool IsGrantedRestricted (Assembly a, IPermission perm)
138 PermissionSet granted = a.GrantedPermissionSet;
\r
139 if (granted != null) {
\r
140 CodeAccessPermission grant = (CodeAccessPermission) granted.GetPermission (perm.GetType ());
141 if (!perm.IsSubsetOf (grant)) {
146 PermissionSet denied = a.DeniedPermissionSet;
147 if (denied != null) {
\r
148 CodeAccessPermission refuse = (CodeAccessPermission) a.DeniedPermissionSet.GetPermission (perm.GetType ());
149 if ((refuse != null) && perm.IsSubsetOf (refuse))
155 // note: in 2.0 *all* permissions (including identity permissions) support unrestricted
156 internal static bool IsGranted (Assembly a, IPermission perm)
158 PermissionSet granted = a.GrantedPermissionSet;
\r
159 if ((granted != null) && !granted.IsUnrestricted ()) {
\r
160 CodeAccessPermission grant = (CodeAccessPermission) granted.GetPermission (perm.GetType ());
\r
161 if (!perm.IsSubsetOf (grant)) {
\r
166 PermissionSet denied = a.DeniedPermissionSet;
\r
167 if ((denied != null) && !denied.IsEmpty ()) {
\r
168 if (denied.IsUnrestricted ())
\r
170 CodeAccessPermission refuse = (CodeAccessPermission) a.DeniedPermissionSet.GetPermission (perm.GetType ());
\r
171 if ((refuse != null) && perm.IsSubsetOf (refuse))
\r
177 internal static IPermission CheckPermissionSet (Assembly a, PermissionSet ps, bool noncas)
182 foreach (IPermission p in ps) {
183 // note: this may contains non CAS permissions
184 if ((!noncas) && (p is CodeAccessPermission)) {
186 if (!IsGranted (a, p))
189 if (p is IUnrestrictedPermission) {
190 if (!IsGranted (a, p))
193 if (!IsGrantedRestricted (a, p))
198 // but non-CAS will throw on failure...
202 catch (SecurityException) {
211 internal static IPermission CheckPermissionSet (AppDomain ad, PermissionSet ps)
213 if ((ps == null) || ps.IsEmpty ())
216 PermissionSet granted = ad.GrantedPermissionSet;
219 if ((ad.GrantedPermissionSet.Count == 0) && ad.GrantedPermissionSet.IsUnrestricted ())
222 foreach (IPermission p in ps) {
223 if (p is CodeAccessPermission) {
224 CodeAccessPermission grant = (CodeAccessPermission) granted.GetPermission (p.GetType ());
226 if (!granted.IsUnrestricted () || !(p is IUnrestrictedPermission)) {
227 if (!p.IsSubsetOf (null))
230 } else if (!p.IsSubsetOf (grant)) {
234 // but non-CAS will throw on failure...
238 catch (SecurityException) {
247 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
248 public static PolicyLevel LoadPolicyLevelFromFile (string path, PolicyLevelType type)
251 throw new ArgumentNullException ("path");
253 PolicyLevel pl = null;
255 pl = new PolicyLevel (type.ToString (), type);
256 pl.LoadFromFile (path);
258 catch (Exception e) {
259 throw new ArgumentException (Locale.GetText ("Invalid policy XML"), e);
264 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
265 public static PolicyLevel LoadPolicyLevelFromString (string str, PolicyLevelType type)
268 throw new ArgumentNullException ("str");
270 PolicyLevel pl = null;
272 pl = new PolicyLevel (type.ToString (), type);
273 pl.LoadFromString (str);
275 catch (Exception e) {
276 throw new ArgumentException (Locale.GetText ("Invalid policy XML"), e);
281 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
282 public static IEnumerator PolicyHierarchy ()
287 public static PermissionSet ResolvePolicy (Evidence evidence)
289 // no evidence, no permission
290 if (evidence == null)
291 return new PermissionSet (PermissionState.None);
293 PermissionSet ps = null;
294 // Note: can't call PolicyHierarchy since ControlPolicy isn't required to resolve policies
295 IEnumerator ple = Hierarchy;
296 while (ple.MoveNext ()) {
297 PolicyLevel pl = (PolicyLevel) ple.Current;
298 if (ResolvePolicyLevel (ref ps, pl, evidence)) {
299 break; // i.e. PolicyStatementAttribute.LevelFinal
303 ResolveIdentityPermissions (ps, evidence);
309 [MonoTODO ("(2.0) more tests are needed")]
310 public static PermissionSet ResolvePolicy (Evidence[] evidences)
312 if ((evidences == null) || (evidences.Length == 0) ||
313 ((evidences.Length == 1) && (evidences [0].Count == 0))) {
314 return new PermissionSet (PermissionState.None);
317 // probably not optimal
318 PermissionSet ps = ResolvePolicy (evidences [0]);
319 for (int i=1; i < evidences.Length; i++) {
320 ps = ps.Intersect (ResolvePolicy (evidences [i]));
325 public static PermissionSet ResolveSystemPolicy (Evidence evidence)
327 // no evidence, no permission
328 if (evidence == null)
329 return new PermissionSet (PermissionState.None);
331 // Note: can't call PolicyHierarchy since ControlPolicy isn't required to resolve policies
332 PermissionSet ps = null;
333 IEnumerator ple = Hierarchy;
334 while (ple.MoveNext ()) {
335 PolicyLevel pl = (PolicyLevel) ple.Current;
336 if (pl.Type == PolicyLevelType.AppDomain)
338 if (ResolvePolicyLevel (ref ps, pl, evidence))
339 break; // i.e. PolicyStatementAttribute.LevelFinal
342 ResolveIdentityPermissions (ps, evidence);
347 static private SecurityPermission _execution = new SecurityPermission (SecurityPermissionFlag.Execution);
349 public static PermissionSet ResolvePolicy (Evidence evidence, PermissionSet reqdPset, PermissionSet optPset, PermissionSet denyPset, out PermissionSet denied)
351 PermissionSet resolved = ResolvePolicy (evidence);
352 // do we have the minimal permission requested by the assembly ?
353 if ((reqdPset != null) && !reqdPset.IsSubsetOf (resolved)) {
354 throw new PolicyException (Locale.GetText (
355 "Policy doesn't grant the minimal permissions required to execute the assembly."));
358 // do we check for execution rights ?
359 if (CheckExecutionRights) {
360 bool execute = false;
361 // an empty permissionset doesn't include Execution
362 if (resolved != null) {
363 // unless we have "Full Trust"...
364 if (resolved.IsUnrestricted ()) {
367 // ... we need to find a SecurityPermission
368 IPermission security = resolved.GetPermission (typeof (SecurityPermission));
369 execute = _execution.IsSubsetOf (security);
374 throw new PolicyException (Locale.GetText (
375 "Policy doesn't grant the right to execute the assembly."));
383 public static IEnumerator ResolvePolicyGroups (Evidence evidence)
385 if (evidence == null)
386 throw new ArgumentNullException ("evidence");
388 ArrayList al = new ArrayList ();
389 // Note: can't call PolicyHierarchy since ControlPolicy isn't required to resolve policies
390 IEnumerator ple = Hierarchy;
391 while (ple.MoveNext ()) {
392 PolicyLevel pl = (PolicyLevel) ple.Current;
393 CodeGroup cg = pl.ResolveMatchingCodeGroups (evidence);
396 return al.GetEnumerator ();
399 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
400 public static void SavePolicy ()
402 IEnumerator e = Hierarchy;
403 while (e.MoveNext ()) {
404 PolicyLevel level = (e.Current as PolicyLevel);
409 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
410 public static void SavePolicyLevel (PolicyLevel level)
412 // Yes this will throw a NullReferenceException, just like MS (see FDBK13121)
416 // private/internal stuff
418 private static IEnumerator Hierarchy {
421 if (_hierarchy == null)
422 InitializePolicyHierarchy ();
424 return _hierarchy.GetEnumerator ();
428 private static void InitializePolicyHierarchy ()
430 string machinePolicyPath = Path.GetDirectoryName (Environment.GetMachineConfigPath ());
431 // note: use InternalGetFolderPath to avoid recursive policy initialization
432 string userPolicyPath = Path.Combine (Environment.InternalGetFolderPath (Environment.SpecialFolder.ApplicationData), "mono");
434 PolicyLevel enterprise = new PolicyLevel ("Enterprise", PolicyLevelType.Enterprise);
436 enterprise.LoadFromFile (Path.Combine (machinePolicyPath, "enterprisesec.config"));
438 PolicyLevel machine = new PolicyLevel ("Machine", PolicyLevelType.Machine);
440 machine.LoadFromFile (Path.Combine (machinePolicyPath, "security.config"));
442 PolicyLevel user = new PolicyLevel ("User", PolicyLevelType.User);
444 user.LoadFromFile (Path.Combine (userPolicyPath, "security.config"));
446 ArrayList al = new ArrayList ();
451 _hierarchy = ArrayList.Synchronized (al);
455 internal static bool ResolvePolicyLevel (ref PermissionSet ps, PolicyLevel pl, Evidence evidence)
457 PolicyStatement pst = pl.Resolve (evidence);
460 // only for initial (first) policy level processed
461 ps = pst.PermissionSet;
463 ps = ps.Intersect (pst.PermissionSet);
465 // null is equals to None - exist that null can throw NullReferenceException ;-)
466 ps = new PermissionSet (PermissionState.None);
470 if ((pst.Attributes & PolicyStatementAttribute.LevelFinal) == PolicyStatementAttribute.LevelFinal)
476 internal static void ResolveIdentityPermissions (PermissionSet ps, Evidence evidence)
479 // in 2.0 identity permissions can now be unrestricted
480 if (ps.IsUnrestricted ())
483 // Only host evidence are used for policy resolution
484 IEnumerator ee = evidence.GetHostEnumerator ();
485 while (ee.MoveNext ()) {
486 IIdentityPermissionFactory ipf = (ee.Current as IIdentityPermissionFactory);
488 IPermission p = ipf.CreateIdentityPermission (evidence);
489 ps.AddPermission (p);
494 internal static PolicyLevel ResolvingPolicyLevel {
495 get { return _level; }
496 set { _level = value; }
499 internal static PermissionSet Decode (IntPtr permissions, int length)
501 // Permission sets from the runtime (declarative security) can be cached
502 // for performance as they can never change (i.e. they are read-only).
503 PermissionSet ps = null;
506 if (_declsecCache == null) {
507 _declsecCache = new Hashtable ();
510 object key = (object) (int) permissions;
511 ps = (PermissionSet) _declsecCache [key];
513 // create permissionset and add it to the cache
514 byte[] data = new byte [length];
515 Marshal.Copy (permissions, data, 0, length);
517 ps.DeclarativeSecurity = true;
518 _declsecCache.Add (key, ps);
524 internal static PermissionSet Decode (byte[] encodedPermissions)
526 if ((encodedPermissions == null) || (encodedPermissions.Length < 1))
527 throw new SecurityException ("Invalid metadata format.");
529 switch (encodedPermissions [0]) {
531 // Fx 1.0/1.1 declarative security permissions metadata is in Unicode-encoded XML
532 string xml = Encoding.Unicode.GetString (encodedPermissions);
533 return new PermissionSet (xml);
535 // Fx 2.0 are encoded "somewhat, but not enough, like" custom attributes
536 // note: we still support the older format!
537 return PermissionSet.CreateFromBinaryFormat (encodedPermissions);
539 throw new SecurityException (Locale.GetText ("Unknown metadata format."));
543 internal static PermissionSetCollection DecodeCollection (IntPtr permissions, int length)
545 // Permission sets from the runtime (declarative security) can be cached
546 // for performance as they can never change (i.e. they are read-only).
548 if (_declsecCache == null) {
550 if (_declsecCache == null) {
551 _declsecCache = new Hashtable ();
556 PermissionSetCollection psc = null;
558 object key = (object) (int) permissions;
559 psc = (PermissionSetCollection) _declsecCache [key];
561 // create permissionset and add it to the cache
562 byte[] data = new byte [length];
563 Marshal.Copy (permissions, data, 0, length);
564 psc = DecodeCollection (data);
565 _declsecCache.Add (key, psc);
571 internal static PermissionSetCollection DecodeCollection (byte[] encodedPermissions)
573 if ((encodedPermissions == null) || (encodedPermissions.Length < 1))
574 throw new SecurityException ("Invalid metadata format.");
576 switch (encodedPermissions [0]) {
578 // Fx 1.0/1.1 declarative security permissions metadata is in Unicode-encoded XML
579 throw new SecurityException (Locale.GetText ("1.0 metadata format doesn't support collections."));
581 // Fx 2.0 are encoded "somewhat, but not enough, like" custom attributes
582 // note: we still support the older format!
583 return PermissionSetCollection.CreateFromBinaryFormat (encodedPermissions);
585 throw new SecurityException (Locale.GetText ("Unknown metadata format."));
590 private static IPermission UnmanagedCode {
593 if (_unmanagedCode == null)
594 _unmanagedCode = new SecurityPermission (SecurityPermissionFlag.UnmanagedCode);
596 return _unmanagedCode;
600 // security check when using reflection
602 [MethodImplAttribute(MethodImplOptions.InternalCall)]
603 private static unsafe extern bool GetLinkDemandSecurity (MethodBase method, RuntimeDeclSecurityActions *cdecl, RuntimeDeclSecurityActions *mdecl);
605 // When using reflection LinkDemand are promoted to full Demand (i.e. stack walk)
606 internal unsafe static void ReflectedLinkDemandInvoke (MethodBase mb)
608 RuntimeDeclSecurityActions klass;
609 RuntimeDeclSecurityActions method;
611 if (!GetLinkDemandSecurity (mb, &klass, &method))
614 PermissionSet ps = null;
616 if (klass.cas.size > 0) {
617 ps = Decode (klass.cas.blob, klass.cas.size);
619 if (klass.noncas.size > 0) {
620 PermissionSet p = Decode (klass.noncas.blob, klass.noncas.size);
621 ps = (ps == null) ? p : ps.Union (p);
624 if (method.cas.size > 0) {
625 PermissionSet p = Decode (method.cas.blob, method.cas.size);
626 ps = (ps == null) ? p : ps.Union (p);
628 if (method.noncas.size > 0) {
629 PermissionSet p = Decode (method.noncas.blob, method.noncas.size);
630 ps = (ps == null) ? p : ps.Union (p);
633 // in this case we union-ed the permission sets because we want to do
634 // a single stack walk (not up to 4).
638 // Process LinkDemandChoice (2.0)
639 if (klass.choice.size > 0) {
640 PermissionSetCollection psc = DecodeCollection (klass.choice.blob, klass.choice.size);
643 if (method.choice.size > 0) {
644 PermissionSetCollection psc = DecodeCollection (method.choice.blob, method.choice.size);
650 internal unsafe static bool ReflectedLinkDemandQuery (MethodBase mb)
652 RuntimeDeclSecurityActions klass;
653 RuntimeDeclSecurityActions method;
655 if (!GetLinkDemandSecurity (mb, &klass, &method))
658 return LinkDemand (mb.ReflectedType.Assembly, &klass, &method);
661 // internal - get called at JIT time
663 private static void DemandUnmanaged ()
665 UnmanagedCode.Demand ();
668 private unsafe static bool LinkDemand (Assembly a, RuntimeDeclSecurityActions *klass, RuntimeDeclSecurityActions *method)
671 PermissionSet ps = null;
673 if (klass->cas.size > 0) {
674 ps = Decode (klass->cas.blob, klass->cas.size);
675 result = (SecurityManager.CheckPermissionSet (a, ps, false) == null);
677 if (result && (klass->noncas.size > 0)) {
678 ps = Decode (klass->noncas.blob, klass->noncas.size);
679 result = (SecurityManager.CheckPermissionSet (a, ps, true) == null);
682 if (result && (method->cas.size > 0)) {
683 ps = Decode (method->cas.blob, method->cas.size);
684 result = (SecurityManager.CheckPermissionSet (a, ps, false) == null);
686 if (result && (method->noncas.size > 0)) {
687 ps = Decode (method->noncas.blob, method->noncas.size);
688 result = (SecurityManager.CheckPermissionSet (a, ps, true) == null);
691 // success if one of the permission is granted
692 if (result && (klass->choice.size > 0)) {
693 PermissionSetCollection psc = DecodeCollection (klass->choice.blob, klass->choice.size);
696 foreach (PermissionSet pset in psc) {
697 if (SecurityManager.CheckPermissionSet (a, pset, false) == null) {
704 if (result && (method->choice.size > 0)) {
705 PermissionSetCollection psc = DecodeCollection (method->choice.blob, method->choice.size);
708 foreach (PermissionSet pset in psc) {
709 if (SecurityManager.CheckPermissionSet (a, pset, false) == null) {
719 catch (SecurityException) {
724 private static bool LinkDemandFullTrust (Assembly a)
726 // FullTrust is immutable (and means Unrestricted)
727 // so we can skip the subset operations and jump to IsUnrestricted.
728 PermissionSet granted = a.GrantedPermissionSet;
729 if ((granted != null) && !granted.IsUnrestricted ())
732 PermissionSet denied = a.DeniedPermissionSet;
733 if ((denied != null) && !denied.IsEmpty ())
739 private static bool LinkDemandUnmanaged (Assembly a)
741 // note: we know that UnmanagedCode (SecurityPermission) implements IUnrestrictedPermission
742 return IsGranted (a, UnmanagedCode);
745 // we try to provide as much details as possible to help debugging
746 private static void LinkDemandSecurityException (int securityViolation, Assembly a, MethodInfo method)
748 string message = null;
749 AssemblyName an = null;
750 PermissionSet granted = null;
751 PermissionSet refused = null;
752 object demanded = null;
753 IPermission failed = null;
756 an = a.UnprotectedGetName ();
757 granted = a.GrantedPermissionSet;
758 refused = a.DeniedPermissionSet;
761 switch (securityViolation) {
762 case 1: // MONO_JIT_LINKDEMAND_PERMISSION
763 message = Locale.GetText ("Permissions refused to call this method.");
765 case 2: // MONO_JIT_LINKDEMAND_APTC
766 message = Locale.GetText ("Partially trusted callers aren't allowed to call into this assembly.");
767 demanded = (object) DefaultPolicies.FullTrust; // immutable
769 case 4: // MONO_JIT_LINKDEMAND_ECMA
770 message = Locale.GetText ("Calling internal calls is restricted to ECMA signed assemblies.");
772 case 8: // MONO_JIT_LINKDEMAND_PINVOKE
773 message = Locale.GetText ("Calling unmanaged code isn't allowed from this assembly.");
774 demanded = (object) _unmanagedCode;
775 failed = _unmanagedCode;
778 message = Locale.GetText ("JIT time LinkDemand failed.");
782 throw new SecurityException (message, an, granted, refused, method, SecurityAction.LinkDemand, demanded, failed, null);
785 private static void InheritanceDemandSecurityException (int securityViolation, Assembly a, Type t, MethodInfo method)
787 string message = null;
788 AssemblyName an = null;
789 PermissionSet granted = null;
790 PermissionSet refused = null;
793 an = a.UnprotectedGetName ();
794 granted = a.GrantedPermissionSet;
795 refused = a.DeniedPermissionSet;
798 switch (securityViolation) {
799 case 1: // MONO_METADATA_INHERITANCEDEMAND_CLASS
800 message = String.Format (Locale.GetText ("Class inheritance refused for {0}."), t);
802 case 2: // MONO_METADATA_INHERITANCEDEMAND_CLASS
803 message = Locale.GetText ("Method override refused.");
806 message = Locale.GetText ("Load time InheritDemand failed.");
810 throw new SecurityException (message, an, granted, refused, method, SecurityAction.LinkDemand, null, null, null);
813 // internal - get called by the class loader
816 // - class inheritance
817 // - method overrides
818 private unsafe static bool InheritanceDemand (Assembly a, RuntimeDeclSecurityActions *actions)
821 PermissionSet ps = null;
823 if (actions->cas.size > 0) {
824 ps = Decode (actions->cas.blob, actions->cas.size);
825 result = (SecurityManager.CheckPermissionSet (a, ps, false) == null);
827 if (actions->noncas.size > 0) {
828 ps = Decode (actions->noncas.blob, actions->noncas.size);
829 result = (SecurityManager.CheckPermissionSet (a, ps, true) == null);
832 // success if one of the permission is granted
833 if (result && (actions->choice.size > 0)) {
834 PermissionSetCollection psc = DecodeCollection (actions->choice.blob, actions->choice.size);
837 foreach (PermissionSet pset in psc) {
838 if (SecurityManager.CheckPermissionSet (a, pset, false) == null) {
848 catch (SecurityException) {
854 // internal - get called by JIT generated code
856 private static void InternalDemand (IntPtr permissions, int length)
858 PermissionSet ps = Decode (permissions, length);
862 private static void InternalDemandChoice (IntPtr permissions, int length)
865 PermissionSetCollection psc = DecodeCollection (permissions, length);
868 throw new SecurityException ("SecurityAction.DemandChoice is only possible in 2.0");