1 // MutexSecurityTest.cs - NUnit Test Cases for MutexSecurity
4 // James Bellinger <jfb@zer7.com>
6 // Copyright (C) 2012 James Bellinger
11 using System.Collections.Generic;
12 using System.Security.AccessControl;
13 using System.Security.Principal;
14 using System.Threading;
15 using NUnit.Framework;
17 namespace MonoTests.System.Security.AccessControl
20 public class MutexSecurityTest
22 [Test, ExpectedException (typeof (WaitHandleCannotBeOpenedException))]
23 public void FailsForNonexistantMutex ()
25 if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
29 new MutexSecurity (@"Local\NonexistantMutex", AccessControlSections.Access);
33 public void SucceedsForExistingMutex ()
35 if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
40 string name = @"Local\MonoTestMutex";
42 // Let's be sure the mutex destroys on Close() as well.
43 // Otherwise, many of our tests will fail as they will be accessing the wrong mutex.
44 using (Mutex mutex = new Mutex (false, name, out createdNew)) {
45 Assert.IsTrue (createdNew);
46 new MutexSecurity (name, AccessControlSections.Access);
49 using (Mutex mutex = new Mutex (false, name, out createdNew)) {
50 Assert.IsTrue (createdNew);
51 new MutexSecurity (name, AccessControlSections.Access);
56 public void CanSetAndGetMutexSecurity ()
58 if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
62 MutexAccessRule rule; SecurityIdentifier sid;
63 AuthorizationRuleCollection rulesA, rulesB, rulesC;
64 bool createdNew; MutexSecurity security;
65 string name = @"Local\MonoTestMutex";
67 using (Mutex mutex = new Mutex(false, name, out createdNew)) {
68 Assert.IsTrue (createdNew);
70 security = mutex.GetAccessControl ();
71 rulesA = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
72 Assert.AreNotEqual (0, rulesA.Count);
74 // Contrary to what you'd expect, these classes only try to persist sections that
75 // that were *changed*. Awful, eh? To be fair, if you retrieve and modify it's fine.
76 security = new MutexSecurity ();
77 mutex.SetAccessControl (security);
79 security = mutex.GetAccessControl ();
80 rulesB = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
81 Assert.AreEqual (rulesA.Count, rulesB.Count);
83 // And here's our dummy change. Observe...
84 sid = new SecurityIdentifier( "S-1-5-12-3456-7890");
85 rule = new MutexAccessRule (sid, MutexRights.Synchronize, AccessControlType.Allow);
87 security = new MutexSecurity ();
88 security.RemoveAccessRuleSpecific (rule);
89 mutex.SetAccessControl (security);
91 security = mutex.GetAccessControl ();
92 rulesC = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
93 Assert.AreEqual (0, rulesC.Count);
97 // TODO: Mono System.Threading.Mutex does not throw exceptions on failure!
98 [Test, ExpectedExceptionAttribute (typeof (UnauthorizedAccessException))]
99 public void PermissionsActuallyWork ()
101 if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
105 bool createdNew; MutexSecurity security;
106 string name = @"Local\MonoTestMutex";
108 using (Mutex mutex = new Mutex (false, name, out createdNew)) {
109 Assert.IsFalse (mutex.SafeWaitHandle.IsInvalid);
110 Assert.IsTrue (createdNew);
112 // Make sure our later error will be due to permissions and not some sharing bug.
113 bool createdAnotherNew;
114 using (Mutex anotherMutex = new Mutex (false, name, out createdAnotherNew)) {
115 Assert.IsFalse (mutex.SafeWaitHandle.IsInvalid);
116 Assert.IsFalse (createdAnotherNew);
119 // Let's make a deny all.
120 security = mutex.GetAccessControl ();
122 foreach (MutexAccessRule rule in security.GetAccessRules
123 (true, false, typeof (SecurityIdentifier))) {
124 security.RemoveAccessRuleSpecific (rule);
127 Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
128 mutex.SetAccessControl (security);
130 security = mutex.GetAccessControl ();
131 Assert.AreEqual (0, security.GetAccessRules (true, false, typeof (SecurityIdentifier)).Count);
133 // MS.NET will throw on the first line below.
134 // For Mono testing the latter verifies the rest until the Mutex bug is fixed.
135 // Also, NUnit 2.4 appears to lacks Assert.Pass ().
136 Mutex badMutex = new Mutex(false, name);
137 if (badMutex.SafeWaitHandle.IsInvalid)
138 throw new UnauthorizedAccessException ();