21.18. smtpd --- SMTP サーバー

ソースコード: Lib/smtpd.py


このモジュールは SMTP (email) サーバを実装するためのいくつかのクラスを提供しています。

参考

The aiosmtpd package is a recommended replacement for this module. It is based on asyncio and provides a more straightforward API. smtpd should be considered deprecated.

サーバの実装がいくつかあります。一つはジェネリックで何もしない実装で、オーバーライドすることが出来ます。他の二つは特定のメール送信方策を提供しています。

また、SMTPChannel を拡張して SMTP クライアントとの特定の相互作用挙動を実装することができます。

コードは RFC 5321 に加え、RFC 1870 SIZE と RFC 6531 SMTPUTF8 拡張をサポートしています。

21.18.1. SMTPServer オブジェクト

class smtpd.SMTPServer(localaddr, remoteaddr, data_size_limit=33554432, map=None, enable_SMTPUTF8=False, decode_data=True)

新たな SMTPServer オブジェクトを作成し、それをローカルのアドレス localaddr に関連づけ (bind) ます。 このオブジェクトは remoteaddr を上流の SMTP リレー先とします。 localaddrremoteaddr のどちらも (host, port) タプルである必要があります。 このクラスは asyncore.dispatcher を継承しており、インスタンス化時に自身を asyncore のイベントループに登録します。

data_size_limit には DATA コマンドが受け取る最大のバイト数を指定します。 None0 の場合上限はありません。

map is the socket map to use for connections (an initially empty dictionary is a suitable value). If not specified the asyncore global socket map is used.

enable_SMTPUTF8 determines whether the SMTPUTF8 extension (as defined in RFC 6531) should be enabled. The default is False. If set to True, decode_data must be False (otherwise an error is raised). When True, SMTPUTF8 is accepted as a parameter to the MAIL command and when present is passed to process_message() in the kwargs['mail_options'] list.

decode_data specifies whether the data portion of the SMTP transaction should be decoded using UTF-8. The default is True for backward compatibility reasons, but will change to False in Python 3.6; specify the keyword value explicitly to avoid the DeprecationWarning. When decode_data is set to False the server advertises the 8BITMIME extension (RFC 6152), accepts the BODY=8BITMIME parameter to the MAIL command, and when present passes it to process_message() in the kwargs['mail_options'] list.

process_message(peer, mailfrom, rcpttos, data, **kwargs)

Raise a NotImplementedError exception. Override this in subclasses to do something useful with this message. Whatever was passed in the constructor as remoteaddr will be available as the _remoteaddr attribute. peer is the remote host's address, mailfrom is the envelope originator, rcpttos are the envelope recipients and data is a string containing the contents of the e-mail (which should be in RFC 5321 format).

decode_data コンストラクタ引数が True の場合、 data 引数はユニコード文字列です。False の場合は bytes オブジェクトです。

kwargs is a dictionary containing additional information. It is empty unless at least one of decode_data=False or enable_SMTPUTF8=True was given as an init parameter, in which case it contains the following keys:

mail_options:
MAIL コマンドが受け取る全ての引数のリストです (要素は大文字の文字列です; 例えば ['BODY=8BITMIME', 'SMTPUTF8'])。
rcpt_options:
RCPT コマンドのものである点以外は mail_options と同じです。今のところ RCPT TO オプションはサポートされていないため、これは常に空のリストです。

将来の仕様改善によって kwargs 辞書にキーが追加される可能性があるため、 process_message の実装で追加のキーワード引数を受け取るには **kwargs シグニチャを使うべきです。

通常の 250 Ok 応答には None を返します。そうでない場合求められる応答を RFC 5321 形式の文字列で返します。

channel_class

これを派生クラスでオーバーライドすることで、SMTP クライアントを管理するのにカスタムの SMTPChannel を使います。

バージョン 3.4 で追加: map コンストラクタ引数。

バージョン 3.5 で変更: localaddr および remoteaddr は IPv6 アドレスを持てるようになりました。

バージョン 3.5 で追加: the decode_data and enable_SMTPUTF8 constructor arguments, and the kwargs argument to process_message() when one or more of these is specified.

21.18.2. DebuggingServer オブジェクト

class smtpd.DebuggingServer(localaddr, remoteaddr)

新たなデバッグ用サーバを生成します。引数は SMTPServer と同じです。メッセージが届いても無視し、標準出力に出力します。

21.18.3. PureProxy オブジェクト

class smtpd.PureProxy(localaddr, remoteaddr)

新たな単純プロキシ (pure proxy) サーバを生成します。引数は SMTPServer と同じです。全てのメッセージを remoteaddr にリレーします。このオブジェクトを動作させるとオープンリレーを作成してしまう可能性が多分にあります。注意してください。

21.18.4. MailmanProxy Objects

class smtpd.MailmanProxy(localaddr, remoteaddr)

新たな単純プロキシサーバを生成します。引数は SMTPServer と同じです。全てのメッセージを remoteaddr にリレーしますが、 ローカルの mailman の設定に remoteaddr がある場合には mailman を使って処理します。このオブジェクトを動作させるとオープンリレーを 作成してしまう可能性が多分にあります。注意してください。

21.18.5. SMTPChannel オブジェクト

class smtpd.SMTPChannel(server, conn, addr, data_size_limit=33554432, map=None, enable_SMTPUTF8=False, decode_data=True)

サーバと一つの SMTP クライアント間の通信を管理する SMTPChannel オブジェクトを新たに生成します。

conn and addr are as per the instance variables described below.

data_size_limit には DATA コマンドが受け取る最大のバイト数を指定します。 None0 の場合上限はありません。

enable_SMTPUTF8 determines whether the SMTPUTF8 extension (as defined in RFC 6531) should be enabled. The default is False. A ValueError is raised if both enable_SMTPUTF8 and decode_data are set to True at the same time.

A dictionary can be specified in map to avoid using a global socket map.

decode_data specifies whether the data portion of the SMTP transaction should be decoded using UTF-8. The default is True for backward compatibility reasons, but will change to False in Python 3.6. Specify the keyword value explicitly to avoid the DeprecationWarning.

To use a custom SMTPChannel implementation you need to override the SMTPServer.channel_class of your SMTPServer.

バージョン 3.5 で変更: the decode_data and enable_SMTPUTF8 arguments were added.

SMTPChannel は以下のインスタンス変数を持っています:

smtp_server

このチャンネルを生成した SMTPServer を保持します。

conn

クライアントに接続しているソケットオブジェクトを保持します。

addr

Holds the address of the client, the second value returned by socket.accept

received_lines

Holds a list of the line strings (decoded using UTF-8) received from the client. The lines have their "\r\n" line ending translated to "\n".

smtp_state

Holds the current state of the channel. This will be either COMMAND initially and then DATA after the client sends a "DATA" line.

seen_greeting

Holds a string containing the greeting sent by the client in its "HELO".

mailfrom

Holds a string containing the address identified in the "MAIL FROM:" line from the client.

rcpttos

Holds a list of strings containing the addresses identified in the "RCPT TO:" lines from the client.

received_data

Holds a string containing all of the data sent by the client during the DATA state, up to but not including the terminating "\r\n.\r\n".

fqdn

Holds the fully-qualified domain name of the server as returned by socket.getfqdn().

peer

Holds the name of the client peer as returned by conn.getpeername() where conn is conn.

The SMTPChannel operates by invoking methods named smtp_<command> upon reception of a command line from the client. Built into the base SMTPChannel class are methods for handling the following commands (and responding to them appropriately):

コマンド 行う動作
HELO クライアントのグリーティングを受け取り seen_greeting に格納します。サーバを基本コマンドモードに設定します。
EHLO クライアントのグリーティングを受け取り seen_greeting に格納します。サーバを拡張コマンドモードに設定します。
NOOP 何もしません。
QUIT 接続をきれいに閉じます。
MAIL "MAIL FROM:" シンタックスを受け取り提供されたアドレスを mailfrom として保存します。拡張コマンドモードでは RFC 1870 SIZE 属性を受け取り data_size_limit の値に基づき適切に応答します。
RCPT "RCPT TO:" シンタックスを受け取り提供されたアドレスを rcpttos リストに格納します。
RSET mailfrom, rcpttos, received_data をリセットしますが、グリーティングはリセットしません。
DATA 内部状態を DATA に設定し、クライアントからの残りの行を終端子 "\r\n.\r\n" を受け取るまで received_data に格納します。
HELP 最小の情報をコマンドシンタックスで返します。
VRFY コード 252 (サーバはアドレスが有効か分かりません) を返します。
EXPN コマンドが実装されていないことを報告します。