Народ. Уже в который раз я выкладываю исходники некоторых своих разработак. Мож комунить понадобится в дальнейшем Короче это простенькая программа которая создает цепочку socks5 прокси. Работает кое как. Но всеже работает. Сильно не обращайте на его кривизну и недоделки, т.к. писался он мною давно. Хотя отсутсвует поддержка работы с DNS именами и только частичная реализация RFC. Но этого уже достаточно для того чтобы понять как самому работать серез SOCKS5. Пока что там реализовано тока: 1) многопоточность 2) SOCKS5 connect 3) обычная аутентификация. Вот исходник дельфяный. Сори что почти нет коментов, просто и так понятно будет если взять RFC Code: program Tunnel; {$APPTYPE CONSOLE} uses Windows,winsock2; type proxy=record ip:string; port:word; login:string; password:string; end; tsocks_query_method=record VER,LEN,MTD:byte; end; tsocks_reply_method=record VER,MTD:byte; end; tsocks_query=record VER,CMD,RSV,ATYP:byte; ip:array[0..3] of byte; port:array[0..1] of byte; reserv:array[0..65536] of byte; end; tsocks_reply=record VER,REP,RSV,ATYP:byte; ip:array[0..3] of byte; port:array[0..1] of byte; end; tsocks_pass=record VER,ULEN:byte; UNAME:array of char; PLEN:byte; PASSWD:array of char; end; var ts1,ts2:tsocket; WSData:TWSAData; f:textfile; s:string; proxy_mas:array of proxy; proxy_count:integer=0; csocket,lsocket:tsocket; laddr,caddr:sockaddr_in; thid:dword; size_caddr:integer; ID:integer; function StrToInt(const s:string):integer; var i:integer; begin Val(s,result,i); end; function IntTostr(i:integer):string; begin str(i,result); end; function fileexists(s:string):boolean; var FindData:TWin32FindData; Handle:integer; begin Handle:=FindFirstFile(PChar(s),FindData); if Handle<0 then result:=false else result:=true; end; function GetErrorText(err:integer):string; begin case err of $1:result:='SOCKS-server error'; $2:result:='Connect forbidden'; $3:result:='Network is not accessible'; $4:result:='Host is not accessible'; $5:result:='Refusal in connection'; $6:result:='TTL timeout'; $7:result:='Command not support'; $8:result:='Address type not support'; -1,$9..$FF:result:='Unknown error'; -2:result:='Socks-server RFC error'; -3:result:='Socks-server requires authorized'; -4:result:='Login or Password incorrect'; end; end; function GetProxy(s:string):proxy; begin while pos(' ',s)<>0 do delete(s,pos(' ',s),1); result.ip:=copy(s,1,pos(':',s)-1); delete(s,1,pos(':',s)); result.port:=strtoint(copy(s,1,pos(':',s)-1)); delete(s,1,pos(':',s)); result.login:=copy(s,1,pos(':',s)-1); delete(s,1,pos(':',s)); result.password:=s; end; function ConnectToProxy(ip:string;port:word;login,password:string;sock:tsocket):integer; var sqm:tsocks_query_method; srm:tsocks_reply_method; sq:tsocks_query; sr:tsocks_reply; sp:array[0..512] of char; s:string; auth:boolean; x:integer; begin if (login<>'') and (password<>'') then auth:=true else auth:=false; result:=-1; sqm.VER:=$05; sqm.LEN:=$01; if auth=true then sqm.MTD:=$2 else sqm.MTD:=$00; send(sock,sqm,3,0); recv(sock,srm,2,0); if srm.VER<>$05 then begin result:=-2; exit; end; if auth=true then begin if srm.MTD<>$2 then begin result:=-3; exit; end; end else begin if srm.MTD<>$0 then begin result:=-3; exit; end; end; if auth=true then begin s:=#01+chr(length(login))+login+chr(length(password))+password; for x:=0 to length(s)-1 do sp[x]:=s[x+1]; send(sock,sp,length(s),0); recv(sock,srm,sizeof(srm),0); if srm.VER<>$01 then begin result:=-2; exit; end; if srm.MTD<>00 then begin result:=-4; exit; end; end; sq.VER:=$05; sq.CMD:=$01; sq.RSV:=$00; sq.ATYP:=$01; s:=ip; sq.ip[0]:=strtoint(copy(s,1,pos('.',s)-1)); delete(s,1,pos('.',s)); sq.ip[1]:=strtoint(copy(s,1,pos('.',s)-1)); delete(s,1,pos('.',s)); sq.ip[2]:=strtoint(copy(s,1,pos('.',s)-1)); delete(s,1,pos('.',s)); sq.ip[3]:=strtoint(s); sq.port[0]:=port div 256; sq.port[1]:=port-sq.port[0]*256; send(sock,sq,10,0); recv(sock,sr,sizeof(sr),0); if sr.VER<>$05 then begin result:=-2; exit; end; result:=sr.REP; end; procedure client(sock:tsocket);stdcall; var mysock,proxy_sock:tsocket; caddr:sockaddr_in; sqm:tsocks_query_method; srm:tsocks_reply_method; sq:tsocks_query; sr:tsocks_reply; ip:string; buf:array[0..65535] of char; buf_len:integer; thid:dword; Myid:integer; x:integer; r:integer; procedure reads; var read_sock,write_sock:tsocket; buf:array[0..65535] of char; buf_len:integer; begin read_sock:=ts1; write_sock:=ts2; repeat buf_len:=recv(read_sock,buf,sizeof(buf),0); send(write_sock,buf,buf_len,0); until buf_len<=0; closesocket(read_sock); closesocket(write_sock); end; begin inc(id); MyID:=id; writeln('[+] Client ID #',myid); mysock:=sock; recv(mysock,sqm,3,0); if sqm.VER<>$5 then begin writeln('[-] ID #',myid,' Client RFC error'); closesocket(mysock); exit; end; if sqm.LEN<>$1 then // если длинна !=1 begin writeln('[-] ID #',myid,' Client RFC error'); closesocket(mysock); exit; end; if sqm.MTD<>$0 then // если просит аутентификацию begin srm.VER:=$5; srm.MTD:=$FF; writeln('[-] ID #',myid,' Client requires authorized'); send(mysock,srm,2,0); // послать данные closesocket(mysock); // закрыть соединение exit; end; srm.VER:=$5; srm.MTD:=$0; send(mysock,srm,2,0); // послать данные recv(mysock,sq,sizeof(sq),0); if sq.VER<>$5 then begin writeln('[-] ID #',myid,' Client RFC error'); closesocket(mysock); // закрыть соединение exit; end; if sq.CMD<>$1 then begin sr.VER:=$5; sr.REP:=$2; sr.RSV:=$0; sr.ATYP:=sq.ATYP; writeln('[-] ID #',myid,' Client command not support'); send(mysock,sr,sizeof(sr),0); // послать данные closesocket(mysock); // закрыть соединение exit; end; if sq.ATYP<>$1 then begin sr.VER:=$5; sr.REP:=$8; sr.RSV:=$0; sr.ATYP:=sq.ATYP; writeln('[-] ID #',myid,' Client address type not support'); send(mysock,sr,sizeof(sr),0); // послать данные closesocket(mysock); // закрыть соединение exit; end; proxy_sock:=socket(AF_INET, SOCK_STREAM, 0); caddr.sin_family:=AF_INET; caddr.sin_port:=htons(proxy_mas[0].port); caddr.sin_addr.s_addr:=inet_addr(Pansichar(proxy_mas[0].ip)); if connect(proxy_sock,@caddr,sizeof(caddr))=-1 then begin sr.VER:=$5; sr.REP:=$4; sr.RSV:=$0; sr.ATYP:=sq.ATYP; writeln('[-] ID #',myid,' Not Connect to first proxy'); send(mysock,sr,sizeof(sr),0); // послать данные closesocket(mysock); // закрыть соединение exit; end; for x:=1 to proxy_count-1 do begin r:=ConnectToProxy(proxy_mas[x].ip,proxy_mas[x].port,proxy_mas[x-1].Login,proxy_mas[x-1].password,proxy_sock); if r<>0 then begin sr.VER:=$5; sr.REP:=$4; sr.RSV:=$0; sr.ATYP:=sq.ATYP; writeln('[-] ID #',myid,' Proxy ',x,':',GetErrorText(r)); send(mysock,sr,sizeof(sr),0); // послать данные closesocket(proxy_sock); // закрыть соединение closesocket(mysock); // закрыть соединение exit; end; end; ip:=inttostr(sq.ip[0])+'.'+inttostr(sq.ip[1])+'.'+inttostr(sq.ip[2])+'.'+inttostr(sq.ip[3]); r:=ConnectToProxy(ip,sq.port[0]*256+sq.port[1],proxy_mas[proxy_count-1].Login,proxy_mas[proxy_count-1].password,proxy_sock); if r<>0 then begin sr.VER:=$5; sr.REP:=$4; sr.RSV:=$0; sr.ATYP:=sq.ATYP; writeln('[-] ID #',myid,' Proxy ',proxy_count,':',GetErrorText(r)); send(mysock,sr,sizeof(sr),0); // послать данные closesocket(proxy_sock); // закрыть соединение closesocket(mysock); // закрыть соединение exit; end; writeln('[+] ID #',myid,' Tunnel is constructed'); sr.VER:=$5; sr.REP:=$0; sr.RSV:=$0; sr.ATYP:=sq.ATYP; ts1:=proxy_sock; ts2:=mysock; ThID:=CreateThread(nil, 0, @reads,nil, 0, ThID); // установка потока send(mysock,sr,sizeof(sr),0); // послать данные repeat buf_len:=recv(mysock,buf,sizeof(buf),0); send(proxy_sock,buf,buf_len,0); until buf_len<=0; windows.TerminateThread(ThID,0); writeln('[+] ID #',myid,' Client disconnect'); closesocket(proxy_sock); closesocket(mysock); end; begin if paramstr(1)='' then begin writeln('SocksTunnel (C) SLESH 2006 ([email protected])'); writeln('USAGE: Tunnel.exe [proxy_list_file]'); exit; end; if not fileexists(paramstr(1)) then begin writeln('[-] FILE: ',paramstr(1),' not found'); exit; end; assignfile(f,paramstr(1)); reset(f); while not eof(f) do begin readln(f,s); if length(s)>8 then begin inc(proxy_count); setlength(proxy_mas,proxy_count); proxy_mas[proxy_count-1]:=GetProxy(s); end; end; closefile(f); if proxy_count=0 then begin writeln('[-] PROXY LIST EMPTY'); exit; end; writeln('[+] LOAD ',proxy_count,' PROXY'); size_caddr:=sizeof(caddr); if WSAStartup($202, WSData)=-1 then begin writeln('[-] WSAStartup'); exit; end; lsocket:=socket(AF_INET, SOCK_STREAM, 0); laddr.sin_family:=AF_INET; laddr.sin_port:=htons(1080); laddr.sin_addr.s_addr:=INADDR_ANY; if bind(lsocket,@laddr, sizeof(laddr))<>0 then begin writeln('[-] Bind'); exit; end; if listen(lsocket, $100)<>0 then begin writeln('[-] Listen'); exit; end; writeln('[+] Waiting connection'); while 1=1 do begin csocket:=accept(lsocket,caddr,size_caddr); writeln('[+] Client connected. IP=',inet_ntoa(caddr.sin_addr)); CreateThread(nil, 0, @Client, pointer(csocket), 0, ThID); // установка потока end; end.
Мне, как новичку в кодинге, очень интересна данная тема. Усовершенствуй код и все будет просто отлично.