ForwardedPortDynamic.NET.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.Threading;
  8. using Renci.SshNet.Channels;
  9. using Renci.SshNet.Common;
  10. namespace Renci.SshNet
  11. {
  12. public partial class ForwardedPortDynamic
  13. {
  14. private TcpListener _listener;
  15. partial void InternalStart()
  16. {
  17. // If port already started don't start it again
  18. if (this.IsStarted)
  19. return;
  20. var ip = IPAddress.Any;
  21. if (!string.IsNullOrEmpty(this.BoundHost))
  22. {
  23. ip = Dns.GetHostAddresses(this.BoundHost)[0];
  24. }
  25. var ep = new IPEndPoint(ip, (int)this.BoundPort);
  26. this._listener = new TcpListener(ep);
  27. this._listener.Start();
  28. this._listenerTaskCompleted = new ManualResetEvent(false);
  29. this.ExecuteThread(() =>
  30. {
  31. try
  32. {
  33. while (true)
  34. {
  35. var socket = this._listener.AcceptSocket();
  36. this.ExecuteThread(() =>
  37. {
  38. try
  39. {
  40. using (var channel = this.Session.CreateChannel<ChannelDirectTcpip>())
  41. {
  42. var version = new byte[1];
  43. socket.Receive(version);
  44. if (version[0] == 4)
  45. {
  46. this.HandleSocks4(socket, channel);
  47. }
  48. else if (version[0] == 5)
  49. {
  50. this.HandleSocks5(socket, channel);
  51. }
  52. else
  53. {
  54. throw new NotSupportedException(string.Format("SOCKS version {0} is not supported.", version));
  55. }
  56. channel.Bind();
  57. }
  58. }
  59. catch (Exception exp)
  60. {
  61. this.RaiseExceptionEvent(exp);
  62. }
  63. finally
  64. {
  65. socket.Close();
  66. }
  67. });
  68. }
  69. }
  70. catch (SocketException exp)
  71. {
  72. if (!(exp.SocketErrorCode == SocketError.Interrupted))
  73. {
  74. this.RaiseExceptionEvent(exp);
  75. }
  76. }
  77. catch (Exception exp)
  78. {
  79. this.RaiseExceptionEvent(exp);
  80. }
  81. finally
  82. {
  83. this._listenerTaskCompleted.Set();
  84. }
  85. });
  86. this.IsStarted = true;
  87. }
  88. partial void InternalStop()
  89. {
  90. // If port not started you cant stop it
  91. if (!this.IsStarted)
  92. return;
  93. this._listener.Stop();
  94. this._listenerTaskCompleted.WaitOne(this.Session.ConnectionInfo.Timeout);
  95. this._listenerTaskCompleted.Dispose();
  96. this._listenerTaskCompleted = null;
  97. this.IsStarted = false;
  98. }
  99. private void HandleSocks4(Socket socket, ChannelDirectTcpip channel)
  100. {
  101. using (var stream = new NetworkStream(socket))
  102. {
  103. var commandCode = stream.ReadByte();
  104. // TODO: See what need to be done depends on the code
  105. var portBuffer = new byte[2];
  106. stream.Read(portBuffer, 0, portBuffer.Length);
  107. var port = (uint)(portBuffer[0] * 256 + portBuffer[1]);
  108. var ipBuffer = new byte[4];
  109. stream.Read(ipBuffer, 0, ipBuffer.Length);
  110. var ipAddress = new IPAddress(ipBuffer);
  111. var username = ReadString(stream);
  112. var host = ipAddress.ToString();
  113. this.RaiseRequestReceived(host, port);
  114. channel.Open(host, port, socket);
  115. stream.WriteByte(0x00);
  116. if (channel.IsOpen)
  117. {
  118. stream.WriteByte(0x5a);
  119. }
  120. else
  121. {
  122. stream.WriteByte(0x5b);
  123. }
  124. stream.Write(portBuffer, 0, portBuffer.Length);
  125. stream.Write(ipBuffer, 0, ipBuffer.Length);
  126. }
  127. }
  128. private void HandleSocks5(Socket socket, ChannelDirectTcpip channel)
  129. {
  130. using (var stream = new NetworkStream(socket))
  131. {
  132. var authenticationMethodsCount = stream.ReadByte();
  133. var authenticationMethods = new byte[authenticationMethodsCount];
  134. stream.Read(authenticationMethods, 0, authenticationMethods.Length);
  135. stream.WriteByte(0x05);
  136. if (authenticationMethods.Min() == 0)
  137. {
  138. stream.WriteByte(0x00);
  139. }
  140. else
  141. {
  142. stream.WriteByte(0xFF);
  143. }
  144. var version = stream.ReadByte();
  145. if (version != 5)
  146. throw new ProxyException("SOCKS5: Version 5 is expected.");
  147. var commandCode = stream.ReadByte();
  148. if (stream.ReadByte() != 0)
  149. {
  150. throw new ProxyException("SOCKS5: 0 is expected.");
  151. }
  152. var addressType = stream.ReadByte();
  153. IPAddress ipAddress = null;
  154. byte[] addressBuffer = null;
  155. switch (addressType)
  156. {
  157. case 0x01:
  158. {
  159. addressBuffer = new byte[4];
  160. stream.Read(addressBuffer, 0, 4);
  161. ipAddress = new IPAddress(addressBuffer);
  162. }
  163. break;
  164. case 0x03:
  165. {
  166. var length = stream.ReadByte();
  167. addressBuffer = new byte[length];
  168. stream.Read(addressBuffer, 0, addressBuffer.Length);
  169. ipAddress = IPAddress.Parse(new Renci.SshNet.Common.ASCIIEncoding().GetString(addressBuffer));
  170. }
  171. break;
  172. case 0x04:
  173. {
  174. addressBuffer = new byte[16];
  175. stream.Read(addressBuffer, 0, 16);
  176. ipAddress = new IPAddress(addressBuffer);
  177. }
  178. break;
  179. default:
  180. throw new ProxyException(string.Format("SOCKS5: Address type '{0}' is not supported.", addressType));
  181. }
  182. var portBuffer = new byte[2];
  183. stream.Read(portBuffer, 0, portBuffer.Length);
  184. var port = (uint)(portBuffer[0] * 256 + portBuffer[1]);
  185. var host = ipAddress.ToString();
  186. this.RaiseRequestReceived(host, port);
  187. channel.Open(host, port, socket);
  188. stream.WriteByte(0x05);
  189. if (channel.IsOpen)
  190. {
  191. stream.WriteByte(0x00);
  192. }
  193. else
  194. {
  195. stream.WriteByte(0x01);
  196. }
  197. stream.WriteByte(0x00);
  198. var buffer = ipAddress.GetAddressBytes();
  199. if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
  200. {
  201. stream.WriteByte(0x01);
  202. }
  203. else if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
  204. {
  205. stream.WriteByte(0x04);
  206. }
  207. else
  208. {
  209. throw new NotSupportedException("Not supported address family.");
  210. }
  211. stream.Write(buffer, 0, buffer.Length);
  212. stream.Write(portBuffer, 0, portBuffer.Length);
  213. }
  214. }
  215. private static string ReadString(NetworkStream stream)
  216. {
  217. StringBuilder text = new StringBuilder();
  218. var aa = (char)stream.ReadByte();
  219. while (aa != 0)
  220. {
  221. text.Append(aa);
  222. aa = (char)stream.ReadByte();
  223. }
  224. return text.ToString();
  225. }
  226. }
  227. }