Socks5ConnectorTest_Connect_UserNamePasswordAuthentication_ConnectionSucceeded.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Text;
  7. using System.Threading;
  8. using Microsoft.VisualStudio.TestTools.UnitTesting;
  9. using Moq;
  10. using Renci.SshNet.Common;
  11. using Renci.SshNet.Tests.Common;
  12. namespace Renci.SshNet.Tests.Classes.Connection
  13. {
  14. [TestClass]
  15. public class Socks5ConnectorTest_Connect_UserNamePasswordAuthentication_ConnectionSucceeded : Socks5ConnectorTestBase
  16. {
  17. private ConnectionInfo _connectionInfo;
  18. private AsyncSocketListener _proxyServer;
  19. private Socket _clientSocket;
  20. private List<byte> _bytesReceivedByProxy;
  21. private Socket _actual;
  22. protected override void SetupData()
  23. {
  24. base.SetupData();
  25. _connectionInfo = CreateConnectionInfo(GenerateRandomString(0, 255), GenerateRandomString(0, 255));
  26. _connectionInfo.Timeout = TimeSpan.FromMilliseconds(100);
  27. _bytesReceivedByProxy = new List<byte>();
  28. _clientSocket = SocketFactory.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  29. _proxyServer = new AsyncSocketListener(new IPEndPoint(IPAddress.Loopback, _connectionInfo.ProxyPort));
  30. _proxyServer.BytesReceived += (bytesReceived, socket) =>
  31. {
  32. _bytesReceivedByProxy.AddRange(bytesReceived);
  33. if (_bytesReceivedByProxy.Count == 4)
  34. {
  35. // We received the greeting
  36. _ = socket.Send(new byte[]
  37. {
  38. // SOCKS version
  39. 0x05,
  40. // Require username/password authentication
  41. 0x02
  42. });
  43. }
  44. else if (_bytesReceivedByProxy.Count == 4 + (1 + 1 + _connectionInfo.ProxyUsername.Length + 1 + _connectionInfo.ProxyPassword.Length))
  45. {
  46. // We received the username/password authentication request
  47. _ = socket.Send(new byte[]
  48. {
  49. // Authentication version
  50. 0x01,
  51. // Authentication successful
  52. 0x00
  53. });
  54. }
  55. else if (_bytesReceivedByProxy.Count == 4 + (1 + 1 + _connectionInfo.ProxyUsername.Length + 1 + _connectionInfo.ProxyPassword.Length) + (1 + 1 + 1 + 1 + 4 + 2))
  56. {
  57. // We received the connection request
  58. _ = socket.Send(new byte[]
  59. {
  60. // SOCKS version
  61. 0x05,
  62. // Connection successful
  63. 0x00,
  64. // Reserved byte
  65. 0x00,
  66. });
  67. // Send server bound address
  68. _ = socket.Send(new byte[]
  69. {
  70. // IPv4
  71. 0x01,
  72. // IP address
  73. 0x01,
  74. 0x02,
  75. 0x12,
  76. 0x41,
  77. // Port
  78. 0x01,
  79. 0x02,
  80. });
  81. // Send extra byte to allow us to verify that connector did not consume too much
  82. _ = socket.Send(new byte[]
  83. {
  84. 0xfe
  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 List<byte>();
  126. //
  127. // Client greeting
  128. //
  129. // SOCKS version
  130. expectedSocksRequest.Add(0x05);
  131. // Number of authentication methods supported
  132. expectedSocksRequest.Add(0x02);
  133. // No authentication
  134. expectedSocksRequest.Add(0x00);
  135. // Username/password
  136. expectedSocksRequest.Add(0x02);
  137. //
  138. // Username/password authentication request
  139. //
  140. // Version of the negotiation
  141. expectedSocksRequest.Add(0x01);
  142. // Length of the username
  143. expectedSocksRequest.Add((byte)_connectionInfo.ProxyUsername.Length);
  144. // Username
  145. expectedSocksRequest.AddRange(Encoding.ASCII.GetBytes(_connectionInfo.ProxyUsername));
  146. // Length of the password
  147. expectedSocksRequest.Add((byte)_connectionInfo.ProxyPassword.Length);
  148. // Password
  149. expectedSocksRequest.AddRange(Encoding.ASCII.GetBytes(_connectionInfo.ProxyPassword));
  150. //
  151. // Client connection request
  152. //
  153. // SOCKS version
  154. expectedSocksRequest.Add(0x05);
  155. // Establish a TCP/IP stream connection
  156. expectedSocksRequest.Add(0x01);
  157. // Reserved
  158. expectedSocksRequest.Add(0x00);
  159. // Destination address type (IPv4)
  160. expectedSocksRequest.Add(0x01);
  161. // Destination address (IPv4)
  162. expectedSocksRequest.Add(0x7f);
  163. expectedSocksRequest.Add(0x00);
  164. expectedSocksRequest.Add(0x00);
  165. expectedSocksRequest.Add(0x01);
  166. // Destination port
  167. expectedSocksRequest.Add(0x04);
  168. expectedSocksRequest.Add(0x05);
  169. var errorText = string.Format("Expected:{0}{1}{0}but was:{0}{2}",
  170. Environment.NewLine,
  171. PacketDump.Create(expectedSocksRequest, 2),
  172. PacketDump.Create(_bytesReceivedByProxy, 2));
  173. Assert.IsTrue(expectedSocksRequest.SequenceEqual(_bytesReceivedByProxy), errorText);
  174. }
  175. [TestMethod]
  176. public void OnlySocksResponseShouldHaveBeenConsumed()
  177. {
  178. var buffer = new byte[1];
  179. var bytesRead = _clientSocket.Receive(buffer);
  180. Assert.AreEqual(1, bytesRead);
  181. Assert.AreEqual(0xfe, buffer[0]);
  182. }
  183. [TestMethod]
  184. public void CreateOnSocketFactoryShouldHaveBeenInvokedOnce()
  185. {
  186. SocketFactoryMock.Verify(p => p.Create(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp),
  187. Times.Once());
  188. }
  189. }
  190. }