メールの誤送信を防止するには下記のような手段が考えられる。
- サーバ側で対応する。
Postfixのsmtpd_client_restrictionsなど。 - クライアント側で対応する。
Thunderbirdのcheck and sendなど。
https://addons.mozilla.org/ja/thunderbird/addon/check-and-send/ - サーバ-クライアント間で対応する。
SMTPのProxyを使ってチェックする、AntiVirusっぽくクライアントのOSレイヤーで通信をチェックする、DeepInspection的にパケットの転送経路で通信をチェックする。などなど。
なんとなく、3.の一番目「SMTPのProxyを使って対応する」が可能かコードを書いてみた。結果はページの最後に。PerlのCPANは非常に便利で簡単に書ける。(ただし、テストはあまりしていないので信頼性などは微妙。ここはproof-of-conceptの場所なのでその辺りはつっこまないでください。)
なお、下記のコードは悪意のある人がいる状況下で一定の人にしかメールを送らせないための対応としては使ってはいけない。
なぜなら、RFCで許されるメールアドレスのチェックは難しく、一定文字列が含まれる場合は許可というルールは危険すぎるからである。
http://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9
メールアドレスチェックが難しい理由としては、メールの不正中継をテストするテストパターンも参考になる。(%による転送経路指定とか。)
http://www.atmarkit.co.jp/fsecurity/rensai/securitytips/005checkmail.html
以下、Perlのコード。
use Carp; use Net::SMTP::Server; use Net::SMTP::Server::Client; use Net::SMTP::Server::Relay; use Data::Dumper; my $SMTP_SERVER = "smtp_server"; my $SMTP_PORT = "587"; #メールあて先チェック用 sub is_ok_to{ my $ref_to_ary = shift; foreach my $to (@$ref_to_ary) { #あて先チェックをここに書く。 if($to !~ /[email protected]/){ return 0; } } return 1; } # 以下本体処理部分 #CPANより。 #http://search.cpan.org/~macgyver/SMTP-Server-1.1/Server.pm $server = new Net::SMTP::Server('localhost', 25) || croak("Unable to handle client connection: $!n"); while($conn = $server->accept()) { my $client = new Net::SMTP::Server::Client($conn) || croak("Unable to handle client connection: $!n"); $client->process || next; #ここまでCPANのサンプルコード(コメントは削除) if(is_ok_to($client->{TO})){ &send_mail($client->{FROM},$client->{TO},$client->{MSG}); }else{ print "bad mail [" . Dumper($client). "]"; } } #問題の無いメールを送る sub send_mail{ my $from = shift; my $ref_to_ary = shift; my $msg = shift; $smtp = Net::SMTP->new($SMTP_SERVER, Port=>$SMTP_PORT ); $smtp->mail($from); foreach my $to (@$ref_to_ary) { $smtp->to($to); } $smtp->data($msg); $smtp->quit() || croak "send_mail() failed [" . Dumper($from, $ref_to_ary, $msg). "]"; return; }