File: MutexSecurityTest.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (145 lines) | stat: -rw-r--r-- 4,635 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// MutexSecurityTest.cs - NUnit Test Cases for MutexSecurity
//
// Authors:
//	James Bellinger  <jfb@zer7.com>
//
// Copyright (C) 2012 James Bellinger

#if !MOBILE

using System;
using System.Collections.Generic;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using NUnit.Framework;

namespace MonoTests.System.Security.AccessControl
{
	[TestFixture]
	public class MutexSecurityTest
	{
		[Test, ExpectedException (typeof (WaitHandleCannotBeOpenedException))]
		public void FailsForNonexistantMutex ()
		{
			if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
				Assert.Ignore ();
			}

			new MutexSecurity (@"Local\NonexistantMutex", AccessControlSections.Access);
		}

		[Test]
		public void SucceedsForExistingMutex ()
		{
			if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
				Assert.Ignore ();
			}

			bool createdNew;
			string name = @"Local\MonoTestMutex";

			// Let's be sure the mutex destroys on Close() as well.
			// Otherwise, many of our tests will fail as they will be accessing the wrong mutex.
			using (Mutex mutex = new Mutex (false, name, out createdNew)) {
				Assert.IsTrue (createdNew);
				new MutexSecurity (name, AccessControlSections.Access);
			}

			using (Mutex mutex = new Mutex (false, name, out createdNew)) {
				Assert.IsTrue (createdNew);
				new MutexSecurity (name, AccessControlSections.Access);
			}
		}

		[Test]
		public void CanSetAndGetMutexSecurity ()
		{
			if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
				Assert.Ignore ();
			}

			MutexAccessRule rule; SecurityIdentifier sid;
			AuthorizationRuleCollection rulesA, rulesB, rulesC;
			bool createdNew; MutexSecurity security;
			string name = @"Local\MonoTestMutex";

			using (Mutex mutex = new Mutex(false, name, out createdNew)) {
				Assert.IsTrue (createdNew);

				security = mutex.GetAccessControl ();
				rulesA = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
				Assert.AreNotEqual (0, rulesA.Count);

				// Contrary to what you'd expect, these classes only try to persist sections that
				// that were *changed*. Awful, eh? To be fair, if you retrieve and modify it's fine.
				security = new MutexSecurity ();
				mutex.SetAccessControl (security);

				security = mutex.GetAccessControl ();
				rulesB = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
				Assert.AreEqual (rulesA.Count, rulesB.Count);

				// And here's our dummy change. Observe...
				sid = new SecurityIdentifier( "S-1-5-12-3456-7890");
				rule = new MutexAccessRule (sid, MutexRights.Synchronize, AccessControlType.Allow);

				security = new MutexSecurity ();
				security.RemoveAccessRuleSpecific (rule);
				mutex.SetAccessControl (security);

				security = mutex.GetAccessControl ();
				rulesC = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
				Assert.AreEqual (0, rulesC.Count);
			}
		}

		// TODO: Mono System.Threading.Mutex does not throw exceptions on failure!
		[Test, ExpectedExceptionAttribute (typeof (UnauthorizedAccessException))]
		public void PermissionsActuallyWork ()
		{
			if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
				Assert.Ignore ();
			}

			bool createdNew; MutexSecurity security;
			string name = @"Local\MonoTestMutex";

			using (Mutex mutex = new Mutex (false, name, out createdNew)) {
				Assert.IsFalse (mutex.SafeWaitHandle.IsInvalid);
				Assert.IsTrue (createdNew);

				// Make sure our later error will be due to permissions and not some sharing bug.
				bool createdAnotherNew;
				using (Mutex anotherMutex = new Mutex (false, name, out createdAnotherNew)) {
					Assert.IsFalse (mutex.SafeWaitHandle.IsInvalid);
					Assert.IsFalse (createdAnotherNew);
				}

				// Let's make a deny all.
				security = mutex.GetAccessControl ();

				foreach (MutexAccessRule rule in security.GetAccessRules
				         (true, false, typeof (SecurityIdentifier))) {
					security.RemoveAccessRuleSpecific (rule);
				}

				Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
				mutex.SetAccessControl (security);

				security = mutex.GetAccessControl ();
				Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);

				// MS.NET will throw on the first line below.
				// For Mono testing the latter verifies the rest until the Mutex bug is fixed.
				// Also, NUnit 2.4 appears to lacks Assert.Pass ().
				Mutex badMutex = new Mutex(false, name);
				if (badMutex.SafeWaitHandle.IsInvalid)
					throw new UnauthorizedAccessException ();
			}
		}
	}
}

#endif