私のプログラミング スキルはせいぜい中級で、Perl はあまり使ったことがありません。
受信メールから元の「送信元アドレス」(「エンベロープ送信元アドレス」ではない) を抽出しようとしています。
サーバー上の MailScanner ソフトウェアを通過する受信メールを解析します。私が書いた場合(MailScannerの組み込みメッセージオブジェクトを使用):
my($message) = @_;
MailScanner::Log::InfoLog("from address: @{$message->{headers}}");
次のログ エントリ (サニタイズ済み) を取得します。
Received: from [192.168.12.34] (port=56309 helo=theirserver.theirdomain.tld) by server.mydomain.tld with esmtp (Exim 4.86) (envelope-from <sender@theirdomain.tld>) id 1aG62o-0002ad-Hu for recipient@mydomain.tld; Mon, 04 Jan 2016 09:23:34 -0500 Received: from 00a657f7.theirserver.theirdomain.tld ([127.0.0.1]:8056 helo=theirserver.theirdomain.tld) by theirserver.theirdomain.tld with ESMTP id 00PA657MF7; for <recipient@mydomain.tld>; Mon, 4 Jan 2016 06:22:53 -0800 Date: Mon, 4 Jan 2016 06:22:53 -0800 To: <recipient@mydomain.tld> Message-ID: <70562391089443970564001376171645@theirserver.theirdomain.tld> From: "Sender" <sender@theirdomain.tld> Subject: test Content-Language: en-us MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: multipart/alternative; boundary="----=Part.960.1818.1451917373"
私が書いた場合(MailScannerの作者による提案に基づいて):
my($message) = @_;
my $from_address = grep /^From:\s+/i, @{$message->{headers}};
MailScanner::Log::InfoLog("from address after grep = $from_address ");
次のログ エントリが表示されます。
from address after grep = 0
その結果をどうするかわからないので、オンラインで見つけた MailScanner 互換スクリプトを介して Data::Dumper を使用してみましたが、次の結果が得られました。
> $VAR1 = bless( {
'nameinfected' => 0,
'otherinfected' => 0,
'disarmedtags' => [],
'othertypes' => {},
'file2entity' => {
'' => bless( {
'ME_Parts' => [
bless( {
'ME_Bodyhandle' => bless( {
'MB_Path' => '/var/spool/MailScanner/incoming/9365/1aG62o-0002ad-Hu/nmsg-9365-3.txt'
}, 'MIME::Body::File' ),
'ME_Parts' => [],
'mail_inet_head' => bless( {
'mail_hdr_foldlen' => 79,
'mail_hdr_modify' => 0,
'mail_hdr_list' => [
'Content-Transfer-Encoding: 8bit
',
'Content-Type: text/plain; charset="UTF-8"
'
],
'mail_hdr_hash' => {
'Content-Type' => [
\$VAR1->{'file2entity'}{''}{'ME_Parts'}[0]{'mail_inet_head'}{'mail_hdr_list'}[1]
],
'Content-Transfer-Encoding' => [
\$VAR1->{'file2entity'}{''}{'ME_Parts'}[0]{'mail_inet_head'}{'mail_hdr_list'}[0]
]
},
'mail_hdr_mail_from' => 'KEEP',
'mail_hdr_lengths' => {}
}, 'MIME::Head' )
}, 'MIME::Entity' ),
bless( {
'ME_Bodyhandle' => bless( {
'MB_Path' => '/var/spool/MailScanner/incoming/9365/1aG62o-0002ad-Hu/nmsg-9365-42.html'
}, 'MIME::Body::File' ),
'ME_Parts' => [],
'mail_inet_head' => bless( {
'mail_hdr_foldlen' => 79,
'mail_hdr_modify' => 0,
'mail_hdr_list' => [
'Content-Transfer-Encoding: 8bit
',
'Content-Type: text/html; charset="UTF-8"
'
],
'mail_hdr_hash' => {
'Content-Type' => [
\$VAR1->{'file2entity'}{''}{'ME_Parts'}[1]{'mail_inet_head'}{'mail_hdr_list'}[1]
],
'Content-Transfer-Encoding' => [
\$VAR1->{'file2entity'}{''}{'ME_Parts'}[1]{'mail_inet_head'}{'mail_hdr_list'}[0]
]
},
'mail_hdr_mail_from' => 'KEEP',
'mail_hdr_lengths' => {}
}, 'MIME::Head' )
}, 'MIME::Entity' )
],
'ME_Epilogue' => [
'
'
],
'ME_Preamble' => [],
'mail_inet_head' => bless( {
'mail_hdr_foldlen' => 79,
'mail_hdr_modify' => 0,
'mail_hdr_list' => [
'Received: from [192.168.12.34] (port=56309 helo=theirserver.theirdomain.tld)
by server.mydomain.tld with esmtp (Exim 4.86)
(envelope-from <sender@theirdomain.tld>)
id 1aG62o-0002ad-Hu
for recipient@mydomain.tld; Mon, 04 Jan 2016 09:23:34 -0500
',
'Received: from 00a657f7.theirserver.theirdomain.tld ([127.0.0.1]:8056 helo=theirserver.theirdomain.tld)
by theirserver.theirdomain.tld with ESMTP id 00PA657MF7;
for <recipient@mydomain.tld>; Mon, 4 Jan 2016 06:22:53 -0800
',
'Date: Mon, 4 Jan 2016 06:22:53 -0800
',
'To: <recipient@mydomain.tld>
',
'Message-ID: <70562391089443970564001376171645@theirserver.theirdomain.tld>
',
'From: "Sender" <sender@theirdomain.tld>
',
'Subject: Test
',
'Content-Language: en-us
',
'MIME-Version: 1.0
',
'Content-Transfer-Encoding: 8bit
',
'Content-Type: multipart/alternative;
boundary="----=Part.960.1818.1451917373"
'
],
等々。
そこで次に、mail_hdr_list を次のように解析してみます。
my($message) = @_;
MailScanner::Log::InfoLog("SpamWhitelist $msgid: mail_hdr_list @{$message->{headers}}[mail_hdr_list]");
そして、私はこの結果を得る:
Received: from server.theirdomain.tld ([192.168.165.54]:49620 helo=server.theirdomain.tld)
私は困惑しています。このオブジェクトから From: アドレスを取得する方法がわかりませんが、envelope-from アドレスは取得できません。
私のコードを書き直す助けがあれば大歓迎です。