използвайте NET::SMTP SSL/TLS със SOCKS

Имам известна реализация на свързване, свързване към SOCKS и свързване към SMTP сървър чрез SOCKS. Как мога да използвам тази връзка с SSL/TLS NET::SMTP? Този въпрос не ми помага, защото SSL ръкостискането не може да започне.

DEBUG: .../IO/Socket/SSL.pm:683: waiting for fd to become ready: SSL wants a read first
DEBUG: .../IO/Socket/SSL.pm:693: handshake failed because socket did not became ready

Ето реализация на свързване към отдалечен сървър чрез прокси:

sub connect {
    my ($ip, $port, $is_ssl, $pid, $server) = @_;
    if (defined $socket) {
        my ($packed_cmd, $buffer, @data, %response);
        $packed_cmd = pack("C4Nn", 0x05, 0x01, 0x00, 0x01, $ip, $port);
        $socket->send($packed_cmd);
        if (defined $socket->recv($buffer, 1024)) {
            @data = unpack("C4 L S", $buffer);
            $response{'version'} = $data[0];
            $response{'result'} = $data[1];
            $response{'reg'} = $data[2];
            $response{'type'} = $data[3];
            $response{'ip'} = $data[4];
            $response{'port'} = $data[5];
            $socket->blocking(0);
            if ($is_ssl) {
                &debug(3, $pid, "Try start SSL handshake with [$server]\n");
                IO::Socket::SSL->start_SSL($socket, SSL_version => 'SSLv23', SSL_ca_file => SSL_CA_FILE) or &debug(3, $pid, "Cannot start SSL handshake! $@\n") and return 0; 
                &debug(3, $pid, "SSL handshake done!\n");
            }
            # TODO: Make TLS support
            return 1;
        }
    }
    &debug(3, $pid, "Cannot connect to [$server:$port] through socks server [$socks_name:$socks_server]\n");
    return 0;
}

Завържете ЧОРАПИ

sub bind_socks {
    my ($pid) = @_;
    my ($method, $packed_cmd, $buffer, @data, %response);
    $socket = IO::Socket::INET->new(
        PeerAddr => $socks_server,
        PeerPort => $socks_port,
        Proto => 'tcp',
        Timeout  => SOCKS5_CONNECT_TIMEOUT
    ) or &debug(3, $pid, "Cannot connect to the socks server [$socks_server] $@\n") and return 0;
    &debug(3, $pid, "Connected to the socks server [$socks_name:$socks_server]\n");
    $socket->blocking(1);
    if ($socks_username && $socks_password) {
        $method = 0x02;
    } else {
        $method = 0x00;
    }
    $packed_cmd = pack("C3", 0x05, 0x01, $method);
    $socket->send($packed_cmd);
    if (defined $socket->recv($buffer, 1024)) {
        @data = unpack("C2", $buffer);
        $response{'version'} = $data[0];
        $response{'method'} = $data[1];
        if ((defined $response{'version'}) && (defined $response{'method'}) && ($response{'version'} eq 5) && ($response{'method'} eq $method)) {
            if ($method == 2) {
                $packed_cmd = pack("CC", 0x01, length($socks_username)) . $socks_username . pack("C", length($socks_password)) . $socks_password;
                $socket->send($packed_cmd);
                if (defined $socket->recv($buffer, 1024)) {
                    @data = unpack("C2", $buffer);
                    $response{'version'} = $data[0];
                    $response{'status'} = $data[1];
                    return 1;
                }
            } else {
                return 1;
            }
        } else {
            &debug(3, $pid, "Cannot authenticate on socks server [$socks_name:$socks_server]\n");
            return 0;
        }
    }
    &debug(3, $pid, "Cannot authenticate on socks server [$socks_name:$socks_server]\n");
    return 0;
}

person Kostiuk Aleksandr    schedule 04.03.2015    source източник
comment
Вероятно трябва да покажете повече код тук - т.е. частта от вашия скрипт, която прави настройката на връзката SOCKS (файлов дескриптор и т.н.). Може би нещо като IO::Socket::Socks::Wrapper би помогнало?   -  person G. Cito    schedule 04.03.2015
comment
Добавям реализация на подвързване на чорапи. Вече виждам този модул, но все още не мога да разбера как да използвам установена връзка. И не искам промяна на реализацията на socks, защото вече работи с IMAP.   -  person Kostiuk Aleksandr    schedule 04.03.2015


Отговори (2)


Ако сте добре с IMAP вместо SMTP, това може да помогне, но вероятно не е това, което търсите:

sub login() {

  ## Connect to the IMAP server via SSL
  my $socket = IO::Socket::SSL->new(PeerAddr => 'imap.gmail.com',PeerPort => 993);
  if(!$socket) {
    # handle
  }

  ## Build up a client attached to the SSL socket.
  ## Login is automatic as usual when we provide User and Password
  my $imap = Mail::IMAPClient->new(Socket   => $socket,
                                   User     => $username,
                                   Password => $password,);
  if(!$imap) {
    # handle
  }

  if(!$imap->IsAuthenticated() && ...) {
    # handle
  }

  ## good to go
  my @folders = $imap->folders();
  ...
}
person gfunk    schedule 11.03.2015
comment
IMAP вместо SMTP? Протоколи за напълно различни цели. - person Kostiuk Aleksandr; 12.03.2015

Ето е моят бета код за използване на SMTP чрез socks прокси. SSL работи правилно с всички сървъри, тествани от мен. С TLS все още понякога има проблеми, вероятно нещо не според RFC.

person Kostiuk Aleksandr    schedule 12.03.2015