1:mod:`smtpd` --- SMTP Server 2============================ 3 4.. module:: smtpd 5 :synopsis: A SMTP server implementation in Python. 6 :deprecated: 7 8.. moduleauthor:: Barry Warsaw <[email protected]> 9.. sectionauthor:: Moshe Zadka <[email protected]> 10 11**Source code:** :source:`Lib/smtpd.py` 12 13-------------- 14 15This module offers several classes to implement SMTP (email) servers. 16 17.. deprecated-removed:: 3.6 3.12 18 The :mod:`smtpd` module is deprecated 19 (see :pep:`PEP 594 <594#smtpd>` for details). 20 The `aiosmtpd <https://aiosmtpd.readthedocs.io/>`_ package is a recommended 21 replacement for this module. It is based on :mod:`asyncio` and provides a 22 more straightforward API. 23 24Several server implementations are present; one is a generic 25do-nothing implementation, which can be overridden, while the other two offer 26specific mail-sending strategies. 27 28Additionally the SMTPChannel may be extended to implement very specific 29interaction behaviour with SMTP clients. 30 31The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE and :rfc:`6531` 32SMTPUTF8 extensions. 33 34.. include:: ../includes/wasm-notavail.rst 35 36SMTPServer Objects 37------------------ 38 39 40.. class:: SMTPServer(localaddr, remoteaddr, data_size_limit=33554432,\ 41 map=None, enable_SMTPUTF8=False, decode_data=False) 42 43 Create a new :class:`SMTPServer` object, which binds to local address 44 *localaddr*. It will treat *remoteaddr* as an upstream SMTP relayer. Both 45 *localaddr* and *remoteaddr* should be a :ref:`(host, port) <host_port>` 46 tuple. The object inherits from :class:`asyncore.dispatcher`, and so will 47 insert itself into :mod:`asyncore`'s event loop on instantiation. 48 49 *data_size_limit* specifies the maximum number of bytes that will be 50 accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no 51 limit. 52 53 *map* is the socket map to use for connections (an initially empty 54 dictionary is a suitable value). If not specified the :mod:`asyncore` 55 global socket map is used. 56 57 *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined 58 in :RFC:`6531`) should be enabled. The default is ``False``. 59 When ``True``, ``SMTPUTF8`` is accepted as a parameter to the ``MAIL`` 60 command and when present is passed to :meth:`process_message` in the 61 ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8* 62 cannot be set to ``True`` at the same time. 63 64 *decode_data* specifies whether the data portion of the SMTP transaction 65 should be decoded using UTF-8. When *decode_data* is ``False`` (the 66 default), the server advertises the ``8BITMIME`` 67 extension (:rfc:`6152`), accepts the ``BODY=8BITMIME`` parameter to 68 the ``MAIL`` command, and when present passes it to :meth:`process_message` 69 in the ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8* 70 cannot be set to ``True`` at the same time. 71 72 .. method:: process_message(peer, mailfrom, rcpttos, data, **kwargs) 73 74 Raise a :exc:`NotImplementedError` exception. Override this in subclasses to 75 do something useful with this message. Whatever was passed in the 76 constructor as *remoteaddr* will be available as the :attr:`_remoteaddr` 77 attribute. *peer* is the remote host's address, *mailfrom* is the envelope 78 originator, *rcpttos* are the envelope recipients and *data* is a string 79 containing the contents of the e-mail (which should be in :rfc:`5321` 80 format). 81 82 If the *decode_data* constructor keyword is set to ``True``, the *data* 83 argument will be a unicode string. If it is set to ``False``, it 84 will be a bytes object. 85 86 *kwargs* is a dictionary containing additional information. It is empty 87 if ``decode_data=True`` was given as an init argument, otherwise 88 it contains the following keys: 89 90 *mail_options*: 91 a list of all received parameters to the ``MAIL`` 92 command (the elements are uppercase strings; example: 93 ``['BODY=8BITMIME', 'SMTPUTF8']``). 94 95 *rcpt_options*: 96 same as *mail_options* but for the ``RCPT`` command. 97 Currently no ``RCPT TO`` options are supported, so for now 98 this will always be an empty list. 99 100 Implementations of ``process_message`` should use the ``**kwargs`` 101 signature to accept arbitrary keyword arguments, since future feature 102 enhancements may add keys to the kwargs dictionary. 103 104 Return ``None`` to request a normal ``250 Ok`` response; otherwise 105 return the desired response string in :RFC:`5321` format. 106 107 .. attribute:: channel_class 108 109 Override this in subclasses to use a custom :class:`SMTPChannel` for 110 managing SMTP clients. 111 112 .. versionadded:: 3.4 113 The *map* constructor argument. 114 115 .. versionchanged:: 3.5 116 *localaddr* and *remoteaddr* may now contain IPv6 addresses. 117 118 .. versionadded:: 3.5 119 The *decode_data* and *enable_SMTPUTF8* constructor parameters, and the 120 *kwargs* parameter to :meth:`process_message` when *decode_data* is 121 ``False``. 122 123 .. versionchanged:: 3.6 124 *decode_data* is now ``False`` by default. 125 126 127DebuggingServer Objects 128----------------------- 129 130 131.. class:: DebuggingServer(localaddr, remoteaddr) 132 133 Create a new debugging server. Arguments are as per :class:`SMTPServer`. 134 Messages will be discarded, and printed on stdout. 135 136 137PureProxy Objects 138----------------- 139 140 141.. class:: PureProxy(localaddr, remoteaddr) 142 143 Create a new pure proxy server. Arguments are as per :class:`SMTPServer`. 144 Everything will be relayed to *remoteaddr*. Note that running this has a good 145 chance to make you into an open relay, so please be careful. 146 147 148SMTPChannel Objects 149------------------- 150 151.. class:: SMTPChannel(server, conn, addr, data_size_limit=33554432,\ 152 map=None, enable_SMTPUTF8=False, decode_data=False) 153 154 Create a new :class:`SMTPChannel` object which manages the communication 155 between the server and a single SMTP client. 156 157 *conn* and *addr* are as per the instance variables described below. 158 159 *data_size_limit* specifies the maximum number of bytes that will be 160 accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no 161 limit. 162 163 *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined 164 in :RFC:`6531`) should be enabled. The default is ``False``. 165 *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same 166 time. 167 168 A dictionary can be specified in *map* to avoid using a global socket map. 169 170 *decode_data* specifies whether the data portion of the SMTP transaction 171 should be decoded using UTF-8. The default is ``False``. 172 *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same 173 time. 174 175 To use a custom SMTPChannel implementation you need to override the 176 :attr:`SMTPServer.channel_class` of your :class:`SMTPServer`. 177 178 .. versionchanged:: 3.5 179 The *decode_data* and *enable_SMTPUTF8* parameters were added. 180 181 .. versionchanged:: 3.6 182 *decode_data* is now ``False`` by default. 183 184 The :class:`SMTPChannel` has the following instance variables: 185 186 .. attribute:: smtp_server 187 188 Holds the :class:`SMTPServer` that spawned this channel. 189 190 .. attribute:: conn 191 192 Holds the socket object connecting to the client. 193 194 .. attribute:: addr 195 196 Holds the address of the client, the second value returned by 197 :func:`socket.accept <socket.socket.accept>` 198 199 .. attribute:: received_lines 200 201 Holds a list of the line strings (decoded using UTF-8) received from 202 the client. The lines have their ``"\r\n"`` line ending translated to 203 ``"\n"``. 204 205 .. attribute:: smtp_state 206 207 Holds the current state of the channel. This will be either 208 :attr:`COMMAND` initially and then :attr:`DATA` after the client sends 209 a "DATA" line. 210 211 .. attribute:: seen_greeting 212 213 Holds a string containing the greeting sent by the client in its "HELO". 214 215 .. attribute:: mailfrom 216 217 Holds a string containing the address identified in the "MAIL FROM:" line 218 from the client. 219 220 .. attribute:: rcpttos 221 222 Holds a list of strings containing the addresses identified in the 223 "RCPT TO:" lines from the client. 224 225 .. attribute:: received_data 226 227 Holds a string containing all of the data sent by the client during the 228 DATA state, up to but not including the terminating ``"\r\n.\r\n"``. 229 230 .. attribute:: fqdn 231 232 Holds the fully qualified domain name of the server as returned by 233 :func:`socket.getfqdn`. 234 235 .. attribute:: peer 236 237 Holds the name of the client peer as returned by ``conn.getpeername()`` 238 where ``conn`` is :attr:`conn`. 239 240 The :class:`SMTPChannel` operates by invoking methods named ``smtp_<command>`` 241 upon reception of a command line from the client. Built into the base 242 :class:`SMTPChannel` class are methods for handling the following commands 243 (and responding to them appropriately): 244 245 ======== =================================================================== 246 Command Action taken 247 ======== =================================================================== 248 HELO Accepts the greeting from the client and stores it in 249 :attr:`seen_greeting`. Sets server to base command mode. 250 EHLO Accepts the greeting from the client and stores it in 251 :attr:`seen_greeting`. Sets server to extended command mode. 252 NOOP Takes no action. 253 QUIT Closes the connection cleanly. 254 MAIL Accepts the "MAIL FROM:" syntax and stores the supplied address as 255 :attr:`mailfrom`. In extended command mode, accepts the 256 :rfc:`1870` SIZE attribute and responds appropriately based on the 257 value of *data_size_limit*. 258 RCPT Accepts the "RCPT TO:" syntax and stores the supplied addresses in 259 the :attr:`rcpttos` list. 260 RSET Resets the :attr:`mailfrom`, :attr:`rcpttos`, and 261 :attr:`received_data`, but not the greeting. 262 DATA Sets the internal state to :attr:`DATA` and stores remaining lines 263 from the client in :attr:`received_data` until the terminator 264 ``"\r\n.\r\n"`` is received. 265 HELP Returns minimal information on command syntax 266 VRFY Returns code 252 (the server doesn't know if the address is valid) 267 EXPN Reports that the command is not implemented. 268 ======== =================================================================== 269