"smtpd" --- SMTP サーバー
*************************

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

======================================================================

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

バージョン 3.6 で非推奨: "smtpd" will be removed in Python 3.12 (see
**PEP 594** for details). The aiosmtpd package is a recommended
replacement for this module.  It is based on "asyncio" and provides a
more straightforward API.

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

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

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


SMTPServer オブジェクト
=======================

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

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

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

   *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". 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* and
   *enable_SMTPUTF8* cannot be set to "True" at the same time.

   *decode_data* specifies whether the data portion of the SMTP
   transaction should be decoded using UTF-8.  When *decode_data* is
   "False" (the default), 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.
   *decode_data* and *enable_SMTPUTF8* cannot be set to "True" at the
   same time.

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

      このクラスでは "NotImplementedError" 例外を送出します。受信した
      メッセージを使って何か意味のある処理をしたい場合にはこのメソッド
      をオーバライドしてください。コンストラクタの *remoteaddr* に渡し
      た値は "_remoteaddr" 属性で参照できます。 *peer* はリモートホス
      トのアドレスで、 *mailfrom* はメッセージエンベロープの発信元
      (envelope originator) 、 *rcpttos* はメッセージエンベロープの受
      信対象、そして *data* は電子メールの内容が入った(**RFC 5321** 形
      式の)文字列です。

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

      *kwargs* is a dictionary containing additional information. It
      is empty if "decode_data=True" was given as an init argument,
      otherwise 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 parameters, and the *kwargs* parameter to
   "process_message()" when *decode_data* is "False".

   バージョン 3.6 で変更: *decode_data* がデフォルトで "False" になり
   ました。


DebuggingServer オブジェクト
============================

class smtpd.DebuggingServer(localaddr, remoteaddr)

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


PureProxy オブジェクト
======================

class smtpd.PureProxy(localaddr, remoteaddr)

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


MailmanProxy Objects
====================

class smtpd.MailmanProxy(localaddr, remoteaddr)

   Deprecated since version 3.9, will be removed in version 3.11:
   "MailmanProxy" is deprecated, it depends on a "Mailman" module
   which no longer exists and therefore is already broken.

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


SMTPChannel オブジェクト
========================

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

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

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

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

   *enable_SMTPUTF8* determines whether the "SMTPUTF8" extension (as
   defined in **RFC 6531**) should be enabled.  The default is
   "False". *decode_data* and *enable_SMTPUTF8* cannot be 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 "False".
   *decode_data* and *enable_SMTPUTF8* cannot be set to "True" at the
   same time.

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

   バージョン 3.5 で変更: 引数 *decode_data* と *enable_SMTPUTF8* が追
   加されました.

   バージョン 3.6 で変更: *decode_data* がデフォルトで "False" になり
   ました。

   "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     | コマンドが実装されていないことを報告します。                        |
   +----------+---------------------------------------------------------------------+
