**** Merged from MCS ****
[mono-project.git] / mcs / class / corlib / System.Security.Permissions / EnvironmentPermission.cs
blob15b88492e320c79fa209c969f6f7c854097c30f2
1 //
2 // System.Security.Permissions.EnvironmentPermission.cs
3 //
4 // Authors:
5 // Tim Coleman <tim@timcoleman.com>
6 // Sebastien Pouliot <sebastien@ximian.com>
7 //
8 // Copyright (C) 2002, Tim Coleman
9 // Portions Copyright (C) 2003 Motus Technologies (http://www.motus.com)
10 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Text;
35 namespace System.Security.Permissions {
37 [Serializable]
38 public sealed class EnvironmentPermission : CodeAccessPermission, IUnrestrictedPermission, IBuiltInPermission {
40 #region Fields
42 private const int version = 1;
44 EnvironmentPermissionAccess flags;
45 PermissionState _state;
46 ArrayList readList;
47 ArrayList writeList;
49 #endregion // Fields
51 #region Constructors
53 public EnvironmentPermission (PermissionState state) : base ()
55 _state = CheckPermissionState (state, true);
56 readList = new ArrayList ();
57 writeList = new ArrayList ();
60 public EnvironmentPermission (EnvironmentPermissionAccess flag, string pathList) : base ()
62 readList = new ArrayList ();
63 writeList = new ArrayList ();
64 SetPathList (flag, pathList);
67 #endregion // Constructors
69 #region Methods
71 public void AddPathList (EnvironmentPermissionAccess flag, string pathList)
73 if (pathList == null)
74 throw new ArgumentNullException ("pathList");
76 string[] paths;
77 switch (flag) {
78 case EnvironmentPermissionAccess.AllAccess:
79 paths = pathList.Split (';');
80 foreach (string path in paths) {
81 if (!readList.Contains (path))
82 readList.Add (path);
83 if (!writeList.Contains (path))
84 writeList.Add (path);
86 break;
87 case EnvironmentPermissionAccess.NoAccess:
88 // ??? unit tests doesn't show removal using NoAccess ???
89 break;
90 case EnvironmentPermissionAccess.Read:
91 paths = pathList.Split (';');
92 foreach (string path in paths) {
93 if (!readList.Contains (path))
94 readList.Add (path);
96 break;
97 case EnvironmentPermissionAccess.Write:
98 paths = pathList.Split (';');
99 foreach (string path in paths) {
100 if (!writeList.Contains (path))
101 writeList.Add (path);
103 break;
104 default:
105 ThrowInvalidFlag (flag, false);
106 break;
110 public override IPermission Copy ()
112 EnvironmentPermission ep = new EnvironmentPermission (_state);
113 string path = GetPathList (EnvironmentPermissionAccess.Read);
114 if (path != null)
115 ep.SetPathList (EnvironmentPermissionAccess.Read, path);
116 path = GetPathList (EnvironmentPermissionAccess.Write);
117 if (path != null)
118 ep.SetPathList (EnvironmentPermissionAccess.Write, path);
119 return ep;
122 public override void FromXml (SecurityElement esd)
124 // General validation in CodeAccessPermission
125 CheckSecurityElement (esd, "esd", version, version);
126 // Note: we do not (yet) care about the return value
127 // as we only accept version 1 (min/max values)
129 if (IsUnrestricted (esd))
130 _state = PermissionState.Unrestricted;
132 string read = esd.Attribute ("Read");
133 if ((read != null) && (read.Length > 0))
134 SetPathList (EnvironmentPermissionAccess.Read, read);
136 string write = esd.Attribute ("Write");
137 if ((write != null) && (write.Length > 0))
138 SetPathList (EnvironmentPermissionAccess.Write, write);
141 public string GetPathList (EnvironmentPermissionAccess flag)
143 switch (flag) {
144 case EnvironmentPermissionAccess.AllAccess:
145 case EnvironmentPermissionAccess.NoAccess:
146 ThrowInvalidFlag (flag, true);
147 break;
148 case EnvironmentPermissionAccess.Read:
149 return GetPathList (readList);
150 case EnvironmentPermissionAccess.Write:
151 return GetPathList (writeList);
152 default:
153 ThrowInvalidFlag (flag, false);
154 break;
156 return null; // never reached
159 public override IPermission Intersect (IPermission target)
161 EnvironmentPermission ep = Cast (target);
162 if (ep == null)
163 return null;
165 if (IsUnrestricted ())
166 return ep.Copy ();
167 if (ep.IsUnrestricted ())
168 return Copy ();
170 int n = 0;
171 EnvironmentPermission result = new EnvironmentPermission (PermissionState.None);
172 string readTarget = ep.GetPathList (EnvironmentPermissionAccess.Read);
173 if (readTarget != null) {
174 string[] targets = readTarget.Split (';');
175 foreach (string t in targets) {
176 if (readList.Contains (t)) {
177 result.AddPathList (EnvironmentPermissionAccess.Read, t);
178 n++;
183 string writeTarget = ep.GetPathList (EnvironmentPermissionAccess.Write);
184 if (writeTarget != null) {
185 string[] targets = writeTarget.Split (';');
186 foreach (string t in targets) {
187 if (writeList.Contains (t)) {
188 result.AddPathList (EnvironmentPermissionAccess.Write, t);
189 n++;
193 return ((n > 0) ? result : null);
196 public override bool IsSubsetOf (IPermission target)
198 EnvironmentPermission ep = Cast (target);
199 if (ep == null)
200 return false;
202 if (IsUnrestricted ())
203 return ep.IsUnrestricted ();
204 else if (ep.IsUnrestricted ())
205 return true;
207 foreach (string s in readList) {
208 if (!ep.readList.Contains (s))
209 return false;
212 foreach (string s in writeList) {
213 if (!ep.writeList.Contains (s))
214 return false;
217 return true;
220 public bool IsUnrestricted ()
222 return (_state == PermissionState.Unrestricted);
225 public void SetPathList (EnvironmentPermissionAccess flag, string pathList)
227 if (pathList == null)
228 throw new ArgumentNullException ("pathList");
229 string[] paths;
230 switch (flag) {
231 case EnvironmentPermissionAccess.AllAccess:
232 readList.Clear ();
233 writeList.Clear ();
234 paths = pathList.Split (';');
235 foreach (string path in paths) {
236 readList.Add (path);
237 writeList.Add (path);
239 break;
240 case EnvironmentPermissionAccess.NoAccess:
241 // ??? unit tests doesn't show removal using NoAccess ???
242 break;
243 case EnvironmentPermissionAccess.Read:
244 readList.Clear ();
245 paths = pathList.Split (';');
246 foreach (string path in paths) {
247 readList.Add (path);
249 break;
250 case EnvironmentPermissionAccess.Write:
251 writeList.Clear ();
252 paths = pathList.Split (';');
253 foreach (string path in paths) {
254 writeList.Add (path);
256 break;
257 default:
258 ThrowInvalidFlag (flag, false);
259 break;
263 public override SecurityElement ToXml ()
265 SecurityElement se = Element (version);
267 if (_state == PermissionState.Unrestricted) {
268 se.AddAttribute ("Unrestricted", "true");
270 else {
271 string path = GetPathList (EnvironmentPermissionAccess.Read);
272 if (path != null)
273 se.AddAttribute ("Read", path);
274 path = GetPathList (EnvironmentPermissionAccess.Write);
275 if (path != null)
276 se.AddAttribute ("Write", path);
278 return se;
281 public override IPermission Union (IPermission other)
283 EnvironmentPermission ep = Cast (other);
284 if (ep == null)
285 return Copy ();
287 if (IsUnrestricted () || ep.IsUnrestricted ())
288 return new EnvironmentPermission (PermissionState.Unrestricted);
290 if (IsEmpty () && ep.IsEmpty ())
291 return null;
293 EnvironmentPermission result = (EnvironmentPermission) Copy ();
294 string path = ep.GetPathList (EnvironmentPermissionAccess.Read);
295 if (path != null)
296 result.AddPathList (EnvironmentPermissionAccess.Read, path);
297 path = ep.GetPathList (EnvironmentPermissionAccess.Write);
298 if (path != null)
299 result.AddPathList (EnvironmentPermissionAccess.Write, path);
300 return result;
303 // IBuiltInPermission
304 int IBuiltInPermission.GetTokenIndex ()
306 return (int) BuiltInToken.Environment;
309 // helpers
311 private bool IsEmpty ()
313 return ((_state == PermissionState.None) && (readList.Count == 0) && (writeList.Count == 0));
316 private EnvironmentPermission Cast (IPermission target)
318 if (target == null)
319 return null;
321 EnvironmentPermission ep = (target as EnvironmentPermission);
322 if (ep == null) {
323 ThrowInvalidPermission (target, typeof (EnvironmentPermission));
326 return ep;
329 internal void ThrowInvalidFlag (EnvironmentPermissionAccess flag, bool context)
331 string msg = null;
332 if (context)
333 msg = Locale.GetText ("Unknown flag '{0}'.");
334 else
335 msg = Locale.GetText ("Invalid flag '{0}' in this context.");
336 throw new ArgumentException (String.Format (msg, flag), "flag");
339 private string GetPathList (ArrayList list)
341 if (IsUnrestricted ())
342 return String.Empty;
343 #if NET_2_0
344 if (list.Count == 0)
345 return String.Empty;
346 #else
347 if (list.Count == 0)
348 return null;
349 #endif
350 StringBuilder sb = new StringBuilder ();
351 foreach (string path in list) {
352 sb.Append (path);
353 sb.Append (";");
356 string result = sb.ToString ();
357 // remove last ';'
358 int n = result.Length;
359 if (n > 0)
360 return result.Substring (0, n - 1);
361 #if NET_2_0
362 return String.Empty;
363 #else
364 return ((_state == PermissionState.Unrestricted) ? String.Empty : null);
365 #endif
368 #endregion // Methods