X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Security.Permissions%2FStrongNameIdentityPermission.cs;h=7b1f4bd7bb593ae4e9189d1d067c0f1976551d8f;hb=aa1c098cb9e5471eaf5a3e5f7088416f06b35e7f;hp=ad6f375a0ec7f6111852ec6111903a369778aa2d;hpb=13d1764537ce5bbe5a06bf133fb2db1a4b5d2131;p=mono.git diff --git a/mcs/class/corlib/System.Security.Permissions/StrongNameIdentityPermission.cs b/mcs/class/corlib/System.Security.Permissions/StrongNameIdentityPermission.cs index ad6f375a0ec..7b1f4bd7bb5 100644 --- a/mcs/class/corlib/System.Security.Permissions/StrongNameIdentityPermission.cs +++ b/mcs/class/corlib/System.Security.Permissions/StrongNameIdentityPermission.cs @@ -2,13 +2,10 @@ // StrongNameIdentityPermission.cs: Strong Name Identity Permission // // Author: -// Sebastien Pouliot (spouliot@motus.com) +// Sebastien Pouliot // // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com) -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.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 @@ -30,99 +27,369 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -using System; +using System.Collections; +using System.Globalization; +using System.Runtime.InteropServices; namespace System.Security.Permissions { + [ComVisible (true)] [Serializable] public sealed class StrongNameIdentityPermission : CodeAccessPermission, IBuiltInPermission { - private StrongNamePublicKeyBlob publickey; - private string name; - private Version version; - + private const int version = 1; + static private Version defaultVersion = new Version (0, 0); + + private struct SNIP { + public StrongNamePublicKeyBlob PublicKey; + public string Name; + public Version AssemblyVersion; + + internal SNIP (StrongNamePublicKeyBlob pk, string name, Version version) + { + PublicKey = pk; + Name = name; + AssemblyVersion = version; + } + + internal static SNIP CreateDefault () + { + return new SNIP (null, String.Empty, (Version) defaultVersion.Clone ()); + } + + internal bool IsNameSubsetOf (string target) + { + if (Name == null) + return (target == null); + if (target == null) + return true; + + int wildcard = Name.LastIndexOf ('*'); + if (wildcard == 0) + return true; // * + if (wildcard == -1) + wildcard = Name.Length; // exact match + + return (String.Compare (Name, 0, target, 0, wildcard, true, CultureInfo.InvariantCulture) == 0); + } + + internal bool IsSubsetOf (SNIP target) + { + if ((PublicKey != null) && PublicKey.Equals (target.PublicKey)) + return true; + + if (!IsNameSubsetOf (target.Name)) + return false; + if ((AssemblyVersion != null) && !AssemblyVersion.Equals (target.AssemblyVersion)) + return false; + // in case PermissionState.None was used in the constructor + if (PublicKey == null) + return (target.PublicKey == null); + return false; + } + } + + private PermissionState _state; + private ArrayList _list; + public StrongNameIdentityPermission (PermissionState state) { - if (state == PermissionState.Unrestricted) - throw new ArgumentException ("state"); - name = String.Empty; - version = new Version (0, 0); + // Identity Permissions can be unrestricted in Fx 2.0 + _state = CheckPermissionState (state, true); + // default values + _list = new ArrayList (); + _list.Add (SNIP.CreateDefault ()); } - + public StrongNameIdentityPermission (StrongNamePublicKeyBlob blob, string name, Version version) { if (blob == null) throw new ArgumentNullException ("blob"); - if (name == null) - throw new ArgumentNullException ("name"); - if (version == null) - throw new ArgumentNullException ("version"); - - publickey = blob; - this.name = name; - this.version = version; + if ((name != null) && (name.Length == 0)) + throw new ArgumentException ("name"); + + _state = PermissionState.None; + _list = new ArrayList (); + _list.Add (new SNIP (blob, name, version)); } - + + internal StrongNameIdentityPermission (StrongNameIdentityPermission snip) + { + _state = snip._state; + _list = new ArrayList (snip._list.Count); + foreach (SNIP e in snip._list) { + _list.Add (new SNIP (e.PublicKey, e.Name, e.AssemblyVersion)); + } + } + + // Properties + public string Name { - get { return name; } - set { name = value; } + get { + if (_list.Count > 1) + throw new NotSupportedException (); + return ((SNIP)_list [0]).Name; + } + set { + if ((value != null) && (value.Length == 0)) + throw new ArgumentException ("name"); + if (_list.Count > 1) + ResetToDefault (); + SNIP snip = (SNIP) _list [0]; + snip.Name = value; + _list [0] = snip; + } } - + public StrongNamePublicKeyBlob PublicKey { - get { return publickey; } + get { + if (_list.Count > 1) + throw new NotSupportedException (); + return ((SNIP)_list [0]).PublicKey; + } set { if (value == null) throw new ArgumentNullException ("value"); - publickey = value; + if (_list.Count > 1) + ResetToDefault (); + SNIP snip = (SNIP) _list [0]; + snip.PublicKey = value; + _list [0] = snip; } } public Version Version { - get { return version; } - set { version = value; } + get { + if (_list.Count > 1) + throw new NotSupportedException (); + return ((SNIP)_list [0]).AssemblyVersion; + } + set { + if (_list.Count > 1) + ResetToDefault (); + SNIP snip = (SNIP) _list [0]; + snip.AssemblyVersion = value; + _list [0] = snip; + } + } + + internal void ResetToDefault () + { + _list.Clear (); + _list.Add (SNIP.CreateDefault ()); } + + // Methods public override IPermission Copy () { - return new StrongNameIdentityPermission (publickey, name, version); + if (IsEmpty ()) + return new StrongNameIdentityPermission (PermissionState.None); + else + return new StrongNameIdentityPermission (this); } - [MonoTODO] public override void FromXml (SecurityElement e) { - if (e == null) - throw new ArgumentNullException ("e"); - throw new NotImplementedException (); + // General validation in CodeAccessPermission + CheckSecurityElement (e, "e", version, version); + // Note: we do not (yet) care about the return value + // as we only accept version 1 (min/max values) + _list.Clear (); + if ((e.Children != null) && (e.Children.Count > 0)) { + foreach (SecurityElement se in e.Children) { + _list.Add (FromSecurityElement (se)); + } + } else { + _list.Add (FromSecurityElement (e)); + } + } + + private SNIP FromSecurityElement (SecurityElement se) + { + string name = se.Attribute ("Name"); + StrongNamePublicKeyBlob publickey = StrongNamePublicKeyBlob.FromString (se.Attribute ("PublicKeyBlob")); + string v = se.Attribute ("AssemblyVersion"); + Version assemblyVersion = (v == null) ? null : new Version (v); + + return new SNIP (publickey, name, assemblyVersion); } - - [MonoTODO] public override IPermission Intersect (IPermission target) { - throw new NotImplementedException (); + if (target == null) + return null; + StrongNameIdentityPermission snip = (target as StrongNameIdentityPermission); + if (snip == null) + throw new ArgumentException (Locale.GetText ("Wrong permission type.")); + if (IsEmpty () || snip.IsEmpty ()) + return null; + if (!Match (snip.Name)) + return null; + + string n = ((Name.Length < snip.Name.Length) ? Name : snip.Name); + if (!Version.Equals (snip.Version)) + return null; + if (!PublicKey.Equals (snip.PublicKey)) + return null; + + return new StrongNameIdentityPermission (this.PublicKey, n, this.Version); } - - [MonoTODO] + public override bool IsSubsetOf (IPermission target) { - throw new NotImplementedException (); + StrongNameIdentityPermission snip = Cast (target); + if (snip == null) + return IsEmpty (); + + if (IsEmpty ()) + return true; + if (IsUnrestricted ()) + return snip.IsUnrestricted (); + else if (snip.IsUnrestricted ()) + return true; + + foreach (SNIP e in _list) { + foreach (SNIP t in snip._list) { + if (!e.IsSubsetOf (t)) + return false; + } + } + return true; } - [MonoTODO] public override SecurityElement ToXml () { - throw new NotImplementedException (); + SecurityElement se = Element (version); + if (_list.Count > 1) { + foreach (SNIP snip in _list) { + SecurityElement child = new SecurityElement ("StrongName"); + ToSecurityElement (child, snip); + se.AddChild (child); + } + } else if (_list.Count == 1) { + SNIP snip = (SNIP)_list [0]; + if (!IsEmpty (snip)) + ToSecurityElement (se, snip); + } + return se; } - - [MonoTODO] + + private void ToSecurityElement (SecurityElement se, SNIP snip) + { + if (snip.PublicKey != null) + se.AddAttribute ("PublicKeyBlob", snip.PublicKey.ToString ()); + if (snip.Name != null) + se.AddAttribute ("Name", snip.Name); + if (snip.AssemblyVersion != null) + se.AddAttribute ("AssemblyVersion", snip.AssemblyVersion.ToString ()); + } + public override IPermission Union (IPermission target) { - throw new NotImplementedException (); + StrongNameIdentityPermission snip = Cast (target); + if ((snip == null) || snip.IsEmpty ()) + return Copy (); + + if (IsEmpty ()) + return snip.Copy (); + + StrongNameIdentityPermission union = (StrongNameIdentityPermission) Copy (); + foreach (SNIP e in snip._list) { + if (!IsEmpty (e) && !Contains (e)) { + union._list.Add (e); + } + } + return union; } // IBuiltInPermission int IBuiltInPermission.GetTokenIndex () { - return 11; + return (int) BuiltInToken.StrongNameIdentity; + } + + // helpers + + private bool IsUnrestricted () + { + return (_state == PermissionState.Unrestricted); + } + + private bool Contains (SNIP snip) + { + foreach (SNIP e in _list) { + bool pk = (((e.PublicKey == null) && (snip.PublicKey == null)) || + ((e.PublicKey != null) && e.PublicKey.Equals (snip.PublicKey))); + bool name = e.IsNameSubsetOf (snip.Name); + bool version = (((e.AssemblyVersion == null) && (snip.AssemblyVersion == null)) || + ((e.AssemblyVersion != null) && e.AssemblyVersion.Equals (snip.AssemblyVersion))); + + if (pk && name && version) + return true; + } + return false; + } + + private bool IsEmpty (SNIP snip) + { + if (PublicKey != null) + return false; + if ((Name != null) && (Name.Length > 0)) + return false; + return ((Version == null) || defaultVersion.Equals (Version)); + } + + private bool IsEmpty () + { + if (IsUnrestricted () || (_list.Count > 1)) + return false; + if (PublicKey != null) + return false; + if ((Name != null) && (Name.Length > 0)) + return false; + return ((Version == null) || defaultVersion.Equals (Version)); + } + + private StrongNameIdentityPermission Cast (IPermission target) + { + if (target == null) + return null; + + StrongNameIdentityPermission snip = (target as StrongNameIdentityPermission); + if (snip == null) { + ThrowInvalidPermission (target, typeof (StrongNameIdentityPermission)); + } + + return snip; + } + + private bool Match (string target) + { + if ((Name == null) || (target == null)) + return false; + + int wcu = Name.LastIndexOf ('*'); + int wct = target.LastIndexOf ('*'); + int length = Int32.MaxValue; + + if ((wcu == -1) && (wct == -1)) { + // no wildcard, this is an exact match + length = Math.Max (Name.Length, target.Length); + } + else if (wcu == -1) { + // only "target" has a wildcard, use it + length = wct; + } + else if (wct == -1) { + // only "this" has a wildcard, use it + length = wcu; + } + else { + // both have wildcards, partial match with the smallest + length = Math.Min (wcu, wct); + } + + return (String.Compare (Name, 0, target, 0, length, true, CultureInfo.InvariantCulture) == 0); } } }