Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

203 lines
6.4 KiB
C#

// PipeSecurityTest.cs - NUnit Test Cases for PipeSecurity
//
// Authors:
// James Bellinger <jfb@zer7.com>
//
// Copyright (C) 2012 James Bellinger
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using NUnit.Framework;
namespace MonoTests.System.IO.Pipes
{
[TestFixture]
public class PipeSecurityTest
{
[Test]
public void NamedPipeDefaultPermissionsWork ()
{
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
string name = @"Local\MonoTestPipeNPNPW";
using (NamedPipeServerStream server = CreateNamedServer (false, name, null, 0)) {
PipeSecurity security = server.GetAccessControl ();
AuthorizationRuleCollection rules = security.GetAccessRules (true, false,
typeof (SecurityIdentifier));
Assert.AreNotEqual (0, rules.Count);
}
}
[Test]
public void NamedPipeSetAccessControlFailsWithoutChangePermissionRight ()
{
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
string name = @"Local\MonoTestPipeNPSACFWCPR";
using (NamedPipeServerStream server = CreateNamedServer (false, name, null, 0)) {
bool unauthorized = false;
try {
AddDenyEveryone (server);
} catch (UnauthorizedAccessException) {
unauthorized = true;
}
Assert.IsTrue (unauthorized, "PipeAccessRights.ChangePermissions was not required");
}
}
[Test]
public void NamedPipePermissionsActuallyWorkSyncAllow ()
{
NamedPipePermissionsActuallyWorkSync (@"Local\MonoTestPipeNPPAWSA", false);
}
[Test]
public void NamedPipePermissionsActuallyWorkSyncDeny ()
{
NamedPipePermissionsActuallyWorkSync (@"Local\MonoTestPipeNPPAWSD", true);
}
void NamedPipePermissionsActuallyWorkSync (string name, bool addDenyEveryone)
{
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
PipeSecurity security = new PipeSecurity ();
SecurityIdentifier worldSid = new SecurityIdentifier ("WD");
PipeAccessRule rule = new PipeAccessRule (worldSid,
PipeAccessRights.FullControl,
AccessControlType.Allow);
security.AddAccessRule (rule);
using (NamedPipeServerStream server = CreateNamedServer (false, name, security,
PipeAccessRights.ChangePermissions)) {
security = server.GetAccessControl ();
AuthorizationRuleCollection rules;
rules = security.GetAccessRules (true, true, typeof (SecurityIdentifier));
Assert.AreEqual (1, rules.Count);
rule = (PipeAccessRule)rules [0];
Assert.AreEqual (AccessControlType.Allow, rule.AccessControlType);
Assert.AreEqual (worldSid, rule.IdentityReference);
Assert.AreEqual (PipeAccessRights.FullControl, rule.PipeAccessRights);
if (addDenyEveryone)
AddDenyEveryone (server);
bool unauthorized = false;
using (NamedPipeClientStream client = CreateNamedClient (false, name)) {
try {
client.Connect (1000);
} catch (UnauthorizedAccessException) {
unauthorized = true;
}
}
Assert.AreEqual (addDenyEveryone, unauthorized);
}
}
[Test]
[Category ("NotWorking")] // Async is completely broken on Mono Win32 pipes.
public void NamedPipePermissionsActuallyWorkAsync ()
{
if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
Assert.Ignore ();
}
IAsyncResult waitForConnection;
string name = @"Local\MonoTestPipeNPPAWA";
using (NamedPipeServerStream server = CreateNamedServer (true, name, null,
PipeAccessRights.ChangePermissions)) {
// Test connecting to make sure our later test throwing is due to permissions.
waitForConnection = server.BeginWaitForConnection (null, null);
using (NamedPipeClientStream client = CreateNamedClient (true, name)) {
client.Connect (1000);
if (!waitForConnection.AsyncWaitHandle.WaitOne (1000)) {
Assert.Fail ("No connection request received."); return;
}
server.EndWaitForConnection (waitForConnection);
server.Disconnect ();
}
// Let's add a Deny for Everyone.
AddDenyEveryone (server);
// This Connect call should fail.
waitForConnection = server.BeginWaitForConnection (null, null);
bool unauthorized = false;
using (NamedPipeClientStream client = CreateNamedClient (true, name)) {
try {
client.Connect (1000);
} catch (UnauthorizedAccessException) {
unauthorized = true;
}
}
Assert.IsTrue (unauthorized, "Client was allowed to connect despite Deny ACE.");
}
}
static void AddDenyEveryone (PipeStream stream)
{
PipeAccessRule rule; PipeSecurity security;
AuthorizationRuleCollection inRules, outRules;
// Let's add a Deny for Everyone.
security = stream.GetAccessControl ();
inRules = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreNotEqual (0, inRules.Count);
rule = new PipeAccessRule (new SecurityIdentifier ("WD"),
PipeAccessRights.FullControl,
AccessControlType.Deny);
security.AddAccessRule (rule);
stream.SetAccessControl (security);
security = stream.GetAccessControl ();
outRules = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
Assert.AreEqual (inRules.Count + 1, outRules.Count);
}
static NamedPipeClientStream CreateNamedClient (bool @async, string name)
{
return new NamedPipeClientStream (".", name,
PipeDirection.InOut,
@async ? PipeOptions.Asynchronous : PipeOptions.None);
}
static NamedPipeServerStream CreateNamedServer (bool @async, string name,
PipeSecurity security,
PipeAccessRights additionalRights)
{
return new NamedPipeServerStream (name,
PipeDirection.InOut, 1,
PipeTransmissionMode.Byte,
@async ? PipeOptions.Asynchronous : PipeOptions.None,
512, 512, security,
HandleInheritability.None,
additionalRights);
}
}
}