(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / corlib / System.Security.Permissions / StrongNameIdentityPermission.cs
blobb77755c349d52956a6617a3ead4125274d439d4b
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 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.Globalization;
32 namespace System.Security.Permissions {
34 [Serializable]
35 public sealed class StrongNameIdentityPermission : CodeAccessPermission, IBuiltInPermission {
37 private const int version = 1;
38 static private Version defaultVersion = new Version (0, 0);
40 private StrongNamePublicKeyBlob publickey;
41 private string name;
42 private Version assemblyVersion;
44 public StrongNameIdentityPermission (PermissionState state)
46 // false == do not allow Unrestricted for Identity Permissions
47 CheckPermissionState (state, false);
48 // default values
49 name = String.Empty;
50 assemblyVersion = (Version) defaultVersion.Clone ();
53 public StrongNameIdentityPermission (StrongNamePublicKeyBlob blob, string name, Version version)
55 if (blob == null)
56 throw new ArgumentNullException ("blob");
58 Name = name;
59 publickey = blob;
60 assemblyVersion = version;
63 public string Name {
64 get { return name; }
65 set {
66 #if NET_2_0
67 if ((value != null) && (value.Length == 0))
68 throw new ArgumentException ("name");
69 #endif
70 name = value;
74 public StrongNamePublicKeyBlob PublicKey {
75 get { return publickey; }
76 set {
77 if (value == null)
78 throw new ArgumentNullException ("value");
79 publickey = value;
83 public Version Version {
84 get { return assemblyVersion; }
85 set { assemblyVersion = value; }
88 public override IPermission Copy ()
90 if (IsEmpty ())
91 return new StrongNameIdentityPermission (PermissionState.None);
92 else
93 return new StrongNameIdentityPermission (publickey, name, assemblyVersion);
94 // Note: this will throw an ArgumentException if Name is still equals to String.Empty
95 // but MS implementation has the same bug/design issue
98 public override void FromXml (SecurityElement e)
100 // General validation in CodeAccessPermission
101 CheckSecurityElement (e, "e", version, version);
102 // Note: we do not (yet) care about the return value
103 // as we only accept version 1 (min/max values)
105 name = e.Attribute ("Name");
106 publickey = StrongNamePublicKeyBlob.FromString (e.Attribute ("PublicKeyBlob"));
107 string v = e.Attribute ("AssemblyVersion");
108 assemblyVersion = (v == null) ? null : new Version (v);
111 public override IPermission Intersect (IPermission target)
113 StrongNameIdentityPermission snip = (target as StrongNameIdentityPermission);
114 if ((snip == null) || IsEmpty ())
115 return null;
116 if (snip.IsEmpty ())
117 return new StrongNameIdentityPermission (PermissionState.None);
118 if (!Match (snip.name))
119 return null;
121 string n = ((name.Length < snip.name.Length) ? name : snip.name);
122 if (!assemblyVersion.Equals (snip.assemblyVersion))
123 return null;
124 if (!publickey.Equals (snip.publickey))
125 return null;
127 return new StrongNameIdentityPermission (publickey, n, assemblyVersion);
130 public override bool IsSubsetOf (IPermission target)
132 StrongNameIdentityPermission snip = Cast (target);
133 if (snip == null)
134 return IsEmpty ();
136 if (IsEmpty ())
137 return true;
139 if ((name != null) && (name.Length > 0) && !IsNameSubsetOf (snip.Name))
140 return false;
141 if ((assemblyVersion != null) && !assemblyVersion.Equals (snip.assemblyVersion))
142 return false;
143 // in case PermissionState.None was used in the constructor
144 if (publickey == null)
145 return (snip.publickey == null);
146 else
147 return publickey.Equals (snip.publickey);
150 public override SecurityElement ToXml ()
152 SecurityElement se = Element (version);
153 if (publickey != null)
154 se.AddAttribute ("PublicKeyBlob", publickey.ToString ());
155 if (name != null)
156 se.AddAttribute ("Name", name);
157 if (assemblyVersion != null)
158 se.AddAttribute ("AssemblyVersion", assemblyVersion.ToString ());
159 return se;
162 public override IPermission Union (IPermission target)
164 StrongNameIdentityPermission snip = Cast (target);
165 if ((snip == null) || snip.IsEmpty ())
166 return Copy ();
168 if (IsEmpty ())
169 return snip.Copy ();
171 if (!publickey.Equals (snip.publickey)) {
172 #if NET_2_0
173 string msg = Locale.GetText ("Permissions have different public keys.");
174 throw new ArgumentException (msg, "target");
175 #else
176 return null;
177 #endif
180 string n = name;
181 if ((n == null) || (n.Length == 0)) {
182 n = snip.name;
184 else if (Match (snip.name)) {
185 n = ((name.Length > snip.name.Length) ? name : snip.name);
187 else if ((snip.name != null) && (snip.name.Length > 0) && (n != snip.name)) {
188 #if NET_2_0
189 string msg = String.Format (Locale.GetText ("Name mismatch: '{0}' versus '{1}'"), n, snip.Name);
190 throw new ArgumentException (msg, "target");
191 #else
192 return null;
193 #endif
196 Version v = assemblyVersion;
197 if (v == null) {
198 v = snip.assemblyVersion;
200 else if ((snip.assemblyVersion != null) && (v != snip.assemblyVersion)) {
201 #if NET_2_0
202 string msg = String.Format (Locale.GetText ("Version mismatch: '{0}' versus '{1}'"), v, snip.assemblyVersion);
203 throw new ArgumentException (msg, "target");
204 #else
205 return null;
206 #endif
209 return new StrongNameIdentityPermission (publickey, n, v);
212 // IBuiltInPermission
213 int IBuiltInPermission.GetTokenIndex ()
215 return (int) BuiltInToken.StrongNameIdentity;
218 // helpers
220 private bool IsEmpty ()
222 if (publickey != null)
223 return false;
224 if ((name != null) && (name.Length > 0))
225 return false;
226 return ((assemblyVersion == null) || defaultVersion.Equals (assemblyVersion));
229 private StrongNameIdentityPermission Cast (IPermission target)
231 if (target == null)
232 return null;
234 StrongNameIdentityPermission snip = (target as StrongNameIdentityPermission);
235 if (snip == null) {
236 ThrowInvalidPermission (target, typeof (StrongNameIdentityPermission));
239 return snip;
242 private bool IsNameSubsetOf (string target)
244 int wildcard = name.LastIndexOf ('*');
245 if (wildcard == 0)
246 return true; // *
247 if (wildcard == -1)
248 wildcard = name.Length; // exact match
250 return (String.Compare (name, 0, target, 0, wildcard, true, CultureInfo.InvariantCulture) == 0);
253 private bool Match (string target)
255 if ((name == null) || (target == null))
256 return false;
258 int wcu = name.LastIndexOf ('*');
259 int wct = target.LastIndexOf ('*');
260 int length = Int32.MaxValue;
262 if ((wcu == -1) && (wct == -1)) {
263 // no wildcard, this is an exact match
264 length = Math.Max (name.Length, target.Length);
266 else if (wcu == -1) {
267 // only "target" has a wildcard, use it
268 length = wct;
270 else if (wct == -1) {
271 // only "this" has a wildcard, use it
272 length = wcu;
274 else {
275 // both have wildcards, partial match with the smallest
276 length = Math.Min (wcu, wct);
279 return (String.Compare (name, 0, target, 0, length, true, CultureInfo.InvariantCulture) == 0);