我编写了一个使用 POP3 从 Gmail 帐户检索邮件的 Perl 脚本。不久前,脚本损坏了,我怀疑是因为 Gmail 在使用 POP3 时开始要求 SSL 或 TLS 连接。
我找到了 this interesting post在 Mike B 的博客上,其中包含此示例代码:
#!/usr/bin/env perl
use strict;
use warnings;
use Net::SSLGlue::POP3;
use Mozilla::CA;
my $host = 'pop.aol.com';
my $login = 'myusername@aol.com';
my $pass = '4Radfsai8fsfd9sdf9sdf';
my $pop3 = Net::POP3->new( $host) || die "Can't connect to $host: $!";
$pop3->starttls(
SSL_verify_mode => 1,
SSL_ca_file => Mozilla::CA::SSL_ca_file(),
) || die "Can't perform starttls: $!";
my $messages = $pop3->login( $login, $pass )
|| die "Failed to authenticate login $login on $host: $!";
print "There are $messages messages on $host for $login.\n";
这是我的一部分代码(出于安全原因更改了一些细节):
use YAML;
use Net::SSLGlue::POP3;
use Mozilla::CA;
use Email::Find;
use Data::Dumper;
use LWP::Simple;
my $email_finder = Email::Find->new(\&process_email);
my $verbose = 1;
my $email_account = 'my.email@mydomain.net';
my $email_password = 'somepassword';
my $mail_server = "mail.mydomain.net";
print("\nStarted\n") if ($verbose);
$pop = Net::POP3->new($mail_server) || die("Could not log on to server.");
print(" - starttls using " . Mozilla::CA::SSL_ca_file() . "\n") if ($verbose);
$pop->starttls(
SSL_verify_mode => 1,
SSL_ca_file => Mozilla::CA::SSL_ca_file()
) || die "Can't perform starttls: $!";
我的问题是...
$pop->starttls(
SSL_verify_mode => 1,
SSL_ca_file => Mozilla::CA::SSL_ca_file()
) || die "Can't perform starttls: $!";
... 失败了,但我不知道为什么。有什么建议吗?
更新...
谢谢史蒂芬。我通过添加 Debug => 1 和输出 $IO::Socket::SSL::SSL_ERROR 更新了我的代码:
$pop = Net::POP3->new($mail_server, Debug => 1)
|| die("Could not log on to server.");
print(" - starttls using " . Mozilla::CA::SSL_ca_file() . "\n") if ($verbose);
$pop->starttls(
SSL_verify_mode => 1,
SSL_ca_file => Mozilla::CA::SSL_ca_file()
) || die "Can't perform starttls: $!\n" . $IO::Socket::SSL::SSL_ERROR;
现在的错误信息是:
Net::POP3>>> Net::POP3(2.29)
Net::POP3>>> Net::Cmd(2.29)
Net::POP3>>> Exporter(5.63)
Net::POP3>>> IO::Socket::INET(1.31)
Net::POP3>>> IO::Socket(1.31)
Net::POP3>>> IO::Handle(1.28)
Net::POP3=GLOB(0xb41980)<<< +OK Dovecot ready.
- starttls using /usr/local/share/perl/5.10.1/Mozilla/CA/cacert.pem
Net::POP3=GLOB(0xb41980)>>> STLS
Net::POP3=GLOB(0xb41980)<<< +OK Begin TLS negotiation now.
Can't perform starttls:
**SSL connect attempt failed with unknown error error:14090086:SSL
routines:SSL3_GET_SERVER_CERTIFICATE:certificate
verify failed at (my script) line 26.**
这基本上是在说,“Mozilla::CA 证书对你不起作用。”?
最佳答案
失败的原因可能有多种,如果您在 Net::POP3->new 中添加 Debug => 1 会有所帮助。 我可以想到以下原因:
- 服务器不支持 STLS 命令。在这种情况下,您会在使用 Debug 标志运行时看到一条错误消息,您也可以打印 $pop->message。
- 服务器支持 STLS,但 SSL 握手失败。在这种情况下,您将在 $IO::Socket::SSL::SSL_ERROR 变量中找到更多信息。握手可能失败的典型例子
- 证书的 CA 未知(例如,不在 Mozilla::CA 提供的 CA 存储中)。这通常是来自私有(private)、公司或大学内部的服务器的情况。他们通常不使用公共(public) CA 来签署他们的证书,甚至不使用自签名证书
- 找不到共享密码。对于喜欢执行 MD5 的旧服务器可能就是这种情况。 IO::Socket::SSL 或 OpenSSL 的最新版本默认禁用这些不安全的密码。
如果这没有帮助,请发布 Debug 的输出,也可以设置 $IO::Socket::SSL::DEBUG=10。
Steffen(Net::SSLGlue::POP3 的作者,IO::Socket::SSL 的现任开发者)
关于perl - 在 Perl 中使用 TLS 的 POP3 - 帮助启动 starttls 工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21193149/