2 // System.Security.PermissionSet.cs
5 // Nick Drochak(ndrochak@gol.com)
6 // Sebastien Pouliot (spouliot@motus.com)
9 // Portions (C) 2003, 2004 Motus Technologies Inc. (http://www.motus.com)
13 using System.Collections;
14 using System.Security.Permissions;
15 using System.Security;
16 using System.Runtime.Serialization;
18 namespace System.Security {
21 public class PermissionSet: ISecurityEncodable, ICollection, IEnumerable, IStackWalk, IDeserializationCallback {
23 private PermissionState state;
24 private ArrayList list;
28 // for PolicyLevel (to avoid validation duplication)
29 internal PermissionSet ()
31 list = new ArrayList ();
34 public PermissionSet (PermissionState state)
36 if (!Enum.IsDefined(typeof(System.Security.Permissions.PermissionState), state))
37 throw new System.ArgumentException(); // state is not a valid System.Security.Permissions.PermissionState value.
39 list = new ArrayList ();
42 public PermissionSet (PermissionSet permSet) : this (PermissionState.None)
44 // LAMESPEC: This would be handled by the compiler. No way permSet is not a PermissionSet.
45 //if (!(permSet is PermissionSet))
46 // throw new System.ArgumentException(); // permSet is not an instance of System.Security.PermissionSet.
48 state = PermissionState.Unrestricted;
50 foreach (IPermission p in permSet.list)
57 public virtual IPermission AddPermission (IPermission perm)
62 IPermission existing = GetPermission (perm.GetType ());
64 perm = perm.Union (existing);
71 public virtual void Assert ()
75 public virtual PermissionSet Copy ()
77 return new PermissionSet (this);
80 public virtual void CopyTo (Array array, int index)
83 throw new System.ArgumentException("Array has more than one dimension"); // array has more than one dimension.
84 if (index < 0 || index >= array.Length)
85 throw new System.IndexOutOfRangeException(); // index is outside the range of allowable values for array.
87 throw new System.ArgumentNullException(); // array is null.
88 list.CopyTo (array, index);
92 public virtual void Demand ()
97 public virtual void Deny ()
101 // to be re-used by NamedPermissionSet (and other derived classes)
102 internal void FromXml (SecurityElement et, string className)
105 throw new ArgumentNullException ("et");
106 if (et.Tag != "PermissionSet")
107 throw new ArgumentException ("not PermissionSet");
108 if (!(et.Attributes ["class"] as string).EndsWith (className))
109 throw new ArgumentException ("not " + className);
110 // version isn't checked
111 // if ((et.Attributes ["version"] as string) != "1")
112 // throw new ArgumentException ("wrong version");
114 if ((et.Attributes ["Unrestricted"] as string) == "true")
115 state = PermissionState.Unrestricted;
117 state = PermissionState.None;
120 public virtual void FromXml (SecurityElement et)
123 FromXml (et, "PermissionSet");
124 if (et.Children != null) {
125 foreach (SecurityElement se in et.Children) {
126 string className = (se.Attributes ["class"] as string);
127 Type classType = Type.GetType (className);
128 object [] psNone = new object [1] { PermissionState.None };
129 IPermission p = (IPermission) Activator.CreateInstance (classType, psNone);
136 public virtual IEnumerator GetEnumerator ()
138 return list.GetEnumerator ();
141 public virtual bool IsSubsetOf (PermissionSet target)
143 // if target is empty we must be empty too
144 if ((target == null) || (target.IsEmpty ()))
145 return this.IsEmpty ();
146 // if we're unrestricted then target must also be unrestricted
147 if (this.IsUnrestricted () && target.IsUnrestricted ())
150 // if each of our permission is (a) present and (b) a subset of target
151 foreach (IPermission p in list) {
152 // for every type in both list
153 IPermission i = target.GetPermission (p.GetType ());
155 return false; // not present (condition a)
156 if (!p.IsSubsetOf (i))
157 return false; // not a subset (condition b)
163 public virtual void PermitOnly ()
167 public bool ContainsNonCodeAccessPermissions ()
169 foreach (IPermission p in list) {
170 if (! p.GetType ().IsSubclassOf (typeof(CodeAccessPermission)))
176 // undocumented behavior
178 public static byte[] ConvertPermissionSet (string inFormat, byte[] inData, string outFormat)
183 public virtual IPermission GetPermission (Type permClass)
185 foreach (object o in list) {
186 if (o.GetType ().Equals (permClass))
187 return (IPermission) o;
192 public virtual PermissionSet Intersect (PermissionSet other)
194 // no intersection possible
195 if ((other == null) || (other.IsEmpty ()) || (this.IsEmpty ()))
196 return new PermissionSet (PermissionState.None);
197 // intersections with unrestricted
198 if (this.IsUnrestricted ())
199 return other.Copy ();
200 if (other.IsUnrestricted ())
203 PermissionSet interSet = new PermissionSet (PermissionState.None);
204 foreach (IPermission p in other.list) {
205 // for every type in both list
206 IPermission i = interSet.GetPermission (p.GetType ());
208 // add intersection for this type
209 interSet.AddPermission (p.Intersect (i));
216 public virtual bool IsEmpty ()
218 // note: Unrestricted isn't empty
219 return ((state == PermissionState.Unrestricted) ? false : (list.Count == 0));
222 public virtual bool IsUnrestricted ()
224 return (state == PermissionState.Unrestricted);
227 public virtual IPermission RemovePermission (Type permClass)
229 foreach (object o in list) {
230 if (o.GetType ().Equals (permClass)) {
232 return (IPermission) o;
238 public virtual IPermission SetPermission (IPermission perm)
240 if (perm is IUnrestrictedPermission)
241 state = PermissionState.None;
242 RemovePermission (perm.GetType ());
247 public override string ToString ()
249 return ToXml ().ToString ();
252 public virtual SecurityElement ToXml ()
254 SecurityElement se = new SecurityElement ("PermissionSet");
255 se.AddAttribute ("class", GetType ().FullName);
256 se.AddAttribute ("version", "1");
257 if (state == PermissionState.Unrestricted)
258 se.AddAttribute ("Unrestricted", "true");
260 foreach (IPermission p in list)
261 se.AddChild (p.ToXml ());
266 public virtual PermissionSet Union (PermissionSet other)
270 if (this.IsUnrestricted () || other.IsUnrestricted ())
271 return new PermissionSet (PermissionState.Unrestricted);
273 PermissionSet copy = this.Copy ();
274 foreach (IPermission p in other.list) {
275 copy.AddPermission (p);
280 public virtual int Count {
281 get { return list.Count; }
284 public virtual bool IsSynchronized {
285 get { return list.IsSynchronized; }
288 public virtual bool IsReadOnly {
289 get { return false; } // always false
292 public virtual object SyncRoot {
293 get { return list.SyncRoot; }
297 void IDeserializationCallback.OnDeserialization (object sender)