blob: 71ccd2a207c0e6798835e01b096456bdb460433f [file] [log] [blame]
Benjamin Peterson90f5ba52010-03-11 22:53:45 +00001#! /usr/bin/env python3
Barry Warsaw4c4bec81998-12-22 03:02:20 +00002
Barry Warsawa1ae8842000-07-09 21:24:31 +00003'''SMTP/ESMTP client class.
Guido van Rossumbbe323e1998-01-29 17:24:40 +00004
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +00005This should follow RFC 821 (SMTP), RFC 1869 (ESMTP), RFC 2554 (SMTP
6Authentication) and RFC 2487 (Secure SMTP over TLS).
Guido van Rossumbbe323e1998-01-29 17:24:40 +00007
Guido van Rossumfcfb6321998-08-04 15:29:54 +00008Notes:
9
10Please remember, when doing ESMTP, that the names of the SMTP service
Barry Warsaw4c4bec81998-12-22 03:02:20 +000011extensions are NOT the same thing as the option keywords for the RCPT
Guido van Rossumfcfb6321998-08-04 15:29:54 +000012and MAIL commands!
13
Guido van Rossumbbe323e1998-01-29 17:24:40 +000014Example:
15
Barry Warsawa7d9bdf1998-12-22 03:24:27 +000016 >>> import smtplib
17 >>> s=smtplib.SMTP("localhost")
Guido van Rossum7131f842007-02-09 20:13:25 +000018 >>> print(s.help())
Barry Warsawa7d9bdf1998-12-22 03:24:27 +000019 This is Sendmail version 8.8.4
20 Topics:
21 HELO EHLO MAIL RCPT DATA
22 RSET NOOP QUIT HELP VRFY
23 EXPN VERB ETRN DSN
24 For more info use "HELP <topic>".
25 To report bugs in the implementation send email to
26 sendmail-bugs@sendmail.org.
27 For local information send email to Postmaster at your site.
28 End of HELP info
29 >>> s.putcmd("vrfy","someone@here")
30 >>> s.getreply()
31 (250, "Somebody OverHere <somebody@here.my.org>")
32 >>> s.quit()
Barry Warsawa1ae8842000-07-09 21:24:31 +000033'''
Guido van Rossumbbe323e1998-01-29 17:24:40 +000034
Guido van Rossum98d9fd32000-02-28 15:12:25 +000035# Author: The Dragon De Monsyne <dragondm@integral.org>
36# ESMTP support, test code and doc fixes added by
37# Eric S. Raymond <esr@thyrsus.com>
38# Better RFC 821 compliance (MAIL and RCPT, and CRLF in data)
39# by Carey Evans <c.evans@clear.net.nz>, for picky mail servers.
Guido van Rossumae010462001-09-11 15:57:46 +000040# RFC 2554 (authentication) support by Gerhard Haering <gerhard@bigfoot.de>.
Tim Peters495ad3c2001-01-15 01:36:40 +000041#
Guido van Rossum98d9fd32000-02-28 15:12:25 +000042# This was modified from the Python 1.5 library HTTP lib.
43
Guido van Rossumbbe323e1998-01-29 17:24:40 +000044import socket
R. David Murray7dff9e02010-11-08 17:15:13 +000045import io
Barry Warsaw07201771998-12-22 20:37:36 +000046import re
Thomas Woutersb2137042007-02-01 18:02:27 +000047import email.utils
R. David Murray7dff9e02010-11-08 17:15:13 +000048import email.message
49import email.generator
Guido van Rossumae010462001-09-11 15:57:46 +000050import base64
51import hmac
R David Murrayac4e5ab2011-07-02 21:03:19 -040052import copy
R David Murray0c49b892015-04-16 17:14:42 -040053import datetime
54import sys
Barry Warsaw2cc1f6d2007-08-30 14:28:55 +000055from email.base64mime import body_encode as encode_base64
Guido van Rossumbbe323e1998-01-29 17:24:40 +000056
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +000057__all__ = ["SMTPException", "SMTPServerDisconnected", "SMTPResponseException",
58 "SMTPSenderRefused", "SMTPRecipientsRefused", "SMTPDataError",
59 "SMTPConnectError", "SMTPHeloError", "SMTPAuthenticationError",
60 "quoteaddr", "quotedata", "SMTP"]
Skip Montanaro0de65802001-02-15 22:15:14 +000061
Guido van Rossumbbe323e1998-01-29 17:24:40 +000062SMTP_PORT = 25
Thomas Wouters89f507f2006-12-13 04:49:30 +000063SMTP_SSL_PORT = 465
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +000064CRLF = "\r\n"
65bCRLF = b"\r\n"
Georg Brandlb38b5c42014-02-10 22:11:21 +010066_MAXLINE = 8192 # more than 8 times larger than RFC 821, 4.5.3
Guido van Rossumbbe323e1998-01-29 17:24:40 +000067
Piers Lauder385a77a2002-07-27 00:38:30 +000068OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)
69
Tim Peters495ad3c2001-01-15 01:36:40 +000070# Exception classes used by this module.
R David Murray8a345962013-04-14 06:46:35 -040071class SMTPException(OSError):
Guido van Rossum296e1431999-04-07 15:03:39 +000072 """Base class for all exceptions raised by this module."""
73
R David Murraycee7cf62015-05-16 13:58:14 -040074class SMTPNotSupportedError(SMTPException):
75 """The command or option is not supported by the SMTP server.
76
77 This exception is raised when an attempt is made to run a command or a
78 command with an option which is not supported by the server.
79 """
80
Guido van Rossum296e1431999-04-07 15:03:39 +000081class SMTPServerDisconnected(SMTPException):
82 """Not connected to any SMTP server.
83
84 This exception is raised when the server unexpectedly disconnects,
85 or when an attempt is made to use the SMTP instance before
86 connecting it to a server.
87 """
88
89class SMTPResponseException(SMTPException):
90 """Base class for all exceptions that include an SMTP error code.
91
92 These exceptions are generated in some instances when the SMTP
93 server returns an error code. The error code is stored in the
94 `smtp_code' attribute of the error, and the `smtp_error' attribute
95 is set to the error message.
96 """
97
98 def __init__(self, code, msg):
99 self.smtp_code = code
100 self.smtp_error = msg
101 self.args = (code, msg)
102
103class SMTPSenderRefused(SMTPResponseException):
104 """Sender address refused.
Guido van Rossumae010462001-09-11 15:57:46 +0000105
Guido van Rossum296e1431999-04-07 15:03:39 +0000106 In addition to the attributes set by on all SMTPResponseException
Barry Warsawd25c1b71999-11-28 17:11:06 +0000107 exceptions, this sets `sender' to the string that the SMTP refused.
Guido van Rossum296e1431999-04-07 15:03:39 +0000108 """
109
110 def __init__(self, code, msg, sender):
111 self.smtp_code = code
112 self.smtp_error = msg
113 self.sender = sender
114 self.args = (code, msg, sender)
115
Guido van Rossum20c92281999-04-21 16:52:20 +0000116class SMTPRecipientsRefused(SMTPException):
Barry Warsawd25c1b71999-11-28 17:11:06 +0000117 """All recipient addresses refused.
Guido van Rossumae010462001-09-11 15:57:46 +0000118
Thomas Wouters7e474022000-07-16 12:04:32 +0000119 The errors for each recipient are accessible through the attribute
Tim Peters495ad3c2001-01-15 01:36:40 +0000120 'recipients', which is a dictionary of exactly the same sort as
121 SMTP.sendmail() returns.
Guido van Rossum296e1431999-04-07 15:03:39 +0000122 """
123
124 def __init__(self, recipients):
125 self.recipients = recipients
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000126 self.args = (recipients,)
Guido van Rossum296e1431999-04-07 15:03:39 +0000127
128
Guido van Rossum296e1431999-04-07 15:03:39 +0000129class SMTPDataError(SMTPResponseException):
130 """The SMTP server didn't accept the data."""
131
132class SMTPConnectError(SMTPResponseException):
Barry Warsawd25c1b71999-11-28 17:11:06 +0000133 """Error during connection establishment."""
Guido van Rossum296e1431999-04-07 15:03:39 +0000134
135class SMTPHeloError(SMTPResponseException):
Barry Warsawd25c1b71999-11-28 17:11:06 +0000136 """The server refused our HELO reply."""
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000137
Guido van Rossumae010462001-09-11 15:57:46 +0000138class SMTPAuthenticationError(SMTPResponseException):
139 """Authentication error.
140
141 Most probably the server didn't accept the username/password
142 combination provided.
143 """
Peter Schneider-Kamp7bc82bb2000-08-10 14:02:23 +0000144
R David Murray4c14bba2011-07-18 21:59:53 -0400145def quoteaddr(addrstring):
Guido van Rossum69a79bc1998-07-13 15:18:49 +0000146 """Quote a subset of the email addresses defined by RFC 821.
147
Georg Brandl9f0f9602008-06-12 22:23:59 +0000148 Should be able to handle anything email.utils.parseaddr can handle.
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000149 """
R David Murray4c14bba2011-07-18 21:59:53 -0400150 displayname, addr = email.utils.parseaddr(addrstring)
151 if (displayname, addr) == ('', ''):
152 # parseaddr couldn't parse it, use it as is and hope for the best.
153 if addrstring.strip().startswith('<'):
154 return addrstring
155 return "<%s>" % addrstring
156 return "<%s>" % addr
Guido van Rossum69a79bc1998-07-13 15:18:49 +0000157
R David Murray46346762011-07-18 21:38:54 -0400158def _addr_only(addrstring):
159 displayname, addr = email.utils.parseaddr(addrstring)
160 if (displayname, addr) == ('', ''):
161 # parseaddr couldn't parse it, so use it as is.
162 return addrstring
163 return addr
164
R. David Murray7dff9e02010-11-08 17:15:13 +0000165# Legacy method kept for backward compatibility.
Guido van Rossum69a79bc1998-07-13 15:18:49 +0000166def quotedata(data):
167 """Quote data for email.
168
Barry Warsawd25c1b71999-11-28 17:11:06 +0000169 Double leading '.', and change Unix newline '\\n', or Mac '\\r' into
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000170 Internet CRLF end-of-line.
171 """
Guido van Rossum69a79bc1998-07-13 15:18:49 +0000172 return re.sub(r'(?m)^\.', '..',
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000173 re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data))
Guido van Rossum69a79bc1998-07-13 15:18:49 +0000174
R. David Murray7dff9e02010-11-08 17:15:13 +0000175def _quote_periods(bindata):
R David Murray0f663d02011-06-09 15:05:57 -0400176 return re.sub(br'(?m)^\.', b'..', bindata)
R. David Murray7dff9e02010-11-08 17:15:13 +0000177
178def _fix_eols(data):
179 return re.sub(r'(?:\r\n|\n|\r(?!\n))', CRLF, data)
180
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000181try:
182 import ssl
Brett Cannoncd171c82013-07-04 17:43:24 -0400183except ImportError:
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000184 _have_ssl = False
185else:
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000186 _have_ssl = True
187
Peter Schneider-Kamp7bc82bb2000-08-10 14:02:23 +0000188
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000189class SMTP:
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000190 """This class manages a connection to an SMTP or ESMTP server.
191 SMTP Objects:
Tim Peters495ad3c2001-01-15 01:36:40 +0000192 SMTP objects have the following attributes:
193 helo_resp
194 This is the message given by the server in response to the
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000195 most recent HELO command.
Tim Peters495ad3c2001-01-15 01:36:40 +0000196
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000197 ehlo_resp
Tim Peters495ad3c2001-01-15 01:36:40 +0000198 This is the message given by the server in response to the
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000199 most recent EHLO command. This is usually multiline.
200
Tim Peters495ad3c2001-01-15 01:36:40 +0000201 does_esmtp
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000202 This is a True value _after you do an EHLO command_, if the
203 server supports ESMTP.
204
Tim Peters495ad3c2001-01-15 01:36:40 +0000205 esmtp_features
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000206 This is a dictionary, which, if the server supports ESMTP,
Barry Warsawd25c1b71999-11-28 17:11:06 +0000207 will _after you do an EHLO command_, contain the names of the
208 SMTP service extensions this server supports, and their
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000209 parameters (if any).
Barry Warsawd25c1b71999-11-28 17:11:06 +0000210
Tim Peters495ad3c2001-01-15 01:36:40 +0000211 Note, all extension names are mapped to lower case in the
212 dictionary.
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000213
Barry Warsawd25c1b71999-11-28 17:11:06 +0000214 See each method's docstrings for details. In general, there is a
215 method of the same name to perform each SMTP command. There is also a
216 method called 'sendmail' that will do an entire mail transaction.
217 """
Guido van Rossum95e6f701998-06-25 02:15:50 +0000218 debuglevel = 0
219 file = None
220 helo_resp = None
Guido van Rossumd8faa362007-04-27 19:54:29 +0000221 ehlo_msg = "ehlo"
Guido van Rossum95e6f701998-06-25 02:15:50 +0000222 ehlo_resp = None
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000223 does_esmtp = 0
Antoine Pitrouc1d52062011-05-07 19:39:37 +0200224 default_port = SMTP_PORT
Guido van Rossum95e6f701998-06-25 02:15:50 +0000225
Georg Brandlf78e02b2008-06-10 17:40:04 +0000226 def __init__(self, host='', port=0, local_hostname=None,
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800227 timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
228 source_address=None):
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000229 """Initialize a new instance.
230
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000231 If specified, `host' is the name of the remote host to which to
232 connect. If specified, `port' specifies the port to which to connect.
R David Murray14ee3cf2013-04-13 14:40:33 -0400233 By default, smtplib.SMTP_PORT is used. If a host is specified the
R David Murray021362d2013-06-23 16:05:44 -0400234 connect method is called, and if it returns anything other than a
235 success code an SMTPConnectError is raised. If specified,
236 `local_hostname` is used as the FQDN of the local host in the HELO/EHLO
237 command. Otherwise, the local hostname is found using
238 socket.getfqdn(). The `source_address` parameter takes a 2-tuple (host,
239 port) for the socket to bind to as its source address before
240 connecting. If the host is '' and port is 0, the OS default behavior
241 will be used.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000242
243 """
Christian Heimesa5768f72013-12-02 20:44:17 +0100244 self._host = host
Guido van Rossumd8faa362007-04-27 19:54:29 +0000245 self.timeout = timeout
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000246 self.esmtp_features = {}
R David Murraycee7cf62015-05-16 13:58:14 -0400247 self.command_encoding = 'ascii'
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800248 self.source_address = source_address
249
Guido van Rossum296e1431999-04-07 15:03:39 +0000250 if host:
251 (code, msg) = self.connect(host, port)
252 if code != 220:
253 raise SMTPConnectError(code, msg)
Raymond Hettingerf13eb552002-06-02 00:40:05 +0000254 if local_hostname is not None:
Barry Warsaw13e34f72002-03-26 20:27:35 +0000255 self.local_hostname = local_hostname
Neil Schemenauer6730f262002-03-24 15:30:40 +0000256 else:
Barry Warsaw13e34f72002-03-26 20:27:35 +0000257 # RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and
258 # if that can't be calculated, that we should use a domain literal
259 # instead (essentially an encoded IP address like [A.B.C.D]).
260 fqdn = socket.getfqdn()
261 if '.' in fqdn:
262 self.local_hostname = fqdn
263 else:
264 # We can't find an fqdn hostname, so use a domain literal
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000265 addr = '127.0.0.1'
266 try:
267 addr = socket.gethostbyname(socket.gethostname())
268 except socket.gaierror:
269 pass
Barry Warsaw13e34f72002-03-26 20:27:35 +0000270 self.local_hostname = '[%s]' % addr
Tim Peters495ad3c2001-01-15 01:36:40 +0000271
Barry Warsaw1f5c9582011-03-15 15:04:44 -0400272 def __enter__(self):
273 return self
274
275 def __exit__(self, *args):
276 try:
277 code, message = self.docmd("QUIT")
278 if code != 221:
279 raise SMTPResponseException(code, message)
280 except SMTPServerDisconnected:
281 pass
282 finally:
283 self.close()
284
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000285 def set_debuglevel(self, debuglevel):
286 """Set the debug output level.
287
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000288 A non-false value results in debug messages for connection and for all
289 messages sent to and received from the server.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000290
291 """
292 self.debuglevel = debuglevel
293
R David Murray0c49b892015-04-16 17:14:42 -0400294 def _print_debug(self, *args):
295 if self.debuglevel > 1:
296 print(datetime.datetime.now().time(), *args, file=sys.stderr)
297 else:
298 print(*args, file=sys.stderr)
299
Barry Warsawc9181712008-03-19 14:25:51 +0000300 def _get_socket(self, host, port, timeout):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000301 # This makes it simpler for SMTP_SSL to use the SMTP connect code
302 # and just alter the socket connection bit.
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000303 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400304 self._print_debug('connect: to', (host, port), self.source_address)
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800305 return socket.create_connection((host, port), timeout,
306 self.source_address)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000307
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800308 def connect(self, host='localhost', port=0, source_address=None):
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000309 """Connect to a host on a given port.
Guido van Rossum95e6f701998-06-25 02:15:50 +0000310
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000311 If the hostname ends with a colon (`:') followed by a number, and
312 there is no port specified, that suffix will be stripped off and the
313 number interpreted as the port number to use.
Guido van Rossum95e6f701998-06-25 02:15:50 +0000314
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000315 Note: This method is automatically invoked by __init__, if a host is
316 specified during instantiation.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000317
318 """
Senthil Kumaranb351a482011-07-31 09:14:17 +0800319
320 if source_address:
321 self.source_address = source_address
322
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000323 if not port and (host.find(':') == host.rfind(':')):
Martin v. Löwisa43c2f82001-07-24 20:34:08 +0000324 i = host.rfind(':')
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000325 if i >= 0:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000326 host, port = host[:i], host[i + 1:]
327 try:
328 port = int(port)
Eric S. Raymond8d876032001-02-09 10:14:53 +0000329 except ValueError:
Andrew Svetlov2ade6f22012-12-17 18:57:16 +0200330 raise OSError("nonnumeric port")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000331 if not port:
332 port = self.default_port
333 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400334 self._print_debug('connect:', (host, port))
Guido van Rossumd8faa362007-04-27 19:54:29 +0000335 self.sock = self._get_socket(host, port, self.timeout)
Antoine Pitrouf068ab82011-06-06 19:17:09 +0200336 self.file = None
Martin v. Löwisa43c2f82001-07-24 20:34:08 +0000337 (code, msg) = self.getreply()
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000338 if self.debuglevel > 0:
R David Murray37f1ba92015-04-16 18:54:56 -0400339 self._print_debug('connect:', repr(msg))
Martin v. Löwisa43c2f82001-07-24 20:34:08 +0000340 return (code, msg)
Tim Peters495ad3c2001-01-15 01:36:40 +0000341
Guido van Rossum8a392d72007-11-21 22:09:45 +0000342 def send(self, s):
343 """Send `s' to the server."""
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000344 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400345 self._print_debug('send:', repr(s))
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000346 if hasattr(self, 'sock') and self.sock:
Guido van Rossum8a392d72007-11-21 22:09:45 +0000347 if isinstance(s, str):
R David Murraycee7cf62015-05-16 13:58:14 -0400348 # send is used by the 'data' command, where command_encoding
349 # should not be used, but 'data' needs to convert the string to
350 # binary itself anyway, so that's not a problem.
351 s = s.encode(self.command_encoding)
Guido van Rossum2880f6e1998-08-10 20:07:00 +0000352 try:
Guido van Rossum8a392d72007-11-21 22:09:45 +0000353 self.sock.sendall(s)
Andrew Svetlov2ade6f22012-12-17 18:57:16 +0200354 except OSError:
Barry Warsaw76750972001-12-14 20:34:20 +0000355 self.close()
Guido van Rossum40233ea1999-01-15 03:23:55 +0000356 raise SMTPServerDisconnected('Server not connected')
Guido van Rossumfc40a831998-01-29 17:26:45 +0000357 else:
Guido van Rossum40233ea1999-01-15 03:23:55 +0000358 raise SMTPServerDisconnected('please run connect() first')
Tim Peters495ad3c2001-01-15 01:36:40 +0000359
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000360 def putcmd(self, cmd, args=""):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000361 """Send a command to the server."""
Guido van Rossumdb23d3d1999-06-09 15:13:10 +0000362 if args == "":
363 str = '%s%s' % (cmd, CRLF)
364 else:
365 str = '%s %s%s' % (cmd, args, CRLF)
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000366 self.send(str)
Tim Peters495ad3c2001-01-15 01:36:40 +0000367
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000368 def getreply(self):
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000369 """Get a reply from the server.
Tim Peters495ad3c2001-01-15 01:36:40 +0000370
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000371 Returns a tuple consisting of:
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000372
373 - server response code (e.g. '250', or such, if all goes well)
374 Note: returns -1 if it can't read response code.
375
376 - server response string corresponding to response code (multiline
377 responses are converted to a single, multiline string).
Guido van Rossumf123f841999-03-29 20:33:21 +0000378
379 Raises SMTPServerDisconnected if end-of-file is reached.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000380 """
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000381 resp = []
Guido van Rossum296e1431999-04-07 15:03:39 +0000382 if self.file is None:
383 self.file = self.sock.makefile('rb')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000384 while 1:
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000385 try:
Georg Brandlb38b5c42014-02-10 22:11:21 +0100386 line = self.file.readline(_MAXLINE + 1)
Andrew Svetlov2ade6f22012-12-17 18:57:16 +0200387 except OSError as e:
Antoine Pitrou6b2e1602011-08-28 01:20:42 +0200388 self.close()
389 raise SMTPServerDisconnected("Connection unexpectedly closed: "
390 + str(e))
Guido van Rossum806c2462007-08-06 23:33:07 +0000391 if not line:
Guido van Rossum296e1431999-04-07 15:03:39 +0000392 self.close()
393 raise SMTPServerDisconnected("Connection unexpectedly closed")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000394 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400395 self._print_debug('reply:', repr(line))
Georg Brandlb38b5c42014-02-10 22:11:21 +0100396 if len(line) > _MAXLINE:
Senthil Kumaran4ce118e2014-06-03 07:24:54 -0700397 self.close()
Georg Brandlb38b5c42014-02-10 22:11:21 +0100398 raise SMTPResponseException(500, "Line too long.")
Guido van Rossum806c2462007-08-06 23:33:07 +0000399 resp.append(line[4:].strip(b' \t\r\n'))
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000400 code = line[:3]
Guido van Rossum296e1431999-04-07 15:03:39 +0000401 # Check that the error code is syntactically correct.
402 # Don't attempt to read a continuation line if it is broken.
403 try:
Eric S. Raymondc013f302001-02-09 05:40:38 +0000404 errcode = int(code)
Guido van Rossum296e1431999-04-07 15:03:39 +0000405 except ValueError:
406 errcode = -1
407 break
Guido van Rossumf123f841999-03-29 20:33:21 +0000408 # Check if multiline response.
Guido van Rossum806c2462007-08-06 23:33:07 +0000409 if line[3:4] != b"-":
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000410 break
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000411
Guido van Rossumc43e79f2007-06-18 18:26:36 +0000412 errmsg = b"\n".join(resp)
Tim Peters495ad3c2001-01-15 01:36:40 +0000413 if self.debuglevel > 0:
R David Murray37f1ba92015-04-16 18:54:56 -0400414 self._print_debug('reply: retcode (%s); Msg: %a' % (errcode, errmsg))
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000415 return errcode, errmsg
Tim Peters495ad3c2001-01-15 01:36:40 +0000416
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000417 def docmd(self, cmd, args=""):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000418 """Send a command, and return its response code."""
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000419 self.putcmd(cmd, args)
Guido van Rossum296e1431999-04-07 15:03:39 +0000420 return self.getreply()
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000421
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000422 # std smtp commands
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000423 def helo(self, name=''):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000424 """SMTP 'helo' command.
425 Hostname to send for this command defaults to the FQDN of the local
426 host.
427 """
Neil Schemenauer6730f262002-03-24 15:30:40 +0000428 self.putcmd("helo", name or self.local_hostname)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000429 (code, msg) = self.getreply()
430 self.helo_resp = msg
431 return (code, msg)
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000432
Guido van Rossum95e6f701998-06-25 02:15:50 +0000433 def ehlo(self, name=''):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000434 """ SMTP 'ehlo' command.
435 Hostname to send for this command defaults to the FQDN of the local
436 host.
437 """
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000438 self.esmtp_features = {}
Guido van Rossumd8faa362007-04-27 19:54:29 +0000439 self.putcmd(self.ehlo_msg, name or self.local_hostname)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000440 (code, msg) = self.getreply()
Tim Peters495ad3c2001-01-15 01:36:40 +0000441 # According to RFC1869 some (badly written)
442 # MTA's will disconnect on an ehlo. Toss an exception if
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000443 # that happens -ddm
444 if code == -1 and len(msg) == 0:
Barry Warsaw76750972001-12-14 20:34:20 +0000445 self.close()
Guido van Rossum40233ea1999-01-15 03:23:55 +0000446 raise SMTPServerDisconnected("Server not connected")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000447 self.ehlo_resp = msg
Fred Drake8152d322000-12-12 23:20:45 +0000448 if code != 250:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000449 return (code, msg)
450 self.does_esmtp = 1
Thomas Wouters7e474022000-07-16 12:04:32 +0000451 #parse the ehlo response -ddm
Guido van Rossum04110fb2007-08-24 16:32:05 +0000452 assert isinstance(self.ehlo_resp, bytes), repr(self.ehlo_resp)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000453 resp = self.ehlo_resp.decode("latin-1").split('\n')
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000454 del resp[0]
Guido van Rossum2880f6e1998-08-10 20:07:00 +0000455 for each in resp:
Piers Lauder385a77a2002-07-27 00:38:30 +0000456 # To be able to communicate with as many SMTP servers as possible,
457 # we have to take the old-style auth advertisement into account,
458 # because:
459 # 1) Else our SMTP feature parser gets confused.
460 # 2) There are some servers that only advertise the auth methods we
461 # support using the old style.
462 auth_match = OLDSTYLE_AUTH.match(each)
463 if auth_match:
464 # This doesn't remove duplicates, but that's no problem
465 self.esmtp_features["auth"] = self.esmtp_features.get("auth", "") \
466 + " " + auth_match.groups(0)[0]
467 continue
468
Barry Warsawbe22ae62002-04-15 20:03:30 +0000469 # RFC 1869 requires a space between ehlo keyword and parameters.
470 # It's actually stricter, in that only spaces are allowed between
471 # parameters, but were not going to check for that here. Note
472 # that the space isn't present if there are no parameters.
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000473 m = re.match(r'(?P<feature>[A-Za-z0-9][A-Za-z0-9\-]*) ?', each)
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000474 if m:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000475 feature = m.group("feature").lower()
476 params = m.string[m.end("feature"):].strip()
Piers Lauder385a77a2002-07-27 00:38:30 +0000477 if feature == "auth":
478 self.esmtp_features[feature] = self.esmtp_features.get(feature, "") \
479 + " " + params
480 else:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000481 self.esmtp_features[feature] = params
482 return (code, msg)
Guido van Rossum95e6f701998-06-25 02:15:50 +0000483
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000484 def has_extn(self, opt):
485 """Does the server support a given SMTP service extension?"""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000486 return opt.lower() in self.esmtp_features
Guido van Rossum95e6f701998-06-25 02:15:50 +0000487
Guido van Rossum18586f41998-04-03 17:03:13 +0000488 def help(self, args=''):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000489 """SMTP 'help' command.
490 Returns help text from server."""
Guido van Rossum18586f41998-04-03 17:03:13 +0000491 self.putcmd("help", args)
Kurt B. Kaiser58bd1902005-06-26 18:27:36 +0000492 return self.getreply()[1]
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000493
494 def rset(self):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000495 """SMTP 'rset' command -- resets session."""
R David Murraycee7cf62015-05-16 13:58:14 -0400496 self.command_encoding = 'ascii'
Guido van Rossum296e1431999-04-07 15:03:39 +0000497 return self.docmd("rset")
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000498
R David Murrayafb151a2014-04-14 18:21:38 -0400499 def _rset(self):
500 """Internal 'rset' command which ignores any SMTPServerDisconnected error.
501
502 Used internally in the library, since the server disconnected error
503 should appear to the application when the *next* command is issued, if
504 we are doing an internal "safety" reset.
505 """
506 try:
507 self.rset()
508 except SMTPServerDisconnected:
509 pass
510
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000511 def noop(self):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000512 """SMTP 'noop' command -- doesn't do anything :>"""
Guido van Rossum296e1431999-04-07 15:03:39 +0000513 return self.docmd("noop")
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000514
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000515 def mail(self, sender, options=[]):
R David Murraycee7cf62015-05-16 13:58:14 -0400516 """SMTP 'mail' command -- begins mail xfer session.
517
518 This method may raise the following exceptions:
519
520 SMTPNotSupportedError The options parameter includes 'SMTPUTF8'
521 but the SMTPUTF8 extension is not supported by
522 the server.
523 """
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000524 optionlist = ''
525 if options and self.does_esmtp:
R David Murraycee7cf62015-05-16 13:58:14 -0400526 if any(x.lower()=='smtputf8' for x in options):
527 if self.has_extn('smtputf8'):
528 self.command_encoding = 'utf-8'
529 else:
530 raise SMTPNotSupportedError(
531 'SMTPUTF8 not supported by server')
Eric S. Raymondc013f302001-02-09 05:40:38 +0000532 optionlist = ' ' + ' '.join(options)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000533 self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000534 return self.getreply()
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000535
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000536 def rcpt(self, recip, options=[]):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000537 """SMTP 'rcpt' command -- indicates 1 recipient for this mail."""
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000538 optionlist = ''
539 if options and self.does_esmtp:
Eric S. Raymondc013f302001-02-09 05:40:38 +0000540 optionlist = ' ' + ' '.join(options)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000541 self.putcmd("rcpt", "TO:%s%s" % (quoteaddr(recip), optionlist))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000542 return self.getreply()
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000543
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000544 def data(self, msg):
Tim Peters495ad3c2001-01-15 01:36:40 +0000545 """SMTP 'DATA' command -- sends message data to server.
Guido van Rossum296e1431999-04-07 15:03:39 +0000546
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000547 Automatically quotes lines beginning with a period per rfc821.
Guido van Rossum296e1431999-04-07 15:03:39 +0000548 Raises SMTPDataError if there is an unexpected reply to the
549 DATA command; the return value from this method is the final
R. David Murray7dff9e02010-11-08 17:15:13 +0000550 response code received when the all data is sent. If msg
Serhiy Storchaka9f8a8912015-04-03 18:12:41 +0300551 is a string, lone '\\r' and '\\n' characters are converted to
552 '\\r\\n' characters. If msg is bytes, it is transmitted as is.
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000553 """
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000554 self.putcmd("data")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000555 (code, repl) = self.getreply()
556 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400557 self._print_debug('data:', (code, repl))
Fred Drake8152d322000-12-12 23:20:45 +0000558 if code != 354:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000559 raise SMTPDataError(code, repl)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000560 else:
R. David Murray7dff9e02010-11-08 17:15:13 +0000561 if isinstance(msg, str):
562 msg = _fix_eols(msg).encode('ascii')
563 q = _quote_periods(msg)
564 if q[-2:] != bCRLF:
565 q = q + bCRLF
566 q = q + b"." + bCRLF
Guido van Rossum20c92281999-04-21 16:52:20 +0000567 self.send(q)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000568 (code, msg) = self.getreply()
569 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400570 self._print_debug('data:', (code, msg))
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000571 return (code, msg)
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000572
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000573 def verify(self, address):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000574 """SMTP 'verify' command -- checks for address validity."""
R David Murray46346762011-07-18 21:38:54 -0400575 self.putcmd("vrfy", _addr_only(address))
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000576 return self.getreply()
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000577 # a.k.a.
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000578 vrfy = verify
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000579
580 def expn(self, address):
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000581 """SMTP 'expn' command -- expands a mailing list."""
R David Murray46346762011-07-18 21:38:54 -0400582 self.putcmd("expn", _addr_only(address))
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000583 return self.getreply()
584
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000585 # some useful methods
Guido van Rossumae010462001-09-11 15:57:46 +0000586
Christian Heimes679db4a2008-01-18 09:56:22 +0000587 def ehlo_or_helo_if_needed(self):
588 """Call self.ehlo() and/or self.helo() if needed.
589
590 If there has been no previous EHLO or HELO command this session, this
591 method tries ESMTP EHLO first.
592
593 This method may raise the following exceptions:
594
595 SMTPHeloError The server didn't reply properly to
596 the helo greeting.
597 """
598 if self.helo_resp is None and self.ehlo_resp is None:
599 if not (200 <= self.ehlo()[0] <= 299):
600 (code, resp) = self.helo()
601 if not (200 <= code <= 299):
602 raise SMTPHeloError(code, resp)
603
R David Murray76e13c12014-07-03 14:47:46 -0400604 def auth(self, mechanism, authobject):
605 """Authentication command - requires response processing.
606
607 'mechanism' specifies which authentication mechanism is to
608 be used - the valid values are those listed in the 'auth'
609 element of 'esmtp_features'.
610
611 'authobject' must be a callable object taking a single argument:
612
613 data = authobject(challenge)
614
615 It will be called to process the server's challenge response; the
616 challenge argument it is passed will be a bytes. It should return
617 bytes data that will be base64 encoded and sent to the server.
618 """
619
620 mechanism = mechanism.upper()
621 (code, resp) = self.docmd("AUTH", mechanism)
622 # Server replies with 334 (challenge) or 535 (not supported)
623 if code == 334:
624 challenge = base64.decodebytes(resp)
625 response = encode_base64(
626 authobject(challenge).encode('ascii'), eol='')
627 (code, resp) = self.docmd(response)
628 if code in (235, 503):
629 return (code, resp)
630 raise SMTPAuthenticationError(code, resp)
631
632 def auth_cram_md5(self, challenge):
633 """ Authobject to use with CRAM-MD5 authentication. Requires self.user
634 and self.password to be set."""
635 return self.user + " " + hmac.HMAC(
636 self.password.encode('ascii'), challenge, 'md5').hexdigest()
637
638 def auth_plain(self, challenge):
639 """ Authobject to use with PLAIN authentication. Requires self.user and
640 self.password to be set."""
641 return "\0%s\0%s" % (self.user, self.password)
642
643 def auth_login(self, challenge):
644 """ Authobject to use with LOGIN authentication. Requires self.user and
645 self.password to be set."""
646 (code, resp) = self.docmd(
647 encode_base64(self.user.encode('ascii'), eol=''))
648 if code == 334:
649 return self.password
650 raise SMTPAuthenticationError(code, resp)
651
Guido van Rossumae010462001-09-11 15:57:46 +0000652 def login(self, user, password):
653 """Log in on an SMTP server that requires authentication.
654
655 The arguments are:
R David Murray76e13c12014-07-03 14:47:46 -0400656 - user: The user name to authenticate with.
657 - password: The password for the authentication.
Guido van Rossumae010462001-09-11 15:57:46 +0000658
659 If there has been no previous EHLO or HELO command this session, this
660 method tries ESMTP EHLO first.
661
662 This method will return normally if the authentication was successful.
663
664 This method may raise the following exceptions:
665
666 SMTPHeloError The server didn't reply properly to
667 the helo greeting.
668 SMTPAuthenticationError The server didn't accept the username/
669 password combination.
R David Murraycee7cf62015-05-16 13:58:14 -0400670 SMTPNotSupportedError The AUTH command is not supported by the
671 server.
Fred Drake2f8f4d32001-10-13 18:35:32 +0000672 SMTPException No suitable authentication method was
Guido van Rossumae010462001-09-11 15:57:46 +0000673 found.
674 """
675
Christian Heimes679db4a2008-01-18 09:56:22 +0000676 self.ehlo_or_helo_if_needed()
Guido van Rossumae010462001-09-11 15:57:46 +0000677 if not self.has_extn("auth"):
R David Murraycee7cf62015-05-16 13:58:14 -0400678 raise SMTPNotSupportedError(
679 "SMTP AUTH extension not supported by server.")
Guido van Rossumae010462001-09-11 15:57:46 +0000680
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000681 # Authentication methods the server claims to support
682 advertised_authlist = self.esmtp_features["auth"].split()
Guido van Rossumae010462001-09-11 15:57:46 +0000683
R David Murray76e13c12014-07-03 14:47:46 -0400684 # Authentication methods we can handle in our preferred order:
685 preferred_auths = ['CRAM-MD5', 'PLAIN', 'LOGIN']
Guido van Rossumae010462001-09-11 15:57:46 +0000686
R David Murray76e13c12014-07-03 14:47:46 -0400687 # We try the supported authentications in our preferred order, if
688 # the server supports them.
689 authlist = [auth for auth in preferred_auths
690 if auth in advertised_authlist]
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000691 if not authlist:
Fred Drake2f8f4d32001-10-13 18:35:32 +0000692 raise SMTPException("No suitable authentication method found.")
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000693
694 # Some servers advertise authentication methods they don't really
695 # support, so if authentication fails, we continue until we've tried
696 # all methods.
R David Murray76e13c12014-07-03 14:47:46 -0400697 self.user, self.password = user, password
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000698 for authmethod in authlist:
R David Murray76e13c12014-07-03 14:47:46 -0400699 method_name = 'auth_' + authmethod.lower().replace('-', '_')
700 try:
701 (code, resp) = self.auth(authmethod, getattr(self, method_name))
702 # 235 == 'Authentication successful'
703 # 503 == 'Error: already authenticated'
704 if code in (235, 503):
705 return (code, resp)
706 except SMTPAuthenticationError as e:
707 last_exception = e
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000708
R David Murray76e13c12014-07-03 14:47:46 -0400709 # We could not login successfully. Return result of last attempt.
710 raise last_exception
Guido van Rossumae010462001-09-11 15:57:46 +0000711
Antoine Pitroue0650202011-05-18 18:03:09 +0200712 def starttls(self, keyfile=None, certfile=None, context=None):
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000713 """Puts the connection to the SMTP server into TLS mode.
Tim Petersb64bec32001-09-18 02:26:39 +0000714
Christian Heimes679db4a2008-01-18 09:56:22 +0000715 If there has been no previous EHLO or HELO command this session, this
716 method tries ESMTP EHLO first.
717
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000718 If the server supports TLS, this will encrypt the rest of the SMTP
719 session. If you provide the keyfile and certfile parameters,
720 the identity of the SMTP server and client can be checked. This,
721 however, depends on whether the socket module really checks the
722 certificates.
Christian Heimes679db4a2008-01-18 09:56:22 +0000723
724 This method may raise the following exceptions:
725
726 SMTPHeloError The server didn't reply properly to
727 the helo greeting.
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000728 """
Christian Heimes679db4a2008-01-18 09:56:22 +0000729 self.ehlo_or_helo_if_needed()
730 if not self.has_extn("starttls"):
R David Murraycee7cf62015-05-16 13:58:14 -0400731 raise SMTPNotSupportedError(
732 "STARTTLS extension not supported by server.")
Tim Petersb64bec32001-09-18 02:26:39 +0000733 (resp, reply) = self.docmd("STARTTLS")
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000734 if resp == 220:
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000735 if not _have_ssl:
736 raise RuntimeError("No SSL support included in this Python")
Antoine Pitroue0650202011-05-18 18:03:09 +0200737 if context is not None and keyfile is not None:
738 raise ValueError("context and keyfile arguments are mutually "
739 "exclusive")
740 if context is not None and certfile is not None:
741 raise ValueError("context and certfile arguments are mutually "
742 "exclusive")
Christian Heimes67986f92013-11-23 22:43:47 +0100743 if context is None:
744 context = ssl._create_stdlib_context(certfile=certfile,
745 keyfile=keyfile)
Christian Heimesa5768f72013-12-02 20:44:17 +0100746 self.sock = context.wrap_socket(self.sock,
Benjamin Peterson7243b572014-11-23 17:04:34 -0600747 server_hostname=self._host)
Antoine Pitrouf068ab82011-06-06 19:17:09 +0200748 self.file = None
Christian Heimes679db4a2008-01-18 09:56:22 +0000749 # RFC 3207:
750 # The client MUST discard any knowledge obtained from
751 # the server, such as the list of SMTP service extensions,
752 # which was not obtained from the TLS negotiation itself.
753 self.helo_resp = None
754 self.ehlo_resp = None
755 self.esmtp_features = {}
756 self.does_esmtp = 0
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000757 return (resp, reply)
Tim Petersb64bec32001-09-18 02:26:39 +0000758
Jeremy Hylton31bb8ce1998-08-13 19:57:46 +0000759 def sendmail(self, from_addr, to_addrs, msg, mail_options=[],
Tim Peters495ad3c2001-01-15 01:36:40 +0000760 rcpt_options=[]):
761 """This command performs an entire mail transaction.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000762
Tim Peters495ad3c2001-01-15 01:36:40 +0000763 The arguments are:
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000764 - from_addr : The address sending this mail.
765 - to_addrs : A list of addresses to send this mail to. A bare
766 string will be treated as a list with 1 address.
Tim Peters495ad3c2001-01-15 01:36:40 +0000767 - msg : The message to send.
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000768 - mail_options : List of ESMTP options (such as 8bitmime) for the
769 mail command.
770 - rcpt_options : List of ESMTP options (such as DSN commands) for
771 all the rcpt commands.
772
R. David Murray7dff9e02010-11-08 17:15:13 +0000773 msg may be a string containing characters in the ASCII range, or a byte
774 string. A string is encoded to bytes using the ascii codec, and lone
R David Murrayac4e5ab2011-07-02 21:03:19 -0400775 \\r and \\n characters are converted to \\r\\n characters.
R. David Murray7dff9e02010-11-08 17:15:13 +0000776
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000777 If there has been no previous EHLO or HELO command this session, this
778 method tries ESMTP EHLO first. If the server does ESMTP, message size
779 and each of the specified options will be passed to it. If EHLO
780 fails, HELO will be tried and ESMTP options suppressed.
781
782 This method will return normally if the mail is accepted for at least
Barry Warsawd25c1b71999-11-28 17:11:06 +0000783 one recipient. It returns a dictionary, with one entry for each
784 recipient that was refused. Each entry contains a tuple of the SMTP
785 error code and the accompanying error message sent by the server.
Guido van Rossum296e1431999-04-07 15:03:39 +0000786
787 This method may raise the following exceptions:
788
789 SMTPHeloError The server didn't reply properly to
Tim Peters495ad3c2001-01-15 01:36:40 +0000790 the helo greeting.
Barry Warsawd25c1b71999-11-28 17:11:06 +0000791 SMTPRecipientsRefused The server rejected ALL recipients
Guido van Rossum296e1431999-04-07 15:03:39 +0000792 (no mail was sent).
793 SMTPSenderRefused The server didn't accept the from_addr.
794 SMTPDataError The server replied with an unexpected
795 error code (other than a refusal of
796 a recipient).
R David Murraycee7cf62015-05-16 13:58:14 -0400797 SMTPNotSupportedError The mail_options parameter includes 'SMTPUTF8'
798 but the SMTPUTF8 extension is not supported by
799 the server.
Guido van Rossum296e1431999-04-07 15:03:39 +0000800
801 Note: the connection will be open even after an exception is raised.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000802
Guido van Rossum95e6f701998-06-25 02:15:50 +0000803 Example:
Tim Peters495ad3c2001-01-15 01:36:40 +0000804
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000805 >>> import smtplib
806 >>> s=smtplib.SMTP("localhost")
Guido van Rossumfc40a831998-01-29 17:26:45 +0000807 >>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"]
Martin v. Löwis301b1cd2002-07-28 16:52:01 +0000808 >>> msg = '''\\
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000809 ... From: Me@my.org
810 ... Subject: testin'...
811 ...
812 ... This is a test '''
813 >>> s.sendmail("me@my.org",tolist,msg)
814 { "three@three.org" : ( 550 ,"User unknown" ) }
815 >>> s.quit()
Tim Peters495ad3c2001-01-15 01:36:40 +0000816
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000817 In the above example, the message was accepted for delivery to three
818 of the four addresses, and one was rejected, with the error code
Barry Warsawd25c1b71999-11-28 17:11:06 +0000819 550. If all addresses are accepted, then the method will return an
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000820 empty dictionary.
821
822 """
Christian Heimes679db4a2008-01-18 09:56:22 +0000823 self.ehlo_or_helo_if_needed()
Guido van Rossum95e6f701998-06-25 02:15:50 +0000824 esmtp_opts = []
R. David Murray7dff9e02010-11-08 17:15:13 +0000825 if isinstance(msg, str):
826 msg = _fix_eols(msg).encode('ascii')
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000827 if self.does_esmtp:
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000828 if self.has_extn('size'):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000829 esmtp_opts.append("size=%d" % len(msg))
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000830 for option in mail_options:
Guido van Rossum95e6f701998-06-25 02:15:50 +0000831 esmtp_opts.append(option)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000832 (code, resp) = self.mail(from_addr, esmtp_opts)
Fred Drake8152d322000-12-12 23:20:45 +0000833 if code != 250:
R David Murrayd312c742013-03-20 20:36:14 -0400834 if code == 421:
835 self.close()
836 else:
R David Murrayafb151a2014-04-14 18:21:38 -0400837 self._rset()
Guido van Rossum296e1431999-04-07 15:03:39 +0000838 raise SMTPSenderRefused(code, resp, from_addr)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000839 senderrs = {}
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000840 if isinstance(to_addrs, str):
Jeremy Hylton31bb8ce1998-08-13 19:57:46 +0000841 to_addrs = [to_addrs]
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000842 for each in to_addrs:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000843 (code, resp) = self.rcpt(each, rcpt_options)
Fred Drake8152d322000-12-12 23:20:45 +0000844 if (code != 250) and (code != 251):
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000845 senderrs[each] = (code, resp)
R David Murrayd312c742013-03-20 20:36:14 -0400846 if code == 421:
847 self.close()
848 raise SMTPRecipientsRefused(senderrs)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000849 if len(senderrs) == len(to_addrs):
Guido van Rossum95e6f701998-06-25 02:15:50 +0000850 # the server refused all our recipients
R David Murrayafb151a2014-04-14 18:21:38 -0400851 self._rset()
Guido van Rossum296e1431999-04-07 15:03:39 +0000852 raise SMTPRecipientsRefused(senderrs)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000853 (code, resp) = self.data(msg)
Fred Drake8152d322000-12-12 23:20:45 +0000854 if code != 250:
R David Murrayd312c742013-03-20 20:36:14 -0400855 if code == 421:
856 self.close()
857 else:
R David Murrayafb151a2014-04-14 18:21:38 -0400858 self._rset()
Guido van Rossum296e1431999-04-07 15:03:39 +0000859 raise SMTPDataError(code, resp)
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000860 #if we got here then somebody got our mail
Tim Peters495ad3c2001-01-15 01:36:40 +0000861 return senderrs
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000862
R. David Murray7dff9e02010-11-08 17:15:13 +0000863 def send_message(self, msg, from_addr=None, to_addrs=None,
864 mail_options=[], rcpt_options={}):
865 """Converts message to a bytestring and passes it to sendmail.
866
867 The arguments are as for sendmail, except that msg is an
R David Murrayac4e5ab2011-07-02 21:03:19 -0400868 email.message.Message object. If from_addr is None or to_addrs is
869 None, these arguments are taken from the headers of the Message as
870 described in RFC 2822 (a ValueError is raised if there is more than
871 one set of 'Resent-' headers). Regardless of the values of from_addr and
872 to_addr, any Bcc field (or Resent-Bcc field, when the Message is a
873 resent) of the Message object won't be transmitted. The Message
874 object is then serialized using email.generator.BytesGenerator and
R David Murray83084442015-05-17 19:27:22 -0400875 sendmail is called to transmit the message. If the sender or any of
876 the recipient addresses contain non-ASCII and the server advertises the
877 SMTPUTF8 capability, the policy is cloned with utf8 set to True for the
878 serialization, and SMTPUTF8 and BODY=8BITMIME are asserted on the send.
879 If the server does not support SMTPUTF8, an SMPTNotSupported error is
880 raised. Otherwise the generator is called without modifying the
881 policy.
R David Murrayac4e5ab2011-07-02 21:03:19 -0400882
R. David Murray7dff9e02010-11-08 17:15:13 +0000883 """
R David Murrayac4e5ab2011-07-02 21:03:19 -0400884 # 'Resent-Date' is a mandatory field if the Message is resent (RFC 2822
885 # Section 3.6.6). In such a case, we use the 'Resent-*' fields. However,
886 # if there is more than one 'Resent-' block there's no way to
887 # unambiguously determine which one is the most recent in all cases,
888 # so rather than guess we raise a ValueError in that case.
889 #
890 # TODO implement heuristics to guess the correct Resent-* block with an
891 # option allowing the user to enable the heuristics. (It should be
892 # possible to guess correctly almost all of the time.)
Senthil Kumaranb351a482011-07-31 09:14:17 +0800893
R David Murray83084442015-05-17 19:27:22 -0400894 self.ehlo_or_helo_if_needed()
Senthil Kumaranb351a482011-07-31 09:14:17 +0800895 resent = msg.get_all('Resent-Date')
R David Murrayac4e5ab2011-07-02 21:03:19 -0400896 if resent is None:
897 header_prefix = ''
898 elif len(resent) == 1:
899 header_prefix = 'Resent-'
900 else:
901 raise ValueError("message has more than one 'Resent-' header block")
R. David Murray7dff9e02010-11-08 17:15:13 +0000902 if from_addr is None:
R David Murrayac4e5ab2011-07-02 21:03:19 -0400903 # Prefer the sender field per RFC 2822:3.6.2.
Senthil Kumaranb351a482011-07-31 09:14:17 +0800904 from_addr = (msg[header_prefix + 'Sender']
905 if (header_prefix + 'Sender') in msg
906 else msg[header_prefix + 'From'])
R. David Murray7dff9e02010-11-08 17:15:13 +0000907 if to_addrs is None:
Senthil Kumaranb351a482011-07-31 09:14:17 +0800908 addr_fields = [f for f in (msg[header_prefix + 'To'],
909 msg[header_prefix + 'Bcc'],
R David Murray83084442015-05-17 19:27:22 -0400910 msg[header_prefix + 'Cc'])
911 if f is not None]
R. David Murray7dff9e02010-11-08 17:15:13 +0000912 to_addrs = [a[1] for a in email.utils.getaddresses(addr_fields)]
R David Murrayac4e5ab2011-07-02 21:03:19 -0400913 # Make a local copy so we can delete the bcc headers.
914 msg_copy = copy.copy(msg)
915 del msg_copy['Bcc']
916 del msg_copy['Resent-Bcc']
R David Murray83084442015-05-17 19:27:22 -0400917 international = False
918 try:
919 ''.join([from_addr, *to_addrs]).encode('ascii')
920 except UnicodeEncodeError:
921 if not self.has_extn('smtputf8'):
922 raise SMTPNotSupportedError(
923 "One or more source or delivery addresses require"
924 " internationalized email support, but the server"
925 " does not advertise the required SMTPUTF8 capability")
926 international = True
R. David Murray7dff9e02010-11-08 17:15:13 +0000927 with io.BytesIO() as bytesmsg:
R David Murray83084442015-05-17 19:27:22 -0400928 if international:
929 g = email.generator.BytesGenerator(
930 bytesmsg, policy=msg.policy.clone(utf8=True))
931 mail_options += ['SMTPUTF8', 'BODY=8BITMIME']
932 else:
933 g = email.generator.BytesGenerator(bytesmsg)
R David Murrayac4e5ab2011-07-02 21:03:19 -0400934 g.flatten(msg_copy, linesep='\r\n')
R. David Murray7dff9e02010-11-08 17:15:13 +0000935 flatmsg = bytesmsg.getvalue()
936 return self.sendmail(from_addr, to_addrs, flatmsg, mail_options,
937 rcpt_options)
938
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000939 def close(self):
940 """Close the connection to the SMTP server."""
Serhiy Storchaka7e7a3db2015-04-10 13:24:41 +0300941 try:
942 file = self.file
943 self.file = None
944 if file:
945 file.close()
946 finally:
947 sock = self.sock
948 self.sock = None
949 if sock:
950 sock.close()
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000951
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000952 def quit(self):
Guido van Rossum95e6f701998-06-25 02:15:50 +0000953 """Terminate the SMTP session."""
Christian Heimesba4af492008-03-28 00:55:15 +0000954 res = self.docmd("quit")
R David Murray0cff49f2014-08-30 16:51:59 -0400955 # A new EHLO is required after reconnecting with connect()
956 self.ehlo_resp = self.helo_resp = None
957 self.esmtp_features = {}
958 self.does_esmtp = False
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000959 self.close()
Christian Heimesba4af492008-03-28 00:55:15 +0000960 return res
Guido van Rossum95e6f701998-06-25 02:15:50 +0000961
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000962if _have_ssl:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000963
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000964 class SMTP_SSL(SMTP):
R David Murray021362d2013-06-23 16:05:44 -0400965 """ This is a subclass derived from SMTP that connects over an SSL
966 encrypted socket (to use this class you need a socket module that was
967 compiled with SSL support). If host is not specified, '' (the local
968 host) is used. If port is omitted, the standard SMTP-over-SSL port
969 (465) is used. local_hostname and source_address have the same meaning
970 as they do in the SMTP class. keyfile and certfile are also optional -
971 they can contain a PEM formatted private key and certificate chain file
972 for the SSL connection. context also optional, can contain a
973 SSLContext, and is an alternative to keyfile and certfile; If it is
974 specified both keyfile and certfile must be None.
975
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000976 """
Antoine Pitrouc1d52062011-05-07 19:39:37 +0200977
978 default_port = SMTP_SSL_PORT
979
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000980 def __init__(self, host='', port=0, local_hostname=None,
Georg Brandlf78e02b2008-06-10 17:40:04 +0000981 keyfile=None, certfile=None,
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800982 timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
983 source_address=None, context=None):
Antoine Pitroue0650202011-05-18 18:03:09 +0200984 if context is not None and keyfile is not None:
985 raise ValueError("context and keyfile arguments are mutually "
986 "exclusive")
987 if context is not None and certfile is not None:
988 raise ValueError("context and certfile arguments are mutually "
989 "exclusive")
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000990 self.keyfile = keyfile
991 self.certfile = certfile
Christian Heimes67986f92013-11-23 22:43:47 +0100992 if context is None:
993 context = ssl._create_stdlib_context(certfile=certfile,
994 keyfile=keyfile)
Antoine Pitroue0650202011-05-18 18:03:09 +0200995 self.context = context
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800996 SMTP.__init__(self, host, port, local_hostname, timeout,
997 source_address)
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000998
999 def _get_socket(self, host, port, timeout):
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +00001000 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -04001001 self._print_debug('connect:', (host, port))
Senthil Kumaran3d23fd62011-07-30 10:56:50 +08001002 new_socket = socket.create_connection((host, port), timeout,
1003 self.source_address)
Christian Heimesa5768f72013-12-02 20:44:17 +01001004 new_socket = self.context.wrap_socket(new_socket,
Benjamin Peterson7243b572014-11-23 17:04:34 -06001005 server_hostname=self._host)
R. David Murray87e20742009-05-23 01:30:26 +00001006 return new_socket
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001007
1008 __all__.append("SMTP_SSL")
Barry Warsaw4c4bec81998-12-22 03:02:20 +00001009
Guido van Rossumd8faa362007-04-27 19:54:29 +00001010#
1011# LMTP extension
1012#
1013LMTP_PORT = 2003
1014
1015class LMTP(SMTP):
1016 """LMTP - Local Mail Transfer Protocol
1017
1018 The LMTP protocol, which is very similar to ESMTP, is heavily based
R David Murray021362d2013-06-23 16:05:44 -04001019 on the standard SMTP client. It's common to use Unix sockets for
1020 LMTP, so our connect() method must support that as well as a regular
R David Murray36beb662013-06-23 15:47:50 -04001021 host:port server. local_hostname and source_address have the same
R David Murray021362d2013-06-23 16:05:44 -04001022 meaning as they do in the SMTP class. To specify a Unix socket,
1023 you must use an absolute path as the host, starting with a '/'.
Guido van Rossumd8faa362007-04-27 19:54:29 +00001024
1025 Authentication is supported, using the regular SMTP mechanism. When
1026 using a Unix socket, LMTP generally don't support or require any
1027 authentication, but your mileage might vary."""
1028
1029 ehlo_msg = "lhlo"
1030
Senthil Kumaran3d23fd62011-07-30 10:56:50 +08001031 def __init__(self, host='', port=LMTP_PORT, local_hostname=None,
1032 source_address=None):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001033 """Initialize a new instance."""
Senthil Kumaranb351a482011-07-31 09:14:17 +08001034 SMTP.__init__(self, host, port, local_hostname=local_hostname,
1035 source_address=source_address)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001036
Senthil Kumaran3d23fd62011-07-30 10:56:50 +08001037 def connect(self, host='localhost', port=0, source_address=None):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001038 """Connect to the LMTP daemon, on either a Unix or a TCP socket."""
1039 if host[0] != '/':
Senthil Kumaranb351a482011-07-31 09:14:17 +08001040 return SMTP.connect(self, host, port, source_address=source_address)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001041
1042 # Handle Unix-domain sockets.
1043 try:
1044 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
Antoine Pitrouf068ab82011-06-06 19:17:09 +02001045 self.file = None
Guido van Rossumd8faa362007-04-27 19:54:29 +00001046 self.sock.connect(host)
Andrew Svetlov2ade6f22012-12-17 18:57:16 +02001047 except OSError:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +00001048 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -04001049 self._print_debug('connect fail:', host)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001050 if self.sock:
1051 self.sock.close()
1052 self.sock = None
Andrew Svetlovb6693c42012-12-17 18:54:53 +02001053 raise
Guido van Rossumd8faa362007-04-27 19:54:29 +00001054 (code, msg) = self.getreply()
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +00001055 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -04001056 self._print_debug('connect:', msg)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001057 return (code, msg)
1058
1059
Guido van Rossum95e6f701998-06-25 02:15:50 +00001060# Test the sendmail method, which tests most of the others.
1061# Note: This always sends to localhost.
1062if __name__ == '__main__':
Andrew M. Kuchling6be424f2001-08-13 14:41:39 +00001063 import sys
Guido van Rossum95e6f701998-06-25 02:15:50 +00001064
1065 def prompt(prompt):
1066 sys.stdout.write(prompt + ": ")
Ezio Melotti6bfecd12011-10-18 13:20:07 +03001067 sys.stdout.flush()
Eric S. Raymondc013f302001-02-09 05:40:38 +00001068 return sys.stdin.readline().strip()
Guido van Rossum95e6f701998-06-25 02:15:50 +00001069
1070 fromaddr = prompt("From")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +00001071 toaddrs = prompt("To").split(',')
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001072 print("Enter message, end with ^D:")
Guido van Rossum95e6f701998-06-25 02:15:50 +00001073 msg = ''
1074 while 1:
1075 line = sys.stdin.readline()
1076 if not line:
1077 break
1078 msg = msg + line
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001079 print("Message length is %d" % len(msg))
Guido van Rossum95e6f701998-06-25 02:15:50 +00001080
1081 server = SMTP('localhost')
1082 server.set_debuglevel(1)
1083 server.sendmail(fromaddr, toaddrs, msg)
1084 server.quit()