首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过SOCKS5代理的SSL连接

通过SOCKS5代理的SSL连接
EN

Stack Overflow用户
提问于 2019-03-30 19:41:29
回答 1查看 2.9K关注 0票数 0

我试图编写一个C代码,通过SOCKS5代理服务器打开与远程服务器的SSL连接。

我已经成功地打开了与SOCKS5代理服务器的tcp连接。但是,我不知道如何与远程服务器(不同于代理服务器)建立SSL连接。

代码语言:javascript
复制
// p->ai_addr has the SOCKS5 proxy address
m_sock_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
connect(m_sock_fd, p->ai_addr, p->ai_addrlen);

char socks5_request[256] = {0}, response[256] = {0};
sprintf(socks5_request, "\5\1\0");
send(m_sock_fd, socks5_request, 4, 0);
recv(m_sock_fd, response, 256, 0);

assert(response[0] == '\5' && response[1] == '\0'); // OK

m_ssl_ctx = SSL_CTX_new(SSLv23_client_method());
m_ssl = SSL_new(m_ssl_ctx);
SSL_set_fd(m_ssl, m_sock_fd);

SSL_connect(m_ssl); // returns -1

SSL_connect失败并给出了错误:1408F10B:ssl routines:ssl3_get_record:wrong版本号:ssl/routines:ssl3_get_record:wrong/ssl3_routines:ssl3_get_record:wrong.c:332:

我有两个问题。

  1. 我为什么要犯这个错误?
  2. 在进行SSL连接时,我应该在哪里指定远程IP地址?

更新4/2/2019

下面的代码用于将连接请求发送到代理服务器。对CheckConnectivity()的最后一次调用发现连接已关闭。

代码语言:javascript
复制
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("*.*.*.*");
addr.sin_port = htons(443);

SOCKSRequest connect_request;

// 5: protocol number, 1: connect, 0: reserved, 1: ipv4
connect_request.m_version = '\5';
connect_request.m_type = '\1';
connect_request.m_reserved = '\0';
connect_request.m_addr_type = '\1';

connect_request.m_ip = addr.sin_addr.s_addr;
connect_request.m_port = addr.sin_port;

CheckConnectivitiy();

if (!send(m_sock_fd, &connect_request, 4, 0))
    return 0;

CheckConnectivitiy();

if (!send(m_sock_fd, &connect_request.m_ip, sizeof(in_addr), 0))
    return 0;

CheckConnectivitiy();

if (!send(m_sock_fd, &connect_request.m_port, 2, 0))
    return 0;

CheckConnectivitiy();  // connection was closed by peer here!

CheckConnectivity的实现。

代码语言:javascript
复制
int CheckConnectivitiy() const
{
    int error = 0;
    socklen_t len = sizeof (error);
    int retval = getsockopt (m_sock_fd, SOL_SOCKET, SO_ERROR, &error, &len);

    if (retval != 0) 
    {
        /* there was a problem getting the error code */
        fprintf(stderr, "error getting socket error code: %s\n", strerror(retval));
        return 0;
    }

    if (error != 0) 
    {
        /* socket has a non zero error status */
        fprintf(stderr, "socket error: %s\n", strerror(error));
        return 0;
    }

    return 1;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-30 19:52:02

你只需要一个连接,你到代理。您可以告诉代理它应该连接到next (您没有这样做!)。只有当代理成功连接时,才会有到目标服务器的有效连接。只有这样,您才能发送SSL/TLS握手,就好像您已经直接连接到目标服务器一样。

我建议你阅读RFC 1928的SOCKS v5协议。您正在发送身份验证请求并读取其响应,但在尝试使用SSL/TLS之前,您不会发送Connect请求和读取是响应。这就是为什么握手失败的原因。您尚未连接到目标服务器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55435087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档