disable broken tests on net_4_0
[mcs.git] / class / corlib / System.Security.Permissions / StrongNameIdentityPermission.cs
blob7b1f4bd7bb593ae4e9189d1d067c0f1976551d8f
1 //
2 // StrongNameIdentityPermission.cs: Strong Name Identity Permission
3 //
4 // Author:
5 // Sebastien Pouliot <sebastien@ximian.com>
6 //
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Collections;
31 using System.Globalization;
32 using System.Runtime.InteropServices;
34 namespace System.Security.Permissions {
36 [ComVisible (true)]
37 [Serializable]
38 public sealed class StrongNameIdentityPermission : CodeAccessPermission, IBuiltInPermission {
40 private const int version = 1;
41 static private Version defaultVersion = new Version (0, 0);
43 private struct SNIP {
44 public StrongNamePublicKeyBlob PublicKey;
45 public string Name;
46 public Version AssemblyVersion;
48 internal SNIP (StrongNamePublicKeyBlob pk, string name, Version version)
50 PublicKey = pk;
51 Name = name;
52 AssemblyVersion = version;
55 internal static SNIP CreateDefault ()
57 return new SNIP (null, String.Empty, (Version) defaultVersion.Clone ());
60 internal bool IsNameSubsetOf (string target)
62 if (Name == null)
63 return (target == null);
64 if (target == null)
65 return true;
67 int wildcard = Name.LastIndexOf ('*');
68 if (wildcard == 0)
69 return true; // *
70 if (wildcard == -1)
71 wildcard = Name.Length; // exact match
73 return (String.Compare (Name, 0, target, 0, wildcard, true, CultureInfo.InvariantCulture) == 0);
76 internal bool IsSubsetOf (SNIP target)
78 if ((PublicKey != null) && PublicKey.Equals (target.PublicKey))
79 return true;
81 if (!IsNameSubsetOf (target.Name))
82 return false;
83 if ((AssemblyVersion != null) && !AssemblyVersion.Equals (target.AssemblyVersion))
84 return false;
85 // in case PermissionState.None was used in the constructor
86 if (PublicKey == null)
87 return (target.PublicKey == null);
88 return false;
92 private PermissionState _state;
93 private ArrayList _list;
95 public StrongNameIdentityPermission (PermissionState state)
97 // Identity Permissions can be unrestricted in Fx 2.0
98 _state = CheckPermissionState (state, true);
99 // default values
100 _list = new ArrayList ();
101 _list.Add (SNIP.CreateDefault ());
104 public StrongNameIdentityPermission (StrongNamePublicKeyBlob blob, string name, Version version)
106 if (blob == null)
107 throw new ArgumentNullException ("blob");
108 if ((name != null) && (name.Length == 0))
109 throw new ArgumentException ("name");
111 _state = PermissionState.None;
112 _list = new ArrayList ();
113 _list.Add (new SNIP (blob, name, version));
116 internal StrongNameIdentityPermission (StrongNameIdentityPermission snip)
118 _state = snip._state;
119 _list = new ArrayList (snip._list.Count);
120 foreach (SNIP e in snip._list) {
121 _list.Add (new SNIP (e.PublicKey, e.Name, e.AssemblyVersion));
125 // Properties
127 public string Name {
128 get {
129 if (_list.Count > 1)
130 throw new NotSupportedException ();
131 return ((SNIP)_list [0]).Name;
133 set {
134 if ((value != null) && (value.Length == 0))
135 throw new ArgumentException ("name");
136 if (_list.Count > 1)
137 ResetToDefault ();
138 SNIP snip = (SNIP) _list [0];
139 snip.Name = value;
140 _list [0] = snip;
144 public StrongNamePublicKeyBlob PublicKey {
145 get {
146 if (_list.Count > 1)
147 throw new NotSupportedException ();
148 return ((SNIP)_list [0]).PublicKey;
150 set {
151 if (value == null)
152 throw new ArgumentNullException ("value");
153 if (_list.Count > 1)
154 ResetToDefault ();
155 SNIP snip = (SNIP) _list [0];
156 snip.PublicKey = value;
157 _list [0] = snip;
161 public Version Version {
162 get {
163 if (_list.Count > 1)
164 throw new NotSupportedException ();
165 return ((SNIP)_list [0]).AssemblyVersion;
167 set {
168 if (_list.Count > 1)
169 ResetToDefault ();
170 SNIP snip = (SNIP) _list [0];
171 snip.AssemblyVersion = value;
172 _list [0] = snip;
176 internal void ResetToDefault ()
178 _list.Clear ();
179 _list.Add (SNIP.CreateDefault ());
182 // Methods
184 public override IPermission Copy ()
186 if (IsEmpty ())
187 return new StrongNameIdentityPermission (PermissionState.None);
188 else
189 return new StrongNameIdentityPermission (this);
192 public override void FromXml (SecurityElement e)
194 // General validation in CodeAccessPermission
195 CheckSecurityElement (e, "e", version, version);
196 // Note: we do not (yet) care about the return value
197 // as we only accept version 1 (min/max values)
198 _list.Clear ();
199 if ((e.Children != null) && (e.Children.Count > 0)) {
200 foreach (SecurityElement se in e.Children) {
201 _list.Add (FromSecurityElement (se));
203 } else {
204 _list.Add (FromSecurityElement (e));
208 private SNIP FromSecurityElement (SecurityElement se)
210 string name = se.Attribute ("Name");
211 StrongNamePublicKeyBlob publickey = StrongNamePublicKeyBlob.FromString (se.Attribute ("PublicKeyBlob"));
212 string v = se.Attribute ("AssemblyVersion");
213 Version assemblyVersion = (v == null) ? null : new Version (v);
215 return new SNIP (publickey, name, assemblyVersion);
217 public override IPermission Intersect (IPermission target)
219 if (target == null)
220 return null;
221 StrongNameIdentityPermission snip = (target as StrongNameIdentityPermission);
222 if (snip == null)
223 throw new ArgumentException (Locale.GetText ("Wrong permission type."));
224 if (IsEmpty () || snip.IsEmpty ())
225 return null;
226 if (!Match (snip.Name))
227 return null;
229 string n = ((Name.Length < snip.Name.Length) ? Name : snip.Name);
230 if (!Version.Equals (snip.Version))
231 return null;
232 if (!PublicKey.Equals (snip.PublicKey))
233 return null;
235 return new StrongNameIdentityPermission (this.PublicKey, n, this.Version);
238 public override bool IsSubsetOf (IPermission target)
240 StrongNameIdentityPermission snip = Cast (target);
241 if (snip == null)
242 return IsEmpty ();
244 if (IsEmpty ())
245 return true;
246 if (IsUnrestricted ())
247 return snip.IsUnrestricted ();
248 else if (snip.IsUnrestricted ())
249 return true;
251 foreach (SNIP e in _list) {
252 foreach (SNIP t in snip._list) {
253 if (!e.IsSubsetOf (t))
254 return false;
257 return true;
260 public override SecurityElement ToXml ()
262 SecurityElement se = Element (version);
263 if (_list.Count > 1) {
264 foreach (SNIP snip in _list) {
265 SecurityElement child = new SecurityElement ("StrongName");
266 ToSecurityElement (child, snip);
267 se.AddChild (child);
269 } else if (_list.Count == 1) {
270 SNIP snip = (SNIP)_list [0];
271 if (!IsEmpty (snip))
272 ToSecurityElement (se, snip);
274 return se;
277 private void ToSecurityElement (SecurityElement se, SNIP snip)
279 if (snip.PublicKey != null)
280 se.AddAttribute ("PublicKeyBlob", snip.PublicKey.ToString ());
281 if (snip.Name != null)
282 se.AddAttribute ("Name", snip.Name);
283 if (snip.AssemblyVersion != null)
284 se.AddAttribute ("AssemblyVersion", snip.AssemblyVersion.ToString ());
287 public override IPermission Union (IPermission target)
289 StrongNameIdentityPermission snip = Cast (target);
290 if ((snip == null) || snip.IsEmpty ())
291 return Copy ();
293 if (IsEmpty ())
294 return snip.Copy ();
296 StrongNameIdentityPermission union = (StrongNameIdentityPermission) Copy ();
297 foreach (SNIP e in snip._list) {
298 if (!IsEmpty (e) && !Contains (e)) {
299 union._list.Add (e);
302 return union;
305 // IBuiltInPermission
306 int IBuiltInPermission.GetTokenIndex ()
308 return (int) BuiltInToken.StrongNameIdentity;
311 // helpers
313 private bool IsUnrestricted ()
315 return (_state == PermissionState.Unrestricted);
318 private bool Contains (SNIP snip)
320 foreach (SNIP e in _list) {
321 bool pk = (((e.PublicKey == null) && (snip.PublicKey == null)) ||
322 ((e.PublicKey != null) && e.PublicKey.Equals (snip.PublicKey)));
323 bool name = e.IsNameSubsetOf (snip.Name);
324 bool version = (((e.AssemblyVersion == null) && (snip.AssemblyVersion == null)) ||
325 ((e.AssemblyVersion != null) && e.AssemblyVersion.Equals (snip.AssemblyVersion)));
327 if (pk && name && version)
328 return true;
330 return false;
333 private bool IsEmpty (SNIP snip)
335 if (PublicKey != null)
336 return false;
337 if ((Name != null) && (Name.Length > 0))
338 return false;
339 return ((Version == null) || defaultVersion.Equals (Version));
342 private bool IsEmpty ()
344 if (IsUnrestricted () || (_list.Count > 1))
345 return false;
346 if (PublicKey != null)
347 return false;
348 if ((Name != null) && (Name.Length > 0))
349 return false;
350 return ((Version == null) || defaultVersion.Equals (Version));
353 private StrongNameIdentityPermission Cast (IPermission target)
355 if (target == null)
356 return null;
358 StrongNameIdentityPermission snip = (target as StrongNameIdentityPermission);
359 if (snip == null) {
360 ThrowInvalidPermission (target, typeof (StrongNameIdentityPermission));
363 return snip;
366 private bool Match (string target)
368 if ((Name == null) || (target == null))
369 return false;
371 int wcu = Name.LastIndexOf ('*');
372 int wct = target.LastIndexOf ('*');
373 int length = Int32.MaxValue;
375 if ((wcu == -1) && (wct == -1)) {
376 // no wildcard, this is an exact match
377 length = Math.Max (Name.Length, target.Length);
379 else if (wcu == -1) {
380 // only "target" has a wildcard, use it
381 length = wct;
383 else if (wct == -1) {
384 // only "this" has a wildcard, use it
385 length = wcu;
387 else {
388 // both have wildcards, partial match with the smallest
389 length = Math.Min (wcu, wct);
392 return (String.Compare (Name, 0, target, 0, length, true, CultureInfo.InvariantCulture) == 0);