c++ - 如何向 socks5 代理服务器添加身份验证?

标签 c++ sockets authentication proxy winsock

我正在尝试使用我在谷歌搜索中发现的代码构建一个 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 之后,我可以知道是否正在发送 auth(0x1 不是 auth,0x2 是 auth)。

现在,我如何读取发送的用户名和密码?

我尝试嗅探网络,但没有显示任何有用信息。

最佳答案

SOCKS5 协议(protocol)在 RFC 1928 中定义. RFC 1929 中定义了 0x02 用户/密码身份验证方法.摘录:

   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)。客户端可能支持多种身份验证方法。

关于c++ - 如何向 socks5 代理服务器添加身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6054092/

相关文章:

c++ - 回调例程未被触发

c++ - 短路评估对我来说安全吗?

javascript - 为什么 http-auth 不能与 express.static 中间件一起使用?

jquery - 使用 JQuery 发布到 ASP.NET MVC [Authenticate] 包装的操作

c# - 在 ASP.net MVC 单页应用程序中删除身份验证

c++ - 读取多个文件

c++ - 通用继承和重载运算符 +

python - 更改已运行的服务器的套接字端口(python)

c# - 为什么 System.Net.Sockets.Socket.AcceptAsync 在长时间不活动后完成 ConnectionReset?

C Socket/Client fork(),共享结构体内存