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のプログラムを書いているのならコイツを使えば簡単にできる。

使い方について書き途中・・・


debian Valid HTML 4.01 Strict [VALID RSS!]