Advertisement
Guest User

Untitled

a guest
May 25th, 2017
549
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 7.81 KB | None | 0 0
  1. unit uSocks5;
  2. {
  3. +-----------------------------------------------------------+
  4. |name:        uSocks5                                       |
  5. |description: etablishes a SOCKS5 server, supporting AUTH   |
  6. |Author:      Hamtaro aka CorVu5                            |
  7. |date:        16.10.09   / released: 24.10.09               |
  8. |History:     first try                                     |
  9. |ToDo:                                                      |
  10. |[*] Add support for Proxychains (!) & UDP (?)       |
  11. |[*] Add support for IPv6                            |
  12. +-----------------------------------------------------------+
  13. | This code can be changed or used without any restrictions |
  14. |    Leben heißt ein Bild malen, nicht eine Summe ziehen    |
  15. +-----------------------------------------------------------+
  16. }
  17. interface
  18. uses Windows, WinSock;
  19.  
  20. type
  21.   TSocks5Config = record
  22.     Port     : Dword;
  23.     UserName : String;
  24.     Password : String;
  25. end;
  26. type PSocks5Config = ^TSocks5Config;
  27. type
  28.   TSocks5MethodSel = record
  29.     Version  : Byte;
  30.     nMethods : Byte;
  31.     Methods : array[0..255] of Byte;
  32. end;
  33.  
  34. type TSocks5Request = record
  35.        ucVersion : byte;
  36.        ucCommand : byte;
  37.        ucRzv : byte;
  38.        ucAtyp : byte;
  39.        dwDestIp  : dword;
  40.        wDestPort : word;
  41. end;
  42.  
  43. function StartSocks5(conf : PSocks5Config) : Boolean; stdcall;
  44. var
  45.   config : TSocks5Config;
  46. implementation
  47. procedure SocksProc(sock : Cardinal); stdcall;
  48. var
  49.     m : TSocks5MethodSel;
  50.     req : TSocks5Request;
  51.     auth :array[0..600] of Byte;
  52.     buf  :array[0..500] of Byte;
  53.     buffer : array[0..4095] of Byte;//4kb
  54.     recv_len : Integer;
  55.     i : Integer;
  56.     recvsock : TSocket;
  57.     UserName, password : String;
  58.     tunneladdr_in : sockaddr_in;
  59.     tunneldomain : String;
  60.     tunnelsock : TSocket;
  61.     hostent : PHostEnt;
  62.     tv : Ttimeval;
  63.     fset : tfdset;
  64.     self_addr : sockaddr_in;
  65.     self_Len : Integer;
  66. begin
  67.   recvsock := sock;
  68.   if recv(recvsock,m,2,MSG_PEEK) > 0 then begin
  69.     if m.Version = 5 then begin     //it is socks5
  70.       recv(recvsock,m, 2 + m.nMethods,0); //request complete Header
  71.       for i := 0 to m.nMethods - 1 Do begin
  72.         if (m.Methods[i] = 2) then begin           //password auth
  73.           if (config.UserName = '') and (config.Password = '') then begin
  74.             m.nMethods := $00;
  75.             send(recvsock, m,2,0);
  76.             end else begin
  77.             m.nMethods := 2;
  78.             send(recvsock, m,2,0);
  79.             recv(recvsock, auth,SizeOf(auth),0);
  80.             if auth[0] = 1 Then begin
  81.               //get username
  82.               SetString(username,Pchar(@auth[2]),auth[1]);
  83.               //get password
  84.               SetString(password,Pchar(Cardinal(@auth) + 3 + auth[1]),auth[2 + auth[1]]);
  85.               if (config.UserName = UserName) and (config.Password = password) then begin   //auth successful!
  86.                 auth[1] := 0;
  87.                 send(recvsock,auth,2,0);
  88.               end else begin
  89.                 MessageBox(0,'auth fail','fffuuuuuuu-',0);
  90.                 auth[1] := $FF; //nothing but fail
  91.                 send(recvsock,auth,2,0);
  92.                 break;
  93.               end;
  94.             end;
  95.           end;
  96.         end else if (m.Methods[i] = 0) Then begin
  97.           if (config.password = '') and (config.UserName = '') Then begin
  98.             m.nMethods := 0;
  99.             send(recvsock,m,2,0);
  100.           end else begin
  101.             m.nMethods := $FF;
  102.             send(recvsock,m,2,0);
  103.             break;
  104.           end;
  105.         end else if i = m.nMethods then begin
  106.           m.nMethods := $FF;
  107.           send(recvsock,m,2,0);
  108.           Break;
  109.         end;
  110.         recv(recvsock, req, sizeof(Tsocks5Request), MSG_PEEK);
  111.         if  req.ucCommand = 1 then begin        //TCP Verbindung, ok
  112.           Zeromemory(@tunneladdr_in,sizeof(tunneladdr_in));
  113.           if req.ucAtyp = 1 Then begin  //ip4
  114.             recv(recvsock, req, sizeof(Tsocks5Request), 0);
  115.             tunneladdr_in.sin_port := req.wDestPort;
  116.             CopyMemory(@tunneladdr_in.sin_addr,@req.dwDestIp,sizeof(tunneladdr_in.sin_addr));
  117.           end else if req.ucAtyp = 3 Then begin //domain name
  118.             ZeroMemory(@buf,SizeOf(buf));
  119.             recv(recvsock,buf,7 + Byte(req.dwDestIp),0);
  120.             SetString(tunneldomain,PChar(Cardinal(@buf) + 5),Integer(Byte(req.dwDestIp)));
  121.             hostent := gethostbyname(PChar(tunneldomain));
  122.             PInteger(@tunneladdr_in.sin_addr.S_addr)^:=PInteger(HostEnt.h_addr^)^;
  123.             tunneladdr_in.sin_port := htons(Word(Pointer(Cardinal(@buf) + 6 + Byte(req.dwDestIp))^));
  124.           end; //todo: PIv6
  125.           tunneladdr_in.sin_family := AF_INET;
  126.           tunnelsock := socket(PF_INET, SOCK_STREAM, 0);
  127.           if connect(tunnelsock,tunneladdr_in,sizeof(tunneladdr_in)) = 0 Then begin//success!
  128.             req.ucCommand := 0;  //success
  129.           end else begin
  130.             req.ucCommand := 1; //General Failure reporting in
  131.           end;
  132.           req.ucVersion := 5;
  133.           req.ucRzv := 0;
  134.           req.ucAtyp := 1;
  135.           ZeroMemory(@self_addr,SizeOf(sockaddr_in));
  136.           self_Len := SizeOf(sockaddr_in);
  137.           getsockname(tunnelsock,self_addr,self_len);
  138.           CopyMemory(@req.dwDestIp,@self_addr.sin_addr,sizeof(self_addr.sin_addr));
  139.           req.wDestPort := self_addr.sin_port;
  140.           send(recvsock,req,10,0);
  141.           //now tunneling everything!
  142.           tv.tv_sec := 5;
  143.           while 1 =1 Do begin
  144.             //waiting for incoming data
  145.             FD_ZERO(fset);
  146.             FD_SET(recvsock,fset);
  147.             FD_SET(tunnelsock,fset);
  148.             if select(0,@fset,nil,nil,nil) <> SOCKET_ERROR Then begin
  149.               if FD_ISSET(tunnelsock,fset) THEN begin //data on the recvsock
  150.                 ZeroMemory(@buffer,sizeof(buffer));
  151. //                      MessageBoxa(0,'Data from the tunnelsock!','FF',0);
  152.                 recv_len := recv(tunnelsock, buffer,sizeof(buffer),0);
  153.                 if recv_len = SOCKET_ERROR Then break; //error?
  154. //                      messagebox(0,PChar('tunnel' + #13#10 + pchar(@buffer)),0,0);
  155.                 send(recvsock,buffer,recv_len,0);
  156.               end;
  157.               if FD_ISSET(recvsock,fset) THEN begin //data on the recvsock
  158.                 ZeroMemory(@buffer,sizeof(buffer));
  159. //                      MessageBoxa(0,'Data from the recvsock!','FF',0);
  160.                 recv_len := recv(recvsock, buffer,sizeof(buffer),0);
  161.                 if recv_len = SOCKET_ERROR Then break; //error?
  162. //                      messagebox(0,PChar('recv' + #13#10 + pchar(@buffer)),0,0);
  163.                 send(tunnelsock,buffer,recv_len,0);
  164.               end;
  165.             end;
  166.             Sleep(150); //zzZZzzZZZZzz
  167.           end;
  168.         end;
  169.         Break;
  170.       end;
  171.     end;
  172.   end;
  173. //  MessageBox(0,PChar('Error Code: ' + inttostr(WSAGetLastError)),'Error!',0);
  174.   closesocket(recvsock);
  175.   closesocket(tunnelsock);
  176. end;
  177.  
  178. function StartSocks5(conf : PSocks5Config) : Boolean; stdcall;
  179. var
  180.   wsaData : TWSAData;
  181.   sock    : TSOCKET;
  182.   sockaddr: SockAddr_in;
  183.   conn    : Integer;
  184.   client  : TSockAddr;
  185.   tid : Cardinal;
  186.   size : Integer;
  187. begin
  188.   result := 0;
  189.   Move(conf^,config,SizeOf(TSocks5Config));
  190.   WSAStartup($101, wsaData);
  191.   sock := socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  192.   ZeroMemory(@SockAddr, sizeof(SockAddr));
  193.   sockaddr.sin_family := AF_INET;
  194.   sockaddr.sin_port   := htons(config.Port);
  195.   sockaddr.sin_addr.S_addr   := INADDR_ANY;
  196.   if (bind  (sock  ,sockaddr,SizeOf(sockaddr)) = 0) AND
  197.      (listen(sock,SOMAXCONN)                   = 0) then begin
  198.       while 1 = 1 Do begin
  199.         size := SizeOf(client);
  200.         conn := accept(sock,@client,@size);
  201.         if conn <> SOCKET_ERROR then  begin
  202.           CreateThread(nil,0,@SocksProc,Pointer(conn),0,tid);
  203.         end;
  204.         Sleep(100);
  205.       end;
  206.   end;
  207.  
  208. end;
  209. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement