Socks5ConnectorTest_Connect_NoAuthentication_ConnectionSucceeded.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. using Microsoft.VisualStudio.TestTools.UnitTesting;
  2. using Moq;
  3. using Renci.SshNet.Common;
  4. using Renci.SshNet.Tests.Common;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Net;
  9. using System.Net.Sockets;
  10. using System.Threading;
  11. namespace Renci.SshNet.Tests.Classes.Connection
  12. {
  13. [TestClass]
  14. public class Socks5Connector_Connect_NoAuthentication_Succeed : Socks5ConnectorTestBase
  15. {
  16. private ConnectionInfo _connectionInfo;
  17. private AsyncSocketListener _proxyServer;
  18. private Socket _clientSocket;
  19. private List<byte> _bytesReceivedByProxy;
  20. private Socket _actual;
  21. protected override void SetupData()
  22. {
  23. base.SetupData();
  24. _connectionInfo = CreateConnectionInfo(new string('a', 255), new string('b', 255));
  25. _connectionInfo.Timeout = TimeSpan.FromMilliseconds(100);
  26. _bytesReceivedByProxy = new List<byte>();
  27. _clientSocket = SocketFactory.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  28. _proxyServer = new AsyncSocketListener(new IPEndPoint(IPAddress.Loopback, _connectionInfo.ProxyPort));
  29. _proxyServer.BytesReceived += (bytesReceived, socket) =>
  30. {
  31. _bytesReceivedByProxy.AddRange(bytesReceived);
  32. if (_bytesReceivedByProxy.Count == 4)
  33. {
  34. // We received the greeting
  35. _ = socket.Send(new byte[]
  36. {
  37. // SOCKS version
  38. 0x05,
  39. // Require no authentication
  40. 0x00
  41. });
  42. }
  43. else if (_bytesReceivedByProxy.Count == 4 + (1 + 1 + 1 + 1 + 4 + 2))
  44. {
  45. // We received the connection request
  46. _ = socket.Send(new byte[]
  47. {
  48. // SOCKS version
  49. 0x05,
  50. // Connection successful
  51. 0x00,
  52. // Reserved byte
  53. 0x00,
  54. });
  55. // Send server bound address
  56. _ = socket.Send(new byte[]
  57. {
  58. // IPv6
  59. 0x04,
  60. // IP address
  61. 0x01,
  62. 0x02,
  63. 0x12,
  64. 0x41,
  65. 0x31,
  66. 0x02,
  67. 0x42,
  68. 0x41,
  69. 0x71,
  70. 0x02,
  71. 0x32,
  72. 0x81,
  73. 0x01,
  74. 0x52,
  75. 0x12,
  76. 0x91,
  77. // Port
  78. 0x0f,
  79. 0x1b,
  80. });
  81. // Send extra byte to allow us to verify that connector did not consume too much
  82. _ = socket.Send(new byte[]
  83. {
  84. 0xff
  85. });
  86. }
  87. };
  88. _proxyServer.Start();
  89. }
  90. protected override void SetupMocks()
  91. {
  92. _ = SocketFactoryMock.Setup(p => p.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
  93. .Returns(_clientSocket);
  94. }
  95. protected override void TearDown()
  96. {
  97. base.TearDown();
  98. _proxyServer?.Dispose();
  99. if (_clientSocket != null)
  100. {
  101. _clientSocket.Shutdown(SocketShutdown.Both);
  102. _clientSocket.Dispose();
  103. }
  104. }
  105. protected override void Act()
  106. {
  107. _actual = Connector.Connect(_connectionInfo);
  108. // Give some time to process all messages
  109. Thread.Sleep(200);
  110. }
  111. [TestMethod]
  112. public void ConnectShouldHaveReturnedSocketCreatedUsingSocketFactory()
  113. {
  114. Assert.IsNotNull(_actual);
  115. Assert.AreSame(_clientSocket, _actual);
  116. }
  117. [TestMethod]
  118. public void ClientSocketShouldBeConnected()
  119. {
  120. Assert.IsTrue(_clientSocket.Connected);
  121. }
  122. [TestMethod]
  123. public void ProxyShouldHaveReceivedExpectedSocksRequest()
  124. {
  125. var expectedSocksRequest = new byte[]
  126. {
  127. //
  128. // Client greeting
  129. //
  130. // SOCKS version
  131. 0x05,
  132. // Number of authentication methods supported
  133. 0x02,
  134. // No authentication
  135. 0x00,
  136. // Username/password
  137. 0x02,
  138. //
  139. // Client connection request
  140. //
  141. // SOCKS version
  142. 0x05,
  143. // Establish a TCP/IP stream connection
  144. 0x01,
  145. // Reserved
  146. 0x00,
  147. // Destination address type (IPv4)
  148. 0x01,
  149. // Destination address (IPv4)
  150. 0x7f,
  151. 0x00,
  152. 0x00,
  153. 0x01,
  154. // Destination port
  155. 0x03,
  156. 0x09
  157. };
  158. var errorText = string.Format("Expected:{0}{1}{0}but was:{0}{2}",
  159. Environment.NewLine,
  160. PacketDump.Create(expectedSocksRequest, 2),
  161. PacketDump.Create(_bytesReceivedByProxy, 2));
  162. Assert.IsTrue(expectedSocksRequest.SequenceEqual(_bytesReceivedByProxy), errorText);
  163. }
  164. [TestMethod]
  165. public void OnlySocksResponseShouldHaveBeenConsumed()
  166. {
  167. var buffer = new byte[1];
  168. var bytesRead = _clientSocket.Receive(buffer);
  169. Assert.AreEqual(1, bytesRead);
  170. Assert.AreEqual(0xff, buffer[0]);
  171. }
  172. [TestMethod]
  173. public void CreateOnSocketFactoryShouldHaveBeenInvokedOnce()
  174. {
  175. SocketFactoryMock.Verify(p => p.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp),
  176. Times.Once());
  177. }
  178. }
  179. }