SSL соединение через прокси SOCKS5 - PullRequest
0 голосов
/ 30 марта 2019

Я пытаюсь написать код C, чтобы открыть соединение SSL с удаленным сервером через прокси-сервер SOCKS5.

Я успешно открыл TCP-соединение с прокси-сервером SOCKS5. Однако я не знаю, как установить SSL-соединение с удаленным сервером (отличается от прокси-сервера).

// 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: ssl3_get_record: неправильный номер версии: ssl / record / ssl3_record.c: 332:

У меня два вопроса.

  1. Почему я получаю эту ошибку?
  2. где указать удаленный IP-адрес при установлении соединения SSL?

Обновление 4/2/2019

Код ниже предназначен для отправки запроса на подключение к прокси-серверу. Последний вызов CheckConnectivity () обнаружил, что соединение закрыто.

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.

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

1 Ответ

0 голосов
/ 30 марта 2019

Вам нужно только 1 соединение, вы к прокси.Вы указываете прокси, где он должен подключиться к следующему (вы этого не делаете!).Только в случае успешного подключения прокси-сервера у вас будет действительное соединение с целевым сервером.Только тогда вы можете отправить рукопожатие SSL / TLS, как если бы вы подключились к целевому серверу напрямую.

Я предлагаю вам прочитать RFC 1928 для протокола SOCKS v5.Вы отправляете запрос аутентификации и читаете его ответ, но не отправляете запрос Connect, а чтение является ответом, прежде чем пытаться использовать SSL / TLS.Вот почему рукопожатие терпит неудачу.Вы еще не подключены к целевому серверу.

...