Как использовать Perl для отправки почты через ретранслятор, который поддерживает только аутентификацию на основе сертификатов - PullRequest
1 голос
/ 10 апреля 2011

Я использую Email::Sender с Email::Sender::Transport::SMTP::TLS для отправки электронной почты с использованием реле STARTTLS. Реле недавно изменилось на использование сертификатов X.509 для аутентификации. Однако я отмечаю, что Email::Sender::Transport::SMTP::TLS не может указать мой сертификат. Так же как и Net::SMTP::TLS, на котором основан Email::Sender::Transport::SMTP::TLS.

Может кто-нибудь предложить решение? Возможно, еще один модуль позволит мне пройти аутентификацию с использованием сертификата.

Спасибо

Ответы [ 2 ]

3 голосов
/ 11 апреля 2011

Проверка дерева зависимостей: Email::Sender::Transport::SMTP::TLS ==> Net::SMTP::TLS::ButMaintained ==> IO::Socket::SSL ==> Net::SSLeay

Оба IO::Socket::SSL и Net::SSLeay поддерживают сертификаты клиента X.509. Поэтому Net::SMTP::TLS::ButMaintained и Email::Sender::Transport::SMTP::TLS должны быть улучшены для поддержки клиентских сертификатов. Надлежащим образом следует обновить оба модуля, чтобы разрешить параметры SSL_key|SSL_key_file и SSL_cert|SSL_cert_file.

Вот быстрый грязный - вам нужно создать измененный Net::SMTP::TLS::ButMaintained и хранить его локально.

# modify the Net::SMTP::TLS::ButMaintained; 
# built a private version which have client certificates
sub starttls {
    my $me = shift;
    $me->_command("STARTTLS");
    my ( $num, $txt ) = $me->_response();
    if ( not $num == 220 ) {
        croak "Invalid response for STARTTLS: $num $txt\n";
    }
    if (
        not IO::Socket::SSL::socket_to_SSL(
            $me->{sock}, 
            SSL_version => "SSLv3 TLSv1", 
            ### private changes begin: append following two lines. 
            SSL_use_cert => 1,
            SSL_cert_file => "path_to/your/certificate_file.pem",
            SSL_key_file => "path_to/your/private_key_file.pem"
            ### private changes end:
        )
      )
    {
        croak "Couldn't start TLS: " . IO::Socket::SSL::errstr . "\n";
    }
    $me->hello();
}

Пожалуйста, оставьте параметр User and Password пустым.

Удачи!

1 голос
/ 20 ноября 2015

для полноты картины Net :: SMTP может сделать это, если IO :: Socket :: SSL доступен (не спрашивайте меня с тех пор, когда, но я знаю, что он работает с последними версиями обоих модулей).

Код:

use strict;
use warnings;
use Net::SMTP;

my $smtp = Net::SMTP->new(
    Host    => 'host.domain.tld',
    Hello   => 'hi there',
    Port    => 587,
    Timeout => 5,
    Debug   => 4,
);

$smtp->starttls(
    SSL_cert_file   => "/path/to/crt",
    SSL_key_file    => "/path/to/key",
);

$smtp->mail("user\+perl\@domain\.nl\n");
$smtp->to("user\@otherdomain\.tld\n");
$smtp->data;
$smtp->datasend("From: Your Name <user\@domain.tld>\n");
$smtp->datasend("To: Recipient <user\@otherdomain.tld>\n");
$smtp->datasend("Subject: certificate based relay testing\n");
$smtp->datasend("MIME-Version: 1.0\n");
$smtp->datasend("Content-Type: text/plain; charset=us-ascii\n");
$smtp->datasend("X-Mailer: Net::SMTP IO::Socket::SSL\n");
$smtp->datasend( "X-mydate: " . localtime() . "\n" );
$smtp->datasend("\n");
$smtp->datasend("testing again\n");
$smtp->dataend;
$smtp->quit;

Хост должен точно соответствовать теме в сертификате, иначе он не будет проверяться.

Я предполагаю, что ваша система доверяет центру сертификации сервера ретрансляции, в противном случаевам тоже нужно это исправить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...