如何使用Perl通过仅支持基于证书的身份验证的中继发送邮件

时间:2011-04-09 20:15:47

标签: perl email authentication certificate

我一直在使用Email::Sender Email::Sender::Transport::SMTP::TLS使用启用了STARTTLS的中继发送电子邮件。最近,中继已更改为使用X.509证书进行身份验证。但是我注意到Email::Sender::Transport::SMTP::TLS没有选择指向我的证书。 Net::SMTP::TLS所基于的Email::Sender::Transport::SMTP::TLS也不是。{1}}。

有人可以提出解决方案吗?另一个模块可能允许我使用证书进行身份验证。

谢谢

2 个答案:

答案 0 :(得分:3)

检查依赖关系树:Email::Sender::Transport::SMTP::TLS ==> Net::SMTP::TLS::ButMaintained ==> IO::Socket::SSL ==> Net::SSLeay

IO::Socket::SSLNet::SSLeay都支持X.509客户端证书。因此,应增强Net::SMTP::TLS::ButMaintainedEmail::Sender::Transport::SMTP::TLS以支持客户端证书。正确的方法是更新两个模块以允许SSL_key|SSL_key_fileSSL_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和Password参数保留为空白。

祝你好运!

答案 1 :(得分:1)

为了完整起见,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;

主机必须与证书中的主题完全匹配,否则将无法验证。

我假设您的系统信任中继服务器的证书颁发机构,否则您也需要修复它。