Email::SenderでSMTPサーバから外部ドメインへメール送信できなかった件
http://gihyo.jp/dev/serial/01/modern-perl/0020?page=3
※こちらの内容を元にしたコードを使っていると仮定
Email::Sender::Transport::SMTP を使って「外部ドメイン」へ送信したら…
そのままだとエラーで送信出来なかった。
メールサーバ*1での設定でなんとかなるみたいだったのだが、
そっちはいじりたくなかったので認証使ってどうにかしようとしたときのメモメモ。
まずはEmail::Sender::Transport::SMTPで普通に認証
ユーザ名とパスワードを設定したけど、認証エラーで送信出来ない。
my $transport = Email::Sender::Transport::SMTP->new( host => '192.168.0.xx', port => 587, sasl_username => $user, sasl_password => $pass, );
Net::SMTPから接続してみる
perlから最小限コードでSMTP認証してみたところ、
こちらは依然失敗してしまう。
ログを確認すると「CRAM-MD5」認証で失敗している様子。
※ここで盛大にハマる
まず、大きな勘違い
Windowsのメールクライアントからは「CRAM-MD5認証」のチェックが入っていて問題なく送信されていた。
なので、そもそもメールサーバが「CRAM-MD5認証」できていると思い込んでいた。が…
Windowsメールクライアントのプロトコルログを確認
すると、CRAM-MD5の認証は「失敗」してた!
メールクライアントの挙動を見てみると
「CRAM-MD5失敗」→「再度plainログイン」
という動作をしていたようだ。
Email::Sender::Transport::SMTPはNet::SMTPを利用しているので
「Net::SMTPからPLAIN認証したい」のだが、ソースを見てみると
Authen::SASLのmechanismを指定する所がなさそうなんですが…(自動判定っぽい)
http://cpansearch.perl.org/src/GBARR/libnet-1.22/Net/SMTP.pm
sub auth { my ($self, $username, $password) = @_; eval { require MIME::Base64; require Authen::SASL; } or $self->set_status(500, ["Need MIME::Base64 and Authen::SASL todo auth"]), return 0; my $mechanisms = $self->supports('AUTH', 500, ["Command unknown: 'AUTH'"]); return unless defined $mechanisms; my $sasl; if (ref($username) and UNIVERSAL::isa($username, 'Authen::SASL')) { $sasl = $username; $sasl->mechanism($mechanisms); } else { die "auth(username, password)" if not length $username; $sasl = Authen::SASL->new( mechanism => $mechanisms, callback => { user => $username, pass => $password, authname => $username, } ); } ...(以下略)
これで
Email::Sender::Transport::SMTPから認証がうまく行ったよ!
やほい
※参考URL
http://nai.homelinux.net/telnet_smtp_auth.html
http://yoosee.net/d/archives/2004/08/25/002.html