socks.cs
上传用户:szltgg
上传日期:2019-05-16
资源大小:604k
文件大小:10k
源码类别:

Telnet服务器

开发平台:

C#

  1. /*
  2. * Copyright (c) 2005 Poderosa Project, All Rights Reserved.
  3. * $Id: socks.cs,v 1.2 2005/04/20 08:45:46 okajima Exp $
  4. */
  5. using System;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using System.Diagnostics;
  9. using System.IO;
  10. using System.Net;
  11. using System.Net.Sockets;
  12. namespace Poderosa.Communication
  13. {
  14. public class Socks {
  15. private int _version;
  16. private string _serverName;
  17. private short _serverPort;
  18. private string _account;
  19. private string _password;
  20. private string _destName;       //_destName, _destAddress偼偳偪傜偐偺傒巊梡
  21. private string _excludingNetworks;
  22. private IPAddress _destAddress;
  23. private short  _destPort;
  24. public Socks() {
  25. _version = 5;
  26. }
  27. public int Version {
  28. get {
  29. return _version;
  30. }
  31. set {
  32. if(value!=5 && value!=4) throw new IOException("Wrong SOCKS version");
  33. _version = value;
  34. }
  35. }
  36. public string Account {
  37. get {
  38. return _account;
  39. }
  40. set {
  41. _account = value;
  42. }
  43. }
  44. public string Password {
  45. get {
  46. return _password;
  47. }
  48. set {
  49. _password = value;
  50. }
  51. }
  52. public string DestName {
  53. get {
  54. return _destName;
  55. }
  56. set {
  57. _destName = value;
  58. }
  59. }
  60. public IPAddress DestAddress {
  61. get {
  62. return _destAddress;
  63. }
  64. set {
  65. _destAddress = value;
  66. }
  67. }
  68. public short DestPort {
  69. get {
  70. return _destPort;
  71. }
  72. set {
  73. _destPort = value;
  74. }
  75. }
  76. public string ServerName {
  77. get {
  78. return _serverName;
  79. }
  80. set {
  81. _serverName = value;
  82. }
  83. }
  84. public short ServerPort {
  85. get {
  86. return _serverPort;
  87. }
  88. set {
  89. _serverPort = value;
  90. }
  91. }
  92. public string ExcludingNetworks {
  93. get {
  94. return _excludingNetworks;
  95. }
  96. set {
  97. _excludingNetworks = value;
  98. }
  99. }
  100. public void Connect(Socket s) {
  101. if(_version==4)
  102. ConnectBySocks4(s);
  103. else
  104. ConnectBySocks5(s);
  105. }  
  106. private void ConnectBySocks4(Socket s) {
  107. MemoryStream u = new MemoryStream();
  108. BinaryWriter wr = new BinaryWriter(u);
  109. wr.Write((byte)4);
  110. wr.Write((byte)1);
  111. wr.Write(IPAddress.HostToNetworkOrder(_destPort));
  112. if(_destAddress==null) { //host偑巜掕偝傟偨
  113. //埲壓偱傛偄偲巚偭偨偑丄偳偆傕摦偐側偄丅僾儘僩僐儖4a偲偄偆傗偮偑僒億乕僩偝傟偰偄側偄偺偐丠
  114. throw new IOException("The address is not specified.");
  115. /*
  116. wr.Write(IPAddress.HostToNetworkOrder(1));
  117. wr.Write(Encoding.ASCII.GetBytes(_account));
  118. wr.Write((byte)0); //null char
  119. wr.Write(Encoding.ASCII.GetBytes(_destName));
  120. wr.Write((byte)0);
  121. */
  122. }
  123. else {
  124. wr.Write(_destAddress.GetAddressBytes());
  125. wr.Write(Encoding.ASCII.GetBytes(_account));
  126. wr.Write((byte)0); //null char
  127. }
  128. wr.Close();
  129. byte[] payload = u.ToArray();
  130. s.Send(payload, 0, payload.Length, SocketFlags.None);
  131. byte[] response = new byte[8];
  132. s.Receive(response, 0, response.Length, SocketFlags.None);
  133. if(response[1]!=90)
  134. throw new IOException("SOCKS authentication failed.");
  135. /*
  136. #define SOCKS4_REP_SUCCEEDED 90  rquest granted (succeeded) 
  137. #define SOCKS4_REP_REJECTED 91  request rejected or failed
  138. #define SOCKS4_REP_IDENT_FAIL 92  cannot connect identd 
  139. #define SOCKS4_REP_USERID 93 user id not matched 
  140. */
  141. }
  142. private void ConnectBySocks5(Socket s) {
  143. byte[] first = new byte[] { 5,2,0,2 };
  144. s.Send(first, 0, 4, SocketFlags.None);
  145. //s.WriteByte((byte)5);
  146. //s.WriteByte((byte)2);
  147. //s.WriteByte((byte)0); //no auth
  148. //s.WriteByte((byte)2); //user/pass
  149. byte[] response = new byte[4];
  150. int r = s.Receive(response, 0, 2, SocketFlags.None);
  151. //Debug.WriteLine("[0] len="+r+" res="+response[1]);
  152. if(r!=2) throw new IOException("Failed to communicate with the SOCKS server.");
  153. if(response[0]!=5) throw new IOException(String.Format("The SOCKS server specified an unsupported authentication method [{0}].", response[0]));
  154. if(response[1]==0) {
  155. ; //no auth
  156. }
  157. else if(response[1]==2) {
  158. Sock5Auth(s);
  159. }
  160. else
  161. throw new IOException(String.Format("The SOCKS server specified an unsupported authentication method [{0}].", response[1]));
  162. MemoryStream u = new MemoryStream();
  163. BinaryWriter wr = new BinaryWriter(u);
  164. wr.Write((byte)5);
  165. wr.Write((byte)1); //command
  166. wr.Write((byte)0);
  167. if(_destAddress==null) {
  168. wr.Write((byte)3);
  169. wr.Write((byte)_destName.Length);
  170. wr.Write(Encoding.ASCII.GetBytes(_destName));
  171. }
  172. else {
  173. wr.Write((byte)1);
  174. wr.Write(_destAddress.GetAddressBytes());
  175. }
  176. wr.Write(IPAddress.HostToNetworkOrder(_destPort));
  177. wr.Close();
  178. byte[] payload = u.ToArray();
  179. s.Send(payload, 0, payload.Length, SocketFlags.None);
  180. r = s.Receive(response, 0, 4, SocketFlags.None);
  181. if(response[1]!=0)
  182. throw new IOException("Failed to communicate with the SOCKS server." + GetSocks5ErrorMessage(response[1]));
  183. //read addr and port
  184. if(response[3]==3) {
  185. byte[] t = new byte[1];
  186. s.Receive(t, 0, 1, SocketFlags.None);
  187. byte[] t2 = new byte[t[0]];
  188. s.Receive(t2, 0, t2.Length, SocketFlags.None);
  189. }
  190. else if(response[3]==1) {
  191. byte[] t = new byte[6];
  192. s.Receive(t, 0, 6, SocketFlags.None);
  193. }
  194. else
  195. throw new IOException("unexpected destination addr type " + response[3]);
  196. }
  197. private void Sock5Auth(Socket s) {
  198. MemoryStream u = new MemoryStream();
  199. u.WriteByte(1);
  200. byte[] t = Encoding.ASCII.GetBytes(_account);
  201. u.WriteByte((byte)t.Length);
  202. u.Write(t, 0, t.Length);
  203. t = Encoding.ASCII.GetBytes(_password);
  204. u.WriteByte((byte)t.Length);
  205. u.Write(t, 0, t.Length);
  206. byte[] payload = u.ToArray();
  207. s.Send(payload, 0, payload.Length, SocketFlags.None);
  208. byte[] response = new byte[2];
  209. int r = s.Receive(response, 0, 2, SocketFlags.None);
  210. if(r!=2 || response[1]!=0)
  211. throw new IOException("SOCKS authentication failed.");
  212. }
  213. private static string GetSocks5ErrorMessage(byte code) {
  214. /*
  215.              o  X'01' general SOCKS server failure
  216.              o  X'02' connection not allowed by ruleset
  217.              o  X'03' Network unreachable
  218.              o  X'04' Host unreachable
  219.              o  X'05' Connection refused
  220.              o  X'06' TTL expired
  221.              o  X'07' Command not supported
  222.              o  X'08' Address type not supported
  223.              o  X'09' to X'FF' unassigned
  224.  */
  225. switch(code) {
  226. case 1:
  227. return "SOCKS server error";
  228. case 2:
  229. return "The connection is not allowed.";
  230. case 3:
  231. return "Failed to reach the destination network.";
  232. case 4:
  233. return "Failed to reach the destination host.";
  234. case 5:
  235. return "The access is denied.";
  236. case 6:
  237. return "TTL is disposed.";
  238. case 7:
  239. return "The SOCKS command is not supported.";
  240. case 8:
  241. return "The type of address is not supported.";
  242. default:
  243. return String.Format("Unknown Code {0}", code);
  244. }
  245. }
  246. /*
  247. public static void Test() {
  248. TcpClient tcp = new TcpClient();
  249. tcp.Connect("akamatsu", 1080);
  250. Socks s = new Socks();
  251. s.Version = 5;
  252. s.DestName = "ume";
  253. //s.DestAddress = IPAddress.Parse("192.168.10.23");
  254. s.DestPort = 23;
  255. s.Account = "okajima";
  256. s.Password = "okajima";
  257. s.Connect(tcp.GetStream());
  258. }
  259. */
  260. }
  261. //V4/V6偦傟偧傟侾偮偺傾僪儗僗傪帩偪丄乽椉懳墳丄偨偩偟椉曽巊偊傞偲偒偼V6桪愭乿偲偄偆惈幙傪傕偮傛偆偵偡傞
  262. public class IPAddressSet {
  263. private IPAddress _v4Address;
  264. private IPAddress _v6Address;
  265. public IPAddressSet(string host) {
  266. //IPAddress[] t = Dns.GetHostByName(host).AddressList;
  267.             IPAddress[] t = Dns.GetHostEntry(host).AddressList;
  268. foreach(IPAddress a in t) {
  269. if(a.AddressFamily==AddressFamily.InterNetwork && _v4Address==null) _v4Address = a;
  270. else if(a.AddressFamily==AddressFamily.InterNetworkV6 && _v6Address==null) _v6Address = a;
  271. }
  272. }
  273. public IPAddressSet(IPAddress a) {
  274. if(a.AddressFamily==AddressFamily.InterNetwork) _v4Address = a;
  275. else if(a.AddressFamily==AddressFamily.InterNetworkV6) _v6Address = a;
  276. }
  277. public IPAddressSet(IPAddress v4, IPAddress v6) {
  278. _v4Address = v4;
  279. _v6Address = v6;
  280. }
  281. public IPAddress Primary {
  282. get {
  283. return _v6Address!=null? _v6Address : _v4Address;
  284. }
  285. }
  286. public IPAddress Secondary {
  287. get {
  288. return _v6Address!=null? _v4Address : null;
  289. }
  290. }
  291. }
  292. public class NetUtil {
  293. public static Socket ConnectTCPSocket(IPAddressSet addr, int port) {
  294. IPAddress primary = addr.Primary;
  295. if(primary==null) return null;
  296. Socket s = new Socket(primary.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  297. try {
  298. s.Connect(new IPEndPoint(primary, port));
  299. return s;
  300. }
  301. catch(Exception ex) {
  302. IPAddress secondary = addr.Secondary;
  303. if(secondary==null) throw ex;
  304. s = new Socket(secondary.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  305. s.Connect(new IPEndPoint(secondary, port));
  306. return s;
  307. }
  308. }
  309. public static bool IsNetworkAddress(string netaddress) {
  310. try {
  311. Regex re = new Regex("([\dA-Fa-f\.\:]+)/\d+");
  312. Match m = re.Match(netaddress);
  313. if(m.Length!=netaddress.Length || m.Index!=0) return false;
  314. //偐偭偙偑IP傾僪儗僗側傜OK
  315. string a = m.Groups[1].Value;
  316. IPAddress.Parse(a);
  317. return true;
  318. }
  319. catch(Exception) {
  320. return false;
  321. }
  322. }
  323. public static bool NetAddressIncludesIPAddress(string netaddress, IPAddress target) {
  324. int slash = netaddress.IndexOf('/');
  325. int bits = Int32.Parse(netaddress.Substring(slash+1));
  326. IPAddress net = IPAddress.Parse(netaddress.Substring(0, slash));
  327. if(net.AddressFamily!=target.AddressFamily) return false;
  328. byte[] bnet = net.GetAddressBytes();
  329. byte[] btarget = target.GetAddressBytes();
  330. Debug.Assert(bnet.Length==btarget.Length);
  331. for(int i=0; i<bnet.Length; i++) {
  332. byte b1 = bnet[i];
  333. byte b2 = btarget[i];
  334. if(bits<=0)
  335. return true;
  336. else if(bits>=8) {
  337. if(b1!=b2) return false;
  338. }
  339. else {
  340. b1 >>= (8 - bits);
  341. b2 >>= (8 - bits);
  342. if(b1!=b2) return false;
  343. }
  344. bits -= 8;
  345. }
  346. return true;
  347. }
  348. }
  349. }