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-2005 Novell, Inc (http://www.novell.com) 11 // 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. 30 // 31 32 using System.Collections; 33 using System.Runtime.InteropServices; 34 using System.Text; 35 36 namespace System.Security.Permissions { 37 38 [ComVisible (true)] 39 [Serializable] 40 public sealed class EnvironmentPermission : CodeAccessPermission, IUnrestrictedPermission, IBuiltInPermission { 41 42 #region Fields 43 44 private const int version = 1; 45 46 // EnvironmentPermissionAccess flags; 47 PermissionState _state; 48 ArrayList readList; 49 ArrayList writeList; 50 51 #endregion // Fields 52 53 #region Constructors 54 EnvironmentPermission(PermissionState state)55 public EnvironmentPermission (PermissionState state) : base () 56 { 57 _state = CheckPermissionState (state, true); 58 readList = new ArrayList (); 59 writeList = new ArrayList (); 60 } 61 EnvironmentPermission(EnvironmentPermissionAccess flag, string pathList)62 public EnvironmentPermission (EnvironmentPermissionAccess flag, string pathList) : base () 63 { 64 readList = new ArrayList (); 65 writeList = new ArrayList (); 66 SetPathList (flag, pathList); 67 } 68 69 #endregion // Constructors 70 71 #region Methods 72 AddPathList(EnvironmentPermissionAccess flag, string pathList)73 public void AddPathList (EnvironmentPermissionAccess flag, string pathList) 74 { 75 if (pathList == null) 76 throw new ArgumentNullException ("pathList"); 77 78 string[] paths; 79 switch (flag) { 80 case EnvironmentPermissionAccess.AllAccess: 81 paths = pathList.Split (';'); 82 foreach (string path in paths) { 83 if (!readList.Contains (path)) 84 readList.Add (path); 85 if (!writeList.Contains (path)) 86 writeList.Add (path); 87 } 88 break; 89 case EnvironmentPermissionAccess.NoAccess: 90 // ??? unit tests doesn't show removal using NoAccess ??? 91 break; 92 case EnvironmentPermissionAccess.Read: 93 paths = pathList.Split (';'); 94 foreach (string path in paths) { 95 if (!readList.Contains (path)) 96 readList.Add (path); 97 } 98 break; 99 case EnvironmentPermissionAccess.Write: 100 paths = pathList.Split (';'); 101 foreach (string path in paths) { 102 if (!writeList.Contains (path)) 103 writeList.Add (path); 104 } 105 break; 106 default: 107 ThrowInvalidFlag (flag, false); 108 break; 109 } 110 } 111 Copy()112 public override IPermission Copy () 113 { 114 EnvironmentPermission ep = new EnvironmentPermission (_state); 115 string path = GetPathList (EnvironmentPermissionAccess.Read); 116 if (path != null) 117 ep.SetPathList (EnvironmentPermissionAccess.Read, path); 118 path = GetPathList (EnvironmentPermissionAccess.Write); 119 if (path != null) 120 ep.SetPathList (EnvironmentPermissionAccess.Write, path); 121 return ep; 122 } 123 FromXml(SecurityElement esd)124 public override void FromXml (SecurityElement esd) 125 { 126 // General validation in CodeAccessPermission 127 CheckSecurityElement (esd, "esd", version, version); 128 // Note: we do not (yet) care about the return value 129 // as we only accept version 1 (min/max values) 130 131 if (IsUnrestricted (esd)) 132 _state = PermissionState.Unrestricted; 133 134 string read = esd.Attribute ("Read"); 135 if ((read != null) && (read.Length > 0)) 136 SetPathList (EnvironmentPermissionAccess.Read, read); 137 138 string write = esd.Attribute ("Write"); 139 if ((write != null) && (write.Length > 0)) 140 SetPathList (EnvironmentPermissionAccess.Write, write); 141 } 142 GetPathList(EnvironmentPermissionAccess flag)143 public string GetPathList (EnvironmentPermissionAccess flag) 144 { 145 switch (flag) { 146 case EnvironmentPermissionAccess.AllAccess: 147 case EnvironmentPermissionAccess.NoAccess: 148 ThrowInvalidFlag (flag, true); 149 break; 150 case EnvironmentPermissionAccess.Read: 151 return GetPathList (readList); 152 case EnvironmentPermissionAccess.Write: 153 return GetPathList (writeList); 154 default: 155 ThrowInvalidFlag (flag, false); 156 break; 157 } 158 return null; // never reached 159 } 160 Intersect(IPermission target)161 public override IPermission Intersect (IPermission target) 162 { 163 EnvironmentPermission ep = Cast (target); 164 if (ep == null) 165 return null; 166 167 if (IsUnrestricted ()) 168 return ep.Copy (); 169 if (ep.IsUnrestricted ()) 170 return Copy (); 171 172 int n = 0; 173 EnvironmentPermission result = new EnvironmentPermission (PermissionState.None); 174 string readTarget = ep.GetPathList (EnvironmentPermissionAccess.Read); 175 if (readTarget != null) { 176 string[] targets = readTarget.Split (';'); 177 foreach (string t in targets) { 178 if (readList.Contains (t)) { 179 result.AddPathList (EnvironmentPermissionAccess.Read, t); 180 n++; 181 } 182 } 183 } 184 185 string writeTarget = ep.GetPathList (EnvironmentPermissionAccess.Write); 186 if (writeTarget != null) { 187 string[] targets = writeTarget.Split (';'); 188 foreach (string t in targets) { 189 if (writeList.Contains (t)) { 190 result.AddPathList (EnvironmentPermissionAccess.Write, t); 191 n++; 192 } 193 } 194 } 195 return ((n > 0) ? result : null); 196 } 197 IsSubsetOf(IPermission target)198 public override bool IsSubsetOf (IPermission target) 199 { 200 EnvironmentPermission ep = Cast (target); 201 if (ep == null) 202 return false; 203 204 if (IsUnrestricted ()) 205 return ep.IsUnrestricted (); 206 else if (ep.IsUnrestricted ()) 207 return true; 208 209 foreach (string s in readList) { 210 if (!ep.readList.Contains (s)) 211 return false; 212 } 213 214 foreach (string s in writeList) { 215 if (!ep.writeList.Contains (s)) 216 return false; 217 } 218 219 return true; 220 } 221 IsUnrestricted()222 public bool IsUnrestricted () 223 { 224 return (_state == PermissionState.Unrestricted); 225 } 226 SetPathList(EnvironmentPermissionAccess flag, string pathList)227 public void SetPathList (EnvironmentPermissionAccess flag, string pathList) 228 { 229 if (pathList == null) 230 throw new ArgumentNullException ("pathList"); 231 string[] paths; 232 switch (flag) { 233 case EnvironmentPermissionAccess.AllAccess: 234 readList.Clear (); 235 writeList.Clear (); 236 paths = pathList.Split (';'); 237 foreach (string path in paths) { 238 readList.Add (path); 239 writeList.Add (path); 240 } 241 break; 242 case EnvironmentPermissionAccess.NoAccess: 243 // ??? unit tests doesn't show removal using NoAccess ??? 244 break; 245 case EnvironmentPermissionAccess.Read: 246 readList.Clear (); 247 paths = pathList.Split (';'); 248 foreach (string path in paths) { 249 readList.Add (path); 250 } 251 break; 252 case EnvironmentPermissionAccess.Write: 253 writeList.Clear (); 254 paths = pathList.Split (';'); 255 foreach (string path in paths) { 256 writeList.Add (path); 257 } 258 break; 259 default: 260 ThrowInvalidFlag (flag, false); 261 break; 262 } 263 } 264 ToXml()265 public override SecurityElement ToXml () 266 { 267 SecurityElement se = Element (version); 268 269 if (_state == PermissionState.Unrestricted) { 270 se.AddAttribute ("Unrestricted", "true"); 271 } 272 else { 273 string path = GetPathList (EnvironmentPermissionAccess.Read); 274 if (path != null) 275 se.AddAttribute ("Read", path); 276 path = GetPathList (EnvironmentPermissionAccess.Write); 277 if (path != null) 278 se.AddAttribute ("Write", path); 279 } 280 return se; 281 } 282 Union(IPermission other)283 public override IPermission Union (IPermission other) 284 { 285 EnvironmentPermission ep = Cast (other); 286 if (ep == null) 287 return Copy (); 288 289 if (IsUnrestricted () || ep.IsUnrestricted ()) 290 return new EnvironmentPermission (PermissionState.Unrestricted); 291 292 if (IsEmpty () && ep.IsEmpty ()) 293 return null; 294 295 EnvironmentPermission result = (EnvironmentPermission) Copy (); 296 string path = ep.GetPathList (EnvironmentPermissionAccess.Read); 297 if (path != null) 298 result.AddPathList (EnvironmentPermissionAccess.Read, path); 299 path = ep.GetPathList (EnvironmentPermissionAccess.Write); 300 if (path != null) 301 result.AddPathList (EnvironmentPermissionAccess.Write, path); 302 return result; 303 } 304 305 // IBuiltInPermission IBuiltInPermission.GetTokenIndex()306 int IBuiltInPermission.GetTokenIndex () 307 { 308 return (int) BuiltInToken.Environment; 309 } 310 311 // helpers 312 IsEmpty()313 private bool IsEmpty () 314 { 315 return ((_state == PermissionState.None) && (readList.Count == 0) && (writeList.Count == 0)); 316 } 317 Cast(IPermission target)318 private EnvironmentPermission Cast (IPermission target) 319 { 320 if (target == null) 321 return null; 322 323 EnvironmentPermission ep = (target as EnvironmentPermission); 324 if (ep == null) { 325 ThrowInvalidPermission (target, typeof (EnvironmentPermission)); 326 } 327 328 return ep; 329 } 330 ThrowInvalidFlag(EnvironmentPermissionAccess flag, bool context)331 internal void ThrowInvalidFlag (EnvironmentPermissionAccess flag, bool context) 332 { 333 string msg = null; 334 if (context) 335 msg = Locale.GetText ("Unknown flag '{0}'."); 336 else 337 msg = Locale.GetText ("Invalid flag '{0}' in this context."); 338 throw new ArgumentException (String.Format (msg, flag), "flag"); 339 } 340 GetPathList(ArrayList list)341 private string GetPathList (ArrayList list) 342 { 343 if (IsUnrestricted ()) 344 return String.Empty; 345 if (list.Count == 0) 346 return String.Empty; 347 StringBuilder sb = new StringBuilder (); 348 foreach (string path in list) { 349 sb.Append (path); 350 sb.Append (";"); 351 } 352 353 string result = sb.ToString (); 354 // remove last ';' 355 int n = result.Length; 356 if (n > 0) 357 return result.Substring (0, n - 1); 358 359 return String.Empty; 360 } 361 362 #endregion // Methods 363 } 364 } 365