//
// Author
// Duncan Mak (duncan@ximian.com)
+// Sebastien Pouliot <sebastien@ximian.com>
//
// (C) 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Motus Technologies Inc. (http://www.motus.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
using System.Globalization;
+using System.Runtime.InteropServices;
using System.Security.Permissions;
-using System.Security.Policy;
+
+using Mono.Security;
namespace System.Security.Policy {
- [Serializable]
- public sealed class Url: IIdentityPermissionFactory {
+ [Serializable]
+#if NET_2_0
+ [ComVisible (true)]
+#endif
+ public sealed class Url: IIdentityPermissionFactory, IBuiltInEvidence {
- string origin_url;
- SecurityElement element;
+ private string origin_url;
public Url (string name)
+ : this (name, false)
{
- if (name == null)
- throw new ArgumentNullException (Locale.GetText ("name is null"));
-
- origin_url = name;
- element = new SecurityElement (
- typeof (System.Security.Policy.Url).FullName);
-
- element.AddAttribute ("version", "1");
- element.AddChild (new SecurityElement ("Url", name));
}
- private Url (string name, SecurityElement security_element)
- {
- origin_url = name;
- element = security_element;
- }
+ internal Url (string name, bool validated)
+ {
+ origin_url = validated ? name : Prepare (name);
+ }
+
+ // methods
public object Copy ()
{
- return new Url (origin_url, element);
+ // dont re-validate the Url
+ return new Url (origin_url, true);
}
public IPermission CreateIdentityPermission (Evidence evidence)
public override bool Equals (object o)
{
- return (o is System.Security.Policy.Url && ((Url) o).Value == Value);
+ Url u = (o as System.Security.Policy.Url);
+ if (u == null)
+ return false;
+
+ string url1 = u.Value;
+ string url2 = origin_url;
+#if NET_2_0
+ if (url1.IndexOf (Uri.SchemeDelimiter) < 0)
+ url1 = "file://" + url1;
+ if (url2.IndexOf (Uri.SchemeDelimiter) < 0)
+ url2 = "file://" + url2;
+#endif
+ return (String.Compare (url1, url2, true, CultureInfo.InvariantCulture) == 0);
}
public override int GetHashCode ()
{
- return origin_url.GetHashCode ();
+ string s = origin_url;
+#if NET_2_0
+ if (s.IndexOf (Uri.SchemeDelimiter) < 0)
+ s = "file://" + s;
+#endif
+ return s.GetHashCode ();
}
public override string ToString ()
{
- return element.ToString ();
+ SecurityElement element = new SecurityElement ("System.Security.Policy.Url");
+ element.AddAttribute ("version", "1");
+ element.AddChild (new SecurityElement ("Url", origin_url));
+ return element.ToString ();
}
public string Value {
- get {
- return origin_url;
- }
+ get { return origin_url; }
}
- }
+
+ // interface IBuiltInEvidence
+
+ int IBuiltInEvidence.GetRequiredSize (bool verbose)
+ {
+ return (verbose ? 3 : 1) + origin_url.Length;
+ }
+
+ [MonoTODO ("IBuiltInEvidence")]
+ int IBuiltInEvidence.InitFromBuffer (char [] buffer, int position)
+ {
+ return 0;
+ }
+
+ [MonoTODO ("IBuiltInEvidence")]
+ int IBuiltInEvidence.OutputToBuffer (char [] buffer, int position, bool verbose)
+ {
+ return 0;
+ }
+
+ // internal
+#if NET_2_0
+ private string Prepare (string url)
+ {
+ if (url == null)
+ throw new ArgumentNullException ("Url");
+ if (url == String.Empty)
+ throw new FormatException (Locale.GetText ("Invalid (empty) Url"));
+
+ int protocolPos = url.IndexOf (Uri.SchemeDelimiter); // '://'
+ if (protocolPos > 0) {
+ if (url.StartsWith ("file://")) {
+ // convert file url into uppercase
+ url = "file://" + url.Substring (7);
+ }
+ // don't escape and don't reduce (e.g. '.' and '..')
+ Uri uri = new Uri (url, false, false);
+ url = uri.ToString ();
+ }
+
+ int lastpos = url.Length - 1;
+ if (url [lastpos] == '/')
+ url = url.Substring (0, lastpos);
+
+ return url;
+ }
+#else
+ private string Prepare (string url)
+ {
+ if (url == null)
+ throw new ArgumentNullException ("Url");
+ if (url == String.Empty)
+ throw new FormatException (Locale.GetText ("Invalid (empty) Url"));
+
+ int protocolPos = url.IndexOf (Uri.SchemeDelimiter); // '://'
+ if (protocolPos > 0) {
+ if (url.StartsWith ("file://")) {
+ // convert file url into uppercase
+ url = "file://" + url.Substring (7).ToUpperInvariant ();
+ } else {
+ // add a trailing slash if none (lonely one) is present
+ if (url.LastIndexOf ("/") == protocolPos + 2)
+ url += "/";
+ }
+ } else {
+ // add file scheme (default) and convert url to uppercase
+ url = "file://" + url.ToUpperInvariant ();
+ }
+
+ // don't escape and don't reduce (e.g. '.' and '..')
+ Uri uri = new Uri (url, false, false);
+ if ((uri.Host.IndexOf ('*') < 0) || (uri.Host.Length < 2)) // lone star case
+ url = uri.ToString ();
+ else {
+ string msg = Locale.GetText ("Invalid * character in url");
+ throw new ArgumentException (msg, "name");
+ }
+
+ return url;
+ }
+#endif
+ }
}