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 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
.Globalization
;
32 namespace System
.Security
.Permissions
{
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
;
42 private Version assemblyVersion
;
44 public StrongNameIdentityPermission (PermissionState state
)
46 // false == do not allow Unrestricted for Identity Permissions
47 CheckPermissionState (state
, false);
50 assemblyVersion
= (Version
) defaultVersion
.Clone ();
53 public StrongNameIdentityPermission (StrongNamePublicKeyBlob blob
, string name
, Version version
)
56 throw new ArgumentNullException ("blob");
60 assemblyVersion
= version
;
67 if ((value != null) && (value.Length
== 0))
68 throw new ArgumentException ("name");
74 public StrongNamePublicKeyBlob PublicKey
{
75 get { return publickey; }
78 throw new ArgumentNullException ("value");
83 public Version Version
{
84 get { return assemblyVersion; }
85 set { assemblyVersion = value; }
88 public override IPermission
Copy ()
91 return new StrongNameIdentityPermission (PermissionState
.None
);
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 ())
117 return new StrongNameIdentityPermission (PermissionState
.None
);
118 if (!Match (snip
.name
))
121 string n
= ((name
.Length
< snip
.name
.Length
) ? name
: snip
.name
);
122 if (!assemblyVersion
.Equals (snip
.assemblyVersion
))
124 if (!publickey
.Equals (snip
.publickey
))
127 return new StrongNameIdentityPermission (publickey
, n
, assemblyVersion
);
130 public override bool IsSubsetOf (IPermission target
)
132 StrongNameIdentityPermission snip
= Cast (target
);
139 if ((name
!= null) && (name
.Length
> 0) && !IsNameSubsetOf (snip
.Name
))
141 if ((assemblyVersion
!= null) && !assemblyVersion
.Equals (snip
.assemblyVersion
))
143 // in case PermissionState.None was used in the constructor
144 if (publickey
== null)
145 return (snip
.publickey
== null);
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 ());
156 se
.AddAttribute ("Name", name
);
157 if (assemblyVersion
!= null)
158 se
.AddAttribute ("AssemblyVersion", assemblyVersion
.ToString ());
162 public override IPermission
Union (IPermission target
)
164 StrongNameIdentityPermission snip
= Cast (target
);
165 if ((snip
== null) || snip
.IsEmpty ())
171 if (!publickey
.Equals (snip
.publickey
)) {
173 string msg
= Locale
.GetText ("Permissions have different public keys.");
174 throw new ArgumentException (msg
, "target");
181 if ((n
== null) || (n
.Length
== 0)) {
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
)) {
189 string msg
= String
.Format (Locale
.GetText ("Name mismatch: '{0}' versus '{1}'"), n
, snip
.Name
);
190 throw new ArgumentException (msg
, "target");
196 Version v
= assemblyVersion
;
198 v
= snip
.assemblyVersion
;
200 else if ((snip
.assemblyVersion
!= null) && (v
!= snip
.assemblyVersion
)) {
202 string msg
= String
.Format (Locale
.GetText ("Version mismatch: '{0}' versus '{1}'"), v
, snip
.assemblyVersion
);
203 throw new ArgumentException (msg
, "target");
209 return new StrongNameIdentityPermission (publickey
, n
, v
);
212 // IBuiltInPermission
213 int IBuiltInPermission
.GetTokenIndex ()
215 return (int) BuiltInToken
.StrongNameIdentity
;
220 private bool IsEmpty ()
222 if (publickey
!= null)
224 if ((name
!= null) && (name
.Length
> 0))
226 return ((assemblyVersion
== null) || defaultVersion
.Equals (assemblyVersion
));
229 private StrongNameIdentityPermission
Cast (IPermission target
)
234 StrongNameIdentityPermission snip
= (target
as StrongNameIdentityPermission
);
236 ThrowInvalidPermission (target
, typeof (StrongNameIdentityPermission
));
242 private bool IsNameSubsetOf (string target
)
244 int wildcard
= name
.LastIndexOf ('*');
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))
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
270 else if (wct
== -1) {
271 // only "this" has a wildcard, use it
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);