1 // System.Security.Policy.CodeGroup
4 // Nick Drochak (ndrochak@gol.com)
6 // (C) 2001 Nick Drochak, All rights reserved.
9 // Copyright (C) 2004 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.Security.Policy;
35 using System.Security.Permissions;
36 //using System; // for MonoTODO attribute
38 namespace System.Security.Policy {
41 public abstract class CodeGroup {
42 PolicyStatement m_policy = null;
43 IMembershipCondition m_membershipCondition = null;
44 string m_description = null;
46 ArrayList m_children = new ArrayList();
49 public CodeGroup (IMembershipCondition membershipCondition, PolicyStatement policy)
51 if (null == membershipCondition)
52 throw new ArgumentNullException("Value cannot be null.");
55 m_membershipCondition = membershipCondition;
58 // for PolicyLevel (to avoid validation duplication)
59 internal CodeGroup (SecurityElement e)
66 public abstract CodeGroup Copy();
67 public abstract string MergeLogic {get;}
68 public abstract PolicyStatement Resolve (Evidence evidence);
69 public abstract CodeGroup ResolveMatchingCodeGroups(Evidence evidence);
71 public PolicyStatement PolicyStatement {
73 get { return m_policy; }
75 set { m_policy = value; }
78 public string Description {
80 get { return m_description; }
82 set { m_description = value; }
85 public IMembershipCondition MembershipCondition {
88 return m_membershipCondition;
93 throw new ArgumentException("Value cannot be null");
94 m_membershipCondition = value;
99 get { return m_name; }
100 set { m_name = value; }
103 public IList Children {
104 get { return m_children; }
107 throw new ArgumentNullException ("value");
108 m_children = new ArrayList(value);
112 public virtual string AttributeString {
114 if (null != m_policy)
115 return m_policy.AttributeString;
120 public virtual string PermissionSetName {
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("The group parameter cannot be null");
132 m_children.Add(group);
135 public override bool Equals(object o)
137 if (!(o is CodeGroup))
140 return Equals((CodeGroup)o, false);
143 public bool Equals(CodeGroup cg, bool compareChildren)
145 if (cg.Name != this.Name)
148 if (cg.Description != this.Description)
151 // FIXME: this compiles with CSC. Didn't succeed at creating a smaller/different test case :(
152 // if (!cg.MembershipCondition.Equals (m_membershipCondition))
153 if (((object) cg.MembershipCondition).ToString () !=
154 ((object) m_membershipCondition).ToString ())
157 if (compareChildren) {
158 int childCount = cg.Children.Count;
159 if (this.Children.Count != childCount)
162 for (int index = 0; index < childCount; index++) {
163 // LAMESPEC: are we supposed to check child equality recursively?
164 // The docs imply 'no' but it seems natural to do a 'deep' compare.
165 // Will check the children's children, and so-on unless we find out that
167 if (!((CodeGroup)(this.Children[index])).Equals((CodeGroup)(cg.Children[index]), true))
174 public void RemoveChild (CodeGroup group)
177 m_children.Remove (group);
180 public override int GetHashCode ()
182 int hashCode = m_membershipCondition.GetHashCode ();
183 if (m_policy != null)
184 hashCode += m_policy.GetHashCode ();
188 public void FromXml (SecurityElement e)
193 public void FromXml (SecurityElement e, PolicyLevel level)
196 throw new ArgumentNullException("e");
198 PermissionSet ps = null;
199 SecurityElement pset = e.SearchForChildByTag ("PermissionSet");
201 Type classType = Type.GetType (pset.Attribute ("class"));
202 ps = (PermissionSet) Activator.CreateInstance (classType, true);
206 ps = new NamedPermissionSet ("Nothing", new PermissionSet (PermissionState.None));
207 m_policy = new PolicyStatement (ps);
210 if ((e.Children != null) && (e.Children.Count > 0)) {
211 foreach (SecurityElement se in e.Children) {
212 if (se.Tag == "CodeGroup") {
213 this.AddChild (CodeGroup.CreateFromXml (se));
218 m_membershipCondition = null;
219 SecurityElement mc = e.SearchForChildByTag ("IMembershipCondition");
221 string className = mc.Attribute ("class");
222 Type classType = Type.GetType (className);
223 if (classType == null)
224 classType = Type.GetType ("System.Security.Policy." + className);
225 m_membershipCondition = (IMembershipCondition) Activator.CreateInstance (classType);
226 m_membershipCondition.FromXml (mc, level);
229 m_name = e.Attribute("Name");
230 m_description = e.Attribute("Description");
232 // seems like we might need this to Resolve() in subclasses
238 protected virtual void ParseXml(SecurityElement e, PolicyLevel level)
242 public SecurityElement ToXml()
247 public SecurityElement ToXml (PolicyLevel level)
249 SecurityElement e = new SecurityElement("CodeGroup");
250 e.AddAttribute("class", this.GetType().AssemblyQualifiedName);
251 e.AddAttribute("version", "1");
254 e.AddAttribute("Name", Name);
256 if (null != Description)
257 e.AddAttribute("Description", Description);
259 if (null != MembershipCondition)
260 e.AddChild(MembershipCondition.ToXml());
262 if ((PolicyStatement != null) && (PolicyStatement.PermissionSet != null))
263 e.AddChild (PolicyStatement.PermissionSet.ToXml ());
265 foreach (CodeGroup child in Children)
266 e.AddChild(child.ToXml());
272 protected virtual void CreateXml(SecurityElement element, PolicyLevel level)
278 internal static CodeGroup CreateFromXml (SecurityElement se)
280 string fullClassName = se.Attribute ("class");
281 string className = fullClassName;
282 // many possible formats
283 // a. "FirstMatchCodeGroup"
284 // b. "System.Security.Policy.FirstMatchCodeGroup"
285 // 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"
286 int n = className.IndexOf (",");
288 className = className.Substring (0, n);
290 n = className.LastIndexOf (".");
292 className = className.Substring (n + 1);
293 // much faster than calling Activator.CreateInstance
295 case "FileCodeGroup":
296 return new FileCodeGroup (se);
297 case "FirstMatchCodeGroup":
298 return new FirstMatchCodeGroup (se);
300 return new NetCodeGroup (se);
301 case "UnionCodeGroup":
302 return new UnionCodeGroup (se);
304 Type classType = Type.GetType (fullClassName);
305 return (CodeGroup) Activator.CreateInstance (classType, true);
308 } // public abstract class CodeGroup
309 } // namespace System.Security.Policy