2 // System.Security.Policy.CodeGroup
5 // Nick Drochak (ndrochak@gol.com)
6 // Sebastien Pouliot <sebastien@ximian.com>
8 // (C) 2001 Nick Drochak, All rights reserved.
9 // Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Collections;
32 using System.Globalization;
33 using System.Reflection;
34 using System.Runtime.InteropServices;
35 using System.Security.Permissions;
37 namespace System.Security.Policy {
41 public abstract class CodeGroup {
42 PolicyStatement m_policy;
43 IMembershipCondition m_membershipCondition;
46 ArrayList m_children = new ArrayList();
47 // PolicyLevel m_level;
49 protected CodeGroup (IMembershipCondition membershipCondition, PolicyStatement policy)
51 if (null == membershipCondition)
52 throw new ArgumentNullException ("membershipCondition");
55 m_policy = policy.Copy ();
56 m_membershipCondition = membershipCondition.Copy ();
59 // for PolicyLevel (to avoid validation duplication)
60 internal CodeGroup (SecurityElement e, PolicyLevel level)
67 public abstract CodeGroup Copy ();
69 public abstract string MergeLogic { get; }
71 public abstract PolicyStatement Resolve (Evidence evidence);
73 public abstract CodeGroup ResolveMatchingCodeGroups (Evidence evidence);
77 public PolicyStatement PolicyStatement {
78 get { return m_policy; }
79 set { m_policy = value; }
82 public string Description {
83 get { return m_description; }
84 set { m_description = value; }
87 public IMembershipCondition MembershipCondition {
88 get { return m_membershipCondition; }
91 throw new ArgumentException ("value");
92 m_membershipCondition = value;
97 get { return m_name; }
98 set { m_name = value; }
101 public IList Children {
102 get { return m_children; }
105 throw new ArgumentNullException ("value");
106 m_children = new ArrayList (value);
110 public virtual string AttributeString {
112 if (null != m_policy)
113 return m_policy.AttributeString;
118 public virtual string PermissionSetName {
120 if (m_policy == null)
122 if (m_policy.PermissionSet is Security.NamedPermissionSet)
123 return ((NamedPermissionSet)(m_policy.PermissionSet)).Name;
128 public void AddChild (CodeGroup group)
131 throw new ArgumentNullException ("group");
133 m_children.Add (group.Copy ());
136 public override bool Equals (object o)
138 CodeGroup cg = (o as CodeGroup);
142 return Equals (cg, false);
145 public bool Equals (CodeGroup cg, bool compareChildren)
147 if (cg.Name != this.Name)
150 if (cg.Description != this.Description)
153 if (!cg.MembershipCondition.Equals (m_membershipCondition))
156 if (compareChildren) {
157 int childCount = cg.Children.Count;
158 if (this.Children.Count != childCount)
161 for (int index = 0; index < childCount; index++) {
162 // not a deep compare
163 if (!((CodeGroup)(this.Children [index])).Equals ((CodeGroup)(cg.Children [index]), false))
170 public void RemoveChild (CodeGroup group)
173 m_children.Remove (group);
176 public override int GetHashCode ()
178 int hashCode = m_membershipCondition.GetHashCode ();
179 if (m_policy != null)
180 hashCode += m_policy.GetHashCode ();
184 public void FromXml (SecurityElement e)
189 public void FromXml (SecurityElement e, PolicyLevel level)
192 throw new ArgumentNullException("e");
194 PermissionSet ps = null;
195 string psetname = e.Attribute ("PermissionSetName");
196 if ((psetname != null) && (level != null)) {
197 ps = level.GetNamedPermissionSet (psetname);
200 SecurityElement pset = e.SearchForChildByTag ("PermissionSet");
202 Type classType = Type.GetType (pset.Attribute ("class"));
203 ps = (PermissionSet) Activator.CreateInstance (classType, true);
207 ps = new PermissionSet (new PermissionSet (PermissionState.None));
210 m_policy = new PolicyStatement (ps);
213 if ((e.Children != null) && (e.Children.Count > 0)) {
214 foreach (SecurityElement se in e.Children) {
215 if (se.Tag == "CodeGroup") {
216 this.AddChild (CodeGroup.CreateFromXml (se, level));
221 m_membershipCondition = null;
222 SecurityElement mc = e.SearchForChildByTag ("IMembershipCondition");
224 string className = mc.Attribute ("class");
225 Type classType = Type.GetType (className);
226 if (classType == null)
227 classType = Type.GetType ("System.Security.Policy." + className);
228 m_membershipCondition = (IMembershipCondition) Activator.CreateInstance (classType, true);
229 m_membershipCondition.FromXml (mc, level);
232 m_name = e.Attribute("Name");
233 m_description = e.Attribute("Description");
235 // seems like we might need this to Resolve() in subclasses
241 protected virtual void ParseXml (SecurityElement e, PolicyLevel level)
245 public SecurityElement ToXml ()
250 public SecurityElement ToXml (PolicyLevel level)
252 SecurityElement e = new SecurityElement("CodeGroup");
253 e.AddAttribute("class", this.GetType().AssemblyQualifiedName);
254 e.AddAttribute("version", "1");
257 e.AddAttribute("Name", Name);
259 if (null != Description)
260 e.AddAttribute("Description", Description);
262 if (null != MembershipCondition)
263 e.AddChild(MembershipCondition.ToXml());
265 if ((PolicyStatement != null) && (PolicyStatement.PermissionSet != null))
266 e.AddChild (PolicyStatement.PermissionSet.ToXml ());
268 foreach (CodeGroup child in Children)
269 e.AddChild(child.ToXml());
275 protected virtual void CreateXml (SecurityElement element, PolicyLevel level)
281 internal static CodeGroup CreateFromXml (SecurityElement se, PolicyLevel level)
283 string fullClassName = se.Attribute ("class");
284 string className = fullClassName;
285 // many possible formats
286 // a. "FirstMatchCodeGroup"
287 // b. "System.Security.Policy.FirstMatchCodeGroup"
288 // 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"
289 int n = className.IndexOf (",");
291 className = className.Substring (0, n);
293 n = className.LastIndexOf (".");
295 className = className.Substring (n + 1);
296 // much faster than calling Activator.CreateInstance
298 case "FileCodeGroup":
299 return new FileCodeGroup (se, level);
300 case "FirstMatchCodeGroup":
301 return new FirstMatchCodeGroup (se, level);
303 return new NetCodeGroup (se, level);
304 case "UnionCodeGroup":
305 return new UnionCodeGroup (se, level);
307 Type classType = Type.GetType (fullClassName);
308 CodeGroup cg = (CodeGroup) Activator.CreateInstance (classType, true);
309 cg.FromXml (se, level);