2
0

PipeSecurityTest.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // PipeSecurityTest.cs - NUnit Test Cases for PipeSecurity
  2. //
  3. // Authors:
  4. // James Bellinger <[email protected]>
  5. //
  6. // Copyright (C) 2012 James Bellinger
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.IO.Pipes;
  11. using System.Security.AccessControl;
  12. using System.Security.Principal;
  13. using System.Threading;
  14. using NUnit.Framework;
  15. namespace MonoTests.System.IO.Pipes
  16. {
  17. [TestFixture]
  18. public class PipeSecurityTest
  19. {
  20. [Test]
  21. public void NamedPipeDefaultPermissionsWork ()
  22. {
  23. if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
  24. Assert.Ignore ();
  25. }
  26. string name = @"Local\MonoTestPipeNPNPW";
  27. using (NamedPipeServerStream server = CreateNamedServer (false, name, null, 0)) {
  28. PipeSecurity security = server.GetAccessControl ();
  29. AuthorizationRuleCollection rules = security.GetAccessRules (true, false,
  30. typeof (SecurityIdentifier));
  31. Assert.AreNotEqual (0, rules.Count);
  32. }
  33. }
  34. [Test]
  35. public void NamedPipeSetAccessControlFailsWithoutChangePermissionRight ()
  36. {
  37. if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
  38. Assert.Ignore ();
  39. }
  40. string name = @"Local\MonoTestPipeNPSACFWCPR";
  41. using (NamedPipeServerStream server = CreateNamedServer (false, name, null, 0)) {
  42. bool unauthorized = false;
  43. try {
  44. AddDenyEveryone (server);
  45. } catch (UnauthorizedAccessException) {
  46. unauthorized = true;
  47. }
  48. Assert.IsTrue (unauthorized, "PipeAccessRights.ChangePermissions was not required");
  49. }
  50. }
  51. [Test]
  52. public void NamedPipePermissionsActuallyWorkSyncAllow ()
  53. {
  54. NamedPipePermissionsActuallyWorkSync (@"Local\MonoTestPipeNPPAWSA", false);
  55. }
  56. [Test]
  57. public void NamedPipePermissionsActuallyWorkSyncDeny ()
  58. {
  59. NamedPipePermissionsActuallyWorkSync (@"Local\MonoTestPipeNPPAWSD", true);
  60. }
  61. void NamedPipePermissionsActuallyWorkSync (string name, bool addDenyEveryone)
  62. {
  63. if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
  64. Assert.Ignore ();
  65. }
  66. PipeSecurity security = new PipeSecurity ();
  67. SecurityIdentifier worldSid = new SecurityIdentifier ("WD");
  68. PipeAccessRule rule = new PipeAccessRule (worldSid,
  69. PipeAccessRights.FullControl,
  70. AccessControlType.Allow);
  71. security.AddAccessRule (rule);
  72. using (NamedPipeServerStream server = CreateNamedServer (false, name, security,
  73. PipeAccessRights.ChangePermissions)) {
  74. security = server.GetAccessControl ();
  75. AuthorizationRuleCollection rules;
  76. rules = security.GetAccessRules (true, true, typeof (SecurityIdentifier));
  77. Assert.AreEqual (1, rules.Count);
  78. rule = (PipeAccessRule)rules [0];
  79. Assert.AreEqual (AccessControlType.Allow, rule.AccessControlType);
  80. Assert.AreEqual (worldSid, rule.IdentityReference);
  81. Assert.AreEqual (PipeAccessRights.FullControl, rule.PipeAccessRights);
  82. if (addDenyEveryone)
  83. AddDenyEveryone (server);
  84. bool unauthorized = false;
  85. using (NamedPipeClientStream client = CreateNamedClient (false, name)) {
  86. try {
  87. client.Connect (1000);
  88. } catch (UnauthorizedAccessException) {
  89. unauthorized = true;
  90. }
  91. }
  92. Assert.AreEqual (addDenyEveryone, unauthorized);
  93. }
  94. }
  95. [Test]
  96. [Category ("NotWorking")] // Async is completely broken on Mono Win32 pipes.
  97. public void NamedPipePermissionsActuallyWorkAsync ()
  98. {
  99. if (PlatformID.Win32NT != Environment.OSVersion.Platform) {
  100. Assert.Ignore ();
  101. }
  102. IAsyncResult waitForConnection;
  103. string name = @"Local\MonoTestPipeNPPAWA";
  104. using (NamedPipeServerStream server = CreateNamedServer (true, name, null,
  105. PipeAccessRights.ChangePermissions)) {
  106. // Test connecting to make sure our later test throwing is due to permissions.
  107. waitForConnection = server.BeginWaitForConnection (null, null);
  108. using (NamedPipeClientStream client = CreateNamedClient (true, name)) {
  109. client.Connect (1000);
  110. if (!waitForConnection.AsyncWaitHandle.WaitOne (1000)) {
  111. Assert.Fail ("No connection request received."); return;
  112. }
  113. server.EndWaitForConnection (waitForConnection);
  114. server.Disconnect ();
  115. }
  116. // Let's add a Deny for Everyone.
  117. AddDenyEveryone (server);
  118. // This Connect call should fail.
  119. waitForConnection = server.BeginWaitForConnection (null, null);
  120. bool unauthorized = false;
  121. using (NamedPipeClientStream client = CreateNamedClient (true, name)) {
  122. try {
  123. client.Connect (1000);
  124. } catch (UnauthorizedAccessException) {
  125. unauthorized = true;
  126. }
  127. }
  128. Assert.IsTrue (unauthorized, "Client was allowed to connect despite Deny ACE.");
  129. }
  130. }
  131. static void AddDenyEveryone (PipeStream stream)
  132. {
  133. PipeAccessRule rule; PipeSecurity security;
  134. AuthorizationRuleCollection inRules, outRules;
  135. // Let's add a Deny for Everyone.
  136. security = stream.GetAccessControl ();
  137. inRules = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
  138. Assert.AreNotEqual (0, inRules.Count);
  139. rule = new PipeAccessRule (new SecurityIdentifier ("WD"),
  140. PipeAccessRights.FullControl,
  141. AccessControlType.Deny);
  142. security.AddAccessRule (rule);
  143. stream.SetAccessControl (security);
  144. security = stream.GetAccessControl ();
  145. outRules = security.GetAccessRules (true, false, typeof (SecurityIdentifier));
  146. Assert.AreEqual (inRules.Count + 1, outRules.Count);
  147. }
  148. static NamedPipeClientStream CreateNamedClient (bool @async, string name)
  149. {
  150. return new NamedPipeClientStream (".", name,
  151. PipeDirection.InOut,
  152. @async ? PipeOptions.Asynchronous : PipeOptions.None);
  153. }
  154. static NamedPipeServerStream CreateNamedServer (bool @async, string name,
  155. PipeSecurity security,
  156. PipeAccessRights additionalRights)
  157. {
  158. return new NamedPipeServerStream (name,
  159. PipeDirection.InOut, 1,
  160. PipeTransmissionMode.Byte,
  161. @async ? PipeOptions.Asynchronous : PipeOptions.None,
  162. 512, 512, security,
  163. HandleInheritability.None,
  164. additionalRights);
  165. }
  166. }
  167. }