How to add authentication to a socks5 proxy server?
I am trying to build a socks5 proxy server using codes I found googling and customizing them. Everything works fine so far but now I want to add authentication to the socks5.
This is the code that handle the requests:
SOCKET socks5Handler( SOCKET Client, char* Buffer )
{
SOCKS5AUTH sAuth;
char *Host = NULL;
SOCKET Target = INVALID_SOCKET;
ulong Ip = 0;
ushort Port = 0;
byte Command = 0,
Type = 0;
int i = 0;
if( sockRecv(Client, Buffer, 1) < 0 )
return INVALID_SOCKET;
if( sockRecv(Client, Buffer, Buffer[0]) < 0 )
return INVALID_SOCKET;
Buffer[0] = 0x05;
Buffer[1] = 0x00;
send( Client, Buffer, 2, 0 );
if( sockRecv(Client, Buffer, 4) < 0 )
return INVALID_SOCKET;
Command = Buffer[1];
Type = Buffer[3];
if( Type == 0x01 ) {
if( sockRecv(Client, Buffer, 4) < 0 )
return INVALID_SOCKET;
Ip = *((ulong*)Buffer);
} else if( Type == 0x03 ) {
if( sockRecv(Client, Buffer, 1) < 0 )
return INVALID_SOCKET;
i = Buffer[0];
if( sockRecv(Client, Buffer, i) < 0 )
return INVALID_SOCKET;
Buffer[i] = 0;
Host = Buffer;
} else
return INVALID_SOCKET;
if( sockRecv(Client, (char*)&Port, 2) < 0)
return INVALID_SOCKET;
if( Command == 0x01 ) {
if( Host )
Ip = sock_resolve( Host );
Target = sock_connect( sock_create(), Ip, htons(Port) );
if( Target == INVALID_SOCKET )
return INVALID_SOCKET;
} else
return INVAL开发者_高级运维ID_SOCKET;
Buffer[0] = 0x05;
Buffer[1] = 0x00;
Buffer[2] = 0x00;
Buffer[3] = 0x01;
*((ulong* )(Buffer + 4)) = Ip;
*((ushort*)(Buffer + 8)) = Port;
send( Client, Buffer, 10, 0 );
return Target;
}
BOOL sockRecv( SOCKET Sock, char* Buffer, int Length )
{
int r = 0;
while( Length )
{
r = recv( Sock, Buffer, Length, 0 );
if( r <= 0 )
return FALSE;
Buffer += r;
Length -= r;
}
return TRUE;
}
I figured out that if I add:
if(Buffer[0] != 0x02)
return INVALID_SOCKET;
after the first sockRecv, I can know if auth is being sent or not (0x1 is not auth and 0x2 is auth).
Now, how could I read the username and password sent?
I tried sniffing the network but that didn't show me anything good.
The SOCKS5 protocol is defined in RFC 1928. The 0x02 user/password authentication method is defined in RFC 1929. An excerpt:
Once the SOCKS V5 server has started, and the client has selected the Username/Password Authentication protocol, the Username/Password subnegotiation begins. This begins with the client producing a Username/Password request: +----+------+----------+------+----------+ |VER | ULEN | UNAME | PLEN | PASSWD | +----+------+----------+------+----------+ | 1 | 1 | 1 to 255 | 1 | 1 to 255 | +----+------+----------+------+----------+ The VER field contains the current version of the subnegotiation, which is X'01'. The ULEN field contains the length of the UNAME field that follows. The UNAME field contains the username as known to the source operating system. The PLEN field contains the length of the PASSWD field that follows. The PASSWD field contains the password association with the given UNAME. The server verifies the supplied UNAME and PASSWD, and sends the following response: +----+--------+ |VER | STATUS | +----+--------+ | 1 | 1 | +----+--------+ A STATUS field of X'00' indicates success. If the server returns a `failure' (STATUS value other than X'00') status, it MUST close the connection.
Actually, that's nearly the entire RFC copied and pasted. It's very simple.
By the way, "no authentication" is method 0x00. Method 0x01 is GSSAPI (see RFC 1961). A client may support multiple authentication methods.
精彩评论