7989ee4dbd5a2108106718265337c68d75407ddd
[mono.git] / mcs / class / referencesource / mscorlib / system / security / securityruntime.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // <OWNER>Microsoft</OWNER>
7 // 
8
9 namespace System.Security {
10     using System;
11     using System.Globalization;
12     using System.Threading;
13     using System.Reflection;
14     using System.Collections;
15     using System.Runtime.CompilerServices;
16     using System.Security.Permissions;
17     using System.Runtime.Versioning;
18     using System.Diagnostics.Contracts;
19
20     internal class SecurityRuntime
21     {
22         private SecurityRuntime(){}
23
24         // Returns the security object for the caller of the method containing
25         // 'stackMark' on its frame.
26         //
27         // THE RETURNED OBJECT IS THE LIVE RUNTIME OBJECT. BE CAREFUL WITH IT!
28         //
29         // Internal only, do not doc.
30         // 
31         [System.Security.SecurityCritical]  // auto-generated
32         [ResourceExposure(ResourceScope.None)]
33         [MethodImplAttribute(MethodImplOptions.InternalCall)]
34         internal static extern 
35         FrameSecurityDescriptor GetSecurityObjectForFrame(ref StackCrawlMark stackMark,
36                                                           bool create);
37
38         // Constants used to return status to native
39         internal const bool StackContinue  = true;
40         internal const bool StackHalt      = false;
41
42         // this method is a big perf hit, so don't call unnecessarily
43         [System.Security.SecurityCritical]  // auto-generated
44         internal static MethodInfo GetMethodInfo(RuntimeMethodHandleInternal rmh)
45         {
46             if (rmh.IsNullHandle())
47                 return null;
48
49 #if _DEBUG
50             try
51             {
52 #endif
53                 // Assert here because reflection will check grants and if we fail the check,
54                 // there will be an infinite recursion that overflows the stack.
55                 PermissionSet.s_fullTrust.Assert();
56                 return (System.RuntimeType.GetMethodBase(RuntimeMethodHandle.GetDeclaringType(rmh), rmh) as MethodInfo);
57 #if _DEBUG
58             }
59             catch(Exception)
60             {
61                 return null;
62             }
63 #endif
64         }
65
66         [System.Security.SecurityCritical]  // auto-generated
67         private static bool FrameDescSetHelper(FrameSecurityDescriptor secDesc,
68                                                PermissionSet demandSet,
69                                                out PermissionSet alteredDemandSet,
70                                                RuntimeMethodHandleInternal rmh)
71         {
72             return secDesc.CheckSetDemand(demandSet, out alteredDemandSet, rmh);
73         }
74
75         [System.Security.SecurityCritical]  // auto-generated
76         private static bool FrameDescHelper(FrameSecurityDescriptor secDesc,
77                                                IPermission demandIn, 
78                                                PermissionToken permToken,
79                                                RuntimeMethodHandleInternal rmh)
80         {
81             return secDesc.CheckDemand((CodeAccessPermission) demandIn, permToken, rmh);
82         }
83
84 #if FEATURE_COMPRESSEDSTACK
85         [System.Security.SecurityCritical]
86         private static bool CheckDynamicMethodSetHelper(System.Reflection.Emit.DynamicResolver dynamicResolver,
87                                                      PermissionSet demandSet,
88                                                      out PermissionSet alteredDemandSet,
89                                                      RuntimeMethodHandleInternal rmh)
90         {
91             System.Threading.CompressedStack creationStack = dynamicResolver.GetSecurityContext();
92             bool result;
93             try
94             {
95                 result = creationStack.CheckSetDemandWithModificationNoHalt(demandSet, out alteredDemandSet, rmh);
96             }
97             catch (SecurityException ex)
98             {
99                 throw new SecurityException(Environment.GetResourceString("Security_AnonymouslyHostedDynamicMethodCheckFailed"), ex);
100             }
101             
102             return result;
103         }
104
105         [System.Security.SecurityCritical]
106         private static bool CheckDynamicMethodHelper(System.Reflection.Emit.DynamicResolver dynamicResolver,
107                                              IPermission demandIn, 
108                                              PermissionToken permToken,
109                                              RuntimeMethodHandleInternal rmh)
110         {
111             System.Threading.CompressedStack creationStack = dynamicResolver.GetSecurityContext();
112             bool result;
113             try
114             {
115                 result = creationStack.CheckDemandNoHalt((CodeAccessPermission)demandIn, permToken, rmh);
116             }
117             catch (SecurityException ex)
118             {
119                 throw new SecurityException(Environment.GetResourceString("Security_AnonymouslyHostedDynamicMethodCheckFailed"), ex);
120             }
121             return result;
122         }
123 #endif // FEATURE_COMPRESSEDSTACK
124
125         //
126         // API for PermissionSets
127         //
128         
129         [System.Security.SecurityCritical]  // auto-generated
130         internal static void Assert(PermissionSet permSet, ref StackCrawlMark stackMark)
131         {
132             // Note: if the "AssertPermission" is not a permission that implements IUnrestrictedPermission
133             // you need to change the fourth parameter to a zero.
134             FrameSecurityDescriptor secObj = CodeAccessSecurityEngine.CheckNReturnSO(
135                                                 CodeAccessSecurityEngine.AssertPermissionToken,
136                                                 CodeAccessSecurityEngine.AssertPermission,
137                                                 ref stackMark,
138                                                 1 );
139             
140             Contract.Assert(secObj != null,"Failure in SecurityRuntime.Assert() - secObj != null");
141             if (secObj == null)
142             {
143                 // Security: REQ_SQ flag is missing. Bad compiler ?
144                 System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
145             }
146             else
147             {
148                 if (secObj.HasImperativeAsserts())
149                     throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
150
151                 secObj.SetAssert(permSet);
152             }
153         }
154     
155         [System.Security.SecurityCritical]  // auto-generated
156         internal static void AssertAllPossible(ref StackCrawlMark stackMark)
157         {
158             FrameSecurityDescriptor secObj =
159                 SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
160     
161             Contract.Assert(secObj != null, "Failure in SecurityRuntime.AssertAllPossible() - secObj != null");
162             if (secObj == null)
163             {
164                 // Security: REQ_SQ flag is missing. Bad compiler ?
165                 System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
166             }
167             else
168             {
169                 if (secObj.GetAssertAllPossible())
170                     throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
171
172                 secObj.SetAssertAllPossible();
173             }
174         }
175     
176         [System.Security.SecurityCritical]  // auto-generated
177         internal static void Deny(PermissionSet permSet, ref StackCrawlMark stackMark)
178         {
179 #if FEATURE_CAS_POLICY
180             // Deny is only valid in legacy mode
181             if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
182             {
183                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_CasDeny"));
184             }
185 #endif // FEATURE_CAS_POLICY
186
187             FrameSecurityDescriptor secObj =
188                 SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
189     
190             Contract.Assert(secObj != null, "Failure in SecurityRuntime.Deny() - secObj != null");
191             if (secObj == null)
192             {
193                 // Security: REQ_SQ flag is missing. Bad compiler ?
194                 System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
195             }
196             else
197             {
198                 if (secObj.HasImperativeDenials())
199                     throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
200
201                 secObj.SetDeny(permSet);
202             }
203         }
204     
205         [System.Security.SecurityCritical]  // auto-generated
206         internal static void PermitOnly(PermissionSet permSet, ref StackCrawlMark stackMark)
207         {
208             FrameSecurityDescriptor secObj =
209                 SecurityRuntime.GetSecurityObjectForFrame(ref stackMark, true);
210     
211             Contract.Assert(secObj != null, "Failure in SecurityRuntime.PermitOnly() - secObj != null");
212             if (secObj == null)
213             {
214                 // Security: REQ_SQ flag is missing. Bad compiler ?
215                 System.Environment.FailFast(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
216             }
217             else
218             {
219                 if (secObj.HasImperativeRestrictions())
220                     throw new SecurityException( Environment.GetResourceString( "Security_MustRevertOverride" ) );
221
222                 secObj.SetPermitOnly(permSet);
223             }
224         }
225     
226         //
227         // Revert API
228         //
229         
230         [System.Security.SecurityCritical]  // auto-generated
231         internal static void RevertAssert(ref StackCrawlMark stackMark)
232         {
233             FrameSecurityDescriptor secObj = GetSecurityObjectForFrame(ref stackMark, false);
234             if (secObj != null)
235             {
236                 secObj.RevertAssert();
237             }
238             else
239             {
240                 throw new InvalidOperationException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
241             }
242         }
243
244         [System.Security.SecurityCritical]  // auto-generated
245         internal static void RevertDeny(ref StackCrawlMark stackMark)
246         {
247             FrameSecurityDescriptor secObj = GetSecurityObjectForFrame(ref stackMark, false);
248             if (secObj != null)
249             {
250                 secObj.RevertDeny();
251             }
252             else
253             {
254                 throw new InvalidOperationException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
255             }
256         }
257         
258         [System.Security.SecurityCritical]  // auto-generated
259         internal static void RevertPermitOnly(ref StackCrawlMark stackMark)
260         {
261             FrameSecurityDescriptor secObj = GetSecurityObjectForFrame(ref stackMark, false);
262             if (secObj != null)
263             {
264                 secObj.RevertPermitOnly();
265             }
266             else
267             {
268                 throw new InvalidOperationException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
269             }
270         }
271         
272         [System.Security.SecurityCritical]  // auto-generated
273         internal static void RevertAll(ref StackCrawlMark stackMark)
274         {
275             FrameSecurityDescriptor secObj = GetSecurityObjectForFrame(ref stackMark, false);
276             if (secObj != null)
277             {
278                 secObj.RevertAll();
279             }
280             else
281             {
282                 throw new InvalidOperationException(Environment.GetResourceString("ExecutionEngine_MissingSecurityDescriptor"));
283             }
284         }
285     }
286 }
287
288