a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
315 lines
8.6 KiB
C#
315 lines
8.6 KiB
C#
//
|
|
// 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;
|
|
}
|
|
}
|
|
}
|
|
}
|