开发者

How to add authentication to a socks5 proxy server?

开发者 https://www.devze.com 2023-03-06 18:38 出处:网络
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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号