Perl TLS SMTP发送在身份验证步骤失败

rla*_*ter 1 perl smtp smtp-auth

我正在尝试在 Debian buster 服务器上通过 Perl 使用经过身份验证的 SMTP 发送邮件。这是我的代码:

use strict ;
use warnings ;
use autodie ;
use Net::SMTP; # version 3.11
use Authen::SASL;

my $smtp_server = 'smtp.example.com' ;
my $principal   = 'myusername' ;

print "Password: ";
my $password = <STDIN>;
chomp($password);

my $from    = 'joeuser@example.com' ;
my $to      = 'joeuser@example.com' ;
my $subject = 'Test message' ;
my $body    = "The body of the e-mail message.";

my $mailer = Net::SMTP->new($smtp_server, 'SSL' => 1, 'Port' => 465, 'Debug' => 1);

if (!$mailer) { die $@ ; }

if (!$mailer->auth($principal, $password)) {
    warn "error authenticating; status is '" . $mailer->status() . "'\n";
    warn "error authenticating; message is '" . $mailer->message() . "'\n";
    exit 1;
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

Password: secretsecretsecret
Net::SMTP::_SSL>>> Net::SMTP::_SSL
Net::SMTP::_SSL>>>   IO::Socket::SSL(2.060)
Net::SMTP::_SSL>>>     IO::Socket::IP(0.39)
Net::SMTP::_SSL>>>       IO::Socket(1.39)
Net::SMTP::_SSL>>>         IO::Handle(1.39)
Net::SMTP::_SSL>>>           Exporter(5.73)
Net::SMTP::_SSL>>>   Net::SMTP(3.11)
Net::SMTP::_SSL>>>     Net::Cmd(3.11)
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 220 smtp.example.com ESMTP Postfix
Net::SMTP::_SSL=GLOB(0x562cc320f080)>>> EHLO localhost.localdomain
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 250-smtp.example.com
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 250-PIPELINING
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 250-SIZE 51200000
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 250-ETRN
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 250-AUTH PLAIN LOGIN GSSAPI
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 250-ENHANCEDSTATUSCODES
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 250-8BITMIME
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 250-DSN
Net::SMTP::_SSL=GLOB(0x562cc320f080)<<< 250 CHUNKING
error authenticating; status is '2'
error authenticating; message is 'smtp.example.com
PIPELINING
SIZE 51200000
ETRN
AUTH PLAIN LOGIN GSSAPI
ENHANCEDSTATUSCODES
8BITMIME
DSN
CHUNKING

'
Run Code Online (Sandbox Code Playgroud)

但是请注意,在同一台计算机上运行的以下 Python 代码有效

#!/usr/bin/python3                                                                                             
username    = 'joeuser'
principal   = 'myusername'
smtp_server = 'smtp.example.com'
  
import smtplib
from email.mime.text import MIMEText
from getpass import getpass

conn = smtplib.SMTP_SSL(smtp_server, 465)
password = getpass()
conn.login(principal, password)

usermail = username + '@example.com'
content="""\                                                                                                                        
Test message.                                                                                                                       
"""
msg = MIMEText(content, 'plain')
msg['Subject'] = 'Testing authenticated mail send using ' + principal
msg['From']    = usermail
conn.sendmail(usermail, usermail, msg.as_string())
Run Code Online (Sandbox Code Playgroud)

为什么 Perl 代码不起作用?这个Stackoverflow 问题没有帮助。(为什么不直接使用 Python 代码?所需的 Perl 代码是更大的 Perl 项目的一部分,所以我需要在 Perl 中发送电子邮件。)

Ste*_*ich 6

if (!$mailer->auth($principal, $password)) {
    die "error authenticating: $!" ;
}
Run Code Online (Sandbox Code Playgroud)

一般来说,$!当 Net::SMTP 返回错误时,查看不是调试问题的正确方法。相反,应检查状态消息

我有根据的猜测是 status 将返回 500 并且 message 将返回:

Need MIME::Base64 and Authen::SASL todo auth 
Run Code Online (Sandbox Code Playgroud)

这意味着您很可能没有安装进行身份验证所需的Authen::SASL。该模块只是 Net::SMTP 的一个可选先决条件,因为只有在进行身份验证时才需要它。另请参阅auth 方法的文档

尝试 SASL 身份验证。需要 Authen::SASL 模块