Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / mscorlib / system / security / securitymanager.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // <OWNER>Microsoft</OWNER>
7 // 
8
9 //
10 // SecurityManager.cs
11 //
12 // The SecurityManager class provides a general purpose API for interacting
13 // with the security system.
14 //
15
16 namespace System.Security {
17     using System;
18     using System.Security.Util;
19     using System.Security.Policy;
20     using System.Security.Permissions;
21     using System.Collections;
22     using System.Runtime.InteropServices;
23     using System.Runtime.CompilerServices;
24 #if FEATURE_CLICKONCE
25     using System.Runtime.Hosting;
26 #endif // FEATURE_CLICKONCE
27     using System.Text;
28     using System.Threading;
29     using System.Reflection;
30     using System.IO;
31     using System.Globalization;
32     using System.Runtime.Versioning;
33     using System.Diagnostics.Contracts;
34
35     [Serializable]
36     [System.Runtime.InteropServices.ComVisible(true)]
37     public enum PolicyLevelType
38     {
39         User = 0,
40         Machine = 1,
41         Enterprise = 2,
42         AppDomain = 3
43     }
44
45     [System.Runtime.InteropServices.ComVisible(true)]
46     static public class SecurityManager {
47 #if FEATURE_CAS_POLICY
48         private static volatile SecurityPermission executionSecurityPermission = null;
49
50         private static PolicyManager polmgr = new PolicyManager();
51         internal static PolicyManager PolicyManager {
52             get {
53                 return polmgr;
54             }
55         }
56
57         //
58         // Public APIs
59         //
60         [System.Security.SecuritySafeCritical]  // auto-generated
61         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
62         [Obsolete("IsGranted is obsolete and will be removed in a future release of the .NET Framework.  Please use the PermissionSet property of either AppDomain or Assembly instead.")]
63         public static bool IsGranted( IPermission perm )
64         {
65             if (perm == null)
66                 return true;
67
68             PermissionSet granted = null, denied = null;
69             StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
70             GetGrantedPermissions( JitHelpers.GetObjectHandleOnStack(ref granted),
71                                    JitHelpers.GetObjectHandleOnStack(ref denied),
72                                    JitHelpers.GetStackCrawlMarkHandle(ref stackMark) );
73             return granted.Contains( perm ) && (denied == null || !denied.Contains( perm ));
74         }
75
76         // Get a sandbox permission set that the CLR considers safe to grant an application with the given
77         // evidence.  Note that this API is not a policy API, but rather a host helper API so that a host can
78         // determine if an application's requested permission set is reasonable.  This is esentially just a
79         // hard coded mapping of Zone -> Sandbox and is not configurable in any way.
80         public static PermissionSet GetStandardSandbox(Evidence evidence)
81         {
82             if (evidence == null)
83                 throw new ArgumentNullException("evidence");
84             Contract.EndContractBlock();
85
86             //
87             // The top-level switch for grant set is based upon Zone
88             //   MyComputer -> FullTrust
89             //   Intranet   -> LocalIntranet
90             //   Trusted    -> Internet
91             //   Internet   -> Internet
92             //   All else   -> Nothing
93             //   
94             //   Both the Internet and LocalIntranet zones can have permission set extensions applied to them
95             //   if there is Activation.
96             //   
97
98             Zone zone = evidence.GetHostEvidence<Zone>();
99             if (zone == null)
100             {
101                 return new PermissionSet(PermissionState.None);
102             }
103 #if FEATURE_CAS_POLICY
104             else if (zone.SecurityZone == SecurityZone.MyComputer)
105             {
106                 return new PermissionSet(PermissionState.Unrestricted);
107             }
108             else if (zone.SecurityZone == SecurityZone.Intranet)
109             {
110                 PermissionSet intranetGrantSet = BuiltInPermissionSets.LocalIntranet;
111
112                 // We also need to add in same site web and file IO permission
113                 PolicyStatement webPolicy =
114                     new NetCodeGroup(new AllMembershipCondition()).Resolve(evidence);
115                 PolicyStatement filePolicy =
116                     new FileCodeGroup(new AllMembershipCondition(), FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery).Resolve(evidence);
117
118                 if (webPolicy != null)
119                 {
120                     intranetGrantSet.InplaceUnion(webPolicy.PermissionSet);
121                 }
122                 if (filePolicy != null)
123                 {
124                     intranetGrantSet.InplaceUnion(filePolicy.PermissionSet);
125                 }
126
127                 return intranetGrantSet;
128             }
129             else if (zone.SecurityZone == SecurityZone.Internet ||
130                      zone.SecurityZone == SecurityZone.Trusted)
131             {
132                 PermissionSet internetGrantSet = BuiltInPermissionSets.Internet;
133
134                 // We also need to add in same site web permission
135                 PolicyStatement webPolicy =
136                     new NetCodeGroup(new AllMembershipCondition()).Resolve(evidence);
137
138                 if (webPolicy != null)
139                 {
140                     internetGrantSet.InplaceUnion(webPolicy.PermissionSet);
141                 }
142
143                 return internetGrantSet;
144             }
145 #endif // FEATURE_CAS_POLICY
146             else
147             {
148                 return new PermissionSet(PermissionState.None);
149             }
150         }
151
152         /// <internalonly/>
153         [System.Security.SecurityCritical]  // auto-generated_required
154         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
155         static public void GetZoneAndOrigin( out ArrayList zone, out ArrayList origin )
156         {
157             StackCrawlMark mark = StackCrawlMark.LookForMyCaller;
158             CodeAccessSecurityEngine.GetZoneAndOrigin( ref mark, out zone, out origin );
159         }
160         [System.Security.SecuritySafeCritical]  // auto-generated
161         [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
162         [ResourceExposure(ResourceScope.Machine)]
163         [ResourceConsumption(ResourceScope.Machine)]
164         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
165         static public PolicyLevel LoadPolicyLevelFromFile(string path, PolicyLevelType type)
166         {
167             if (path == null)
168                throw new ArgumentNullException( "path" );
169             Contract.EndContractBlock();
170
171             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
172             {
173                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
174             }
175
176             // We need to retain V1.x compatibility by throwing the same exception type.
177             if (!File.InternalExists(path))
178                 throw new ArgumentException( Environment.GetResourceString("Argument_PolicyFileDoesNotExist"));
179
180             String fullPath = Path.GetFullPath( path );
181
182             FileIOPermission perm = new FileIOPermission( PermissionState.None );
183             perm.AddPathList( FileIOPermissionAccess.Read, fullPath );
184             perm.AddPathList( FileIOPermissionAccess.Write, fullPath );
185             perm.Demand();
186
187             using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read)) {
188                 using (StreamReader reader = new StreamReader(stream)) {
189                     return LoadPolicyLevelFromStringHelper(reader.ReadToEnd(), path, type);
190                 }
191             }
192         }
193
194         [System.Security.SecuritySafeCritical]  // auto-generated
195         [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
196         [ResourceExposure(ResourceScope.None)]
197         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
198         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
199         static public PolicyLevel LoadPolicyLevelFromString(string str, PolicyLevelType type)
200         {
201             return LoadPolicyLevelFromStringHelper(str, null, type);
202         }
203
204         [ResourceExposure(ResourceScope.Machine)]
205         [ResourceConsumption(ResourceScope.Machine)]
206         private static PolicyLevel LoadPolicyLevelFromStringHelper (string str, string path, PolicyLevelType type)
207         {
208             if (str == null)
209                 throw new ArgumentNullException( "str" );
210             Contract.EndContractBlock();
211
212             PolicyLevel level = new PolicyLevel(type, path);
213
214             Parser parser = new Parser( str );
215             SecurityElement elRoot = parser.GetTopElement();
216             if (elRoot == null)
217                 throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "configuration" ) );
218
219             SecurityElement elMscorlib = elRoot.SearchForChildByTag( "mscorlib" );
220             if (elMscorlib == null)
221                 throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "mscorlib" ) );
222
223             SecurityElement elSecurity = elMscorlib.SearchForChildByTag( "security" );
224             if (elSecurity == null)
225                 throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "security" ) );
226
227             SecurityElement elPolicy = elSecurity.SearchForChildByTag( "policy" );
228             if (elPolicy == null)
229                 throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "policy" ) );
230
231             SecurityElement elPolicyLevel = elPolicy.SearchForChildByTag( "PolicyLevel" );
232             if (elPolicyLevel != null)
233                 level.FromXml( elPolicyLevel );
234             else
235                 throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, Environment.GetResourceString( "Policy_BadXml" ), "PolicyLevel" ) );
236
237             return level;
238         }
239
240         [System.Security.SecuritySafeCritical]  // auto-generated
241         [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
242         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
243         static public void SavePolicyLevel( PolicyLevel level )
244         {
245             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
246             {
247                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
248             }
249
250             PolicyManager.EncodeLevel( level );
251         }
252
253         [System.Security.SecuritySafeCritical]  // auto-generated
254         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
255         static public PermissionSet ResolvePolicy(Evidence evidence,
256                                                   PermissionSet reqdPset,
257                                                   PermissionSet optPset,
258                                                   PermissionSet denyPset,
259                                                   out PermissionSet denied)
260         {
261             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
262             {
263                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
264             }
265
266             return ResolvePolicy(evidence, reqdPset, optPset, denyPset, out denied, true);
267         }
268
269         [System.Security.SecuritySafeCritical]  // auto-generated
270         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
271         static public PermissionSet ResolvePolicy(Evidence evidence)
272         {
273             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
274             {
275                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
276             }
277
278             // If we aren't passed any evidence, just make an empty object
279             if (evidence == null)
280             {
281                 evidence = new Evidence();
282             }
283
284             return polmgr.Resolve(evidence);
285         }
286
287         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
288         static public PermissionSet ResolvePolicy( Evidence[] evidences )
289         {
290             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
291             {
292                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
293             }
294
295             if (evidences == null || evidences.Length == 0)
296                 evidences = new Evidence[] { null };
297
298             PermissionSet retval = ResolvePolicy( evidences[0] );
299             if (retval == null)
300                 return null;
301
302             for (int i = 1; i < evidences.Length; ++i)
303             {
304                 retval = retval.Intersect( ResolvePolicy( evidences[i] ) );
305                 if (retval == null || retval.IsEmpty())
306                     return retval;
307             }
308
309             return retval;
310         }
311
312 #if FEATURE_CAS_POLICY
313         // Determine if the current thread would require a security context capture if the security state of
314         // the thread needs to be re-created at a later point in time.  This can be used, for instance, if
315         // sensitive data is being obtained after security demands succeed, and that data is to be cached. 
316         // If there is an Assert up the stack, then we wouldn't want to cache the data without capturing the
317         // corresponding security context to go along with it - otherwise we risk leaking data obtained
318         // under an assert to code which may no longer be running with that assert in place.
319         // 
320         // A return value of false indicates that the CLR guarantees all of the following conditions are true:
321         //   1. No partial trust AppDomains are on the stack
322         //   2. No partial trust assemblies are on the stack
323         //   3. There are no currently active PermitOnly or Deny modifiers on the stack
324         //   
325         // A return value of true means only that the CLR cannot guarantee that all of the conditions are
326         // true, and not that one of the conditions really is false.
327         // 
328         // IMPORTANT: The above means is only reliable in the false return case.  If we say that the thread
329         // does not require a context capture, then that answer is guaranteed to be correct.  However, we may
330         // say that the thread does require a capture when it does not actually strictly need to capture the
331         // state.  This is fine, as being overly conservative when capturing context will not lead to
332         // security holes; being overly agresssive in avoding the capture could lead to holes however.
333         // 
334         // This API is SecurityCritical because its main use is to optimize away unnecessary security
335         // context captures, which means that the code using it is security sensitive and needs to be audited.
336         [SecurityCritical]
337         public static bool CurrentThreadRequiresSecurityContextCapture()
338         {
339             // If we know that the thread is not made up of entirely full trust code, and that there are no
340             // security stack modifiers on the thread, then there is no need to capture a security context.
341             return !CodeAccessSecurityEngine.QuickCheckForAllDemands();
342         }
343 #endif // FEATURE_CAS_POLICY
344
345         //
346         // This method resolves the policy for the specified evidence, but it
347         // ignores the AppDomain level even when one is available in the current policy.
348         //
349
350         [System.Security.SecuritySafeCritical]  // auto-generated
351         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
352         public static PermissionSet ResolveSystemPolicy (Evidence evidence)
353         {
354             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
355             {
356                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
357             }
358
359             if (PolicyManager.IsGacAssembly(evidence))
360             {
361                 return new PermissionSet(PermissionState.Unrestricted);
362             }
363
364             return polmgr.CodeGroupResolve(evidence, true);
365         }
366
367         [System.Security.SecuritySafeCritical]  // auto-generated
368         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
369         static public IEnumerator ResolvePolicyGroups(Evidence evidence)
370         {
371             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
372             {
373                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
374             }
375
376             return polmgr.ResolveCodeGroups(evidence);
377         }
378
379         [System.Security.SecuritySafeCritical]  // auto-generated
380         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
381         public static IEnumerator PolicyHierarchy()
382         {
383             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
384             {
385                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
386             }
387
388             return polmgr.PolicyHierarchy();
389         }
390
391         [System.Security.SecuritySafeCritical]  // auto-generated
392         [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPolicy )]
393         [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
394         public static void SavePolicy()
395         {
396             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
397             {
398                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
399             }
400
401             polmgr.Save();
402         }
403
404
405         [System.Security.SecurityCritical]  // auto-generated
406         private static PermissionSet ResolveCasPolicy(Evidence evidence,
407                                                       PermissionSet reqdPset,
408                                                       PermissionSet optPset,
409                                                       PermissionSet denyPset,
410                                                       out PermissionSet denied,
411                                                       out int securitySpecialFlags,
412                                                       bool checkExecutionPermission)
413         {
414             Contract.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled);
415
416             CodeAccessPermission.Assert(true);
417
418             PermissionSet granted = ResolvePolicy(evidence,
419                                                   reqdPset,
420                                                   optPset,
421                                                   denyPset,
422                                                   out denied,
423                                                   checkExecutionPermission);
424
425             securitySpecialFlags = SecurityManager.GetSpecialFlags(granted, denied);
426             return granted;
427         }
428
429         [System.Security.SecurityCritical]  // auto-generated
430         static private PermissionSet ResolvePolicy(Evidence evidence,
431                            PermissionSet reqdPset,
432                            PermissionSet optPset,
433                            PermissionSet denyPset,
434                            out PermissionSet denied,
435                            bool checkExecutionPermission)
436         {
437             Contract.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled);
438
439             if (executionSecurityPermission == null)
440                 executionSecurityPermission = new SecurityPermission(SecurityPermissionFlag.Execution);
441
442             PermissionSet requested = null;
443             PermissionSet optional;
444             PermissionSet allowed;
445
446             Exception savedException = null;
447
448             // We don't want to recurse back into here as a result of a
449             // stackwalk during resolution. So simply assert full trust (this
450             // implies that custom permissions cannot use any permissions that
451             // don't implement IUnrestrictedPermission.
452             // PermissionSet.s_fullTrust.Assert();
453
454             // The requested set is the union of the minimal request and the
455             // optional request. Minimal request defaults to empty, optional
456             // is "AllPossible" (includes any permission that can be defined)
457             // which is symbolized by null.
458             optional = optPset;
459
460             if (reqdPset == null)
461                 requested = optional;
462             else
463                 // If optional is null, the requested set becomes null/"AllPossible".
464                 requested = optional == null ? null : reqdPset.Union(optional);
465
466             // Make sure that the right to execute is requested (if this feature is
467             // enabled).
468
469             if (requested != null && !requested.IsUnrestricted())
470                 requested.AddPermission( executionSecurityPermission );
471
472             // If we aren't passed any evidence, just make an empty object
473             if (evidence == null)
474             {
475                 evidence = new Evidence();
476             }
477
478             allowed = polmgr.Resolve(evidence);
479             // Intersect the grant with the RequestOptional
480             if (requested != null)
481                 allowed.InplaceIntersect(requested);
482
483             // Check that we were granted the right to execute.
484             if (checkExecutionPermission)
485             {
486                 if (!allowed.Contains(executionSecurityPermission) ||
487                     (denyPset != null && denyPset.Contains(executionSecurityPermission)))
488                 {
489                     throw new PolicyException(Environment.GetResourceString("Policy_NoExecutionPermission"),
490                                               System.__HResults.CORSEC_E_NO_EXEC_PERM,
491                                               savedException);
492                 }
493             }
494
495             // Check that we were granted at least the minimal set we asked for. Do
496             // this before pruning away any overlap with the refused set so that
497             // users have the flexability of defining minimal permissions that are
498             // only expressable as set differences (e.g. allow access to "C:\" but
499             // disallow "C:\Windows").
500             if (reqdPset != null && !reqdPset.IsSubsetOf(allowed))
501             {
502                 BCLDebug.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled, "Evaluating assembly level declarative security without legacy CAS policy enabled");
503                 throw new PolicyException(Environment.GetResourceString( "Policy_NoRequiredPermission" ),
504                                           System.__HResults.CORSEC_E_MIN_GRANT_FAIL,
505                                           savedException );
506             }
507
508             // Remove any granted permissions that are safe subsets of some denied
509             // permission. The remaining denied permissions (if any) are returned
510             // along with the modified grant set for use in checks.
511             if (denyPset != null)
512             {
513                 BCLDebug.Assert(AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled, "Evaluating assembly level declarative security without legacy CAS policy enabled");
514                 denied = denyPset.Copy();
515                 allowed.MergeDeniedSet(denied);
516                 if (denied.IsEmpty())
517                     denied = null;
518             }
519             else
520                 denied = null;
521
522             allowed.IgnoreTypeLoadFailures = true;
523
524             return allowed;
525         }
526
527         [Obsolete("Because execution permission checks can no longer be turned off, the CheckExecutionRights property no longer has any effect.")]
528         static public bool CheckExecutionRights
529         {
530             get { return true; }
531
532             set
533             {
534                 // The setter for this property is a no-op since execution checking can no longer be turned off
535             }
536         }
537
538         [Obsolete("Because security can no longer be turned off, the SecurityEnabled property no longer has any effect.")]
539         public static bool SecurityEnabled
540         {
541             get { return true; }
542
543             set
544             {
545                 // The setter for this property is a no-op since security cannot be turned off
546             }
547         }
548 #endif // #if FEATURE_CAS_POLICY
549
550         private static int[][] s_BuiltInPermissionIndexMap = {
551             new int[] { BuiltInPermissionIndex.EnvironmentPermissionIndex, (int) PermissionType.EnvironmentPermission },
552             new int[] { BuiltInPermissionIndex.FileDialogPermissionIndex, (int) PermissionType.FileDialogPermission },
553             new int[] { BuiltInPermissionIndex.FileIOPermissionIndex, (int) PermissionType.FileIOPermission },
554             new int[] { BuiltInPermissionIndex.ReflectionPermissionIndex, (int) PermissionType.ReflectionPermission },
555             new int[] { BuiltInPermissionIndex.SecurityPermissionIndex, (int) PermissionType.SecurityPermission },
556             new int[] { BuiltInPermissionIndex.UIPermissionIndex, (int) PermissionType.UIPermission }
557         };
558
559         private static CodeAccessPermission[] s_UnrestrictedSpecialPermissionMap = {
560             new EnvironmentPermission(PermissionState.Unrestricted),
561             new FileDialogPermission(PermissionState.Unrestricted),
562             new FileIOPermission(PermissionState.Unrestricted),
563             new ReflectionPermission(PermissionState.Unrestricted),
564             new SecurityPermission(PermissionState.Unrestricted),
565             new UIPermission(PermissionState.Unrestricted)
566         };
567
568         internal static int GetSpecialFlags (PermissionSet grantSet, PermissionSet deniedSet) {
569             if ((grantSet != null && grantSet.IsUnrestricted()) && (deniedSet == null || deniedSet.IsEmpty())) {
570                 return -1;
571             }
572             else {
573                 SecurityPermission securityPermission = null;
574 #pragma warning disable 618
575                 SecurityPermissionFlag securityPermissionFlags = SecurityPermissionFlag.NoFlags;
576 #pragma warning restore 618
577                 ReflectionPermission reflectionPermission = null;
578                 ReflectionPermissionFlag reflectionPermissionFlags = ReflectionPermissionFlag.NoFlags;
579
580                 CodeAccessPermission[] specialPermissions = new CodeAccessPermission[6];
581                 if (grantSet != null) {
582                     if (grantSet.IsUnrestricted()) {
583                         securityPermissionFlags = SecurityPermissionFlag.AllFlags;
584                         reflectionPermissionFlags = ReflectionPermission.AllFlagsAndMore;
585                         for (int i = 0; i < specialPermissions.Length; i++) {
586                             specialPermissions[i] = s_UnrestrictedSpecialPermissionMap[i];
587                         }
588                     }
589                     else {
590                         securityPermission = grantSet.GetPermission(BuiltInPermissionIndex.SecurityPermissionIndex) as SecurityPermission;
591                         if (securityPermission != null)
592                             securityPermissionFlags = securityPermission.Flags;
593                         reflectionPermission = grantSet.GetPermission(BuiltInPermissionIndex.ReflectionPermissionIndex) as ReflectionPermission;
594                         if (reflectionPermission != null)
595                             reflectionPermissionFlags = reflectionPermission.Flags;
596                         for (int i = 0; i < specialPermissions.Length; i++) {
597                             specialPermissions[i] = grantSet.GetPermission(s_BuiltInPermissionIndexMap[i][0]) as CodeAccessPermission;
598                         }
599                     }
600                 }
601
602                 if (deniedSet != null) {
603                     if (deniedSet.IsUnrestricted()) {
604                         securityPermissionFlags = SecurityPermissionFlag.NoFlags;
605                         reflectionPermissionFlags = ReflectionPermissionFlag.NoFlags;
606                         for (int i = 0; i < s_BuiltInPermissionIndexMap.Length; i++) {
607                             specialPermissions[i] = null;
608                         }
609                     }
610                     else {
611                         securityPermission = deniedSet.GetPermission(BuiltInPermissionIndex.SecurityPermissionIndex) as SecurityPermission;
612                         if (securityPermission != null)
613                             securityPermissionFlags &= ~securityPermission.Flags;
614                         reflectionPermission = deniedSet.GetPermission(BuiltInPermissionIndex.ReflectionPermissionIndex) as ReflectionPermission;
615                         if (reflectionPermission != null)
616                             reflectionPermissionFlags &= ~reflectionPermission.Flags;
617                         for (int i = 0; i < s_BuiltInPermissionIndexMap.Length; i++) {
618                             CodeAccessPermission deniedSpecialPermission = deniedSet.GetPermission(s_BuiltInPermissionIndexMap[i][0]) as CodeAccessPermission;
619                             if (deniedSpecialPermission != null && !deniedSpecialPermission.IsSubsetOf(null))
620                                 specialPermissions[i] = null; // we don't care about the exact value here.
621                         }
622                     }
623                 }
624                 int flags = MapToSpecialFlags(securityPermissionFlags, reflectionPermissionFlags);
625                 if (flags != -1) {
626                     for (int i = 0; i < specialPermissions.Length; i++) {
627                         if (specialPermissions[i] != null && ((IUnrestrictedPermission) specialPermissions[i]).IsUnrestricted())
628                             flags |= (1 << (int) s_BuiltInPermissionIndexMap[i][1]);
629                     }
630                 }
631                 return flags;
632             }
633         }
634
635 #pragma warning disable 618
636         private static int MapToSpecialFlags (SecurityPermissionFlag securityPermissionFlags, ReflectionPermissionFlag reflectionPermissionFlags) {
637 #pragma warning restore 618
638             int flags = 0;
639 #pragma warning disable 618
640             if ((securityPermissionFlags & SecurityPermissionFlag.UnmanagedCode) == SecurityPermissionFlag.UnmanagedCode)
641 #pragma warning restore 618
642                 flags |= (1 << (int) PermissionType.SecurityUnmngdCodeAccess);
643             if ((securityPermissionFlags & SecurityPermissionFlag.SkipVerification) == SecurityPermissionFlag.SkipVerification)
644                 flags |= (1 << (int) PermissionType.SecuritySkipVerification);
645             if ((securityPermissionFlags & SecurityPermissionFlag.Assertion) == SecurityPermissionFlag.Assertion)
646                 flags |= (1 << (int) PermissionType.SecurityAssert);
647             if ((securityPermissionFlags & SecurityPermissionFlag.SerializationFormatter) == SecurityPermissionFlag.SerializationFormatter)
648                 flags |= (1 << (int) PermissionType.SecuritySerialization);
649             if ((securityPermissionFlags & SecurityPermissionFlag.BindingRedirects) == SecurityPermissionFlag.BindingRedirects)
650                 flags |= (1 << (int) PermissionType.SecurityBindingRedirects);
651             if ((securityPermissionFlags & SecurityPermissionFlag.ControlEvidence) == SecurityPermissionFlag.ControlEvidence)
652                 flags |= (1 << (int) PermissionType.SecurityControlEvidence);
653             if ((securityPermissionFlags & SecurityPermissionFlag.ControlPrincipal) == SecurityPermissionFlag.ControlPrincipal)
654                 flags |= (1 << (int) PermissionType.SecurityControlPrincipal);
655
656             if ((reflectionPermissionFlags & ReflectionPermissionFlag.RestrictedMemberAccess) == ReflectionPermissionFlag.RestrictedMemberAccess)
657                 flags |= (1 << (int)PermissionType.ReflectionRestrictedMemberAccess);
658             if ((reflectionPermissionFlags & ReflectionPermissionFlag.MemberAccess) == ReflectionPermissionFlag.MemberAccess)
659                 flags |= (1 << (int) PermissionType.ReflectionMemberAccess);
660
661             return flags;
662         }
663         
664         [System.Security.SecurityCritical]  // auto-generated
665         [ResourceExposure(ResourceScope.None)]
666         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
667         [SuppressUnmanagedCodeSecurity]
668         internal static extern bool IsSameType(String strLeft, String strRight);
669
670         [System.Security.SecurityCritical]  // auto-generated
671         [ResourceExposure(ResourceScope.None)]
672         [MethodImplAttribute(MethodImplOptions.InternalCall)]
673         internal static extern bool _SetThreadSecurity(bool bThreadSecurity);
674
675         [System.Security.SecurityCritical]  // auto-generated
676         [ResourceExposure(ResourceScope.None)]
677         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
678         [SuppressUnmanagedCodeSecurity]
679         internal static extern void GetGrantedPermissions(ObjectHandleOnStack retGranted, ObjectHandleOnStack retDenied, StackCrawlMarkHandle stackMark);
680     }
681 }