blob: 2ca71ffc3ccd1d2a5955951a30b94d94f75a998e [file] [log] [blame]
Georg Brandl116aa622007-08-15 14:28:22 +00001:mod:`smtpd` --- SMTP Server
2============================
3
4.. module:: smtpd
5 :synopsis: A SMTP server implementation in Python.
6
7.. moduleauthor:: Barry Warsaw <barry@zope.com>
8.. sectionauthor:: Moshe Zadka <moshez@moshez.org>
9
Raymond Hettinger469271d2011-01-27 20:38:46 +000010**Source code:** :source:`Lib/smtpd.py`
Georg Brandl116aa622007-08-15 14:28:22 +000011
Raymond Hettinger469271d2011-01-27 20:38:46 +000012--------------
Georg Brandl116aa622007-08-15 14:28:22 +000013
Richard Jones803ef8a2010-07-24 09:51:40 +000014This module offers several classes to implement SMTP (email) servers.
15
16Several server implementations are present; one is a generic
Georg Brandl116aa622007-08-15 14:28:22 +000017do-nothing implementation, which can be overridden, while the other two offer
18specific mail-sending strategies.
19
Richard Jones803ef8a2010-07-24 09:51:40 +000020Additionally the SMTPChannel may be extended to implement very specific
21interaction behaviour with SMTP clients.
Georg Brandl116aa622007-08-15 14:28:22 +000022
R David Murrayd1a30c92012-05-26 14:33:59 -040023The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE extension.
24
25
Georg Brandl116aa622007-08-15 14:28:22 +000026SMTPServer Objects
27------------------
28
29
R David Murrayd1a30c92012-05-26 14:33:59 -040030.. class:: SMTPServer(localaddr, remoteaddr, data_size_limit=33554432)
Georg Brandl116aa622007-08-15 14:28:22 +000031
32 Create a new :class:`SMTPServer` object, which binds to local address
33 *localaddr*. It will treat *remoteaddr* as an upstream SMTP relayer. It
34 inherits from :class:`asyncore.dispatcher`, and so will insert itself into
35 :mod:`asyncore`'s event loop on instantiation.
36
R David Murrayd1a30c92012-05-26 14:33:59 -040037 *data_size_limit* specifies the maximum number of bytes that will be
38 accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no
39 limit.
40
Benjamin Petersone41251e2008-04-25 01:59:09 +000041 .. method:: process_message(peer, mailfrom, rcpttos, data)
Georg Brandl116aa622007-08-15 14:28:22 +000042
Benjamin Petersone41251e2008-04-25 01:59:09 +000043 Raise :exc:`NotImplementedError` exception. Override this in subclasses to
44 do something useful with this message. Whatever was passed in the
45 constructor as *remoteaddr* will be available as the :attr:`_remoteaddr`
46 attribute. *peer* is the remote host's address, *mailfrom* is the envelope
47 originator, *rcpttos* are the envelope recipients and *data* is a string
48 containing the contents of the e-mail (which should be in :rfc:`2822`
49 format).
Georg Brandl116aa622007-08-15 14:28:22 +000050
Richard Jones803ef8a2010-07-24 09:51:40 +000051 .. attribute:: channel_class
52
53 Override this in subclasses to use a custom :class:`SMTPChannel` for
54 managing SMTP clients.
55
Georg Brandl116aa622007-08-15 14:28:22 +000056
57DebuggingServer Objects
58-----------------------
59
60
61.. class:: DebuggingServer(localaddr, remoteaddr)
62
63 Create a new debugging server. Arguments are as per :class:`SMTPServer`.
64 Messages will be discarded, and printed on stdout.
65
66
67PureProxy Objects
68-----------------
69
70
71.. class:: PureProxy(localaddr, remoteaddr)
72
73 Create a new pure proxy server. Arguments are as per :class:`SMTPServer`.
74 Everything will be relayed to *remoteaddr*. Note that running this has a good
75 chance to make you into an open relay, so please be careful.
76
77
78MailmanProxy Objects
79--------------------
80
81
82.. class:: MailmanProxy(localaddr, remoteaddr)
83
84 Create a new pure proxy server. Arguments are as per :class:`SMTPServer`.
85 Everything will be relayed to *remoteaddr*, unless local mailman configurations
86 knows about an address, in which case it will be handled via mailman. Note that
87 running this has a good chance to make you into an open relay, so please be
88 careful.
89
Richard Jones803ef8a2010-07-24 09:51:40 +000090SMTPChannel Objects
91-------------------
92
93.. class:: SMTPChannel(server, conn, addr)
94
95 Create a new :class:`SMTPChannel` object which manages the communication
96 between the server and a single SMTP client.
97
98 To use a custom SMTPChannel implementation you need to override the
99 :attr:`SMTPServer.channel_class` of your :class:`SMTPServer`.
100
101 The :class:`SMTPChannel` has the following instance variables:
102
103 .. attribute:: smtp_server
104
105 Holds the :class:`SMTPServer` that spawned this channel.
106
107 .. attribute:: conn
108
109 Holds the socket object connecting to the client.
110
111 .. attribute:: addr
112
113 Holds the address of the client, the second value returned by
Ezio Melotti8bbcb582012-09-20 09:06:51 +0300114 :func:`socket.accept <socket.socket.accept>`
Richard Jones803ef8a2010-07-24 09:51:40 +0000115
116 .. attribute:: received_lines
117
118 Holds a list of the line strings (decoded using UTF-8) received from
Ezio Melotti8bbcb582012-09-20 09:06:51 +0300119 the client. The lines have their ``"\r\n"`` line ending translated to
120 ``"\n"``.
Richard Jones803ef8a2010-07-24 09:51:40 +0000121
122 .. attribute:: smtp_state
123
124 Holds the current state of the channel. This will be either
125 :attr:`COMMAND` initially and then :attr:`DATA` after the client sends
126 a "DATA" line.
127
128 .. attribute:: seen_greeting
129
130 Holds a string containing the greeting sent by the client in its "HELO".
131
132 .. attribute:: mailfrom
133
134 Holds a string containing the address identified in the "MAIL FROM:" line
135 from the client.
136
137 .. attribute:: rcpttos
138
139 Holds a list of strings containing the addresses identified in the
140 "RCPT TO:" lines from the client.
141
142 .. attribute:: received_data
143
144 Holds a string containing all of the data sent by the client during the
Ezio Melotti8bbcb582012-09-20 09:06:51 +0300145 DATA state, up to but not including the terminating ``"\r\n.\r\n"``.
Richard Jones803ef8a2010-07-24 09:51:40 +0000146
147 .. attribute:: fqdn
148
149 Holds the fully-qualified domain name of the server as returned by
Ezio Melotti8bbcb582012-09-20 09:06:51 +0300150 :func:`socket.getfqdn`.
Richard Jones803ef8a2010-07-24 09:51:40 +0000151
152 .. attribute:: peer
153
154 Holds the name of the client peer as returned by ``conn.getpeername()``
155 where ``conn`` is :attr:`conn`.
156
157 The :class:`SMTPChannel` operates by invoking methods named ``smtp_<command>``
158 upon reception of a command line from the client. Built into the base
159 :class:`SMTPChannel` class are methods for handling the following commands
160 (and responding to them appropriately):
161
162 ======== ===================================================================
163 Command Action taken
164 ======== ===================================================================
165 HELO Accepts the greeting from the client and stores it in
R David Murrayd1a30c92012-05-26 14:33:59 -0400166 :attr:`seen_greeting`. Sets server to base command mode.
167 EHLO Accepts the greeting from the client and stores it in
168 :attr:`seen_greeting`. Sets server to extended command mode.
Richard Jones803ef8a2010-07-24 09:51:40 +0000169 NOOP Takes no action.
170 QUIT Closes the connection cleanly.
171 MAIL Accepts the "MAIL FROM:" syntax and stores the supplied address as
R David Murrayd1a30c92012-05-26 14:33:59 -0400172 :attr:`mailfrom`. In extended command mode, accepts the
173 :rfc:`1870` SIZE attribute and responds appropriately based on the
Ezio Melottia58d8b02012-09-20 09:09:24 +0300174 value of *data_size_limit*.
Richard Jones803ef8a2010-07-24 09:51:40 +0000175 RCPT Accepts the "RCPT TO:" syntax and stores the supplied addresses in
176 the :attr:`rcpttos` list.
177 RSET Resets the :attr:`mailfrom`, :attr:`rcpttos`, and
178 :attr:`received_data`, but not the greeting.
179 DATA Sets the internal state to :attr:`DATA` and stores remaining lines
180 from the client in :attr:`received_data` until the terminator
Ezio Melotti8bbcb582012-09-20 09:06:51 +0300181 ``"\r\n.\r\n"`` is received.
R David Murrayd1a30c92012-05-26 14:33:59 -0400182 HELP Returns minimal information on command syntax
183 VRFY Returns code 252 (the server doesn't know if the address is valid)
184 EXPN Reports that the command is not implemented.
Raymond Hettinger469271d2011-01-27 20:38:46 +0000185 ======== ===================================================================