X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Security.Permissions%2FPrincipalPermission.cs;h=5052eef0b07e37cbdbfb7a7131c5931c07377970;hb=42874b6479cf103ca2e044b95c27a2edbb21d75c;hp=172354900154f5ec256108552ca1f045c353286c;hpb=b7c17c47e6b3c02192e64175cb5ee0ce7f7dda1b;p=mono.git diff --git a/mcs/class/corlib/System.Security.Permissions/PrincipalPermission.cs b/mcs/class/corlib/System.Security.Permissions/PrincipalPermission.cs index 17235490015..5052eef0b07 100644 --- a/mcs/class/corlib/System.Security.Permissions/PrincipalPermission.cs +++ b/mcs/class/corlib/System.Security.Permissions/PrincipalPermission.cs @@ -2,13 +2,10 @@ // System.Security.Permissions.PrincipalPermission.cs // // Author -// Sebastien Pouliot +// Sebastien Pouliot // // Copyright (C) 2003 Motus Technologies. 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,24 +27,27 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -using System; using System.Collections; +using System.Runtime.InteropServices; using System.Security.Principal; -using System.Text; using System.Threading; namespace System.Security.Permissions { + [ComVisible (true)] [Serializable] public sealed class PrincipalPermission : IPermission, IUnrestrictedPermission, IBuiltInPermission { + private const int version = 1; + internal class PrincipalInfo { private string _name; private string _role; private bool _isAuthenticated; - public PrincipalInfo (string name, string role, bool isAuthenticated) { + public PrincipalInfo (string name, string role, bool isAuthenticated) + { _name = name; _role = role; _isAuthenticated = isAuthenticated; @@ -73,15 +73,9 @@ namespace System.Security.Permissions { public PrincipalPermission (PermissionState state) { principals = new ArrayList (); - switch (state) { - case PermissionState.None: - break; - case PermissionState.Unrestricted: - PrincipalInfo pi = new PrincipalInfo (null, null, true); - principals.Add (pi); - break; - default: - throw new ArgumentException ("unknown PermissionState"); + if (CodeAccessPermission.CheckPermissionState (state, true) == PermissionState.Unrestricted) { + PrincipalInfo pi = new PrincipalInfo (null, null, true); + principals.Add (pi); } } @@ -132,30 +126,33 @@ namespace System.Security.Permissions { } if (!demand) - throw new SecurityException ("invalid Principal"); + throw new SecurityException ("Demand for principal refused."); } } - public void FromXml (SecurityElement esd) + public void FromXml (SecurityElement elem) { - if (esd == null) - throw new ArgumentNullException ("esd"); - if (esd.Tag != "IPermission") - throw new ArgumentException ("not IPermission"); - if (!(esd.Attributes ["class"] as string).StartsWith ("System.Security.Permissions.PrincipalPermission")) - throw new ArgumentException ("not PrincipalPermission"); - if ((esd.Attributes ["version"] as string) != "1") - throw new ArgumentException ("wrong version"); + // General validation in CodeAccessPermission + CheckSecurityElement (elem, "elem", version, version); + // Note: we do not (yet) care about the return value + // as we only accept version 1 (min/max values) principals.Clear (); // Children is null, not empty, when no child is present - if (esd.Children != null) { - foreach (SecurityElement se in esd.Children) { + if (elem.Children != null) { + foreach (SecurityElement se in elem.Children) { if (se.Tag != "Identity") throw new ArgumentException ("not IPermission/Identity"); - string name = (se.Attributes ["Name"] as string); - string role = (se.Attributes ["Role"] as string); - bool isAuthenticated = ((se.Attributes ["Authenticated"] as string) == "true"); + string name = se.Attribute ("ID"); + string role = se.Attribute ("Role"); + string auth = se.Attribute ("Authenticated"); + bool isAuthenticated = false; + if (auth != null) { + try { + isAuthenticated = Boolean.Parse (auth); + } + catch {} + } PrincipalInfo pi = new PrincipalInfo (name, role, isAuthenticated); principals.Add (pi); } @@ -164,27 +161,29 @@ namespace System.Security.Permissions { public IPermission Intersect (IPermission target) { - if (target == null) + PrincipalPermission pp = Cast (target); + if (pp == null) return null; - if (! (target is PrincipalPermission)) - throw new ArgumentException ("wrong type"); - PrincipalPermission o = (PrincipalPermission) target; if (IsUnrestricted ()) - return o.Copy (); - if (o.IsUnrestricted ()) + return pp.Copy (); + if (pp.IsUnrestricted ()) return Copy (); PrincipalPermission intersect = new PrincipalPermission (PermissionState.None); foreach (PrincipalInfo pi in principals) { - foreach (PrincipalInfo opi in o.principals) { + foreach (PrincipalInfo opi in pp.principals) { if (pi.IsAuthenticated == opi.IsAuthenticated) { string name = null; if ((pi.Name == opi.Name) || (opi.Name == null)) name = pi.Name; + else if (pi.Name == null) + name = opi.Name; string role = null; if ((pi.Role == opi.Role) || (opi.Role == null)) role = pi.Role; + else if (pi.Role == null) + role = opi.Role; if ((name != null) || (role != null)) { PrincipalInfo ipi = new PrincipalInfo (name, role, pi.IsAuthenticated); intersect.principals.Add (ipi); @@ -198,22 +197,19 @@ namespace System.Security.Permissions { public bool IsSubsetOf (IPermission target) { - if (target == null) - return false; + PrincipalPermission pp = Cast (target); + if (pp == null) + return IsEmpty (); - if (! (target is PrincipalPermission)) - throw new ArgumentException ("wrong type"); - - PrincipalPermission o = (PrincipalPermission) target; if (IsUnrestricted ()) - return o.IsUnrestricted (); - else if (o.IsUnrestricted ()) + return pp.IsUnrestricted (); + else if (pp.IsUnrestricted ()) return true; // each must be a subset of the target foreach (PrincipalInfo pi in principals) { bool thisItem = false; - foreach (PrincipalInfo opi in o.principals) { + foreach (PrincipalInfo opi in pp.principals) { if (((pi.Name == opi.Name) || (opi.Name == null)) && ((pi.Role == opi.Role) || (opi.Role == null)) && (pi.IsAuthenticated == opi.IsAuthenticated)) @@ -242,16 +238,15 @@ namespace System.Security.Permissions { public SecurityElement ToXml () { - SecurityElement se = new SecurityElement ("IPermission"); + SecurityElement se = new SecurityElement ("Permission"); Type type = this.GetType (); - StringBuilder asmName = new StringBuilder (type.Assembly.ToString ()); - asmName.Replace ('\"', '\''); - se.AddAttribute ("class", type.FullName + ", " + asmName); - se.AddAttribute ("version", "1"); + se.AddAttribute ("class", type.FullName + ", " + type.Assembly.ToString ().Replace ('\"', '\'')); + se.AddAttribute ("version", version.ToString ()); + foreach (PrincipalInfo pi in principals) { SecurityElement sec = new SecurityElement ("Identity"); if (pi.Name != null) - sec.AddAttribute ("Name", pi.Name); + sec.AddAttribute ("ID", pi.Name); if (pi.Role != null) sec.AddAttribute ("Role", pi.Role); if (pi.IsAuthenticated) @@ -261,28 +256,124 @@ namespace System.Security.Permissions { return se; } - public IPermission Union (IPermission target) + public IPermission Union (IPermission other) { - if (target == null) + PrincipalPermission pp = Cast (other); + if (pp == null) return Copy (); - if (! (target is PrincipalPermission)) - throw new ArgumentException ("wrong type"); - PrincipalPermission o = (PrincipalPermission) target; - if (IsUnrestricted () || o.IsUnrestricted ()) + if (IsUnrestricted () || pp.IsUnrestricted ()) return new PrincipalPermission (PermissionState.Unrestricted); PrincipalPermission union = new PrincipalPermission (principals); - foreach (PrincipalInfo pi in o.principals) + foreach (PrincipalInfo pi in pp.principals) union.principals.Add (pi); return union; } + [ComVisible (false)] + public override bool Equals (object obj) + { + if (obj == null) + return false; + + PrincipalPermission pp = (obj as PrincipalPermission); + if (pp == null) + return false; + + // same number of principals ? + if (principals.Count != pp.principals.Count) + return false; + + // then all principals in "this" should be in "pp" + foreach (PrincipalInfo pi in principals) { + bool thisItem = false; + foreach (PrincipalInfo opi in pp.principals) { + if (((pi.Name == opi.Name) || (opi.Name == null)) && + ((pi.Role == opi.Role) || (opi.Role == null)) && + (pi.IsAuthenticated == opi.IsAuthenticated)) { + thisItem = true; + break; + } + } + if (!thisItem) + return false; + } + return true; + } + + // according to documentation (fx 2.0 beta 1) we can have + // different hash code even if both a Equals + [ComVisible (false)] + public override int GetHashCode () + { + return base.GetHashCode (); + } + // IBuiltInPermission int IBuiltInPermission.GetTokenIndex () { - return 8; + return (int) BuiltInToken.Principal; + } + + // helpers + + private PrincipalPermission Cast (IPermission target) + { + if (target == null) + return null; + + PrincipalPermission pp = (target as PrincipalPermission); + if (pp == null) { + CodeAccessPermission.ThrowInvalidPermission (target, typeof (PrincipalPermission)); + } + + return pp; + } + + private bool IsEmpty () + { + return (principals.Count == 0); + } + + // Normally permissions tags are "IPermission" but this (non-CAS) permission use "Permission" + internal int CheckSecurityElement (SecurityElement se, string parameterName, int minimumVersion, int maximumVersion) + { + if (se == null) + throw new ArgumentNullException (parameterName); + + // Tag is case-sensitive + if (se.Tag != "Permission") { + string msg = String.Format (Locale.GetText ("Invalid tag {0}"), se.Tag); + throw new ArgumentException (msg, parameterName); + } + + // Note: we do not care about the class attribute at + // this stage (in fact we don't even if the class + // attribute is present or not). Anyway the object has + // already be created, with success, if we're loading it + + // we assume minimum version if no version number is supplied + int version = minimumVersion; + string v = se.Attribute ("version"); + if (v != null) { + try { + version = Int32.Parse (v); + } + catch (Exception e) { + string msg = Locale.GetText ("Couldn't parse version from '{0}'."); + msg = String.Format (msg, v); + throw new ArgumentException (msg, parameterName, e); + } + } + + if ((version < minimumVersion) || (version > maximumVersion)) { + string msg = Locale.GetText ("Unknown version '{0}', expected versions between ['{1}','{2}']."); + msg = String.Format (msg, version, minimumVersion, maximumVersion); + throw new ArgumentException (msg, parameterName); + } + return version; } } }