[mcs] Replace NET_2_1 by MOBILE
[mono.git] / mcs / class / corlib / System.Security.Policy / Evidence.cs
1 //
2 // System.Security.Policy.Evidence
3 //
4 // Authors:
5 //      Sean MacIsaac (macisaac@ximian.com)
6 //      Nick Drochak (ndrochak@gol.com)
7 //      Jackson Harper (Jackson@LatitudeGeo.com)
8 //      Sebastien Pouliot  <sebastien@ximian.com>
9 //
10 // (C) 2001 Ximian, Inc.
11 // Portions (C) 2003, 2004 Motus Technologies Inc. (http://www.motus.com)
12 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System.Collections;
35 using System.Globalization;
36 using System.Reflection;
37 using System.Runtime.CompilerServices;
38 using System.Runtime.InteropServices;
39 using System.Security.Permissions;
40 using System.Security.Cryptography.X509Certificates;
41 using Mono.Security.Authenticode;
42
43 namespace System.Security.Policy {
44
45         [Serializable]
46         [MonoTODO ("Serialization format not compatible with .NET")]
47         [ComVisible (true)]
48         public sealed class Evidence : ICollection, IEnumerable {
49         
50                 private bool _locked;
51                 private ArrayList hostEvidenceList;     
52                 private ArrayList assemblyEvidenceList;
53
54                 public Evidence () 
55                 {
56                 }
57
58                 public Evidence (Evidence evidence)
59                 {
60                         if (evidence != null)
61                                 Merge (evidence);       
62                 }
63
64                 [Obsolete]
65                 public Evidence (object[] hostEvidence, object[] assemblyEvidence)
66                 {
67                         if (null != hostEvidence)
68                                 HostEvidenceList.AddRange (hostEvidence);
69                         if (null != assemblyEvidence)
70                                 AssemblyEvidenceList.AddRange (assemblyEvidence);
71                 }
72                 
73                 //
74                 // Public Properties
75                 //
76         
77                 [Obsolete]
78                 public int Count {
79                         get {
80                                 int count = 0;
81                                 if (hostEvidenceList != null)
82                                         count += hostEvidenceList.Count;
83                                 if (assemblyEvidenceList!= null)
84                                         count += assemblyEvidenceList.Count;
85                                 return count;
86                         }
87                 }
88
89                 public bool IsReadOnly {
90                         get{ return false; }
91                 }
92                 
93                 public bool IsSynchronized {
94                         get { return false; }
95                 }
96
97                 public bool Locked {
98                         get { return _locked; }
99                         [SecurityPermission (SecurityAction.Demand, ControlEvidence = true)]
100                         set { 
101                                 _locked = value; 
102                         }
103                 }       
104
105                 public object SyncRoot {
106                         get { return this; }
107                 }
108
109                 internal ArrayList HostEvidenceList {
110                         get {
111                                 if (hostEvidenceList == null)
112                                         hostEvidenceList = ArrayList.Synchronized (new ArrayList ());
113                                 return hostEvidenceList;
114                         }
115                 }
116
117                 internal ArrayList AssemblyEvidenceList {
118                         get {
119                                 if (assemblyEvidenceList == null)
120                                         assemblyEvidenceList = ArrayList.Synchronized (new ArrayList ());
121                                 return assemblyEvidenceList;
122                         }
123                 }
124
125                 //
126                 // Public Methods
127                 //
128
129                 [Obsolete]
130                 public void AddAssembly (object id) 
131                 {
132                         AssemblyEvidenceList.Add (id);
133                 }
134
135                 [Obsolete]
136                 public void AddHost (object id) 
137                 {
138                         if (_locked && SecurityManager.SecurityEnabled) {
139                                 new SecurityPermission (SecurityPermissionFlag.ControlEvidence).Demand ();
140                         }
141                         HostEvidenceList.Add (id);
142                 }
143
144                 [ComVisible (false)]
145                 public void Clear ()
146                 {
147                         if (hostEvidenceList != null)
148                                 hostEvidenceList.Clear ();
149                         if (assemblyEvidenceList != null)
150                                 assemblyEvidenceList.Clear ();
151                 }
152
153         [ComVisible(false)]
154         public Evidence Clone ()
155         {
156             return new Evidence(this);
157         }               
158
159                 [Obsolete]
160                 public void CopyTo (Array array, int index) 
161                 {
162                         int hc = 0;
163                         if (hostEvidenceList != null) {
164                                 hc = hostEvidenceList.Count;
165                                 if (hc > 0)
166                                         hostEvidenceList.CopyTo (array, index);
167                         }
168                         if ((assemblyEvidenceList != null) && (assemblyEvidenceList.Count > 0))
169                                 assemblyEvidenceList.CopyTo (array, index + hc);
170                 }
171
172
173                 [Obsolete]
174                 public IEnumerator GetEnumerator () 
175                 {
176                         IEnumerator he = null;
177                         if (hostEvidenceList != null)
178                                 he = hostEvidenceList.GetEnumerator ();
179                         IEnumerator ae = null;
180                         if (assemblyEvidenceList != null)
181                                 ae = assemblyEvidenceList.GetEnumerator ();
182                         return new EvidenceEnumerator (he, ae);
183                 }
184
185                 public IEnumerator GetAssemblyEnumerator () 
186                 {
187                         return AssemblyEvidenceList.GetEnumerator ();
188                 }
189
190                 public IEnumerator GetHostEnumerator () 
191                 {
192                         return HostEvidenceList.GetEnumerator ();
193                 }
194
195                 public void Merge (Evidence evidence) 
196                 {
197                         if ((evidence != null) && (evidence.Count > 0)) {
198                                 if (evidence.hostEvidenceList != null) {
199                                         foreach (object o in evidence.hostEvidenceList)
200                                                 AddHost (o);
201                                 }
202                                 if (evidence.assemblyEvidenceList != null) {
203                                         foreach (object o in evidence.assemblyEvidenceList)
204                                                 AddAssembly (o);
205                                 }
206                         }
207                 }
208
209                 [ComVisible (false)]
210                 public void RemoveType (Type t)
211                 {
212                         for (int i = hostEvidenceList.Count; i >= 0; i--) {
213                                 if (hostEvidenceList.GetType () == t) {
214                                         hostEvidenceList.RemoveAt (i);
215                                 }
216                         }
217                         for (int i = assemblyEvidenceList.Count; i >= 0; i--) {
218                                 if (assemblyEvidenceList.GetType () == t) {
219                                         assemblyEvidenceList.RemoveAt (i);
220                                 }
221                         }
222                 }
223
224                 // Use an icall to avoid multiple file i/o to detect the 
225                 // "possible" presence of an Authenticode signature
226                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
227                 static extern bool IsAuthenticodePresent (Assembly a);
228 #if MOBILE
229                 static internal Evidence GetDefaultHostEvidence (Assembly a)
230                 {
231                         return new Evidence ();
232                 }
233 #else
234                 // this avoid us to build all evidences from the runtime
235                 // (i.e. multiple unmanaged->managed calls) and also allows
236                 // to delay their creation until (if) needed
237                 [FileIOPermission (SecurityAction.Assert, Unrestricted = true)]
238                 static internal Evidence GetDefaultHostEvidence (Assembly a) 
239                 {
240                         Evidence e = new Evidence ();
241                         string aname = a.EscapedCodeBase;
242
243                         // by default all assembly have the Zone, Url and Hash evidences
244                         e.AddHost (Zone.CreateFromUrl (aname));
245                         e.AddHost (new Url (aname));
246                         e.AddHost (new Hash (a));
247
248                         // non local files (e.g. http://) also get a Site evidence
249                         if (String.Compare ("FILE://", 0, aname, 0, 7, true, CultureInfo.InvariantCulture) != 0) {
250                                 e.AddHost (Site.CreateFromUrl (aname));
251                         }
252
253                         // strongnamed assemblies gets a StrongName evidence
254                         AssemblyName an = a.GetName ();
255                         byte[] pk = an.GetPublicKey ();
256                         if ((pk != null) && (pk.Length > 0)) {
257                                 StrongNamePublicKeyBlob blob = new StrongNamePublicKeyBlob (pk);
258                                 e.AddHost (new StrongName (blob, an.Name, an.Version));
259                         }
260
261                         // Authenticode(r) signed assemblies get a Publisher evidence
262                         if (IsAuthenticodePresent (a)) {
263                                 // Note: The certificate is part of the evidences even if it is not trusted!
264                                 // so we can't call X509Certificate.CreateFromSignedFile
265                                 AuthenticodeDeformatter ad = new AuthenticodeDeformatter (a.Location);
266                                 if (ad.SigningCertificate != null) {
267                                         X509Certificate x509 = new X509Certificate (ad.SigningCertificate.RawData);
268                                         if (x509.GetHashCode () != 0) {
269                                                 e.AddHost (new Publisher (x509));
270                                         }
271                                 }
272                         }
273                         // assemblies loaded from the GAC also get a Gac evidence (new in Fx 2.0)
274                         if (a.GlobalAssemblyCache) {
275                                 e.AddHost (new GacInstalled ());
276                         }
277
278                         // the current HostSecurityManager may add/remove some evidence
279                         AppDomainManager dommgr = AppDomain.CurrentDomain.DomainManager;
280                         if (dommgr != null) {
281                                 if ((dommgr.HostSecurityManager.Flags & HostSecurityManagerOptions.HostAssemblyEvidence) ==
282                                         HostSecurityManagerOptions.HostAssemblyEvidence) {
283                                         e = dommgr.HostSecurityManager.ProvideAssemblyEvidence (a, e);
284                                 }
285                         }
286
287                         return e;
288                 }
289
290 #endif // MOBILE
291
292                 private class EvidenceEnumerator : IEnumerator {
293                         
294                         private IEnumerator currentEnum, hostEnum, assemblyEnum;                
295         
296                         public EvidenceEnumerator (IEnumerator hostenum, IEnumerator assemblyenum) 
297                         {
298                                 this.hostEnum = hostenum;
299                                 this.assemblyEnum = assemblyenum;
300                                 currentEnum = hostEnum;         
301                         }
302
303                         public bool MoveNext () 
304                         {
305                                 if (currentEnum == null)
306                                         return false;
307
308                                 bool ret = currentEnum.MoveNext ();
309                                 
310                                 if (!ret && (hostEnum == currentEnum) && (assemblyEnum != null)) {
311                                         currentEnum = assemblyEnum;
312                                         ret = assemblyEnum.MoveNext ();
313                                 }
314
315                                 return ret;
316                         }
317
318                         public void Reset () 
319                         {
320                                 if (hostEnum != null) {
321                                         hostEnum.Reset ();
322                                         currentEnum = hostEnum;
323                                 } else {
324                                         currentEnum = assemblyEnum;
325                                 }
326                                 if (assemblyEnum != null)
327                                         assemblyEnum.Reset ();
328                         }
329
330                         public object Current {
331                                 get {
332                                         return currentEnum.Current;
333                                 }
334                         }
335                 }
336         }
337 }
338