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;
26 public PermissionSet (PermissionState state)
28 if (!Enum.IsDefined(typeof(System.Security.Permissions.PermissionState), state))
29 throw new System.ArgumentException(); // state is not a valid System.Security.Permissions.PermissionState value.
31 list = new ArrayList ();
34 public PermissionSet (PermissionSet permSet) : this (PermissionState.None)
36 // LAMESPEC: This would be handled by the compiler. No way permSet is not a PermissionSet.
37 //if (!(permSet is PermissionSet))
38 // throw new System.ArgumentException(); // permSet is not an instance of System.Security.PermissionSet.
40 state = PermissionState.Unrestricted;
42 foreach (IPermission p in permSet.list)
47 public virtual IPermission AddPermission (IPermission perm)
52 IPermission existing = GetPermission (perm.GetType ());
54 perm = perm.Union (existing);
61 public virtual void Assert ()
65 public virtual PermissionSet Copy ()
67 return new PermissionSet (this);
70 public virtual void CopyTo (Array array, int index)
73 throw new System.ArgumentException("Array has more than one dimension"); // array has more than one dimension.
74 if (index < 0 || index >= array.Length)
75 throw new System.IndexOutOfRangeException(); // index is outside the range of allowable values for array.
77 throw new System.ArgumentNullException(); // array is null.
78 list.CopyTo (array, index);
82 public virtual void Demand ()
87 public virtual void Deny ()
91 // to be re-used by NamedPermissionSet (and other derived classes)
92 internal void FromXml (SecurityElement et, string className)
95 throw new ArgumentNullException ("et");
96 if (et.Tag != "PermissionSet")
97 throw new ArgumentException ("not PermissionSet");
98 if (!(et.Attributes ["class"] as string).StartsWith (className))
99 throw new ArgumentException ("not " + className);
100 // version isn't checked
101 // if ((et.Attributes ["version"] as string) != "1")
102 // throw new ArgumentException ("wrong version");
104 if ((et.Attributes ["Unrestricted"] as string) == "true")
105 state = PermissionState.Unrestricted;
107 state = PermissionState.None;
110 public virtual void FromXml (SecurityElement et)
113 FromXml (et, "System.Security.PermissionSet");
114 if (et.Children != null) {
115 foreach (SecurityElement se in et.Children) {
116 string className = (se.Attributes ["class"] as string);
117 Type classType = Type.GetType (className);
118 object [] psNone = new object [1] { PermissionState.None };
119 IPermission p = (IPermission) Activator.CreateInstance (classType, psNone);
126 public virtual IEnumerator GetEnumerator ()
128 return list.GetEnumerator ();
131 public virtual bool IsSubsetOf (PermissionSet target)
133 // if target is empty we must be empty too
134 if ((target == null) || (target.IsEmpty ()))
135 return this.IsEmpty ();
136 // if we're unrestricted then target must also be unrestricted
137 if (this.IsUnrestricted () && target.IsUnrestricted ())
140 // if each of our permission is (a) present and (b) a subset of target
141 foreach (IPermission p in list) {
142 // for every type in both list
143 IPermission i = target.GetPermission (p.GetType ());
145 return false; // not present (condition a)
146 if (!p.IsSubsetOf (i))
147 return false; // not a subset (condition b)
153 public virtual void PermitOnly ()
157 public bool ContainsNonCodeAccessPermissions ()
159 foreach (IPermission p in list) {
160 if (! p.GetType ().IsSubclassOf (typeof(CodeAccessPermission)))
166 // undocumented behavior
168 public static byte[] ConvertPermissionSet (string inFormat, byte[] inData, string outFormat)
173 public virtual IPermission GetPermission (Type permClass)
175 foreach (object o in list) {
176 if (o.GetType ().Equals (permClass))
177 return (IPermission) o;
182 public virtual PermissionSet Intersect (PermissionSet other)
184 // no intersection possible
185 if ((other == null) || (other.IsEmpty ()) || (this.IsEmpty ()))
186 return new PermissionSet (PermissionState.None);
187 // intersections with unrestricted
188 if (this.IsUnrestricted ())
189 return other.Copy ();
190 if (other.IsUnrestricted ())
193 PermissionSet interSet = new PermissionSet (PermissionState.None);
194 foreach (IPermission p in other.list) {
195 // for every type in both list
196 IPermission i = interSet.GetPermission (p.GetType ());
198 // add intersection for this type
199 interSet.AddPermission (p.Intersect (i));
206 public virtual bool IsEmpty ()
208 // note: Unrestricted isn't empty
209 return ((state == PermissionState.Unrestricted) ? false : (list.Count == 0));
212 public virtual bool IsUnrestricted ()
214 return (state == PermissionState.Unrestricted);
217 public virtual IPermission RemovePermission (Type permClass)
219 foreach (object o in list) {
220 if (o.GetType ().Equals (permClass)) {
222 return (IPermission) o;
228 public virtual IPermission SetPermission (IPermission perm)
230 if (perm is IUnrestrictedPermission)
231 state = PermissionState.None;
232 RemovePermission (perm.GetType ());
237 public override string ToString ()
239 return ToXml ().ToString ();
242 public virtual SecurityElement ToXml ()
244 SecurityElement se = new SecurityElement ("PermissionSet");
245 se.AddAttribute ("class", GetType ().FullName);
246 se.AddAttribute ("version", "1");
247 if (state == PermissionState.Unrestricted)
248 se.AddAttribute ("Unrestricted", "true");
250 foreach (IPermission p in list)
251 se.AddChild (p.ToXml ());
256 public virtual PermissionSet Union (PermissionSet other)
260 if (this.IsUnrestricted () || other.IsUnrestricted ())
261 return new PermissionSet (PermissionState.Unrestricted);
263 PermissionSet copy = this.Copy ();
264 foreach (IPermission p in other.list) {
265 copy.AddPermission (p);
270 public virtual int Count {
271 get { return list.Count; }
274 public virtual bool IsSynchronized {
275 get { return list.IsSynchronized; }
278 public virtual bool IsReadOnly {
279 get { return false; } // always false
282 public virtual object SyncRoot {
283 get { return list.SyncRoot; }
287 void IDeserializationCallback.OnDeserialization (object sender)