1 //
2 // EnvironmentCas.cs - CAS unit tests for System.Environment
3 //
4 // Author:
5 //	Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 
29 #if !MOBILE
30 using NUnit.Framework;
31 
32 using System;
33 using System.Collections;
34 using System.IO;
35 using System.Security;
36 using System.Security.Permissions;
37 
38 namespace MonoCasTests.System {
39 
40 	[TestFixture]
41 	[Category ("CAS")]
42 	public class EnvironmentCas {
43 
44 		[SetUp]
SetUp()45 		public void SetUp ()
46 		{
47 			if (!SecurityManager.SecurityEnabled)
48 				Assert.Ignore ("SecurityManager.SecurityEnabled is OFF");
49 		}
50 
51 		// Partial Trust Tests - i.e. call "normal" unit with reduced privileges
52 
53 		[Test]
54 		[EnvironmentPermission (SecurityAction.PermitOnly, Unrestricted = true)]
PartialTrust_PermitOnly_Environment()55 		public void PartialTrust_PermitOnly_Environment ()
56 		{
57 			MonoTests.System.EnvironmentTest et = new MonoTests.System.EnvironmentTest ();
58 			// call most (all but arguments checking) unit tests from EnvironmentTest
59 			et.ExpandEnvironmentVariables_UnknownVariable ();
60 			et.ExpandEnvironmentVariables_KnownVariable ();
61 			et.ExpandEnvironmentVariables_NotVariable ();
62 			et.ExpandEnvironmentVariables_Alone ();
63 			et.ExpandEnvironmentVariables_End ();
64 			et.ExpandEnvironmentVariables_None ();
65 			et.ExpandEnvironmentVariables_EmptyVariable ();
66 			et.ExpandEnvironmentVariables_Double ();
67 			et.ExpandEnvironmentVariables_ComplexExpandable ();
68 			et.ExpandEnvironmentVariables_ExpandableAndNonExpandable ();
69 			et.ExpandEnvironmentVariables_ExpandableWithTrailingPercent ();
70 			et.ExpandEnvironmentVariables_ComplexExpandable2 ();
71 			et.GetEnvironmentVariables ();
72 			et.GetCommandLineArgs ();
73 		}
74 
75 		// test Demand by denying it's caller from the required privileges
76 
77 		[Test]
78 		[EnvironmentPermission (SecurityAction.Deny, Read = "PATH")]
79 		[ExpectedException (typeof (SecurityException))]
CommandLine()80 		public void CommandLine ()
81 		{
82 			// now that the stack is set, call the method
83 			string s = Environment.CommandLine;
84 		}
85 
86 		[Test]
87 		[EnvironmentPermission (SecurityAction.Deny, Unrestricted = true)]
CurrentDirectory_EnvironmentPermission()88 		public void CurrentDirectory_EnvironmentPermission ()
89 		{
90 			// now that the stack is set, call the methods
91 			string cd = Environment.CurrentDirectory;
92 			Environment.CurrentDirectory = cd;
93 			// nothing to do with EnvironmentPermission
94 		}
95 
96 		[Test]
97 		[SecurityPermission (SecurityAction.Deny, UnmanagedCode = true)]
98 		[ExpectedException (typeof (SecurityException))]
CurrentDirectory_SecurityPermission()99 		public void CurrentDirectory_SecurityPermission ()
100 		{
101 			string cd = null;
102 			try {
103 				cd = Environment.CurrentDirectory;
104 			}
105 			catch (SecurityException) {
106 				// this isn't the part that should fail
107 				Assert.Fail ("shouldn't fail when getting current dir");
108 			}
109 			// now that the stack is set, call the method
110 			Environment.CurrentDirectory = cd;
111 		}
112 
113 
114 		[Test]
115 		[FileIOPermission (SecurityAction.Deny, PathDiscovery = "/")]
116 		[ExpectedException (typeof (SecurityException))]
CurrentDirectory_Get_FileIOPermission()117 		public void CurrentDirectory_Get_FileIOPermission ()
118 		{
119 			// now that the stack is set, call the method
120 			string cd = Environment.CurrentDirectory;
121 		}
122 
123 		[Test]
124 		[FileIOPermission (SecurityAction.Deny, PathDiscovery = "/")]
125 		[ExpectedException (typeof (SecurityException))]
GetFolderPath()126 		public void GetFolderPath ()
127 		{
128 			// now that the stack is set, call the method
129 			string s = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
130 		}
131 
132 		[Test]
CurrentDirectory_Set_FileIOPermission()133 		public void CurrentDirectory_Set_FileIOPermission ()
134 		{
135 			// this test will change the current directory
136 			// and cause tests failures elsewhere...
137 			string cd = Environment.CurrentDirectory;
138 			try {
139 				CurrentDirectory_Set_FileIOPermission_Restricted ();
140 			}
141 			finally {
142 				// ... unless we return to the original directory
143 				Environment.CurrentDirectory = cd;
144 			}
145 		}
146 
147 		[FileIOPermission (SecurityAction.Deny, Unrestricted = true)]
CurrentDirectory_Set_FileIOPermission_Restricted()148 		private void CurrentDirectory_Set_FileIOPermission_Restricted ()
149 		{
150 			// now that the stack is set, call the method
151 #if RUN_ONDOTNET
152 			Environment.CurrentDirectory = "C:\\";
153 #else
154 			Environment.CurrentDirectory = "/";
155 #endif
156 			// no rights are required (as we already know the path)
157 		}
158 
159 		[Test]
160 		[SecurityPermission (SecurityAction.Deny, UnmanagedCode = true)]
161 		[ExpectedException (typeof (SecurityException))]
Exit()162 		public void Exit ()
163 		{
164 			// now that the stack is set, call the method
165 			Environment.Exit (1);
166 		}
167 
168 		[Test]
169 		[PermissionSet (SecurityAction.Deny, Unrestricted = true)]
ExitCode()170 		public void ExitCode ()
171 		{
172 			// now that the stack is set, call the method
173 			int ec = Environment.ExitCode;
174 			Environment.ExitCode = ec;
175 		}
176 
177 		[Test]
178 		[EnvironmentPermission (SecurityAction.Deny, Read = "PATH")]
179 		[ExpectedException (typeof (SecurityException))]
ExpandEnvironmentVariables()180 		public void ExpandEnvironmentVariables ()
181 		{
182 			// now that the stack is set, call the method
183 			string s = Environment.ExpandEnvironmentVariables ("%PATH%");
184 		}
185 
186 		[Test]
187 		[PermissionSet (SecurityAction.Deny, Unrestricted = true)]
188 		[Ignore ("Protected by a LinkDemand, will throw an ExecutionEngineException to stop process")]
FailFast()189 		public void FailFast ()
190 		{
191 			// now that the stack is set, call the method
192 			Environment.FailFast ("bye bye");
193 		}
194 
195 		[Test]
196 		[EnvironmentPermission (SecurityAction.Deny, Read = "PATH")]
197 		[ExpectedException (typeof (SecurityException))]
GetCommandLineArgs()198 		public void GetCommandLineArgs ()
199 		{
200 			// now that the stack is set, call the method
201 			string[] s = Environment.GetCommandLineArgs ();
202 		}
203 
204 		[Test]
205 		[EnvironmentPermission (SecurityAction.Deny, Read = "PATH")]
206 		[ExpectedException (typeof (SecurityException))]
GetEnvironmentVariable()207 		public void GetEnvironmentVariable ()
208 		{
209 			// now that the stack is set, call the method
210 			string s = Environment.GetEnvironmentVariable ("PATH");
211 		}
212 
213 		[Test]
214 		[EnvironmentPermission (SecurityAction.Deny, Read = "MONO")]
GetEnvironmentVariable_Target_Process()215 		public void GetEnvironmentVariable_Target_Process ()
216 		{
217 			// now that the stack is set, call the method
218 			string s = Environment.GetEnvironmentVariable ("PATH",
219 				EnvironmentVariableTarget.Process);
220 			// it doesn't takes Unrestricted access to read from
221 			// Process environment variables (like older API)
222 		}
223 
224 		[Test]
225 		[EnvironmentPermission (SecurityAction.Deny, Read = "MONO")]
226 		[ExpectedException (typeof (SecurityException))]
GetEnvironmentVariable_Target()227 		public void GetEnvironmentVariable_Target ()
228 		{
229 			// now that the stack is set, call the method
230 			string s = Environment.GetEnvironmentVariable ("PATH",
231 				EnvironmentVariableTarget.Machine);
232 			// it takes Unrestricted access to read from Machine
233 			// and User environment variables
234 		}
235 
236 		[Test]
237 		[EnvironmentPermission (SecurityAction.Deny, Write = "MONO")]
238 		[ExpectedException (typeof (SecurityException))]
GetEnvironmentVariable_Target2()239 		public void GetEnvironmentVariable_Target2 ()
240 		{
241 			// note that be removing write access we're no longer
242 			// unrestricted, so this should fail even for a read
243 			string s = Environment.GetEnvironmentVariable ("PATH",
244 				EnvironmentVariableTarget.Machine);
245 			// it takes Unrestricted access to read from Machine
246 			// and User environment variables
247 		}
248 
249 		[Test]
250 		[EnvironmentPermission (SecurityAction.Deny, Read = "PATH")]
251 		[ExpectedException (typeof (SecurityException))]
GetEnvironmentVariables()252 		public void GetEnvironmentVariables ()
253 		{
254 			// note that whis wouldn't fail if no PATH variable
255 			// was part of the environment variables
256 			IDictionary d = Environment.GetEnvironmentVariables ();
257 		}
258 
259 		[Test]
260 		[EnvironmentPermission (SecurityAction.Deny, Read = "PLEASE_NEVER_DEFINE_THIS_VARIABLE")]
261 		// Before 2.0 this required Unrestricted EnvironmentPermission
262 		[ExpectedException (typeof (SecurityException))]
GetEnvironmentVariables_Pass()263 		public void GetEnvironmentVariables_Pass ()
264 		{
265 			// this will work as long as PLEASE_NEVER_DEFINE_THIS_VARIABLE
266 			// isn't an environment variable
267 			IDictionary d = Environment.GetEnvironmentVariables ();
268 		}
269 
270 		[Test]
271 		[EnvironmentPermission (SecurityAction.Deny, Read = "PATH")]
272 		[ExpectedException (typeof (SecurityException))]
GetEnvironmentVariables_Target()273 		public void GetEnvironmentVariables_Target ()
274 		{
275 			// now that the stack is set, call the method
276 			IDictionary d = Environment.GetEnvironmentVariables (
277 				EnvironmentVariableTarget.Machine);
278 			// it takes Unrestricted access to read from Machine
279 			// and User environment variables
280 		}
281 
282 		[Test]
283 		[EnvironmentPermission (SecurityAction.Deny, Write = "PATH")]
284 		[ExpectedException (typeof (SecurityException))]
GetEnvironmentVariables_Target2()285 		public void GetEnvironmentVariables_Target2 ()
286 		{
287 			// note that be removing write access we're no longer
288 			// unrestricted, so this should fail even for a read
289 			IDictionary d = Environment.GetEnvironmentVariables (
290 				EnvironmentVariableTarget.Machine);
291 			// it takes Unrestricted access to read from Machine
292 			// and User environment variables
293 		}
294 
295 		[Test]
296 		[EnvironmentPermission (SecurityAction.Deny, Unrestricted = true)]
GetFolderPath_EnvironmentPermission()297 		public void GetFolderPath_EnvironmentPermission ()
298 		{
299 			// we can get all folders without any EnvironmentPermission
300 			// note: Mono use some environment variable to create the paths
301 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments), "MyDocuments");
302 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.Desktop), "Desktop");
303 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.MyComputer), "MyComputer");
304 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.Personal), "Personal");
305 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.Favorites), "Favorites");
306 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.Startup), "Startup");
307 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.Recent), "Recent");
308 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.SendTo), "SendTo");
309 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.StartMenu), "StartMenu");
310 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.MyMusic), "MyMusic");
311 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.DesktopDirectory), "DesktopDirectory");
312 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.Templates), "Templates");
313 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), "ApplicationData");
314 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData), "LocalApplicationData");
315 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.InternetCache), "InternetCache");
316 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.Cookies), "Cookies");
317 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.History), "History");
318 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData), "CommonApplicationData");
319 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.System), "System");
320 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.ProgramFiles), "ProgramFiles");
321 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.MyPictures), "MyPictures");
322 			Assert.IsNotNull (Environment.GetFolderPath (Environment.SpecialFolder.CommonProgramFiles), "CommonProgramFiles");
323 		}
324 
325 		[Test]
326 		[EnvironmentPermission (SecurityAction.Deny, Write = "PATH")]
327 		[ExpectedException (typeof (SecurityException))]
GetLogicalDrives()328 		public void GetLogicalDrives ()
329 		{
330 			// note that be removing write access we're no longer
331 			// unrestricted, so this should fail even if it's not
332 			// related to environment variables at all!
333 			string[] s = Environment.GetLogicalDrives ();
334 		}
335 
336 		[Test]
337 		[PermissionSet (SecurityAction.Deny, Unrestricted = true)]
HasShutdownStarted()338 		public void HasShutdownStarted ()
339 		{
340 			// now that the stack is set, call the methods
341 			bool b = Environment.HasShutdownStarted;
342 		}
343 
344 		[Test]
345 		[EnvironmentPermission (SecurityAction.Deny, Read = "COMPUTERNAME")]
346 		[ExpectedException (typeof (SecurityException))]
MachineName_EnvironmentPermission()347 		public void MachineName_EnvironmentPermission ()
348 		{
349 			// now that the stack is set, call the method
350 			string s = Environment.MachineName;
351 		}
352 
353 		[Test]
354 		[SecurityPermission (SecurityAction.Deny, UnmanagedCode =true)]
355 		[ExpectedException (typeof (SecurityException))]
MachineName_SecurityPermission()356 		public void MachineName_SecurityPermission ()
357 		{
358 			// now that the stack is set, call the method
359 			string s = Environment.MachineName;
360 		}
361 
362 		[Test]
363 		[PermissionSet (SecurityAction.Deny, Unrestricted = true)]
NewLine()364 		public void NewLine ()
365 		{
366 			// now that the stack is set, call the methods
367 			string s = Environment.NewLine;
368 		}
369 
370 		[Test]
371 		[PermissionSet (SecurityAction.Deny, Unrestricted = true)]
OSVersion()372 		public void OSVersion ()
373 		{
374 			// now that the stack is set, call the methods
375 			OperatingSystem os = Environment.OSVersion;
376 		}
377 
378 		[Test]
379 		[EnvironmentPermission (SecurityAction.Deny, Read = "NUMBER_OF_PROCESSORS")]
380 		[ExpectedException (typeof (SecurityException))]
ProcessorCount()381 		public void ProcessorCount ()
382 		{
383 			// now that the stack is set, call the methods
384 			int i = Environment.ProcessorCount;
385 		}
386 		[Test]
387 		[EnvironmentPermission (SecurityAction.Deny, Write = "MONO")]
388 		[ExpectedException (typeof (SecurityException))]
SetEnvironmentVariable()389 		public void SetEnvironmentVariable ()
390 		{
391 			// now that the stack is set, call the method
392 			Environment.SetEnvironmentVariable ("MONO", "GO");
393 		}
394 
395 		[Test]
396 		[EnvironmentPermission (SecurityAction.Deny, Write = "PATH")]
397 		[ExpectedException (typeof (SecurityException))]
SetEnvironmentVariable2()398 		public void SetEnvironmentVariable2 ()
399 		{
400 			// Note: strangely (but documented as such) it takes
401 			// unrestricted access to call SetEnvironmentVariable
402 			// so denying write to PATH also deny write to any
403 			// other environment variable, like the MONO variable
404 			Environment.SetEnvironmentVariable ("MONO", "GO");
405 		}
406 
407 		[Test]
408 		[EnvironmentPermission (SecurityAction.Deny, Write = "MONO")]
409 		[ExpectedException (typeof (SecurityException))]
SetEnvironmentVariable_Target()410 		public void SetEnvironmentVariable_Target ()
411 		{
412 			// now that the stack is set, call the method
413 			Environment.SetEnvironmentVariable ("MONO", "GO",
414 				EnvironmentVariableTarget.Machine);
415 			// it takes Unrestricted access to read from Machine
416 			// and User environment variables
417 		}
418 
419 		[Test]
420 		[EnvironmentPermission (SecurityAction.Deny, Read = "MONO")]
421 		[ExpectedException (typeof (SecurityException))]
SetEnvironmentVariable_Target2()422 		public void SetEnvironmentVariable_Target2 ()
423 		{
424 			// note that be removing read access we're no longer
425 			// unrestricted, so this should fail even for a write
426 			Environment.SetEnvironmentVariable ("MONO", "GO",
427 				EnvironmentVariableTarget.Machine);
428 			// it takes Unrestricted access to read from Machine
429 			// and User environment variables
430 		}
431 
432 		[Test]
433 		[EnvironmentPermission (SecurityAction.Deny, Write = "MONO")]
434 		[ExpectedException (typeof (SecurityException))]
StackTrace()435 		public void StackTrace ()
436 		{
437 			// note that be removing write access we're no longer
438 			// unrestricted, so this should fail even if the call
439 			// stack isn't related to writing in environment variables
440 			string s = Environment.StackTrace;
441 		}
442 
443 		[Test]
444 #if false && RUN_ONDOTNET
445 		[FileIOPermission (SecurityAction.Deny, PathDiscovery = "C:\\")]
446 		[ExpectedException (typeof (SecurityException))]
447 #endif
SystemDirectory()448 		public void SystemDirectory ()
449 		{
450 			// now that the stack is set, call the method
451 			string s = Environment.SystemDirectory;
452 			// note: Under Linux SystemDirectory is empty (so it's not a path)
453 			Assert.AreEqual (String.Empty, s);
454 		}
455 
456 		[Test]
457 		[PermissionSet (SecurityAction.Deny, Unrestricted = true)]
TickCount()458 		public void TickCount ()
459 		{
460 			// now that the stack is set, call the methods
461 			int i = Environment.TickCount;
462 		}
463 
464 		[Test]
465 		[EnvironmentPermission (SecurityAction.Deny, Read = "USERDOMAINNAME")]
466 		[ExpectedException (typeof (SecurityException))]
UserDomainName()467 		public void UserDomainName ()
468 		{
469 			// now that the stack is set, call the methods
470 			string s = Environment.UserDomainName;
471 		}
472 
473 		[Test]
474 		[PermissionSet (SecurityAction.Deny, Unrestricted = true)]
UserInteractive()475 		public void UserInteractive ()
476 		{
477 			// now that the stack is set, call the methods
478 			bool b = Environment.UserInteractive;
479 		}
480 
481 		[Test]
482 		[EnvironmentPermission (SecurityAction.Deny, Read = "USERNAME")]
483 		[ExpectedException (typeof (SecurityException))]
UserName()484 		public void UserName ()
485 		{
486 			// now that the stack is set, call the methods
487 			string s = Environment.UserName;
488 			// note: the UserName property doesn't really read the
489 			// USERNAME variable. You can test this by impersonating
490 			// another user (see unit tests)
491 		}
492 
493 		[Test]
494 		[PermissionSet (SecurityAction.Deny, Unrestricted = true)]
Version()495 		public void Version ()
496 		{
497 			// now that the stack is set, call the methods
498 			Version v = Environment.Version;
499 		}
500 
501 		[Test]
502 		[EnvironmentPermission (SecurityAction.Deny, Read = "USERNAME")]
503 		[ExpectedException (typeof (SecurityException))]
WorkingSet()504 		public void WorkingSet ()
505 		{
506 			// note that be removing read access to USERNAME we're
507 			// no longer unrestricted, so this should fail even if
508 			// the working set is unrelated to the username
509 			long l = Environment.WorkingSet;
510 		}
511 	}
512 }
513 
514 #endif
515