2 // StrongNameIdentityPermission.cs: Strong Name Identity Permission
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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
{
38 public sealed class StrongNameIdentityPermission
: CodeAccessPermission
, IBuiltInPermission
{
40 private const int version
= 1;
41 static private Version defaultVersion
= new Version (0, 0);
44 public StrongNamePublicKeyBlob PublicKey
;
46 public Version AssemblyVersion
;
48 internal SNIP (StrongNamePublicKeyBlob pk
, string name
, Version version
)
52 AssemblyVersion
= version
;
55 internal static SNIP
CreateDefault ()
57 return new SNIP (null, String
.Empty
, (Version
) defaultVersion
.Clone ());
60 internal bool IsNameSubsetOf (string target
)
63 return (target
== null);
67 int wildcard
= Name
.LastIndexOf ('*');
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
))
81 if (!IsNameSubsetOf (target
.Name
))
83 if ((AssemblyVersion
!= null) && !AssemblyVersion
.Equals (target
.AssemblyVersion
))
85 // in case PermissionState.None was used in the constructor
86 if (PublicKey
== null)
87 return (target
.PublicKey
== null);
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);
100 _list
= new ArrayList ();
101 _list
.Add (SNIP
.CreateDefault ());
104 public StrongNameIdentityPermission (StrongNamePublicKeyBlob blob
, string name
, Version version
)
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
));
130 throw new NotSupportedException ();
131 return ((SNIP
)_list
[0]).Name
;
134 if ((value != null) && (value.Length
== 0))
135 throw new ArgumentException ("name");
138 SNIP snip
= (SNIP
) _list
[0];
144 public StrongNamePublicKeyBlob PublicKey
{
147 throw new NotSupportedException ();
148 return ((SNIP
)_list
[0]).PublicKey
;
152 throw new ArgumentNullException ("value");
155 SNIP snip
= (SNIP
) _list
[0];
156 snip
.PublicKey
= value;
161 public Version Version
{
164 throw new NotSupportedException ();
165 return ((SNIP
)_list
[0]).AssemblyVersion
;
170 SNIP snip
= (SNIP
) _list
[0];
171 snip
.AssemblyVersion
= value;
176 internal void ResetToDefault ()
179 _list
.Add (SNIP
.CreateDefault ());
184 public override IPermission
Copy ()
187 return new StrongNameIdentityPermission (PermissionState
.None
);
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)
199 if ((e
.Children
!= null) && (e
.Children
.Count
> 0)) {
200 foreach (SecurityElement se
in e
.Children
) {
201 _list
.Add (FromSecurityElement (se
));
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
)
221 StrongNameIdentityPermission snip
= (target
as StrongNameIdentityPermission
);
223 throw new ArgumentException (Locale
.GetText ("Wrong permission type."));
224 if (IsEmpty () || snip
.IsEmpty ())
226 if (!Match (snip
.Name
))
229 string n
= ((Name
.Length
< snip
.Name
.Length
) ? Name
: snip
.Name
);
230 if (!Version
.Equals (snip
.Version
))
232 if (!PublicKey
.Equals (snip
.PublicKey
))
235 return new StrongNameIdentityPermission (this.PublicKey
, n
, this.Version
);
238 public override bool IsSubsetOf (IPermission target
)
240 StrongNameIdentityPermission snip
= Cast (target
);
246 if (IsUnrestricted ())
247 return snip
.IsUnrestricted ();
248 else if (snip
.IsUnrestricted ())
251 foreach (SNIP e
in _list
) {
252 foreach (SNIP t
in snip
._list
) {
253 if (!e
.IsSubsetOf (t
))
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
);
269 } else if (_list
.Count
== 1) {
270 SNIP snip
= (SNIP
)_list
[0];
272 ToSecurityElement (se
, snip
);
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 ())
296 StrongNameIdentityPermission union
= (StrongNameIdentityPermission
) Copy ();
297 foreach (SNIP e
in snip
._list
) {
298 if (!IsEmpty (e
) && !Contains (e
)) {
305 // IBuiltInPermission
306 int IBuiltInPermission
.GetTokenIndex ()
308 return (int) BuiltInToken
.StrongNameIdentity
;
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
)
333 private bool IsEmpty (SNIP snip
)
335 if (PublicKey
!= null)
337 if ((Name
!= null) && (Name
.Length
> 0))
339 return ((Version
== null) || defaultVersion
.Equals (Version
));
342 private bool IsEmpty ()
344 if (IsUnrestricted () || (_list
.Count
> 1))
346 if (PublicKey
!= null)
348 if ((Name
!= null) && (Name
.Length
> 0))
350 return ((Version
== null) || defaultVersion
.Equals (Version
));
353 private StrongNameIdentityPermission
Cast (IPermission target
)
358 StrongNameIdentityPermission snip
= (target
as StrongNameIdentityPermission
);
360 ThrowInvalidPermission (target
, typeof (StrongNameIdentityPermission
));
366 private bool Match (string target
)
368 if ((Name
== null) || (target
== null))
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
383 else if (wct
== -1) {
384 // only "this" has a wildcard, use it
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);