Advertisement
Draiget

socks5

Mar 7th, 2015
803
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.99 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Text;
  6.  
  7. namespace ZontWelg_Socks5UDP.Socks
  8. {
  9.     public class SocksError : Exception {
  10.         public SocksError(String parMessage) : base(parMessage) { }
  11.     }
  12.  
  13.     // Socks5 refrence: http://tools.ietf.org/pdf/rfc1928.pdf
  14.     public class SocksConnection {
  15.         private Socket tcp_sock;
  16.         private Socket udp_sock;
  17.  
  18.         private String prox_addr;
  19.         private ushort prox_port;
  20.  
  21.         private String remote_addr;
  22.         private ushort remote_port;
  23.  
  24.         private String sock_bnd_addr;
  25.         private ushort sock_bnd_port;
  26.  
  27.         #region Constants
  28.         public const int SOCKS5_VERSION = 0x05;
  29.  
  30.         public const int SOCKS5_NO_AUTHENTICATION_REQUIRED = 0x00;
  31.         public const int SOCKS5_GSSAPI = 0x01;
  32.         public const int SOCKS5_USERNAME_PASSWORD = 0x02;
  33.         public const int SOCKS5_IANA_ASSIGNED = 0x03;
  34.         public const int SOCKS5_RESERVED_FOR_PRIVATE_METHODS = 0x80;
  35.         public const int SOCKS5_NO_ACCEPTABLE_METHODS = 0xFF;
  36.  
  37.         public const int SOCKS5_CMD_CONNECT = 0x01;
  38.         public const int SOCKS5_CMD_BIND = 0x02;
  39.         public const int SOCKS5_CMD_UDP_ASSOCIATE = 0x03;
  40.  
  41.         public const int SOCKS5_ATYP_IPV4 = 0x01;
  42.         public const int SOCKS5_ATYP_DOMAIN = 0x02;
  43.         public const int SOCKS5_ATYP_IPV6 = 0x03;
  44.  
  45.         public const int SOCKS5_REPLY_SUCCSESS = 0x00;
  46.         public const int SOCKS5_REPLY_GENERAL_SOCKS_SRV_FAILURE = 0x01;
  47.         public const int SOCKS5_REPLY_CONN_NOT_ALLOWED_RULLSET = 0x02;
  48.         public const int SOCKS5_REPLY_NETWORK_UNRECHABLE = 0x03;
  49.         public const int SOCKS5_REPLY_HOST_UNRECHABLE = 0x04;
  50.         public const int SOCKS5_REPLY_CONN_REFUSED = 0x05;
  51.         public const int SOCKS5_REPLY_TTL_EXPIRED = 0x06;
  52.         public const int SOCKS5_REPLY_COMMAND_NOT_SUPPORTED = 0x07;
  53.         public const int SOCKS5_REPLY_ADDR_TYPE_NOT_SUPPORTED = 0x08;
  54.         public const int SOCKS5_REPLY_UNASSIGNED = 0xFF;
  55.         #endregion
  56.  
  57.         public static SocksConnection makeSocks5(string prox_addr, ushort prox_port, string dst_adr, ushort dst_port) {
  58.             SocksConnection conn = new SocksConnection();
  59.             conn.prox_addr = prox_addr;
  60.             conn.prox_port = prox_port;
  61.             conn.remote_addr = dst_adr;
  62.             conn.remote_port = dst_port;
  63.  
  64.             conn.tcp_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  65.             conn.tcp_sock.Connect(prox_addr, prox_port);
  66.  
  67.             // Sending auth method to socks5
  68.             /*
  69.              +----+----------+----------+
  70.              |VER | NMETHODS  | METHODS  |
  71.              +----+----------+----------+
  72.              | 1  | 1         | 1 to 255 |
  73.              +----+----------+----------+
  74.             */
  75.             byte[] auth_req = { 0x05, 0x01, 0x00 };
  76.             conn.tcp_sock.Send(auth_req);
  77.             byte[] receive_buff = new byte[2];
  78.             conn.tcp_sock.Receive(receive_buff);
  79.  
  80.             switch (receive_buff[1]) {
  81.                 case SOCKS5_NO_AUTHENTICATION_REQUIRED:
  82.                     // no socks5 auth need, can send udp commands after connection
  83.                     conn.UDPCommand(SOCKS5_CMD_UDP_ASSOCIATE);
  84.                     break;
  85.                 case SOCKS5_USERNAME_PASSWORD:
  86.                     // socks5 proxy need auth user
  87.                     break;
  88.                 case SOCKS5_NO_ACCEPTABLE_METHODS:
  89.                     // no acceptable methods
  90.                     throw new SocksError("There's no acceptable methods for socks5 connection.");
  91.             }
  92.             return conn;
  93.         }
  94.  
  95.         private void UDPCommand(int udp_command) {
  96.             /*
  97.             +----+-----+-------+------+----------+----------+
  98.             |VER | CMD  | RSV   | ATYP | DST.ADDR | DST.PORT |
  99.             +----+-----+-------+------+----------+----------+
  100.             | 1  | 1   | X’00’ | 1     | Variable | 2        |
  101.             +----+-----+-------+------+----------+----------+
  102.             */
  103.  
  104.             udp_sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
  105.             udp_sock.Bind(new IPEndPoint(IPAddress.Any, 0));
  106.  
  107.             int index = 0;
  108.             byte[] cmd = new byte[256];
  109.             cmd[index++] = SOCKS5_VERSION; //version
  110.             cmd[index++] = (byte)udp_command; //command
  111.             cmd[index++] = 0x00; //reserved
  112.  
  113.             // Dst address
  114.             IPAddress rem_addr = IPAddress.Parse(remote_addr);
  115.             if (rem_addr == null)
  116.                 throw new SocksError("Remote address is null, can't sent UDP command to socks5 proxy server.");
  117.  
  118.             switch (rem_addr.AddressFamily) {
  119.                 case AddressFamily.InterNetwork:
  120.                     cmd[index++] = SOCKS5_ATYP_IPV4; //ATYP
  121.                     break;
  122.                 case AddressFamily.InterNetworkV6:
  123.                     cmd[index++] = SOCKS5_ATYP_IPV6; //ATYP
  124.                     break;
  125.             }
  126.  
  127.             // Copy DST address to socks request
  128.             //byte[] addr_bytes = rem_addr.GetAddressBytes();
  129.             //for (int i = 0; i < addr_bytes.Length; i++) {
  130.             //    cmd[index++] = addr_bytes[i];
  131.             //}
  132.             cmd[index++] = 0x00;
  133.             cmd[index++] = 0x00;
  134.             cmd[index++] = 0x00;
  135.             cmd[index++] = 0x00;
  136.  
  137.             // Copy DST port to socks request
  138.             byte[] port_bytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)remote_port));
  139.             for (int i = 0; i < port_bytes.Length; i++) {
  140.                 cmd[index++] = port_bytes[i];
  141.             }
  142.  
  143.             tcp_sock.Send(cmd);
  144.             /*
  145.             +----+-----+-------+------+----------+----------+
  146.             |VER | REP | RSV   | ATYP  | BND.ADDR | BND.PORT |
  147.             +----+-----+-------+------+----------+----------+
  148.             | 1  | 1   | X’00’ | 1    | Variable  | 2        |
  149.             +----+-----+-------+------+----------+----------+
  150.              
  151.             o VER protocol version: X’05’
  152.             o REP Reply field:
  153.                 o X’00’ succeeded
  154.                 o X’01’ general SOCKS server failure
  155.                 o X’02’ connection not allowed by ruleset
  156.                 o X’03’ Network unreachable
  157.                 o X’04’ Host unreachable
  158.                 o X’05’ Connection refused
  159.                 o X’06’ TTL expired
  160.                 o X’07’ Command not supported
  161.                 o X’08’ Address type not supported
  162.                 o X’09’ to X’FF’ unassigned
  163.             o RSV RESERVED
  164.             o ATYP address type of following address
  165.                 o IP V4 address: X’01’
  166.                 o DOMAINNAME: X’03’
  167.                 o IP V6 address: X’04’
  168.             o BND.ADDR server bound address
  169.             o BND.PORT server bound port in network octet order
  170.             */
  171.             byte[] response = new byte[256];
  172.             tcp_sock.Receive(response);
  173.  
  174.             switch (response[1]) {
  175.                 case SOCKS5_REPLY_SUCCSESS:
  176.                     //TODO: good!
  177.                     break;
  178.                 case SOCKS5_REPLY_ADDR_TYPE_NOT_SUPPORTED:
  179.                     tcp_sock.Close();
  180.                     throw new SocksError("(COMMAND) Address type is not supported by socks5 server.");
  181.                 case SOCKS5_REPLY_COMMAND_NOT_SUPPORTED:
  182.                     tcp_sock.Close();
  183.                     throw new SocksError(string.Format("(COMMAND) Command '{0}' not supported by socks5 server.", udp_command));
  184.                 case SOCKS5_REPLY_CONN_NOT_ALLOWED_RULLSET:
  185.                     tcp_sock.Close();
  186.                     throw new SocksError("(COMMAND) Connection is not allowed by socks5 server ruleset.");
  187.                 case SOCKS5_REPLY_CONN_REFUSED:
  188.                     tcp_sock.Close();
  189.                     throw new SocksError("(COMMAND) Connection refused by socks5 server.");
  190.                 case SOCKS5_REPLY_GENERAL_SOCKS_SRV_FAILURE:
  191.                     tcp_sock.Close();
  192.                     throw new SocksError("(COMMAND) General socks failed on socks5 server.");
  193.                 case SOCKS5_REPLY_HOST_UNRECHABLE:
  194.                     tcp_sock.Close();
  195.                     throw new SocksError("(COMMAND) Remote host was unrechable, socks5 server can't connect.");
  196.                 case SOCKS5_REPLY_NETWORK_UNRECHABLE:
  197.                     tcp_sock.Close();
  198.                     throw new SocksError("(COMMAND) Socks5 server error, remote network unrechable.");
  199.                 case SOCKS5_REPLY_TTL_EXPIRED:
  200.                     tcp_sock.Close();
  201.                     throw new SocksError("(COMMAND) Connection failed, TTL was expired, retry connection.");
  202.                 case SOCKS5_REPLY_UNASSIGNED:
  203.                     tcp_sock.Close();
  204.                     throw new SocksError("(COMMAND) Unassigned reply 0xFF.");
  205.             }
  206.  
  207.             sock_bnd_addr = string.Format("{0}.{1}.{2}.{3}", response[4], response[5], response[6], response[7]);
  208.             if (response[4] == 0x00 && response[5] == 0x00 && response[6] == 0x00 && response[7] == 0x00) {
  209.                 sock_bnd_addr = prox_addr;
  210.             }
  211.             ushort bp = BitConverter.ToUInt16( response, 8 );
  212.             sock_bnd_port = (ushort)IPAddress.NetworkToHostOrder((short)bp);
  213.  
  214.             udp_sock.Connect(prox_addr, sock_bnd_port);
  215.         }
  216.  
  217.         public void SendBuffer(byte[] bytes) {
  218.             byte[] buffer = new byte[10 + bytes.Length];
  219.             makeDgramHeader().CopyTo(buffer, 0);
  220.             bytes.CopyTo(buffer, 10);
  221.             udp_sock.Send(buffer);
  222.         }
  223.  
  224.         private byte[] makeDgramHeader() {
  225.             /*
  226.             +----+------+------+----------+----------+----------+
  227.             |RSV | FRAG | ATYP  | DST.ADDR | DST.PORT | DATA     |
  228.             +----+------+------+----------+----------+----------+
  229.             | 2  | 1    | 1     | Variable | 2        | Variable |
  230.             +----+------+------+----------+----------+----------+
  231.            
  232.             o RSV Reserved X’0000’
  233.             o FRAG Current fragment number
  234.             o ATYP address type of following addresses:
  235.                 o IP V4 address: X’01’
  236.                 o DOMAINNAME: X’03’
  237.                 o IP V6 address: X’04’
  238.             o DST.ADDR desired destination address
  239.             o DST.PORT desired destination port
  240.             o DATA user data
  241.             */
  242.             byte[] header = new byte[10];
  243.             header[0] = 0x00;
  244.             header[1] = 0x00;
  245.             header[2] = 0x01;
  246.             header[3] = SOCKS5_ATYP_IPV4;
  247.  
  248.             IPAddress.Parse(remote_addr).GetAddressBytes().CopyTo(header, 4);
  249.             //header[4] = 0x00;
  250.             //header[5] = 0x00;
  251.             //header[6] = 0x00;
  252.             //header[7] = 0x00;
  253.             BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)remote_port)).CopyTo(header, 8);
  254.  
  255.             return header;
  256.         }
  257.     }
  258. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement