1 //------------------------------------------------------------------------------
\r
3 // System.Security.Permissions.FileIOPermission.cs
\r
5 // Copyright (C) 2001 Nick Drochak, All Rights Reserved
\r
7 // Author: Nick Drochak, ndrochak@gol.com
\r
8 // Created: 2002-01-09
\r
10 //------------------------------------------------------------------------------
\r
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System.Collections;
\r
39 namespace System.Security.Permissions {
\r
42 public sealed class FileIOPermission
\r
43 : CodeAccessPermission, IBuiltInPermission, IUnrestrictedPermission {
\r
45 private static char[] m_badCharacters = {'\"','<', '>', '|', '*', '?'};
\r
46 private bool m_Unrestricted = false;
\r
47 private Hashtable m_PathList = new Hashtable();
\r
48 private FileIOPermissionAccess m_AllFilesAccess = FileIOPermissionAccess.NoAccess;
\r
49 private FileIOPermissionAccess m_AllLocalFilesAccess = FileIOPermissionAccess.NoAccess;
\r
51 public FileIOPermission(PermissionState state) {
\r
52 if (!Enum.IsDefined(typeof(PermissionState), state)){
\r
53 throw new ArgumentException("Invalid permission state.", "state");
\r
55 m_Unrestricted = (PermissionState.Unrestricted == state);
\r
56 if (m_Unrestricted) {
\r
57 m_AllFilesAccess = FileIOPermissionAccess.AllAccess;
\r
58 m_AllLocalFilesAccess = FileIOPermissionAccess.AllAccess;
\r
62 public FileIOPermission(FileIOPermissionAccess access, string path)
65 throw new ArgumentNullException ("path");
67 if ((FileIOPermissionAccess.AllAccess & access) != access){
\r
68 throw new ArgumentException("Illegal enum value: "+access.ToString()+".");
\r
71 if (path.LastIndexOfAny(m_badCharacters) >= 0){
\r
72 throw new ArgumentException("Illegal characters found in input. Security checks can not contain wild card characters.", "path");
\r
75 AddPathList(access, path);
\r
78 public FileIOPermission(FileIOPermissionAccess access, string[] pathList)
81 throw new ArgumentNullException ("pathList");
83 if ((FileIOPermissionAccess.AllAccess & access) != access){
\r
84 throw new ArgumentException("Illegal enum value: "+access.ToString()+".");
\r
87 AddPathList(access, pathList);
\r
90 public FileIOPermissionAccess AllFiles {
\r
92 return m_AllFilesAccess;
\r
95 // if we are already set to unrestricted, don't change this property
\r
96 if (!m_Unrestricted){
\r
97 m_AllFilesAccess = value;
\r
102 public FileIOPermissionAccess AllLocalFiles {
\r
104 return m_AllLocalFilesAccess;
\r
107 // if we are already set to unrestricted, don't change this property
\r
108 if (!m_Unrestricted){
\r
109 m_AllLocalFilesAccess = value;
\r
114 public void AddPathList(FileIOPermissionAccess access, string path){
\r
115 if ((FileIOPermissionAccess.AllAccess & access) != access){
\r
116 throw new ArgumentException("Illegal enum value: {0}.",access.ToString());
\r
119 if (path.LastIndexOfAny(m_badCharacters) >= 0){
\r
120 throw new ArgumentException("Invalid characters in path: '{0}'", path);
\r
123 // LAMESPEC: docs don't say it must be a rooted path, but the MS implementation enforces it, so we will too.
\r
124 if(!Path.IsPathRooted(path)) {
\r
125 throw new ArgumentException("Absolute path information is required.");
\r
128 // don't add the same path twice, instead overwrite access entry for that path
\r
129 if (m_PathList.ContainsKey(path)) {
\r
130 FileIOPermissionAccess currentPermission = (FileIOPermissionAccess)m_PathList[path];
\r
131 currentPermission |= access;
\r
132 m_PathList[path] = currentPermission;
\r
135 m_PathList.Add(path, access);
\r
139 public void AddPathList(FileIOPermissionAccess access, string[] pathList ){
\r
140 foreach(string path in pathList){
\r
141 AddPathList(access, path);
\r
146 // private constructor used by Copy() method
\r
147 private FileIOPermission(Hashtable pathList, FileIOPermissionAccess allFiles,
\r
148 FileIOPermissionAccess allLocalFiles, bool unrestricted){
\r
149 m_PathList = pathList;
\r
150 m_AllFilesAccess = allFiles;
\r
151 m_AllLocalFilesAccess = allLocalFiles;
\r
152 m_Unrestricted = unrestricted;
\r
155 public override IPermission Copy(){
\r
156 if (m_Unrestricted) {
\r
157 return new FileIOPermission(PermissionState.Unrestricted);
\r
160 FileIOPermission retVal = new FileIOPermission(m_PathList, m_AllFilesAccess, m_AllLocalFilesAccess, m_Unrestricted);
\r
165 /* XML Schema for FileIOPermission
\r
166 <IPermission class=
\94FileIOPermission
\94 \r
169 Read=
\94[list of files or folders]
\94 |
\r
170 Write=
\94[list of files or folders]
\94 |
\r
171 Append=
\94[list of files or folders]
\94 \r
172 ) v Unrestricted=
\94true
\94 \r
175 public override void FromXml(SecurityElement esd){
\r
177 throw new ArgumentNullException();
\r
179 if (esd.Tag != "IPermission" || (string)esd.Attributes["class"] != "FileIOPermission"
\r
180 || (string)esd.Attributes["version"] != "1"){
\r
181 throw new ArgumentException("Not a valid permission element");
\r
183 m_PathList.Clear();
\r
184 if ("true" == (string)esd.Attributes["Unrestricted"]){
\r
185 m_Unrestricted = true;
\r
188 m_Unrestricted = false;
\r
190 fileList = (string)esd.Attributes["Read"];
\r
192 if (fileList != null){
\r
193 files = fileList.Split(';');
\r
194 AddPathList(FileIOPermissionAccess.Read, files);
\r
196 fileList = (string)esd.Attributes["Write"];
\r
197 if (fileList != null){
\r
198 files = fileList.Split(';');
\r
199 AddPathList(FileIOPermissionAccess.Write, files);
\r
201 fileList = (string)esd.Attributes["Append"];
\r
202 if (fileList != null){
\r
203 files = fileList.Split(';');
\r
204 AddPathList(FileIOPermissionAccess.Append, files);
\r
209 public string[] GetPathList(FileIOPermissionAccess access){
\r
210 //LAMESPEC: docs says it returns (semicolon separated) list, but return
\r
211 //type is array. I think docs are wrong and it just returns an array
\r
212 if ((FileIOPermissionAccess.AllAccess & access) != access){
\r
213 throw new ArgumentException("Illegal enum value: "+access.ToString()+".");
\r
216 ArrayList matchingPaths = new ArrayList();
\r
217 System.Collections.IDictionaryEnumerator pathListIterator = m_PathList.GetEnumerator();
\r
218 while (pathListIterator.MoveNext()) {
\r
219 if (((FileIOPermissionAccess)pathListIterator.Value & access) != 0) {
\r
220 matchingPaths.Add((string)pathListIterator.Key);
\r
223 if (matchingPaths.Count == 0) {
\r
227 return (string[])matchingPaths.ToArray(typeof(string));
\r
231 public override IPermission Intersect(IPermission target){
\r
232 if (null == target){
\r
236 if (target.GetType() != typeof(FileIOPermission)){
\r
237 throw new ArgumentException();
\r
240 FileIOPermission FIOPTarget = (FileIOPermission)target;
\r
241 if (FIOPTarget.IsUnrestricted() && m_Unrestricted){
\r
242 return new FileIOPermission(PermissionState.Unrestricted);
\r
244 else if (FIOPTarget.IsUnrestricted()){
\r
247 else if (m_Unrestricted){
\r
248 return FIOPTarget.Copy();
\r
251 FileIOPermission retVal = new FileIOPermission(PermissionState.None);
\r
252 retVal.AllFiles = m_AllFilesAccess & FIOPTarget.AllFiles;
\r
253 retVal.AllLocalFiles = m_AllLocalFilesAccess & FIOPTarget.AllLocalFiles;
\r
256 paths = FIOPTarget.GetPathList(FileIOPermissionAccess.Append);
\r
257 if (null != paths) {
\r
258 foreach (string path in paths){
\r
259 if (m_PathList.ContainsKey(path)
\r
260 && ((FileIOPermissionAccess)m_PathList[path] & FileIOPermissionAccess.Append) != 0){
\r
261 retVal.AddPathList(FileIOPermissionAccess.Append, path);
\r
266 paths = FIOPTarget.GetPathList(FileIOPermissionAccess.Read);
\r
267 if (null != paths) {
\r
268 foreach (string path in paths){
\r
269 if (m_PathList.ContainsKey(path)
\r
270 && ((FileIOPermissionAccess)m_PathList[path] & FileIOPermissionAccess.Read) != 0){
\r
271 retVal.AddPathList(FileIOPermissionAccess.Read, path);
\r
276 paths = FIOPTarget.GetPathList(FileIOPermissionAccess.Write);
\r
277 if (null != paths) {
\r
278 foreach (string path in paths){
\r
279 if (m_PathList.ContainsKey(path)
\r
280 && ((FileIOPermissionAccess)m_PathList[path] & FileIOPermissionAccess.Write) != 0){
\r
281 retVal.AddPathList(FileIOPermissionAccess.Write, path);
\r
291 public override bool IsSubsetOf(IPermission target){
\r
292 // X.IsSubsetOf(Y) is true if permission Y includes everything allowed by X.
\r
293 if (target != null && target.GetType() != typeof(FileIOPermission)){
\r
294 throw new ArgumentException();
\r
296 FileIOPermission FIOPTarget = (FileIOPermission)target;
\r
297 if (FIOPTarget.IsUnrestricted()){
\r
300 else if (m_Unrestricted){
\r
303 else if ((m_AllFilesAccess & FIOPTarget.AllFiles) != m_AllFilesAccess) {
\r
306 else if ((m_AllLocalFilesAccess & FIOPTarget.AllLocalFiles) != m_AllLocalFilesAccess) {
\r
310 string[] pathsNeeded;
\r
311 string[] pathsInTarget;
\r
313 pathsNeeded = GetPathList(FileIOPermissionAccess.Append);
\r
314 if (null != pathsNeeded) {
\r
315 pathsInTarget = FIOPTarget.GetPathList(FileIOPermissionAccess.Append);
\r
316 foreach (string path in pathsNeeded){
\r
317 if (Array.IndexOf(pathsInTarget, path) <0) {
\r
323 pathsNeeded = GetPathList(FileIOPermissionAccess.Read);
\r
324 if (null != pathsNeeded) {
\r
325 pathsInTarget = FIOPTarget.GetPathList(FileIOPermissionAccess.Read);
\r
326 foreach (string path in pathsNeeded){
\r
327 if (Array.IndexOf(pathsInTarget, path) <0) {
\r
333 pathsNeeded = GetPathList(FileIOPermissionAccess.Write);
\r
334 if (null != pathsNeeded) {
\r
335 pathsInTarget = FIOPTarget.GetPathList(FileIOPermissionAccess.Write);
\r
336 foreach (string path in pathsNeeded){
\r
337 if (Array.IndexOf(pathsInTarget, path) <0) {
\r
347 public bool IsUnrestricted(){
\r
348 return m_Unrestricted;
\r
351 public void SetPathList(FileIOPermissionAccess access, string path){
\r
352 if ((FileIOPermissionAccess.AllAccess & access) != access){
\r
353 throw new ArgumentException("Illegal enum value: "+access.ToString()+".");
\r
355 if (path.LastIndexOfAny(m_badCharacters) >= 0){
\r
356 throw new ArgumentException("Invalid characters in path: '{0}'", path);
\r
359 m_PathList.Clear();
\r
360 AddPathList(access, path);
\r
363 public void SetPathList(FileIOPermissionAccess access, string[] pathList){
\r
364 if ((FileIOPermissionAccess.AllAccess & access) != access){
\r
365 throw new ArgumentException("Illegal enum value: "+access.ToString()+".");
\r
367 foreach(string path in pathList){
\r
368 if (path.LastIndexOfAny(m_badCharacters) >= 0){
\r
369 throw new ArgumentException("Invalid characters in path entry: '{0}'", path);
\r
373 m_PathList.Clear();
\r
374 AddPathList(access, pathList);
\r
377 public override SecurityElement ToXml(){
\r
378 //Encode the the current permission to XML using the
\r
379 //security element class.
\r
380 SecurityElement element = new SecurityElement("IPermission");
\r
381 Type type = this.GetType();
\r
382 StringBuilder AsmName = new StringBuilder(type.Assembly.ToString());
\r
383 AsmName.Replace('\"', '\'');
\r
384 element.AddAttribute("class", type.FullName + ", " + AsmName);
\r
385 element.AddAttribute("version", "1");
\r
386 if(m_Unrestricted){
\r
387 element.AddAttribute("Unrestricted", "true");
\r
391 paths = GetPathList(FileIOPermissionAccess.Append);
\r
392 if (null != paths && paths.Length >0){
\r
393 element.AddAttribute("Append", String.Join(";",paths));
\r
395 paths = GetPathList(FileIOPermissionAccess.Read);
\r
396 if (null != paths && paths.Length >0){
\r
397 element.AddAttribute("Read", String.Join(";",paths));
\r
399 paths = GetPathList(FileIOPermissionAccess.Write);
\r
400 if (null != paths && paths.Length >0){
\r
401 element.AddAttribute("Write", String.Join(";",paths));
\r
407 public override IPermission Union(IPermission other){
\r
408 if (null == other){
\r
412 if (other.GetType() != typeof(FileIOPermission)){
\r
413 throw new ArgumentException();
\r
416 FileIOPermission FIOPTarget = (FileIOPermission)other;
\r
417 if (FIOPTarget.IsUnrestricted() || m_Unrestricted){
\r
418 return new FileIOPermission(PermissionState.Unrestricted);
\r
421 FileIOPermission retVal = (FileIOPermission)Copy();
\r
422 retVal.AllFiles |= FIOPTarget.AllFiles;
\r
423 retVal.AllLocalFiles |= FIOPTarget.AllLocalFiles;
\r
425 paths = FIOPTarget.GetPathList(FileIOPermissionAccess.Append);
\r
426 if (null != paths){
\r
427 retVal.AddPathList(FileIOPermissionAccess.Append, paths);
\r
429 paths = FIOPTarget.GetPathList(FileIOPermissionAccess.Read);
\r
430 if (null != paths){
\r
431 retVal.AddPathList(FileIOPermissionAccess.Read, paths);
\r
433 paths = FIOPTarget.GetPathList(FileIOPermissionAccess.Write);
\r
434 if (null != paths){
\r
435 retVal.AddPathList(FileIOPermissionAccess.Write, paths);
\r
441 // IBuiltInPermission
\r
442 int IBuiltInPermission.GetTokenIndex ()
\r