//
// System.Security.Policy.CodeGroup
//
// Authors:
// Nick Drochak (ndrochak@gol.com)
// Sebastien Pouliot <sebastien@ximian.com>
//
// (C) 2001 Nick Drochak, All rights reserved.
// Copyright (C) 2004-2006 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.Collections;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Permissions;
namespace System.Security.Policy{
[Serializable]
[ComVisible (true)]
public abstract class CodeGroup {
PolicyStatement m_policy;
IMembershipCondition m_membershipCondition;
string m_description;
string m_name;
ArrayList m_children = new ArrayList();
// PolicyLevel m_level;
protected CodeGroup (IMembershipCondition membershipCondition, PolicyStatement policy)
{
if (null == membershipCondition)
throw new ArgumentNullException ("membershipCondition");
if (policy != null)
m_policy = policy.Copy ();
m_membershipCondition = membershipCondition.Copy ();
}
// for PolicyLevel (to avoid validation duplication)
internal CodeGroup (SecurityElement e, PolicyLevel level)
{
FromXml (e, level);
}
// abstract
public abstract CodeGroup Copy ();
public abstract string MergeLogic { get; }
public abstract PolicyStatement Resolve (Evidence evidence);
public abstract CodeGroup ResolveMatchingCodeGroups (Evidence evidence);
// properties
public PolicyStatement PolicyStatement {
get { return m_policy; }
set { m_policy = value; }
}
public string Description {
get { return m_description; }
set { m_description = value; }
}
public IMembershipCondition MembershipCondition {
get { return m_membershipCondition; }
set {
if (null == value)
throw new ArgumentException ("value");
m_membershipCondition = value;
}
}
public string Name {
get { return m_name; }
set { m_name = value; }
}
public IList Children {
get { return m_children; }
set {
if (null == value)
throw new ArgumentNullException ("value");
m_children = new ArrayList (value);
}
}
public virtual string AttributeString {
get {
if (null != m_policy)
return m_policy.AttributeString;
return null;
}
}
public virtual string PermissionSetName {
get {
if (m_policy == null)
return null;
if (m_policy.PermissionSet is Security.NamedPermissionSet)
return ((NamedPermissionSet)(m_policy.PermissionSet)).Name;
return null;
}
}
public void AddChild (CodeGroup group)
{
if (null == group)
throw new ArgumentNullException ("group");
m_children.Add (group.Copy ());
}
public override bool Equals (object o)
{
CodeGroup cg = (o as CodeGroup);
if (cg == null)
return false;
return Equals (cg, false);
}
public bool Equals (CodeGroup cg, bool compareChildren)
{
if (cg.Name != this.Name)
return false;
if (cg.Description != this.Description)
return false;
if (!cg.MembershipCondition.Equals (m_membershipCondition))
return false;
if (compareChildren) {
int childCount = cg.Children.Count;
if (this.Children.Count != childCount)
return false;
for (int index = 0; index < childCount; index++) {
// not a deep compare
if (!((CodeGroup)(this.Children [index])).Equals ((CodeGroup)(cg.Children [index]), false))
return false;
}
}
return true;
}
public void RemoveChild (CodeGroup group)
{
if (group != null)
m_children.Remove (group);
}
public override int GetHashCode ()
{
int hashCode = m_membershipCondition.GetHashCode ();
if (m_policy != null)
hashCode += m_policy.GetHashCode ();
return hashCode;
}
public void FromXml (SecurityElement e)
{
FromXml (e, null);
}
public void FromXml (SecurityElement e, PolicyLevel level)
{
if (null == e)
throw new ArgumentNullException("e");
PermissionSet ps = null;
string psetname = e.Attribute ("PermissionSetName");
if ((psetname != null) && (level != null)) {
ps = level.GetNamedPermissionSet (psetname);
}
else {
SecurityElement pset = e.SearchForChildByTag ("PermissionSet");
if (pset != null) {
Type classType = Type.GetType (pset.Attribute ("class"));
ps = (PermissionSet) Activator.CreateInstance (classType, true);
ps.FromXml (pset);
}
else {
ps = new PermissionSet (new PermissionSet (PermissionState.None));
}
}
m_policy = new PolicyStatement (ps);
m_children.Clear ();
if ((e.Children != null) && (e.Children.Count > 0)) {
foreach (SecurityElement se in e.Children) {
if (se.Tag == "CodeGroup") {
this.AddChild (CodeGroup.CreateFromXml (se, level));
}
}
}
m_membershipCondition = null;
SecurityElement mc = e.SearchForChildByTag ("IMembershipCondition");
if (mc != null) {
string className = mc.Attribute ("class");
Type classType = Type.GetType (className);
if (classType == null)
classType = Type.GetType ("System.Security.Policy." + className);
m_membershipCondition = (IMembershipCondition) Activator.CreateInstance (classType, true);
m_membershipCondition.FromXml (mc, level);
}
m_name = e.Attribute("Name");
m_description = e.Attribute("Description");
// seems like we might need this to Resolve() in subclasses
//m_level = level;
ParseXml (e, level);
}
protected virtual void ParseXml (SecurityElement e, PolicyLevel level)
{
}
public SecurityElement ToXml ()
{
return ToXml (null);
}
public SecurityElement ToXml (PolicyLevel level)
{
SecurityElement e = new SecurityElement("CodeGroup");
e.AddAttribute("class", this.GetType().AssemblyQualifiedName);
e.AddAttribute("version", "1");
if (null != Name)
e.AddAttribute("Name", Name);
if (null != Description)
e.AddAttribute("Description", Description);
if (null != MembershipCondition)
e.AddChild(MembershipCondition.ToXml());
if ((PolicyStatement != null) && (PolicyStatement.PermissionSet != null))
e.AddChild (PolicyStatement.PermissionSet.ToXml ());
foreach (CodeGroup child in Children)
e.AddChild(child.ToXml());
CreateXml(e, level);
return e;
}
protected virtual void CreateXml (SecurityElement element, PolicyLevel level)
{
}
// internal stuff
internal static CodeGroup CreateFromXml (SecurityElement se, PolicyLevel level)
{
string fullClassName = se.Attribute ("class");
string className = fullClassName;
// many possible formats
// a. "FirstMatchCodeGroup"
// b. "System.Security.Policy.FirstMatchCodeGroup"
// c. "System.Security.Policy.FirstMatchCodeGroup, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\n version=\"1\">\r\n <IMembershipCondition class=\"System.Security.Policy.AllMembershipCondition, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
int n = className.IndexOf (",");
if (n > 0) {
className = className.Substring (0, n);
}
n = className.LastIndexOf (".");
if (n > 0)
className = className.Substring (n + 1);
// much faster than calling Activator.CreateInstance
switch (className) {
case "FileCodeGroup":
return new FileCodeGroup (se, level);
case "FirstMatchCodeGroup":
return new FirstMatchCodeGroup (se, level);
case "NetCodeGroup":
return new NetCodeGroup (se, level);
case "UnionCodeGroup":
return new UnionCodeGroup (se, level);
default: // unknown
Type classType = Type.GetType (fullClassName);
CodeGroup cg = (CodeGroup) Activator.CreateInstance (classType, true);
cg.FromXml (se, level);
return cg;
}
}
}
}
|