0

POP3 を使用して Gmail アカウントからメールを取得する Perl スクリプトを作成しました。少し前に、スクリプトが壊れてしまいました。これは、Gmail が POP3 を使用する際に SSL または TLS 接続を要求し始めたためだと思われます。

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 証明書は役に立たない」ということですか?

4

1 に答える 1

1

失敗する理由はいくつか考えられますが、Net::POP3->new 内に Debug => 1 を追加すると役立ちます。以下の理由が考えられます。

  • サーバーは STLS コマンドをサポートしていません。この場合、Debug フラグを指定して実行するとエラー メッセージが表示されますが、$pop->message を出力することもできます。
  • サーバーは STLS をサポートしていますが、SSL ハンドシェークは失敗します。この場合、$IO::Socket::SSL::SSL_ERROR 変数で詳細を確認できます。ハンドシェイクが失敗する典型的な例
    • 証明書の CA が不明です (たとえば、Mozilla::CA が提供する CA ストアにありません)。これは通常、個人のサーバー、または企業や大学内のサーバーに当てはまります。多くの場合、パブリック CA を使用して証明書に署名したり、自己署名証明書を使用したりすることさえありません。
    • 共有暗号が見つかりません。これは、MD5 を行うのが好きな古いサーバーの場合に当てはまります。IO::Socket::SSL または OpenSSL の最近のバージョンでは、これらの安全でない暗号がデフォルトで無効になっています。

これで問題が解決しない場合は、デバッグからの出力を投稿し、$IO::Socket::SSL::DEBUG=10 も設定してください。

Steffen (Net::SSLGlue::POP3 の作成者、IO::Socket::SSL の現在の開発者)

于 2014-01-17T19:22:07.357 に答える