// Sebastien Pouliot <sebastien@ximian.com>
//
// 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
//
using System.Collections;
+using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Threading;
namespace System.Security.Permissions {
+ [ComVisible (true)]
[Serializable]
public sealed class PrincipalPermission : IPermission, IUnrestrictedPermission, IBuiltInPermission {
internal PrincipalPermission (ArrayList principals)
{
- this.principals = principals;
+ this.principals = (ArrayList) principals.Clone ();
}
// Properties
}
if (!demand)
- throw new SecurityException ("invalid Principal");
+ throw new SecurityException ("Demand for principal refused.");
}
}
- public void FromXml (SecurityElement esd)
+ public void FromXml (SecurityElement elem)
{
// General validation in CodeAccessPermission
- CodeAccessPermission.CheckSecurityElement (esd, "esd", version, version);
+ 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);
}
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);
{
PrincipalPermission pp = Cast (target);
if (pp == null)
- return false;
+ return IsEmpty ();
if (IsUnrestricted ())
return pp.IsUnrestricted ();
public SecurityElement ToXml ()
{
- SecurityElement se = new SecurityElement ("IPermission");
+ SecurityElement se = new SecurityElement ("Permission");
Type type = this.GetType ();
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)
return se;
}
- public IPermission Union (IPermission target)
+ public IPermission Union (IPermission other)
{
- PrincipalPermission pp = Cast (target);
+ PrincipalPermission pp = Cast (other);
if (pp == null)
return Copy ();
PrincipalPermission union = new PrincipalPermission (principals);
foreach (PrincipalInfo pi in pp.principals)
- principals.Add (pi);
+ union.principals.Add (pi);
return union;
}
-#if NET_2_0
+ [ComVisible (false)]
public override bool Equals (object obj)
{
if (obj == null)
// 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 ();
}
-#endif
// IBuiltInPermission
int IBuiltInPermission.GetTokenIndex ()
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;
+ }
}
}