2 // System.Security.Permissions.UrlIdentityPermission.cs
5 // Sebastien Pouliot <sebastien@ximian.com>
7 // Copyright (C) 2003 Motus Technologies. 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.Globalization;
31 using System.Runtime.InteropServices;
33 namespace System.Security.Permissions {
39 public sealed class UrlIdentityPermission : CodeAccessPermission, IBuiltInPermission {
41 private const int version = 1;
45 public UrlIdentityPermission (PermissionState state)
47 // false == do not allow Unrestricted for Identity Permissions
48 CheckPermissionState (state, false);
54 public UrlIdentityPermission (string site)
57 throw new ArgumentNullException ("site");
64 set { url = ((value == null) ? String.Empty : value); }
70 throw new NullReferenceException ("Url");
75 throw new ArgumentNullException ("Url");
81 public override IPermission Copy ()
85 return new UrlIdentityPermission (PermissionState.None);
87 throw new NullReferenceException ("Url");
91 return new UrlIdentityPermission (url);
94 public override void FromXml (SecurityElement esd)
96 // General validation in CodeAccessPermission
97 CheckSecurityElement (esd, "esd", 1, 1);
98 // Note: we do not (yet) care about the return value
99 // as we only accept version 1 (min/max values)
101 string u = esd.Attribute ("Url");
108 public override IPermission Intersect (IPermission target)
110 // if one permission is null (object or url) then there's no intersection
111 // if both are null then intersection is null
112 UrlIdentityPermission uip = Cast (target);
113 if ((uip == null) || (IsEmpty ()))
115 if (Match (uip.url)) {
116 // longest form is the intersection
117 if (url.Length > uip.url.Length)
125 public override bool IsSubsetOf (IPermission target)
127 UrlIdentityPermission uip = Cast (target);
135 // here Match wouldn't work as it is bidirectional
136 int wildcard = uip.url.LastIndexOf ('*');
138 wildcard = uip.url.Length; // exact match
140 return (String.Compare (url, 0, uip.url, 0, wildcard, true, CultureInfo.InvariantCulture) == 0);
143 public override SecurityElement ToXml ()
145 SecurityElement se = Element (version);
147 se.AddAttribute ("Url", url);
151 public override IPermission Union (IPermission target)
153 UrlIdentityPermission uip = Cast (target);
156 if (IsEmpty () && uip.IsEmpty ())
162 if (Match (uip.url)) {
163 // shortest form is the union
164 if (url.Length < uip.url.Length)
170 throw new ArgumentException (Locale.GetText (
171 "Cannot union two different urls."), "target");
177 // IBuiltInPermission
178 int IBuiltInPermission.GetTokenIndex ()
180 return (int) BuiltInToken.UrlIdentity;
185 private bool IsEmpty ()
187 return ((url == null) || (url.Length == 0));
190 private UrlIdentityPermission Cast (IPermission target)
195 UrlIdentityPermission uip = (target as UrlIdentityPermission);
197 ThrowInvalidPermission (target, typeof (UrlIdentityPermission));
203 private bool Match (string target)
205 if ((url == null) || (target == null))
208 int wcu = url.LastIndexOf ('*');
209 int wct = target.LastIndexOf ('*');
210 int length = Int32.MaxValue;
212 if ((wcu == -1) && (wct == -1)) {
213 // no wildcard, this is an exact match
214 length = Math.Max (url.Length, target.Length);
216 else if (wcu == -1) {
217 // only "this" has a wildcard, use it
220 else if (wct == -1) {
221 // only "target" has a wildcard, use it
225 // both have wildcards, partial match with the smallest
226 length = Math.Min (wcu, wct);
229 return (String.Compare (url, 0, target, 0, length, true, CultureInfo.InvariantCulture) == 0);