Merge pull request #2377 from joelmartinez/docs-multiassembly-extension-fix
[mono.git] / mcs / class / referencesource / mscorlib / system / security / securityexception.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*=============================================================================
7 **
8 ** Class: SecurityException
9 ** 
10 ** <OWNER>[....]</OWNER>
11 **
12 **
13 ** Purpose: Exception class for security
14 **
15 **
16 =============================================================================*/
17
18 namespace System.Security
19 {
20     using System.Security;
21     using System;
22     using System.Runtime.Serialization;
23     using System.Security.Permissions;
24     using System.Reflection;
25     using System.Text;
26     using System.Security.Policy;
27     using System.IO;
28 #if FEATURE_SERIALIZATION
29     using System.Runtime.Serialization.Formatters.Binary;
30 #endif // FEATURE_SERIALIZATION
31     using System.Globalization;
32     using System.Security.Util;
33     using System.Diagnostics.Contracts;
34
35     [System.Runtime.InteropServices.ComVisible(true)]
36     [Serializable] public class SecurityException : SystemException
37     {
38 #if FEATURE_CAS_POLICY        
39         private String m_debugString; // NOTE: If you change the name of this field, you'll have to update SOS as well!
40         private SecurityAction m_action;
41         [NonSerialized] private Type m_typeOfPermissionThatFailed;
42         private String m_permissionThatFailed;
43         private String m_demanded;
44         private String m_granted;
45         private String m_refused;
46         private String m_denied;
47         private String m_permitOnly;
48         private AssemblyName m_assemblyName;
49         private byte[] m_serializedMethodInfo;
50         private String m_strMethodInfo;
51         private SecurityZone m_zone;
52         private String m_url;
53
54         private const String ActionName = "Action";
55         private const String FirstPermissionThatFailedName = "FirstPermissionThatFailed";
56         private const String DemandedName = "Demanded";
57         private const String GrantedSetName = "GrantedSet";
58         private const String RefusedSetName = "RefusedSet";
59         private const String DeniedName = "Denied";
60         private const String PermitOnlyName = "PermitOnly";
61         private const String Assembly_Name = "Assembly";
62         private const String MethodName_Serialized = "Method";
63         private const String MethodName_String = "Method_String";
64         private const String ZoneName = "Zone";
65         private const String UrlName = "Url";
66 #endif // #if FEATURE_CAS_POLICY
67
68         [System.Security.SecuritySafeCritical]  // auto-generated
69         internal static string GetResString(string sResourceName)
70         {
71             PermissionSet.s_fullTrust.Assert();
72             return Environment.GetResourceString(sResourceName);
73         }
74
75         [System.Security.SecurityCritical]  // auto-generated
76 #pragma warning disable 618
77         internal static Exception MakeSecurityException(AssemblyName asmName, Evidence asmEvidence, PermissionSet granted, PermissionSet refused, RuntimeMethodHandleInternal rmh, SecurityAction action, Object demand, IPermission permThatFailed)
78 #pragma warning restore 618
79         {
80 #if FEATURE_CAS_POLICY            
81             // See if we need to throw a HostProtectionException instead
82             HostProtectionPermission hostProtectionPerm = permThatFailed as HostProtectionPermission;
83             if(hostProtectionPerm != null)
84                 return new HostProtectionException(GetResString("HostProtection_HostProtection"), HostProtectionPermission.protectedResources, hostProtectionPerm.Resources);
85
86             // Produce relevant strings
87             String message = "";
88             MethodInfo method = null;
89             try
90             {
91                 if(granted == null && refused == null && demand == null)
92                 {
93                     message = GetResString("Security_NoAPTCA");
94                 }
95                 else
96                 {
97                     if(demand != null && demand is IPermission)
98                         message = String.Format(CultureInfo.InvariantCulture,  GetResString("Security_Generic"), demand.GetType().AssemblyQualifiedName );
99                     else if (permThatFailed != null)
100                         message = String.Format(CultureInfo.InvariantCulture, GetResString("Security_Generic"), permThatFailed.GetType().AssemblyQualifiedName);
101                     else
102                         message = GetResString("Security_GenericNoType");
103                 }
104
105                 method = SecurityRuntime.GetMethodInfo(rmh);
106             }
107             catch(Exception e)
108             {
109                 // Environment.GetResourceString will throw if we are ReadyForAbort (thread abort).  (We shouldn't do a Contract.Assert in this case or it will lock up the thread.)
110                 if(e is System.Threading.ThreadAbortException)
111                 throw;
112             }
113
114 /*            catch(System.Threading.ThreadAbortException)
115             {
116                 // Environment.GetResourceString will throw if we are ReadyForAbort (thread abort).  (We shouldn't do a BCLDebug.Assert in this case or it will lock up the thread.)
117                 throw;
118             }
119             catch
120             {
121             }
122 */
123             // make the exception object
124             return new SecurityException(message, asmName, granted, refused, method, action, demand, permThatFailed, asmEvidence);
125 #else
126             return new SecurityException(GetResString("Arg_SecurityException"));
127 #endif
128
129         }
130
131 #if FEATURE_CAS_POLICY            
132         private static byte[] ObjectToByteArray(Object obj)
133         {
134             if(obj == null)
135                 return null;
136             MemoryStream stream = new MemoryStream();
137             BinaryFormatter formatter = new BinaryFormatter();
138             try {
139                 formatter.Serialize(stream, obj);
140                 byte[] array = stream.ToArray();
141                 return array;
142             } catch (NotSupportedException) {
143                 // Serialization of certain methods is not supported (namely
144                 // global methods, since they have no representation outside of
145                 // a module scope).
146                 return null;
147             }
148         }
149
150         private static Object ByteArrayToObject(byte[] array)
151         {
152             if(array == null || array.Length == 0)
153                 return null;
154             MemoryStream stream = new MemoryStream(array);
155             BinaryFormatter formatter = new BinaryFormatter();
156             Object obj = formatter.Deserialize(stream);
157             return obj;
158         }
159 #endif // FEATURE_CAS_POLICY
160
161         public SecurityException() 
162             : base(GetResString("Arg_SecurityException"))
163         {
164             SetErrorCode(System.__HResults.COR_E_SECURITY);
165         }
166     
167         public SecurityException(String message) 
168             : base(message)
169         {
170             // This is the constructor that gets called if you Assert but don't have permission to Assert.  (So don't assert in here.)
171             SetErrorCode(System.__HResults.COR_E_SECURITY);
172         }
173
174 #if FEATURE_CAS_POLICY            
175         [System.Security.SecuritySafeCritical]  // auto-generated
176         public SecurityException(String message, Type type ) 
177             : base(message)
178         {
179             PermissionSet.s_fullTrust.Assert();
180             SetErrorCode(System.__HResults.COR_E_SECURITY);
181             m_typeOfPermissionThatFailed = type;
182         }
183
184         // *** Don't use this constructor internally ***
185         [System.Security.SecuritySafeCritical]  // auto-generated
186         public SecurityException(String message, Type type, String state ) 
187             : base(message)
188         {
189             PermissionSet.s_fullTrust.Assert();
190             SetErrorCode(System.__HResults.COR_E_SECURITY);
191             m_typeOfPermissionThatFailed = type;
192             m_demanded = state;
193         }
194 #endif //FEATURE_CAS_POLICY            
195
196         public SecurityException(String message, Exception inner) 
197             : base(message, inner)
198         {
199             SetErrorCode(System.__HResults.COR_E_SECURITY);
200         }
201
202 #if FEATURE_CAS_POLICY            
203         // *** Don't use this constructor internally ***
204         [System.Security.SecurityCritical]  // auto-generated
205         internal SecurityException( PermissionSet grantedSetObj, PermissionSet refusedSetObj )
206             : base(GetResString("Arg_SecurityException"))
207         {
208             PermissionSet.s_fullTrust.Assert();
209             SetErrorCode(System.__HResults.COR_E_SECURITY);
210             if (grantedSetObj != null)
211                 m_granted = grantedSetObj.ToXml().ToString();
212             if (refusedSetObj != null)
213                 m_refused = refusedSetObj.ToXml().ToString();
214         }
215     
216         // *** Don't use this constructor internally ***
217         [System.Security.SecurityCritical]  // auto-generated
218         internal SecurityException( String message, PermissionSet grantedSetObj, PermissionSet refusedSetObj )
219             : base(message)
220         {
221             PermissionSet.s_fullTrust.Assert();
222             SetErrorCode(System.__HResults.COR_E_SECURITY);
223             if (grantedSetObj != null)
224                 m_granted = grantedSetObj.ToXml().ToString();
225             if (refusedSetObj != null)
226                 m_refused = refusedSetObj.ToXml().ToString();
227         }
228
229         [System.Security.SecuritySafeCritical]  // auto-generated
230         protected SecurityException(SerializationInfo info, StreamingContext context) : base (info, context)
231         {
232             if (info==null)
233                 throw new ArgumentNullException("info");
234             Contract.EndContractBlock();
235
236             try
237             {
238                 m_action = (SecurityAction)info.GetValue(ActionName, typeof(SecurityAction));
239                 m_permissionThatFailed = (String)info.GetValueNoThrow(FirstPermissionThatFailedName, typeof(String));
240                 m_demanded = (String)info.GetValueNoThrow(DemandedName, typeof(String));
241                 m_granted = (String)info.GetValueNoThrow(GrantedSetName, typeof(String));
242                 m_refused = (String)info.GetValueNoThrow(RefusedSetName, typeof(String));
243                 m_denied = (String)info.GetValueNoThrow(DeniedName, typeof(String));
244                 m_permitOnly = (String)info.GetValueNoThrow(PermitOnlyName, typeof(String));
245                 m_assemblyName = (AssemblyName)info.GetValueNoThrow(Assembly_Name, typeof(AssemblyName));
246                 m_serializedMethodInfo = (byte[])info.GetValueNoThrow(MethodName_Serialized, typeof(byte[]));
247                 m_strMethodInfo = (String)info.GetValueNoThrow(MethodName_String, typeof(String));
248                 m_zone = (SecurityZone)info.GetValue(ZoneName, typeof(SecurityZone));
249                 m_url = (String)info.GetValueNoThrow(UrlName, typeof(String));
250             }
251             catch 
252             {
253                 m_action = 0;
254                 m_permissionThatFailed = "";
255                 m_demanded = "";
256                 m_granted = "";
257                 m_refused = "";
258                 m_denied = "";
259                 m_permitOnly = "";
260                 m_assemblyName = null;
261                 m_serializedMethodInfo = null;
262                 m_strMethodInfo = null;
263                 m_zone = SecurityZone.NoZone;
264                 m_url = "";
265             }
266         }
267
268         // ------------------------------------------
269         // | For failures due to insufficient grant |
270         // ------------------------------------------
271         [System.Security.SecuritySafeCritical]  // auto-generated
272         public SecurityException(string message, AssemblyName assemblyName, PermissionSet grant, PermissionSet refused, MethodInfo method, SecurityAction action, Object demanded, IPermission permThatFailed, Evidence evidence)
273             : base(message)
274         {
275             PermissionSet.s_fullTrust.Assert();
276             SetErrorCode(System.__HResults.COR_E_SECURITY);
277             Action = action;
278             if(permThatFailed != null)
279                 m_typeOfPermissionThatFailed = permThatFailed.GetType();
280             FirstPermissionThatFailed = permThatFailed;
281             Demanded = demanded;
282             m_granted = (grant == null ? "" : grant.ToXml().ToString());
283             m_refused = (refused == null ? "" : refused.ToXml().ToString());
284             m_denied = "";
285             m_permitOnly = "";
286             m_assemblyName = assemblyName;
287             Method = method;
288             m_url = "";
289             m_zone = SecurityZone.NoZone;
290             if(evidence != null)
291             {
292                 Url url = evidence.GetHostEvidence<Url>();
293                 if(url != null)
294                     m_url = url.GetURLString().ToString();
295                 Zone zone = evidence.GetHostEvidence<Zone>();
296                 if(zone != null)
297                     m_zone = zone.SecurityZone;
298             }
299             m_debugString = this.ToString(true, false);
300         }
301
302         // ------------------------------------------
303         // | For failures due to deny or PermitOnly |
304         // ------------------------------------------
305         [System.Security.SecuritySafeCritical]  // auto-generated
306         public SecurityException(string message, Object deny, Object permitOnly, MethodInfo method, Object demanded, IPermission permThatFailed)
307             : base(message)
308         {
309             PermissionSet.s_fullTrust.Assert();
310             SetErrorCode(System.__HResults.COR_E_SECURITY);
311             Action = SecurityAction.Demand;
312             if(permThatFailed != null)
313                 m_typeOfPermissionThatFailed = permThatFailed.GetType();
314             FirstPermissionThatFailed = permThatFailed;
315             Demanded = demanded;
316             m_granted = "";
317             m_refused = "";
318             DenySetInstance = deny;
319             PermitOnlySetInstance = permitOnly;
320             m_assemblyName = null;
321             Method = method;
322             m_zone = SecurityZone.NoZone;
323             m_url = "";
324             m_debugString = this.ToString(true, false);
325         }
326
327
328
329
330
331
332
333
334
335
336
337         [System.Runtime.InteropServices.ComVisible(false)]
338         public SecurityAction Action
339         {
340             get
341             {
342                 return m_action;
343             }
344
345             set
346             {
347                 m_action = value;
348             }
349         }
350
351         public Type PermissionType
352         {
353             [System.Security.SecuritySafeCritical]  // auto-generated
354             get
355             {
356                 if(m_typeOfPermissionThatFailed == null)
357                 {
358                     Object ob = XMLUtil.XmlStringToSecurityObject(m_permissionThatFailed);
359                     if(ob == null)
360                         ob = XMLUtil.XmlStringToSecurityObject(m_demanded);
361                     if(ob != null)
362                         m_typeOfPermissionThatFailed = ob.GetType();
363                 }
364                 return m_typeOfPermissionThatFailed;
365             }
366
367             set
368             {
369                 m_typeOfPermissionThatFailed = value;
370             }
371         }
372
373         public IPermission FirstPermissionThatFailed
374         {
375             [System.Security.SecuritySafeCritical]  // auto-generated
376             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
377             get
378             {
379                 return (IPermission)XMLUtil.XmlStringToSecurityObject(m_permissionThatFailed);
380             }
381
382             set
383             {
384                 m_permissionThatFailed = XMLUtil.SecurityObjectToXmlString(value);
385             }
386         }
387
388         public String PermissionState
389         {
390             [System.Security.SecuritySafeCritical]  // auto-generated
391             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
392             get
393             {
394                 return m_demanded;
395             }
396
397             set
398             {
399                 m_demanded = value;
400             }
401         }
402
403         [System.Runtime.InteropServices.ComVisible(false)]
404         public Object Demanded
405         {
406             [System.Security.SecuritySafeCritical]  // auto-generated
407             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
408             get
409             {
410                 return XMLUtil.XmlStringToSecurityObject(m_demanded);
411             }
412
413             set
414             {
415                 m_demanded = XMLUtil.SecurityObjectToXmlString(value);
416             }
417         }
418
419         public String GrantedSet
420         {
421             [System.Security.SecuritySafeCritical]  // auto-generated
422             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
423             get
424             {
425                 return m_granted;
426             }
427
428             set
429             {
430                 m_granted = value;
431             }
432         }
433
434         public String RefusedSet
435         {
436             [System.Security.SecuritySafeCritical]  // auto-generated
437             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
438             get
439             {
440                 return m_refused;
441             }
442
443             set
444             {
445                 m_refused = value;
446             }
447         }
448
449         [System.Runtime.InteropServices.ComVisible(false)]
450         public Object DenySetInstance
451         {
452             [System.Security.SecuritySafeCritical]  // auto-generated
453             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
454             get
455             {
456                 return XMLUtil.XmlStringToSecurityObject(m_denied);
457             }
458
459             set
460             {
461                 m_denied = XMLUtil.SecurityObjectToXmlString(value);
462             }
463         }
464
465         [System.Runtime.InteropServices.ComVisible(false)]
466         public Object PermitOnlySetInstance
467         {
468             [System.Security.SecuritySafeCritical]  // auto-generated
469             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
470             get
471             {
472                 return XMLUtil.XmlStringToSecurityObject(m_permitOnly);
473             }
474
475             set
476             {
477                 m_permitOnly = XMLUtil.SecurityObjectToXmlString(value);
478             }
479         }
480
481         [System.Runtime.InteropServices.ComVisible(false)]
482         public AssemblyName FailedAssemblyInfo
483         {
484             [System.Security.SecuritySafeCritical]  // auto-generated
485             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
486             get
487             {
488                 return m_assemblyName;
489             }
490
491             set
492             {
493                 m_assemblyName = value;
494             }
495             }
496
497         private MethodInfo getMethod()
498         {
499             return (MethodInfo)ByteArrayToObject(m_serializedMethodInfo);
500         }
501
502         [System.Runtime.InteropServices.ComVisible(false)]
503         public MethodInfo Method
504         {
505             [System.Security.SecuritySafeCritical]  // auto-generated
506             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
507             get
508             {
509                 return getMethod();
510             }
511
512             set
513             {
514                 RuntimeMethodInfo m = value as RuntimeMethodInfo;
515                 m_serializedMethodInfo = ObjectToByteArray(m);
516                 if (m != null)
517                 {
518                     m_strMethodInfo = m.ToString();
519                 }
520             }
521         }
522
523         public SecurityZone Zone
524         {
525             get
526             {
527                 return m_zone;
528             }
529
530             set
531             {
532                 m_zone = value;
533             }
534         }
535
536         public String Url
537         {
538             [System.Security.SecuritySafeCritical]  // auto-generated
539             [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy)]
540             get
541             {
542                 return m_url;
543             }
544
545             set
546             {
547                 m_url = value;
548             }
549         }
550
551         private void ToStringHelper(StringBuilder sb, String resourceString, Object attr)
552         {
553             if (attr == null)
554                 return;
555             String attrString = attr as String;
556             if (attrString == null)
557                 attrString = attr.ToString();
558             if (attrString.Length == 0)
559                 return;
560             sb.Append(Environment.NewLine);
561             sb.Append(GetResString(resourceString));
562             sb.Append(Environment.NewLine);
563             sb.Append(attrString);
564         }
565
566         [System.Security.SecurityCritical]  // auto-generated
567         private String ToString(bool includeSensitiveInfo, bool includeBaseInfo)
568         {
569             PermissionSet.s_fullTrust.Assert();
570             StringBuilder sb = new StringBuilder();
571
572             if(includeBaseInfo)
573             sb.Append(base.ToString());
574             if(Action > 0)
575                 ToStringHelper(sb, "Security_Action", Action);
576             ToStringHelper(sb, "Security_TypeFirstPermThatFailed", PermissionType);
577             if(includeSensitiveInfo)
578             {
579                 ToStringHelper(sb, "Security_FirstPermThatFailed", m_permissionThatFailed);
580                 ToStringHelper(sb, "Security_Demanded", m_demanded);
581                 ToStringHelper(sb, "Security_GrantedSet", m_granted);
582                 ToStringHelper(sb, "Security_RefusedSet", m_refused);
583                 ToStringHelper(sb, "Security_Denied", m_denied);
584                 ToStringHelper(sb, "Security_PermitOnly", m_permitOnly);
585                 ToStringHelper(sb, "Security_Assembly", m_assemblyName);
586                 ToStringHelper(sb, "Security_Method", m_strMethodInfo);
587             }
588             if(m_zone != SecurityZone.NoZone)
589                 ToStringHelper(sb, "Security_Zone", m_zone);
590             if(includeSensitiveInfo)
591                 ToStringHelper(sb, "Security_Url", m_url);
592             return sb.ToString();
593         }
594 #else // FEATURE_CAS_POLICY
595         internal SecurityException( PermissionSet grantedSetObj, PermissionSet refusedSetObj )
596             : this(){}
597 #pragma warning disable 618
598         internal SecurityException(string message, AssemblyName assemblyName, PermissionSet grant, PermissionSet refused, MethodInfo method, SecurityAction action, Object demanded, IPermission permThatFailed, Evidence evidence)
599 #pragma warning restore 618
600                     : this(){}
601         
602         internal SecurityException(string message, Object deny, Object permitOnly, MethodInfo method, Object demanded, IPermission permThatFailed)
603                     : this(){}
604                     
605         public override String ToString() 
606                 {
607                     return base.ToString();
608                 }
609         
610 #endif // FEATURE_CAS_POLICY
611
612         [System.Security.SecurityCritical]  // auto-generated
613         private bool CanAccessSensitiveInfo()
614         {
615             bool retVal = false;
616             try
617             {
618 #pragma warning disable 618
619                 new SecurityPermission(SecurityPermissionFlag.ControlEvidence | SecurityPermissionFlag.ControlPolicy).Demand();
620 #pragma warning restore 618
621                 retVal = true;
622             }
623             catch(SecurityException)
624             {
625             }
626             return retVal;
627             }
628 #if FEATURE_CAS_POLICY            
629         [System.Security.SecuritySafeCritical]  // auto-generated
630         public override String ToString() 
631         {
632             return ToString(CanAccessSensitiveInfo(), true);
633         }
634 #endif //FEATURE_CAS_POLICY            
635         [System.Security.SecurityCritical]  // auto-generated_required
636         public override void GetObjectData(SerializationInfo info, StreamingContext context)
637         {
638             if (info==null)
639                 throw new ArgumentNullException("info");
640             Contract.EndContractBlock();
641
642             base.GetObjectData( info, context );
643 #if FEATURE_CAS_POLICY            
644
645             info.AddValue(ActionName, m_action, typeof(SecurityAction));
646             info.AddValue(FirstPermissionThatFailedName, m_permissionThatFailed, typeof(String));
647             info.AddValue(DemandedName, m_demanded, typeof(String));
648             info.AddValue(GrantedSetName, m_granted, typeof(String));
649             info.AddValue(RefusedSetName, m_refused, typeof(String));
650             info.AddValue(DeniedName, m_denied, typeof(String));
651             info.AddValue(PermitOnlyName, m_permitOnly, typeof(String));
652             info.AddValue(Assembly_Name, m_assemblyName, typeof(AssemblyName));
653             info.AddValue(MethodName_Serialized, m_serializedMethodInfo, typeof(byte[]));
654             info.AddValue(MethodName_String, m_strMethodInfo, typeof(String));
655             info.AddValue(ZoneName, m_zone, typeof(SecurityZone));
656             info.AddValue(UrlName, m_url, typeof(String));
657 #endif // FEATURE_CAS_POLICY            
658         }
659     }
660 }