SMTPプロトコルについてとPerlでのテスト。

  1. SMTPプロトコルはRFC5321で規定されている。
  2. SMTPプロトコルでは認証機能があるが、それについてはRFC2554で規定されている。
  3. SMTPプロトコルでのデータ(ヘッダ含む)はインターネットメッセージフォーマットというプロトコルが使われている。
  4. IMFプロトコルはRFC5322で規定されている。

ThuderBird等でメールの送信をしながらWireSharkでsmtpでフィルターをかけて表示すると流れがよくわかる。

メール送信の流れ

ユーザ:telnet等でSMTPサーバへ接続

サーバ:220 foobar.ne.jp SMTP-Gateway Version 1.09 at Tue, 24 May 2016 01:00:05 +0900 (JST)

ユーザ:EHLO [192.168.11.2]

SMTPサーバ:
250-foobar.ne.jp Hello [192.168.11.2] [203.136.30.210], pleased to meet you
250-AUTH CRAM-MD5 LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE 104857600
250-DSN
250-DELIVERBY
250 HELP

ユーザ:AUTH CRAM-MD5

サーバ:334 Base64でエンコードされた文字列
Base64でエンコードされた文字列をデコードした内容は「<2529.28.95.1464019205@foobar.ne.jp>」
↓ユーザ:Base64でエンコードされた文字列
Base64でエンコードされた文字列をデコードした内容は「user@foobar.ne.jp 870214746a7d75c7ccbc2514eed93b28」

サーバ:235 2.7.0 Authentication successful

ユーザ:MAIL FROM:<user@foobar.ne.jp> BODY=8BITMIME SIZE=456

サーバ:250 2.1.0 <user@foobar.ne.jp>… Sender ok

ユーザ:RCPT TO:<user@foobar.ne.jp>

サーバ:250 2.1.5 <user@foobar.ne.jp>… Recipient ok

ユーザ:DATA

ユーザ:354 Enter mail, end with “.” on a line by itself

ユーザ:ヘッダとデータを送信(詳細は下の画像の通り)


サーバ:250 2.0.0 u4NG05xa012846 Message accepted for delivery

ユーザ:QUIT

サーバ:221 2.0.0 foobar.ne.jp closing connection

認証について

チャレンジレスポンス方式で認証される。

チャレンジレスポンス方式の流れ

ユーザ:IDを送信
サーバ:チャレンジと呼ばれる文字列等を送信
ユーザ:IDとパスワードをチャレンジを元にレスポンスを作成して、サーバへ送信
サーバ:IDとパスワードをチャレンジを元にレスポンスを作成して、ユーザから送られてきたレスポンスが正しいかを確認
サーバ:正しければ認証。正しくなければ認証しない。

認証について参考になるサイト

SMTP-AUTH - とほほのWWW入門

Perlでのテストスクリプト

Net::SMTPとAuthen::SASLをインストールしてから動いた。
何かうまく動かなかったら、$@を参照するとエラー内容が書かれている。

#!/usr/bin/perl 

use strict;
use warnings;

sub sendmail_smtp {
	use Net::SMTP;

	# SMTPサーバ
	my $mail_server = "foobar";
	# 自分のIPアドレス、もしくはドメイン
	my $hello = '192.168.11.20';
	# SMTPサーバに接続する時のポート
	my $port = 587;
	# SMTPサーバに接続する時のユーザ名
	my $auth_user = 'foo';
	# SMTPサーバに接続する時のパスワード
	my $auth_pswd = 'bar';
	# 送信元メールアドレス
	my $from = 'foobar';
	# 送信先メールアドレス
	my $to = 'foobar';
	# ヘッダーが格納される変数
	my $header = '';
	# メールの件名
	my $subject = 'PerlMailテストTest';
	# メールの本文
	my $mail_body = <<END_OF_MAIL_BODY;
This is あいうえお PerlTest. かきくけこ
END_OF_MAIL_BODY
        my $flag = 1;
        my $smtp = Net::SMTP -> new($mail_server,
		Hello => $hello,
		Timeout => 60,
		Port => $port
	);
	if (!defined($smtp)) {
		$flag = 0;
		die "PerlMailTest.pl\n" . $! . "\n";
	}
	if ($flag == 1) {
		if (!($smtp -> auth($auth_user, $auth_pswd))) {
			$flag = 0;
			die "PerlMailTest.pl\n" . $! . "\n";
		}
	}
	if ($flag == 1) {
		if (!($smtp -> mail($from))) {
			$flag = 0;
			die "PerlMailTest.pl\n" . $! . "\n";
		}
	}
	# ヘッダーの設定。
	$header = "From:$from\n";
	$header .= "To:$to\n";
	$header .= "Subject:$subject\n";
	$header .= "MIME-Version:1.0\n";
	#$header .= "Content-Type:text/plain; charset=iso-2022-jp\n";
	$header .= "Content-Type:text/plain; charset=utf-8\n";
	$header .= "Content-Transfer-Encoding: 7bit\n";
	# メール送信。
	if ($flag == 1 && $smtp -> to($to)) {
		$smtp -> data();
		$smtp -> datasend($header);
		$smtp -> datasend("\n");
		$smtp -> datasend($mail_body);
	} else {
		die "PerlMailTest.pl\n" . $! . "\n" . $smtp -> message() . "\n";
	}
	$smtp -> quit;
}

&sendmail_smtp;

コメント

タイトルとURLをコピーしました