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
|