17db96d56Sopenharmony_ci:mod:`smtpd` --- SMTP Server 27db96d56Sopenharmony_ci============================ 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ci.. module:: smtpd 57db96d56Sopenharmony_ci :synopsis: A SMTP server implementation in Python. 67db96d56Sopenharmony_ci :deprecated: 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci.. moduleauthor:: Barry Warsaw <barry@python.org> 97db96d56Sopenharmony_ci.. sectionauthor:: Moshe Zadka <moshez@moshez.org> 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci**Source code:** :source:`Lib/smtpd.py` 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ci-------------- 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ciThis module offers several classes to implement SMTP (email) servers. 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci.. deprecated-removed:: 3.6 3.12 187db96d56Sopenharmony_ci The :mod:`smtpd` module is deprecated 197db96d56Sopenharmony_ci (see :pep:`PEP 594 <594#smtpd>` for details). 207db96d56Sopenharmony_ci The `aiosmtpd <https://aiosmtpd.readthedocs.io/>`_ package is a recommended 217db96d56Sopenharmony_ci replacement for this module. It is based on :mod:`asyncio` and provides a 227db96d56Sopenharmony_ci more straightforward API. 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ciSeveral server implementations are present; one is a generic 257db96d56Sopenharmony_cido-nothing implementation, which can be overridden, while the other two offer 267db96d56Sopenharmony_cispecific mail-sending strategies. 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ciAdditionally the SMTPChannel may be extended to implement very specific 297db96d56Sopenharmony_ciinteraction behaviour with SMTP clients. 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ciThe code supports :RFC:`5321`, plus the :rfc:`1870` SIZE and :rfc:`6531` 327db96d56Sopenharmony_ciSMTPUTF8 extensions. 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci.. include:: ../includes/wasm-notavail.rst 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ciSMTPServer Objects 377db96d56Sopenharmony_ci------------------ 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_ci.. class:: SMTPServer(localaddr, remoteaddr, data_size_limit=33554432,\ 417db96d56Sopenharmony_ci map=None, enable_SMTPUTF8=False, decode_data=False) 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci Create a new :class:`SMTPServer` object, which binds to local address 447db96d56Sopenharmony_ci *localaddr*. It will treat *remoteaddr* as an upstream SMTP relayer. Both 457db96d56Sopenharmony_ci *localaddr* and *remoteaddr* should be a :ref:`(host, port) <host_port>` 467db96d56Sopenharmony_ci tuple. The object inherits from :class:`asyncore.dispatcher`, and so will 477db96d56Sopenharmony_ci insert itself into :mod:`asyncore`'s event loop on instantiation. 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci *data_size_limit* specifies the maximum number of bytes that will be 507db96d56Sopenharmony_ci accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no 517db96d56Sopenharmony_ci limit. 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci *map* is the socket map to use for connections (an initially empty 547db96d56Sopenharmony_ci dictionary is a suitable value). If not specified the :mod:`asyncore` 557db96d56Sopenharmony_ci global socket map is used. 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined 587db96d56Sopenharmony_ci in :RFC:`6531`) should be enabled. The default is ``False``. 597db96d56Sopenharmony_ci When ``True``, ``SMTPUTF8`` is accepted as a parameter to the ``MAIL`` 607db96d56Sopenharmony_ci command and when present is passed to :meth:`process_message` in the 617db96d56Sopenharmony_ci ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8* 627db96d56Sopenharmony_ci cannot be set to ``True`` at the same time. 637db96d56Sopenharmony_ci 647db96d56Sopenharmony_ci *decode_data* specifies whether the data portion of the SMTP transaction 657db96d56Sopenharmony_ci should be decoded using UTF-8. When *decode_data* is ``False`` (the 667db96d56Sopenharmony_ci default), the server advertises the ``8BITMIME`` 677db96d56Sopenharmony_ci extension (:rfc:`6152`), accepts the ``BODY=8BITMIME`` parameter to 687db96d56Sopenharmony_ci the ``MAIL`` command, and when present passes it to :meth:`process_message` 697db96d56Sopenharmony_ci in the ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8* 707db96d56Sopenharmony_ci cannot be set to ``True`` at the same time. 717db96d56Sopenharmony_ci 727db96d56Sopenharmony_ci .. method:: process_message(peer, mailfrom, rcpttos, data, **kwargs) 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci Raise a :exc:`NotImplementedError` exception. Override this in subclasses to 757db96d56Sopenharmony_ci do something useful with this message. Whatever was passed in the 767db96d56Sopenharmony_ci constructor as *remoteaddr* will be available as the :attr:`_remoteaddr` 777db96d56Sopenharmony_ci attribute. *peer* is the remote host's address, *mailfrom* is the envelope 787db96d56Sopenharmony_ci originator, *rcpttos* are the envelope recipients and *data* is a string 797db96d56Sopenharmony_ci containing the contents of the e-mail (which should be in :rfc:`5321` 807db96d56Sopenharmony_ci format). 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci If the *decode_data* constructor keyword is set to ``True``, the *data* 837db96d56Sopenharmony_ci argument will be a unicode string. If it is set to ``False``, it 847db96d56Sopenharmony_ci will be a bytes object. 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci *kwargs* is a dictionary containing additional information. It is empty 877db96d56Sopenharmony_ci if ``decode_data=True`` was given as an init argument, otherwise 887db96d56Sopenharmony_ci it contains the following keys: 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci *mail_options*: 917db96d56Sopenharmony_ci a list of all received parameters to the ``MAIL`` 927db96d56Sopenharmony_ci command (the elements are uppercase strings; example: 937db96d56Sopenharmony_ci ``['BODY=8BITMIME', 'SMTPUTF8']``). 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci *rcpt_options*: 967db96d56Sopenharmony_ci same as *mail_options* but for the ``RCPT`` command. 977db96d56Sopenharmony_ci Currently no ``RCPT TO`` options are supported, so for now 987db96d56Sopenharmony_ci this will always be an empty list. 997db96d56Sopenharmony_ci 1007db96d56Sopenharmony_ci Implementations of ``process_message`` should use the ``**kwargs`` 1017db96d56Sopenharmony_ci signature to accept arbitrary keyword arguments, since future feature 1027db96d56Sopenharmony_ci enhancements may add keys to the kwargs dictionary. 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci Return ``None`` to request a normal ``250 Ok`` response; otherwise 1057db96d56Sopenharmony_ci return the desired response string in :RFC:`5321` format. 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_ci .. attribute:: channel_class 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci Override this in subclasses to use a custom :class:`SMTPChannel` for 1107db96d56Sopenharmony_ci managing SMTP clients. 1117db96d56Sopenharmony_ci 1127db96d56Sopenharmony_ci .. versionadded:: 3.4 1137db96d56Sopenharmony_ci The *map* constructor argument. 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_ci .. versionchanged:: 3.5 1167db96d56Sopenharmony_ci *localaddr* and *remoteaddr* may now contain IPv6 addresses. 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci .. versionadded:: 3.5 1197db96d56Sopenharmony_ci The *decode_data* and *enable_SMTPUTF8* constructor parameters, and the 1207db96d56Sopenharmony_ci *kwargs* parameter to :meth:`process_message` when *decode_data* is 1217db96d56Sopenharmony_ci ``False``. 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_ci .. versionchanged:: 3.6 1247db96d56Sopenharmony_ci *decode_data* is now ``False`` by default. 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ci 1277db96d56Sopenharmony_ciDebuggingServer Objects 1287db96d56Sopenharmony_ci----------------------- 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ci.. class:: DebuggingServer(localaddr, remoteaddr) 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci Create a new debugging server. Arguments are as per :class:`SMTPServer`. 1347db96d56Sopenharmony_ci Messages will be discarded, and printed on stdout. 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ciPureProxy Objects 1387db96d56Sopenharmony_ci----------------- 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ci 1417db96d56Sopenharmony_ci.. class:: PureProxy(localaddr, remoteaddr) 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ci Create a new pure proxy server. Arguments are as per :class:`SMTPServer`. 1447db96d56Sopenharmony_ci Everything will be relayed to *remoteaddr*. Note that running this has a good 1457db96d56Sopenharmony_ci chance to make you into an open relay, so please be careful. 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ci 1487db96d56Sopenharmony_ciSMTPChannel Objects 1497db96d56Sopenharmony_ci------------------- 1507db96d56Sopenharmony_ci 1517db96d56Sopenharmony_ci.. class:: SMTPChannel(server, conn, addr, data_size_limit=33554432,\ 1527db96d56Sopenharmony_ci map=None, enable_SMTPUTF8=False, decode_data=False) 1537db96d56Sopenharmony_ci 1547db96d56Sopenharmony_ci Create a new :class:`SMTPChannel` object which manages the communication 1557db96d56Sopenharmony_ci between the server and a single SMTP client. 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci *conn* and *addr* are as per the instance variables described below. 1587db96d56Sopenharmony_ci 1597db96d56Sopenharmony_ci *data_size_limit* specifies the maximum number of bytes that will be 1607db96d56Sopenharmony_ci accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no 1617db96d56Sopenharmony_ci limit. 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_ci *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined 1647db96d56Sopenharmony_ci in :RFC:`6531`) should be enabled. The default is ``False``. 1657db96d56Sopenharmony_ci *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same 1667db96d56Sopenharmony_ci time. 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ci A dictionary can be specified in *map* to avoid using a global socket map. 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci *decode_data* specifies whether the data portion of the SMTP transaction 1717db96d56Sopenharmony_ci should be decoded using UTF-8. The default is ``False``. 1727db96d56Sopenharmony_ci *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same 1737db96d56Sopenharmony_ci time. 1747db96d56Sopenharmony_ci 1757db96d56Sopenharmony_ci To use a custom SMTPChannel implementation you need to override the 1767db96d56Sopenharmony_ci :attr:`SMTPServer.channel_class` of your :class:`SMTPServer`. 1777db96d56Sopenharmony_ci 1787db96d56Sopenharmony_ci .. versionchanged:: 3.5 1797db96d56Sopenharmony_ci The *decode_data* and *enable_SMTPUTF8* parameters were added. 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci .. versionchanged:: 3.6 1827db96d56Sopenharmony_ci *decode_data* is now ``False`` by default. 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_ci The :class:`SMTPChannel` has the following instance variables: 1857db96d56Sopenharmony_ci 1867db96d56Sopenharmony_ci .. attribute:: smtp_server 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci Holds the :class:`SMTPServer` that spawned this channel. 1897db96d56Sopenharmony_ci 1907db96d56Sopenharmony_ci .. attribute:: conn 1917db96d56Sopenharmony_ci 1927db96d56Sopenharmony_ci Holds the socket object connecting to the client. 1937db96d56Sopenharmony_ci 1947db96d56Sopenharmony_ci .. attribute:: addr 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_ci Holds the address of the client, the second value returned by 1977db96d56Sopenharmony_ci :func:`socket.accept <socket.socket.accept>` 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci .. attribute:: received_lines 2007db96d56Sopenharmony_ci 2017db96d56Sopenharmony_ci Holds a list of the line strings (decoded using UTF-8) received from 2027db96d56Sopenharmony_ci the client. The lines have their ``"\r\n"`` line ending translated to 2037db96d56Sopenharmony_ci ``"\n"``. 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_ci .. attribute:: smtp_state 2067db96d56Sopenharmony_ci 2077db96d56Sopenharmony_ci Holds the current state of the channel. This will be either 2087db96d56Sopenharmony_ci :attr:`COMMAND` initially and then :attr:`DATA` after the client sends 2097db96d56Sopenharmony_ci a "DATA" line. 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci .. attribute:: seen_greeting 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci Holds a string containing the greeting sent by the client in its "HELO". 2147db96d56Sopenharmony_ci 2157db96d56Sopenharmony_ci .. attribute:: mailfrom 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci Holds a string containing the address identified in the "MAIL FROM:" line 2187db96d56Sopenharmony_ci from the client. 2197db96d56Sopenharmony_ci 2207db96d56Sopenharmony_ci .. attribute:: rcpttos 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci Holds a list of strings containing the addresses identified in the 2237db96d56Sopenharmony_ci "RCPT TO:" lines from the client. 2247db96d56Sopenharmony_ci 2257db96d56Sopenharmony_ci .. attribute:: received_data 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ci Holds a string containing all of the data sent by the client during the 2287db96d56Sopenharmony_ci DATA state, up to but not including the terminating ``"\r\n.\r\n"``. 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ci .. attribute:: fqdn 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_ci Holds the fully qualified domain name of the server as returned by 2337db96d56Sopenharmony_ci :func:`socket.getfqdn`. 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_ci .. attribute:: peer 2367db96d56Sopenharmony_ci 2377db96d56Sopenharmony_ci Holds the name of the client peer as returned by ``conn.getpeername()`` 2387db96d56Sopenharmony_ci where ``conn`` is :attr:`conn`. 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ci The :class:`SMTPChannel` operates by invoking methods named ``smtp_<command>`` 2417db96d56Sopenharmony_ci upon reception of a command line from the client. Built into the base 2427db96d56Sopenharmony_ci :class:`SMTPChannel` class are methods for handling the following commands 2437db96d56Sopenharmony_ci (and responding to them appropriately): 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_ci ======== =================================================================== 2467db96d56Sopenharmony_ci Command Action taken 2477db96d56Sopenharmony_ci ======== =================================================================== 2487db96d56Sopenharmony_ci HELO Accepts the greeting from the client and stores it in 2497db96d56Sopenharmony_ci :attr:`seen_greeting`. Sets server to base command mode. 2507db96d56Sopenharmony_ci EHLO Accepts the greeting from the client and stores it in 2517db96d56Sopenharmony_ci :attr:`seen_greeting`. Sets server to extended command mode. 2527db96d56Sopenharmony_ci NOOP Takes no action. 2537db96d56Sopenharmony_ci QUIT Closes the connection cleanly. 2547db96d56Sopenharmony_ci MAIL Accepts the "MAIL FROM:" syntax and stores the supplied address as 2557db96d56Sopenharmony_ci :attr:`mailfrom`. In extended command mode, accepts the 2567db96d56Sopenharmony_ci :rfc:`1870` SIZE attribute and responds appropriately based on the 2577db96d56Sopenharmony_ci value of *data_size_limit*. 2587db96d56Sopenharmony_ci RCPT Accepts the "RCPT TO:" syntax and stores the supplied addresses in 2597db96d56Sopenharmony_ci the :attr:`rcpttos` list. 2607db96d56Sopenharmony_ci RSET Resets the :attr:`mailfrom`, :attr:`rcpttos`, and 2617db96d56Sopenharmony_ci :attr:`received_data`, but not the greeting. 2627db96d56Sopenharmony_ci DATA Sets the internal state to :attr:`DATA` and stores remaining lines 2637db96d56Sopenharmony_ci from the client in :attr:`received_data` until the terminator 2647db96d56Sopenharmony_ci ``"\r\n.\r\n"`` is received. 2657db96d56Sopenharmony_ci HELP Returns minimal information on command syntax 2667db96d56Sopenharmony_ci VRFY Returns code 252 (the server doesn't know if the address is valid) 2677db96d56Sopenharmony_ci EXPN Reports that the command is not implemented. 2687db96d56Sopenharmony_ci ======== =================================================================== 269