telnetでsmtp-authをやる
telnetでsmtp-auth
SMTP-AUTH関連のperlを作成していていろいろ試したので書いとく。telnetでSMTP-AUTHはできるが、Base64のエンコードやデコード、MD5でのダイジェストはperlとかのプログラムを使用しないとならない。それならNet::SMTPとか使った方が簡単だ。勉強の用途や、なんかのプログラム作るってなら参考になるかも。
plain
plain認証は以下の形でクライアントからサーバへ渡す
AUTH PLAIN Base64デコード(ユーザ名NULLユーザ名NULLパスワード)
ユーザ名がuserでパスワードがpassなら、こうなる。
AUTH PLAIN dXNlcgB1c2VyAHBhc3M=
エンコードの方法
Base64エンコードはこんなんで変換すればよい
$perl -MMIME::Base64 -e 'print encode_base64("user\0user\0pass");'
やってみる
$ telnet localhost 25 Trying 127.0.0.1... Connected to localhost.localdomain. Escape character is '^]'. 220 BANANA ehlo localhost 250-nai.homelinux.net 250-PIPELINING 250-SIZE 10240000 250-ETRN 250-STARTTLS 250-AUTH NTLM LOGIN PLAIN DIGEST-MD5 CRAM-MD5 250-AUTH=NTLM LOGIN PLAIN DIGEST-MD5 CRAM-MD5 250 8BITMIME auth plain dXNlcgB1c2VyAHBhc3M= 235 Authentication successful quit 221 Bye Connection closed by foreign host.
login
login認証が一番復旧しているのだが、きちんとした仕様が定まっていないらしい。今回はdebianのpostfixでの稼動について書く。
基本的にtelnetのログインみたいに、login?とかpassword?と聞かれるのでそれに答える形になる。生の文字ではなくBase64でエンコードされている。
実際にみてみる
$ telnet localhost 25 Trying 127.0.0.1... Connected to localhost.localdomain. Escape character is '^]'. 220 BANANA ehlo localhost 250-nai.homelinux.net 250-PIPELINING 250-SIZE 10240000 250-ETRN 250-STARTTLS 250-AUTH NTLM LOGIN PLAIN DIGEST-MD5 CRAM-MD5 250-AUTH=NTLM LOGIN PLAIN DIGEST-MD5 CRAM-MD5 250 8BITMIME auth login 334 VXNlcm5hbWU6 dXNlcg== 334 UGFzc3dvcmQ6 cGFzcw== 235 Authentication successful quit 221 Bye Connection closed by foreign host.
まず「auth login」でlogin認証をやると伝える。そうすると「334 VXNlcm5hbWU6」と返ってくる。こいつをデコードすると「Username:」となる。なのでユーザ名であるuserをエンコードすると「dXNlcg==」となる。
次に「334 UGFzc3dvcmQ6」と応答がくる。ユーザ名同様にデコードすると「Password:」なるので、パスワードのpassをエンコードすると「cGFzcw==」となる。
デコードの方法
上で書いたエンコードがあるので大体わかると思うが
$perl -MMIME::Base64 -e 'print decode_base64("VXNlcm5hbWU6");'
cram-md5
cram-md5はサーバから送られてくるキーとパスワードを組み合わせて、MD5ダイジェストを作成しそれにユーザを名を付加してBase64でエンコードする形になる。書くとこんなん。
Base64エンコード(ユーザ名+空白1文字+MD5(Base64デコード(キー)+パスワード))
変換用スクリプト
my $username='user'; my $password='pass'; my $code='xxxxxxxxxxxxxxxxxxxxx'; use MIME::Base64; use Digest::HMAC_MD5 qw(hmac_md5_hex); print encode_base64( $username . " " . hmac_md5_hex( decode_base64($code),$password ) );
やってみる
$ telnet localhost 25 Trying 127.0.0.1... Connected to localhost.localdomain. Escape character is '^]'. 220 BANANA ehlo localhost 250-nai.homelinux.net 250-PIPELINING 250-SIZE 10240000 250-ETRN 250-STARTTLS 250-AUTH NTLM LOGIN PLAIN DIGEST-MD5 CRAM-MD5 250-AUTH=NTLM LOGIN PLAIN DIGEST-MD5 CRAM-MD5 250 8BITMIME auth cram-md5 334 PDE0NDg2MTI1OTAuODQzMzQxM0BuYWkuaG9tZWxpbnV4Lm5ldD4= dXNlciBjYTlmYzllOTRmZWU1ZjEyMzM2YTBhMDA4MDYxZTJjMQ== 235 Authentication successful quit 221 Bye Connection closed by foreign host.
「auth cram-md5」での返答で返ってくるキー「PDE0NDg2MTI1OTAuODQzMzQxM0BuYWkuaG9tZWxpbnV4Lm5ldD4=」を上のスクリプトに入れると「dXNlciBjYTlmYzllOTRmZWU1ZjEyMzM2YTBhMDA4MDYxZTJjMQ==」が返ってくるのでそれで答えれば完了だ。
DIGEST-MD5
書き途中・・・
Authen::SASLについて
Net::SMTPでも使用されているAuthen::SASLを使うと全ての認証をやってくれる。もし、SMTP-AUTHのプログラムを書いているのならコイツを使えば簡単にできる。
使い方について書き途中・・・