program SOCKS4MiniProxy;
{$APPTYPE CONSOLE}
uses
Windows,
Winsock;
type
TSOCKS4Header =
record
Version : Byte;
Command : Byte;
Port : Word;
IP : DWord;
UserID :
Array[0..63]
of Char;
end;
const
Size = $2000;
var
WSAData : TWSAData;
Server : TSocket;
AddrIn : TSockAddrIn;
Client, Host : TSocket;
cAddrIn, hAddrIn : TSockAddrIn;
AddrSize : Integer;
X : Integer;
Header : TSOCKS4Header;
Data :
Array[0..Size-1]
of Char;
DataStr :
String;
const
DefPort = 1080;
SockAddrInSize = SizeOf( TSockAddrIn );
procedure FilterStr(
var Str :
String);
var
i, j : integer;
begin
for i := 1
to Length( Str )
do
begin
j := Ord( Str[i] );
if ( j < 32 )
or ( j > 122 )
then
Str[i] := '
.';
end;
end;
function ConsoleCtrlHandler(dwCtrlType : DWord) : BOOL;
stdcall;
begin
closesocket( Server );
WSACleanup;
Result := True;
end;
begin
WSAStartup( $101, WSAData );
Server := socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
with AddrIn
do
begin
sin_family := AF_INET;
sin_port := htons( DefPort );
sin_addr.S_addr := INADDR_ANY;
end;
bind( Server, AddrIn, SockAddrInSize );
listen( Server, 0 );
X := 0;
ioctlsocket( Server, FIONBIO, X );
SetConsoleCtrlHandler( @ConsoleCtrlHandler, True );
while True
do
begin
AddrSize := SockAddrInSize;
Client := accept( Server, @cAddrIn, @AddrSize );
if Client <> INVALID_SOCKET
then
begin
FillChar( Header, SizeOf( TSOCKS4Header ), 0 );
// receive header
recv( Client, Header, SizeOf( TSOCKS4Header ), 0 );
if Header.Version = $04
then
begin
hAddrIn.sin_family := AF_INET;
hAddrIn.sin_port := Header.Port;
hAddrIn.sin_addr.S_addr := Header.IP;
Host := socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
Header.Version := 0;
if connect( Host, hAddrIn, SockAddrInSize ) = ERROR_SUCCESS
then
begin
Header.Command := $5A;
end else
Header.Command := $5B;
send( Client, Header, SizeOf( TSOCKS4Header ), 0 );
if Header.Command = $5A
then
begin // connection established
// now receive from client, send to host
Writeln( '
-- Connection established --' );
DataStr := '
';
repeat
X := recv( Client, Data[0], Size, 0 );
if X > 0
then
begin
DataStr := DataStr + Copy( Data, 1, X );
send( Host, Data[0], X, 0 );
end;
until X < Size;
Writeln( '
[CLIENT] received data' );
FilterStr( DataStr );
Writeln( DataStr );
// now receive from host, send to client
DataStr := '
';
repeat
X := recv( Host, Data[0], Size, 0 );
if X > 0
then
begin
DataStr := DataStr + Copy( Data, 1, X );
send( Client, Data[0], X, 0 );
end;
until X < Size;
Writeln( '
[HOST] received data' );
FilterStr( DataStr );
Writeln( DataStr );
Writeln( '
-- Connection closed --' );
end;
closesocket( Host );
end;
end;
end;
end.