2010-03-12 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / corlib / System.Security / SecurityManager.cs
1 //
2 // System.Security.SecurityManager.cs
3 //
4 // Authors:
5 //      Nick Drochak(ndrochak@gol.com)
6 //      Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // (C) Nick Drochak
9 // Portions (C) 2004 Motus Technologies Inc. (http://www.motus.com)
10 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
11 //
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:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
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.
30 //
31
32 #if !NET_2_1 || MONOTOUCH
33
34 using System.Collections;
35 using System.Globalization;
36 using System.IO;
37 using System.Reflection;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Security.Permissions;
41 using System.Security.Policy;
42 using System.Text;
43
44 using Mono.Xml;
45
46 namespace System.Security {
47
48         // Must match MonoDeclSecurityActions in /mono/metadata/reflection.h
49         internal struct RuntimeDeclSecurityActions {
50                 public RuntimeDeclSecurityEntry cas;
51                 public RuntimeDeclSecurityEntry noncas;
52                 public RuntimeDeclSecurityEntry choice;
53         }
54
55         [ComVisible (true)]
56         public static class SecurityManager {
57                 private static object _lockObject;
58                 private static ArrayList _hierarchy;
59                 private static IPermission _unmanagedCode;
60                 private static Hashtable _declsecCache;
61                 private static PolicyLevel _level;
62
63                 static SecurityManager () 
64                 {
65                         // lock(this) is bad
66                         // http://msdn.microsoft.com/library/en-us/dnaskdr/html/askgui06032003.asp?frame=true
67                         _lockObject = new object ();
68                 }
69
70                 // properties
71
72                 extern public static bool CheckExecutionRights {
73                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
74                         get;
75
76                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
77                         [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
78                         set;
79                 }
80
81                 [Obsolete ("The security manager cannot be turned off on MS runtime")]
82                 extern public static bool SecurityEnabled {
83                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
84                         get;
85
86                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
87                         [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
88                         set;
89                 }
90
91                 // methods
92
93                 // NOTE: This method doesn't show in the class library status page because
94                 // it cannot be "found" with the StrongNameIdentityPermission for ECMA key.
95                 // But it's there!
96                 // FIXME works for fulltrust (empty), documentation doesn't really make sense, type wise
97                 [MonoTODO ("CAS support is experimental (and unsupported). This method only works in FullTrust.")]
98                 [StrongNameIdentityPermission (SecurityAction.LinkDemand, PublicKey = "0x00000000000000000400000000000000")]
99                 public static void GetZoneAndOrigin (out ArrayList zone, out ArrayList origin) 
100                 {
101                         zone = new ArrayList ();
102                         origin = new ArrayList ();
103                 }
104
105                 public static bool IsGranted (IPermission perm)
106                 {
107                         if (perm == null)
108                                 return true;
109                         if (!SecurityEnabled)
110                                 return true;
111
112                         // - Policy driven
113                         // - Only check the caller (no stack walk required)
114                         // - Not affected by overrides (like Assert, Deny and PermitOnly)
115                         // - calls IsSubsetOf even for non CAS permissions
116                         //   (i.e. it does call Demand so any code there won't be executed)
117                         // with 2.0 identity permission are unrestrictable
118                         return IsGranted (Assembly.GetCallingAssembly (), perm);
119                 }
120
121                 // note: in 2.0 *all* permissions (including identity permissions) support unrestricted
122                 internal static bool IsGranted (Assembly a, IPermission perm)
123                 {
124                         PermissionSet granted = a.GrantedPermissionSet;
125                         if ((granted != null) && !granted.IsUnrestricted ()) {
126                                 CodeAccessPermission grant = (CodeAccessPermission) granted.GetPermission (perm.GetType ());
127                                 if (!perm.IsSubsetOf (grant)) {
128                                         return false;
129                                 }
130                         }
131
132                         PermissionSet denied = a.DeniedPermissionSet;
133                         if ((denied != null) && !denied.IsEmpty ()) {
134                                 if (denied.IsUnrestricted ())
135                                         return false;
136                                 CodeAccessPermission refuse = (CodeAccessPermission) a.DeniedPermissionSet.GetPermission (perm.GetType ());
137                                 if ((refuse != null) && perm.IsSubsetOf (refuse))
138                                         return false;
139                         }
140                         return true;
141                 }
142
143                 internal static IPermission CheckPermissionSet (Assembly a, PermissionSet ps, bool noncas)
144                 {
145                         if (ps.IsEmpty ())
146                                 return null;
147
148                         foreach (IPermission p in ps) {
149                                 // note: this may contains non CAS permissions
150                                 if ((!noncas) && (p is CodeAccessPermission)) {
151                                         if (!IsGranted (a, p))
152                                                 return p;
153                                 } else {
154                                         // but non-CAS will throw on failure...
155                                         try {
156                                                 p.Demand ();
157                                         }
158                                         catch (SecurityException) {
159                                                 // ... so we catch
160                                                 return p;
161                                         }
162                                 }
163                         }
164                         return null;
165                 }
166
167                 internal static IPermission CheckPermissionSet (AppDomain ad, PermissionSet ps)
168                 {
169                         if ((ps == null) || ps.IsEmpty ())
170                                 return null;
171
172                         PermissionSet granted = ad.GrantedPermissionSet;
173                         if (granted == null)
174                                 return null;
175                         if (granted.IsUnrestricted ())
176                                 return null;
177                         if (ps.IsUnrestricted ())
178                                 return new SecurityPermission (SecurityPermissionFlag.NoFlags);
179
180                         foreach (IPermission p in ps) {
181                                 if (p is CodeAccessPermission) {
182                                         CodeAccessPermission grant = (CodeAccessPermission) granted.GetPermission (p.GetType ());
183                                         if (grant == null) {
184                                                 if (!granted.IsUnrestricted () || !(p is IUnrestrictedPermission)) {
185                                                         if (!p.IsSubsetOf (null))
186                                                                 return p;
187                                                 }
188                                         } else if (!p.IsSubsetOf (grant)) {
189                                                 return p;
190                                         }
191                                 } else {
192                                         // but non-CAS will throw on failure...
193                                         try {
194                                                 p.Demand ();
195                                         }
196                                         catch (SecurityException) {
197                                                 // ... so we catch
198                                                 return p;
199                                         }
200                                 }
201                         }
202                         return null;
203                 }
204
205                 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
206                 public static PolicyLevel LoadPolicyLevelFromFile (string path, PolicyLevelType type)
207                 {
208                         if (path == null)
209                                 throw new ArgumentNullException ("path");
210
211                         PolicyLevel pl = null;
212                         try {
213                                 pl = new PolicyLevel (type.ToString (), type);
214                                 pl.LoadFromFile (path);
215                         }
216                         catch (Exception e) {
217                                 throw new ArgumentException (Locale.GetText ("Invalid policy XML"), e);
218                         }
219                         return pl;
220                 }
221
222                 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
223                 public static PolicyLevel LoadPolicyLevelFromString (string str, PolicyLevelType type)
224                 {
225                         if (null == str)
226                                 throw new ArgumentNullException ("str");
227
228                         PolicyLevel pl = null;
229                         try {
230                                 pl = new PolicyLevel (type.ToString (), type);
231                                 pl.LoadFromString (str);
232                         }
233                         catch (Exception e) {
234                                 throw new ArgumentException (Locale.GetText ("Invalid policy XML"), e);
235                         }
236                         return pl;
237                 }
238
239                 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
240                 public static IEnumerator PolicyHierarchy ()
241                 {
242                         return Hierarchy;
243                 }
244
245                 public static PermissionSet ResolvePolicy (Evidence evidence)
246                 {
247                         // no evidence, no permission
248                         if (evidence == null)
249                                 return new PermissionSet (PermissionState.None);
250
251                         PermissionSet ps = null;
252                         // Note: can't call PolicyHierarchy since ControlPolicy isn't required to resolve policies
253                         IEnumerator ple = Hierarchy;
254                         while (ple.MoveNext ()) {
255                                 PolicyLevel pl = (PolicyLevel) ple.Current;
256                                 if (ResolvePolicyLevel (ref ps, pl, evidence)) {
257                                         break;  // i.e. PolicyStatementAttribute.LevelFinal
258                                 }
259                         }
260
261                         ResolveIdentityPermissions (ps, evidence);
262
263                         return ps;
264                 }
265
266                 [MonoTODO ("(2.0) more tests are needed")]
267                 public static PermissionSet ResolvePolicy (Evidence[] evidences)
268                 {
269                         if ((evidences == null) || (evidences.Length == 0) ||
270                                 ((evidences.Length == 1) && (evidences [0].Count == 0))) {
271                                 return new PermissionSet (PermissionState.None);
272                         }
273
274                         // probably not optimal
275                         PermissionSet ps = ResolvePolicy (evidences [0]);
276                         for (int i=1; i < evidences.Length; i++) {
277                                 ps = ps.Intersect (ResolvePolicy (evidences [i]));
278                         }
279                         return ps;
280                 }
281
282                 public static PermissionSet ResolveSystemPolicy (Evidence evidence)
283                 {
284                         // no evidence, no permission
285                         if (evidence == null)
286                                 return new PermissionSet (PermissionState.None);
287
288                         // Note: can't call PolicyHierarchy since ControlPolicy isn't required to resolve policies
289                         PermissionSet ps = null;
290                         IEnumerator ple = Hierarchy;
291                         while (ple.MoveNext ()) {
292                                 PolicyLevel pl = (PolicyLevel) ple.Current;
293                                 if (pl.Type == PolicyLevelType.AppDomain)
294                                         break;
295                                 if (ResolvePolicyLevel (ref ps, pl, evidence))
296                                         break;  // i.e. PolicyStatementAttribute.LevelFinal
297                         }
298
299                         ResolveIdentityPermissions (ps, evidence);
300                         return ps;
301                 }
302
303                 static private SecurityPermission _execution = new SecurityPermission (SecurityPermissionFlag.Execution);
304
305                 public static PermissionSet ResolvePolicy (Evidence evidence, PermissionSet reqdPset, PermissionSet optPset, PermissionSet denyPset, out PermissionSet denied)
306                 {
307                         PermissionSet resolved = ResolvePolicy (evidence);
308                         // do we have the minimal permission requested by the assembly ?
309                         if ((reqdPset != null) && !reqdPset.IsSubsetOf (resolved)) {
310                                 throw new PolicyException (Locale.GetText (
311                                         "Policy doesn't grant the minimal permissions required to execute the assembly."));
312                         }
313
314                         // do we check for execution rights ?
315                         if (CheckExecutionRights) {
316                                 bool execute = false;
317                                 // an empty permissionset doesn't include Execution
318                                 if (resolved != null) {
319                                         // unless we have "Full Trust"...
320                                         if (resolved.IsUnrestricted ()) {
321                                                 execute = true;
322                                         } else {
323                                                 // ... we need to find a SecurityPermission
324                                                 IPermission security = resolved.GetPermission (typeof (SecurityPermission));
325                                                 execute = _execution.IsSubsetOf (security);
326                                         }
327                                 }
328
329                                 if (!execute) {
330                                         throw new PolicyException (Locale.GetText (
331                                                 "Policy doesn't grant the right to execute the assembly."));
332                                 }
333                         }
334
335                         denied = denyPset;
336                         return resolved;
337                 }
338
339                 public static IEnumerator ResolvePolicyGroups (Evidence evidence)
340                 {
341                         if (evidence == null)
342                                 throw new ArgumentNullException ("evidence");
343
344                         ArrayList al = new ArrayList ();
345                         // Note: can't call PolicyHierarchy since ControlPolicy isn't required to resolve policies
346                         IEnumerator ple = Hierarchy;
347                         while (ple.MoveNext ()) {
348                                 PolicyLevel pl = (PolicyLevel) ple.Current;
349                                 CodeGroup cg = pl.ResolveMatchingCodeGroups (evidence);
350                                 al.Add (cg);
351                         }
352                         return al.GetEnumerator ();
353                 }
354
355                 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
356                 public static void SavePolicy () 
357                 {
358                         IEnumerator e = Hierarchy;
359                         while (e.MoveNext ()) {
360                                 PolicyLevel level = (e.Current as PolicyLevel);
361                                 level.Save ();
362                         }
363                 }
364
365                 [SecurityPermission (SecurityAction.Demand, ControlPolicy = true)]
366                 public static void SavePolicyLevel (PolicyLevel level) 
367                 {
368                         // Yes this will throw a NullReferenceException, just like MS (see FDBK13121)
369                         level.Save ();
370                 }
371
372                 // private/internal stuff
373
374                 private static IEnumerator Hierarchy {
375                         get {
376                                 lock (_lockObject) {
377                                         if (_hierarchy == null)
378                                                 InitializePolicyHierarchy ();
379                                 }
380                                 return _hierarchy.GetEnumerator ();
381                         }
382                 }
383
384                 private static void InitializePolicyHierarchy ()
385                 {
386                         string machinePolicyPath = Path.GetDirectoryName (Environment.GetMachineConfigPath ());
387                         // note: use InternalGetFolderPath to avoid recursive policy initialization
388                         string userPolicyPath = Path.Combine (Environment.InternalGetFolderPath (Environment.SpecialFolder.ApplicationData), "mono");
389
390                         PolicyLevel enterprise = new PolicyLevel ("Enterprise", PolicyLevelType.Enterprise);
391                         _level = enterprise;
392                         enterprise.LoadFromFile (Path.Combine (machinePolicyPath, "enterprisesec.config"));
393
394                         PolicyLevel machine = new PolicyLevel ("Machine", PolicyLevelType.Machine);
395                         _level = machine;
396                         machine.LoadFromFile (Path.Combine (machinePolicyPath, "security.config"));
397
398                         PolicyLevel user = new PolicyLevel ("User", PolicyLevelType.User);
399                         _level = user;
400                         user.LoadFromFile (Path.Combine (userPolicyPath, "security.config"));
401
402                         ArrayList al = new ArrayList ();
403                         al.Add (enterprise);
404                         al.Add (machine);
405                         al.Add (user);
406
407                         _hierarchy = ArrayList.Synchronized (al);
408                         _level = null;
409                 }
410
411                 internal static bool ResolvePolicyLevel (ref PermissionSet ps, PolicyLevel pl, Evidence evidence)
412                 {
413                         PolicyStatement pst = pl.Resolve (evidence);
414                         if (pst != null) {
415                                 if (ps == null) {
416                                         // only for initial (first) policy level processed
417                                         ps = pst.PermissionSet;
418                                 } else {
419                                         ps = ps.Intersect (pst.PermissionSet);
420                                         if (ps == null) {
421                                                 // null is equals to None - exist that null can throw NullReferenceException ;-)
422                                                 ps = new PermissionSet (PermissionState.None);
423                                         }
424                                 }
425
426                                 if ((pst.Attributes & PolicyStatementAttribute.LevelFinal) == PolicyStatementAttribute.LevelFinal)
427                                         return true;
428                         }
429                         return false;
430                 }
431
432                 internal static void ResolveIdentityPermissions (PermissionSet ps, Evidence evidence)
433                 {
434                         // in 2.0 identity permissions can now be unrestricted
435                         if (ps.IsUnrestricted ())
436                                 return;
437
438                         // Only host evidence are used for policy resolution
439                         IEnumerator ee = evidence.GetHostEnumerator ();
440                         while (ee.MoveNext ()) {
441                                 IIdentityPermissionFactory ipf = (ee.Current as IIdentityPermissionFactory);
442                                 if (ipf != null) {
443                                         IPermission p = ipf.CreateIdentityPermission (evidence);
444                                         ps.AddPermission (p);
445                                 }
446                         }
447                 }
448
449                 internal static PolicyLevel ResolvingPolicyLevel {
450                         get { return _level; }
451                         set { _level = value; }
452                 }
453
454                 internal static PermissionSet Decode (IntPtr permissions, int length)
455                 {
456                         // Permission sets from the runtime (declarative security) can be cached
457                         // for performance as they can never change (i.e. they are read-only).
458                         PermissionSet ps = null;
459
460                         lock (_lockObject) {
461                                 if (_declsecCache == null) {
462                                         _declsecCache = new Hashtable ();
463                                 }
464
465                                 object key = (object) (int) permissions;
466                                 ps = (PermissionSet) _declsecCache [key];
467                                 if (ps == null) {
468                                         // create permissionset and add it to the cache
469                                         byte[] data = new byte [length];
470                                         Marshal.Copy (permissions, data, 0, length);
471                                         ps = Decode (data);
472                                         ps.DeclarativeSecurity = true;
473                                         _declsecCache.Add (key, ps);
474                                 }
475                         }
476                         return ps;
477                 }
478
479                 internal static PermissionSet Decode (byte[] encodedPermissions)
480                 {
481                         if ((encodedPermissions == null) || (encodedPermissions.Length < 1))
482                                 throw new SecurityException ("Invalid metadata format.");
483
484                         switch (encodedPermissions [0]) {
485                         case 60:
486                                 // Fx 1.0/1.1 declarative security permissions metadata is in Unicode-encoded XML
487                                 string xml = Encoding.Unicode.GetString (encodedPermissions);
488                                 return new PermissionSet (xml);
489                         case 0x2E:
490                                 // Fx 2.0 are encoded "somewhat, but not enough, like" custom attributes
491                                 // note: we still support the older format!
492                                 return PermissionSet.CreateFromBinaryFormat (encodedPermissions);
493                         default:
494                                 throw new SecurityException (Locale.GetText ("Unknown metadata format."));
495                         }
496                 }
497
498                 private static IPermission UnmanagedCode {
499                         get {
500                                 lock (_lockObject) {
501                                         if (_unmanagedCode == null)
502                                                 _unmanagedCode = new SecurityPermission (SecurityPermissionFlag.UnmanagedCode);
503                                 }
504                                 return _unmanagedCode;
505                         }
506                 }
507
508                 //  security check when using reflection
509
510                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
511                 private static unsafe extern bool GetLinkDemandSecurity (MethodBase method, RuntimeDeclSecurityActions *cdecl, RuntimeDeclSecurityActions *mdecl);
512
513                 // When using reflection LinkDemand are promoted to full Demand (i.e. stack walk)
514                 internal unsafe static void ReflectedLinkDemandInvoke (MethodBase mb)
515                 {
516                         RuntimeDeclSecurityActions klass;
517                         RuntimeDeclSecurityActions method;
518
519                         if (!GetLinkDemandSecurity (mb, &klass, &method))
520                                 return;
521
522                         PermissionSet ps = null;
523
524                         if (klass.cas.size > 0) {
525                                 ps = Decode (klass.cas.blob, klass.cas.size);
526                         }
527                         if (klass.noncas.size > 0) {
528                                 PermissionSet p = Decode (klass.noncas.blob, klass.noncas.size);
529                                 ps = (ps == null) ? p : ps.Union (p);
530                         }
531
532                         if (method.cas.size > 0) {
533                                 PermissionSet p = Decode (method.cas.blob, method.cas.size);
534                                 ps = (ps == null) ? p : ps.Union (p);
535                         }
536                         if (method.noncas.size > 0) {
537                                 PermissionSet p = Decode (method.noncas.blob, method.noncas.size);
538                                 ps = (ps == null) ? p : ps.Union (p);
539                         }
540
541                         // in this case we union-ed the permission sets because we want to do 
542                         // a single stack walk (not up to 4).
543                         if (ps != null)
544                                 ps.Demand ();
545                 }
546
547                 internal unsafe static bool ReflectedLinkDemandQuery (MethodBase mb)
548                 {
549                         RuntimeDeclSecurityActions klass;
550                         RuntimeDeclSecurityActions method;
551
552                         if (!GetLinkDemandSecurity (mb, &klass, &method))
553                                 return true;
554
555                         return LinkDemand (mb.ReflectedType.Assembly, &klass, &method);
556                 }
557
558                 private unsafe static bool LinkDemand (Assembly a, RuntimeDeclSecurityActions *klass, RuntimeDeclSecurityActions *method)
559                 {
560                         try {
561                                 PermissionSet ps = null;
562                                 bool result = true;
563                                 if (klass->cas.size > 0) {
564                                         ps = Decode (klass->cas.blob, klass->cas.size);
565                                         result = (SecurityManager.CheckPermissionSet (a, ps, false) == null);
566                                 }
567                                 if (result && (klass->noncas.size > 0)) {
568                                         ps = Decode (klass->noncas.blob, klass->noncas.size);
569                                         result = (SecurityManager.CheckPermissionSet (a, ps, true) == null);
570                                 }
571
572                                 if (result && (method->cas.size > 0)) {
573                                         ps = Decode (method->cas.blob, method->cas.size);
574                                         result = (SecurityManager.CheckPermissionSet (a, ps, false) == null);
575                                 }
576                                 if (result && (method->noncas.size > 0)) {
577                                         ps = Decode (method->noncas.blob, method->noncas.size);
578                                         result = (SecurityManager.CheckPermissionSet (a, ps, true) == null);
579                                 }
580                                 return result;
581                         }
582                         catch (SecurityException) {
583                                 return false;
584                         }
585                 }
586
587 #pragma warning disable 169
588                 private static bool LinkDemandFullTrust (Assembly a)
589                 {
590                         // FullTrust is immutable (and means Unrestricted) 
591                         // so we can skip the subset operations and jump to IsUnrestricted.
592                         PermissionSet granted = a.GrantedPermissionSet;
593                         if ((granted != null) && !granted.IsUnrestricted ())
594                                 return false;
595
596                         PermissionSet denied = a.DeniedPermissionSet;
597                         if ((denied != null) && !denied.IsEmpty ())
598                                 return false;
599
600                         return true;
601                 }
602
603                 private static bool LinkDemandUnmanaged (Assembly a)
604                 {
605                         // note: we know that UnmanagedCode (SecurityPermission) implements IUnrestrictedPermission
606                         return IsGranted (a, UnmanagedCode);
607                 }
608
609                 // we try to provide as much details as possible to help debugging
610                 private static void LinkDemandSecurityException (int securityViolation, IntPtr methodHandle)
611                 {
612                         RuntimeMethodHandle runtimeHandle = new RuntimeMethodHandle (methodHandle);
613                         MethodInfo method = (MethodInfo)(MethodBase.GetMethodFromHandle (runtimeHandle));
614                         Assembly a = method.DeclaringType.Assembly;
615
616                         string message = null;
617                         AssemblyName an = null;
618                         PermissionSet granted = null;
619                         PermissionSet refused = null;
620                         object demanded = null;
621                         IPermission failed = null;
622
623                         if (a != null) {
624                                 an = a.UnprotectedGetName ();
625                                 granted = a.GrantedPermissionSet;
626                                 refused = a.DeniedPermissionSet;
627                         }
628
629                         switch (securityViolation) {
630                         case 1: // MONO_JIT_LINKDEMAND_PERMISSION
631                                 message = Locale.GetText ("Permissions refused to call this method.");
632                                 break;
633                         case 2: // MONO_JIT_LINKDEMAND_APTC
634                                 message = Locale.GetText ("Partially trusted callers aren't allowed to call into this assembly.");
635                                 demanded = (object) DefaultPolicies.FullTrust; // immutable
636                                 break;
637                         case 4: // MONO_JIT_LINKDEMAND_ECMA
638                                 message = Locale.GetText ("Calling internal calls is restricted to ECMA signed assemblies.");
639                                 break;
640                         case 8: // MONO_JIT_LINKDEMAND_PINVOKE
641                                 message = Locale.GetText ("Calling unmanaged code isn't allowed from this assembly.");
642                                 demanded = (object) _unmanagedCode;
643                                 failed = _unmanagedCode;
644                                 break;
645                         default:
646                                 message = Locale.GetText ("JIT time LinkDemand failed.");
647                                 break;
648                         }
649
650                         throw new SecurityException (message, an, granted, refused, method, SecurityAction.LinkDemand, demanded, failed, null);
651                 }
652
653                 private static void InheritanceDemandSecurityException (int securityViolation, Assembly a, Type t, MethodInfo method)
654                 {
655                         string message = null;
656                         AssemblyName an = null;
657                         PermissionSet granted = null;
658                         PermissionSet refused = null;
659
660                         if (a != null) {
661                                 an = a.UnprotectedGetName ();
662                                 granted = a.GrantedPermissionSet;
663                                 refused = a.DeniedPermissionSet;
664                         }
665
666                         switch (securityViolation) {
667                         case 1: // MONO_METADATA_INHERITANCEDEMAND_CLASS
668                                 message = String.Format (Locale.GetText ("Class inheritance refused for {0}."), t);
669                                 break;
670                         case 2: // MONO_METADATA_INHERITANCEDEMAND_CLASS
671                                 message = Locale.GetText ("Method override refused.");
672                                 break;
673                         default:
674                                 message = Locale.GetText ("Load time InheritDemand failed.");
675                                 break;
676                         }
677
678                         throw new SecurityException (message, an, granted, refused, method, SecurityAction.InheritanceDemand, null, null, null);
679                 }
680
681                 // called by the runtime when CoreCLR is enabled
682
683                 private static void ThrowException (Exception ex)
684                 {
685                         throw ex;
686                 }
687
688                 // internal - get called by the class loader
689
690                 // Called when
691                 // - class inheritance
692                 // - method overrides
693                 private unsafe static bool InheritanceDemand (AppDomain ad, Assembly a, RuntimeDeclSecurityActions *actions)
694                 {
695                         try {
696                                 PermissionSet ps = null;
697                                 bool result = true;
698                                 if (actions->cas.size > 0) {
699                                         ps = Decode (actions->cas.blob, actions->cas.size);
700                                         result = (SecurityManager.CheckPermissionSet (a, ps, false) == null);
701                                         if (result) {
702                                                 // also check appdomain
703                                                 result = (SecurityManager.CheckPermissionSet (ad, ps) == null);
704                                         }
705                                 }
706                                 if (actions->noncas.size > 0) {
707                                         ps = Decode (actions->noncas.blob, actions->noncas.size);
708                                         result = (SecurityManager.CheckPermissionSet (a, ps, true) == null);
709                                         if (result) {
710                                                 // also check appdomain
711                                                 result = (SecurityManager.CheckPermissionSet (ad, ps) == null);
712                                         }
713                                 }
714                                 return result;
715                         }
716                         catch (SecurityException) {
717                                 return false;
718                         }
719                 }
720
721                 // internal - get called at JIT time
722
723                 private static void DemandUnmanaged ()
724                 {
725                         UnmanagedCode.Demand ();
726                 }
727
728                 // internal - get called by JIT generated code
729
730                 private static void InternalDemand (IntPtr permissions, int length)
731                 {
732                         PermissionSet ps = Decode (permissions, length);
733                         ps.Demand ();
734                 }
735
736                 private static void InternalDemandChoice (IntPtr permissions, int length)
737                 {
738                         throw new SecurityException ("SecurityAction.DemandChoice was removed from 2.0");
739                 }
740 #pragma warning restore 169             
741         }
742 }
743
744 #endif
745