Как добавить аутентификацию на прокси-сервер socks5? - PullRequest
0 голосов
/ 19 мая 2011

Я пытаюсь создать прокси-сервер socks5, используя найденные мной коды и настраивая их. Пока все работает нормально, но теперь я хочу добавить аутентификацию в socks5.

Это код, который обрабатывает запросы:

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 INVALID_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;
}

Я понял, что если я добавлю:

if(Buffer[0] != 0x02)
     return INVALID_SOCKET;

после первого sockRecv я могу знать, отправляется аутентификация или нет (0x1 не аутентификация, а 0x2 аутентификация).

Теперь, как я могу прочитать отправленное имя пользователя и пароль?

Я пытался понюхать сеть, но это не показало мне ничего хорошего.

1 Ответ

1 голос
/ 19 мая 2011

Протокол SOCKS5 определен в RFC 1928 .Метод аутентификации пользователя / пароля 0x02 определен в RFC 1929 .Выдержка:

   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.

На самом деле, это почти весь RFC, скопированный и вставленный.Это очень просто.

Кстати, «без аутентификации» - это метод 0x00.Метод 0x01 - это GSSAPI (см. RFC 1961 ).Клиент может поддерживать несколько методов аутентификации.

...