blob: 01f3d4386f58580cdd0bb425a0678ebda87d02e1 [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
Romuald Brunet7b313972018-10-09 16:31:55 +0200219
220 sock = None
Guido van Rossum95e6f701998-06-25 02:15:50 +0000221 file = None
222 helo_resp = None
Guido van Rossumd8faa362007-04-27 19:54:29 +0000223 ehlo_msg = "ehlo"
Guido van Rossum95e6f701998-06-25 02:15:50 +0000224 ehlo_resp = None
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000225 does_esmtp = 0
Antoine Pitrouc1d52062011-05-07 19:39:37 +0200226 default_port = SMTP_PORT
Guido van Rossum95e6f701998-06-25 02:15:50 +0000227
Georg Brandlf78e02b2008-06-10 17:40:04 +0000228 def __init__(self, host='', port=0, local_hostname=None,
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800229 timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
230 source_address=None):
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000231 """Initialize a new instance.
232
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000233 If specified, `host' is the name of the remote host to which to
234 connect. If specified, `port' specifies the port to which to connect.
R David Murray14ee3cf2013-04-13 14:40:33 -0400235 By default, smtplib.SMTP_PORT is used. If a host is specified the
R David Murray021362d2013-06-23 16:05:44 -0400236 connect method is called, and if it returns anything other than a
237 success code an SMTPConnectError is raised. If specified,
238 `local_hostname` is used as the FQDN of the local host in the HELO/EHLO
239 command. Otherwise, the local hostname is found using
240 socket.getfqdn(). The `source_address` parameter takes a 2-tuple (host,
241 port) for the socket to bind to as its source address before
242 connecting. If the host is '' and port is 0, the OS default behavior
243 will be used.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000244
245 """
Christian Heimesa5768f72013-12-02 20:44:17 +0100246 self._host = host
Guido van Rossumd8faa362007-04-27 19:54:29 +0000247 self.timeout = timeout
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000248 self.esmtp_features = {}
R David Murraycee7cf62015-05-16 13:58:14 -0400249 self.command_encoding = 'ascii'
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800250 self.source_address = source_address
251
Guido van Rossum296e1431999-04-07 15:03:39 +0000252 if host:
253 (code, msg) = self.connect(host, port)
254 if code != 220:
Joel Hillacre9e98cd02017-05-23 23:14:50 -0600255 self.close()
Guido van Rossum296e1431999-04-07 15:03:39 +0000256 raise SMTPConnectError(code, msg)
Raymond Hettingerf13eb552002-06-02 00:40:05 +0000257 if local_hostname is not None:
Barry Warsaw13e34f72002-03-26 20:27:35 +0000258 self.local_hostname = local_hostname
Neil Schemenauer6730f262002-03-24 15:30:40 +0000259 else:
Barry Warsaw13e34f72002-03-26 20:27:35 +0000260 # RFC 2821 says we should use the fqdn in the EHLO/HELO verb, and
261 # if that can't be calculated, that we should use a domain literal
262 # instead (essentially an encoded IP address like [A.B.C.D]).
263 fqdn = socket.getfqdn()
264 if '.' in fqdn:
265 self.local_hostname = fqdn
266 else:
267 # We can't find an fqdn hostname, so use a domain literal
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000268 addr = '127.0.0.1'
269 try:
270 addr = socket.gethostbyname(socket.gethostname())
271 except socket.gaierror:
272 pass
Barry Warsaw13e34f72002-03-26 20:27:35 +0000273 self.local_hostname = '[%s]' % addr
Tim Peters495ad3c2001-01-15 01:36:40 +0000274
Barry Warsaw1f5c9582011-03-15 15:04:44 -0400275 def __enter__(self):
276 return self
277
278 def __exit__(self, *args):
279 try:
280 code, message = self.docmd("QUIT")
281 if code != 221:
282 raise SMTPResponseException(code, message)
283 except SMTPServerDisconnected:
284 pass
285 finally:
286 self.close()
287
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000288 def set_debuglevel(self, debuglevel):
289 """Set the debug output level.
290
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000291 A non-false value results in debug messages for connection and for all
292 messages sent to and received from the server.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000293
294 """
295 self.debuglevel = debuglevel
296
R David Murray0c49b892015-04-16 17:14:42 -0400297 def _print_debug(self, *args):
298 if self.debuglevel > 1:
299 print(datetime.datetime.now().time(), *args, file=sys.stderr)
300 else:
301 print(*args, file=sys.stderr)
302
Barry Warsawc9181712008-03-19 14:25:51 +0000303 def _get_socket(self, host, port, timeout):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000304 # This makes it simpler for SMTP_SSL to use the SMTP connect code
305 # and just alter the socket connection bit.
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000306 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400307 self._print_debug('connect: to', (host, port), self.source_address)
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800308 return socket.create_connection((host, port), timeout,
309 self.source_address)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000310
Senthil Kumaran3d23fd62011-07-30 10:56:50 +0800311 def connect(self, host='localhost', port=0, source_address=None):
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000312 """Connect to a host on a given port.
Guido van Rossum95e6f701998-06-25 02:15:50 +0000313
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000314 If the hostname ends with a colon (`:') followed by a number, and
315 there is no port specified, that suffix will be stripped off and the
316 number interpreted as the port number to use.
Guido van Rossum95e6f701998-06-25 02:15:50 +0000317
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000318 Note: This method is automatically invoked by __init__, if a host is
319 specified during instantiation.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000320
321 """
Senthil Kumaranb351a482011-07-31 09:14:17 +0800322
323 if source_address:
324 self.source_address = source_address
325
Martin v. Löwis4eb59402001-07-26 13:37:33 +0000326 if not port and (host.find(':') == host.rfind(':')):
Martin v. Löwisa43c2f82001-07-24 20:34:08 +0000327 i = host.rfind(':')
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000328 if i >= 0:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000329 host, port = host[:i], host[i + 1:]
330 try:
331 port = int(port)
Eric S. Raymond8d876032001-02-09 10:14:53 +0000332 except ValueError:
Andrew Svetlov2ade6f22012-12-17 18:57:16 +0200333 raise OSError("nonnumeric port")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000334 if not port:
335 port = self.default_port
336 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400337 self._print_debug('connect:', (host, port))
Steve Dower60419a72019-06-24 08:42:54 -0700338 sys.audit("smtplib.SMTP.connect", self, host, port)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000339 self.sock = self._get_socket(host, port, self.timeout)
Antoine Pitrouf068ab82011-06-06 19:17:09 +0200340 self.file = None
Martin v. Löwisa43c2f82001-07-24 20:34:08 +0000341 (code, msg) = self.getreply()
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000342 if self.debuglevel > 0:
R David Murray37f1ba92015-04-16 18:54:56 -0400343 self._print_debug('connect:', repr(msg))
Martin v. Löwisa43c2f82001-07-24 20:34:08 +0000344 return (code, msg)
Tim Peters495ad3c2001-01-15 01:36:40 +0000345
Guido van Rossum8a392d72007-11-21 22:09:45 +0000346 def send(self, s):
347 """Send `s' to the server."""
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000348 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400349 self._print_debug('send:', repr(s))
Romuald Brunet7b313972018-10-09 16:31:55 +0200350 if self.sock:
Guido van Rossum8a392d72007-11-21 22:09:45 +0000351 if isinstance(s, str):
R David Murraycee7cf62015-05-16 13:58:14 -0400352 # send is used by the 'data' command, where command_encoding
353 # should not be used, but 'data' needs to convert the string to
354 # binary itself anyway, so that's not a problem.
355 s = s.encode(self.command_encoding)
Steve Dower60419a72019-06-24 08:42:54 -0700356 sys.audit("smtplib.SMTP.send", self, s)
Guido van Rossum2880f6e1998-08-10 20:07:00 +0000357 try:
Guido van Rossum8a392d72007-11-21 22:09:45 +0000358 self.sock.sendall(s)
Andrew Svetlov2ade6f22012-12-17 18:57:16 +0200359 except OSError:
Barry Warsaw76750972001-12-14 20:34:20 +0000360 self.close()
Guido van Rossum40233ea1999-01-15 03:23:55 +0000361 raise SMTPServerDisconnected('Server not connected')
Guido van Rossumfc40a831998-01-29 17:26:45 +0000362 else:
Guido van Rossum40233ea1999-01-15 03:23:55 +0000363 raise SMTPServerDisconnected('please run connect() first')
Tim Peters495ad3c2001-01-15 01:36:40 +0000364
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000365 def putcmd(self, cmd, args=""):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000366 """Send a command to the server."""
Guido van Rossumdb23d3d1999-06-09 15:13:10 +0000367 if args == "":
368 str = '%s%s' % (cmd, CRLF)
369 else:
370 str = '%s %s%s' % (cmd, args, CRLF)
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000371 self.send(str)
Tim Peters495ad3c2001-01-15 01:36:40 +0000372
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000373 def getreply(self):
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000374 """Get a reply from the server.
Tim Peters495ad3c2001-01-15 01:36:40 +0000375
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000376 Returns a tuple consisting of:
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000377
378 - server response code (e.g. '250', or such, if all goes well)
379 Note: returns -1 if it can't read response code.
380
381 - server response string corresponding to response code (multiline
382 responses are converted to a single, multiline string).
Guido van Rossumf123f841999-03-29 20:33:21 +0000383
384 Raises SMTPServerDisconnected if end-of-file is reached.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000385 """
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000386 resp = []
Guido van Rossum296e1431999-04-07 15:03:39 +0000387 if self.file is None:
388 self.file = self.sock.makefile('rb')
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000389 while 1:
Benjamin Petersone1cdfd72009-01-18 21:02:37 +0000390 try:
Georg Brandlb38b5c42014-02-10 22:11:21 +0100391 line = self.file.readline(_MAXLINE + 1)
Andrew Svetlov2ade6f22012-12-17 18:57:16 +0200392 except OSError as e:
Antoine Pitrou6b2e1602011-08-28 01:20:42 +0200393 self.close()
394 raise SMTPServerDisconnected("Connection unexpectedly closed: "
395 + str(e))
Guido van Rossum806c2462007-08-06 23:33:07 +0000396 if not line:
Guido van Rossum296e1431999-04-07 15:03:39 +0000397 self.close()
398 raise SMTPServerDisconnected("Connection unexpectedly closed")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000399 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400400 self._print_debug('reply:', repr(line))
Georg Brandlb38b5c42014-02-10 22:11:21 +0100401 if len(line) > _MAXLINE:
Senthil Kumaran4ce118e2014-06-03 07:24:54 -0700402 self.close()
Georg Brandlb38b5c42014-02-10 22:11:21 +0100403 raise SMTPResponseException(500, "Line too long.")
Guido van Rossum806c2462007-08-06 23:33:07 +0000404 resp.append(line[4:].strip(b' \t\r\n'))
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000405 code = line[:3]
Guido van Rossum296e1431999-04-07 15:03:39 +0000406 # Check that the error code is syntactically correct.
407 # Don't attempt to read a continuation line if it is broken.
408 try:
Eric S. Raymondc013f302001-02-09 05:40:38 +0000409 errcode = int(code)
Guido van Rossum296e1431999-04-07 15:03:39 +0000410 except ValueError:
411 errcode = -1
412 break
Guido van Rossumf123f841999-03-29 20:33:21 +0000413 # Check if multiline response.
Guido van Rossum806c2462007-08-06 23:33:07 +0000414 if line[3:4] != b"-":
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000415 break
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000416
Guido van Rossumc43e79f2007-06-18 18:26:36 +0000417 errmsg = b"\n".join(resp)
Tim Peters495ad3c2001-01-15 01:36:40 +0000418 if self.debuglevel > 0:
R David Murray37f1ba92015-04-16 18:54:56 -0400419 self._print_debug('reply: retcode (%s); Msg: %a' % (errcode, errmsg))
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000420 return errcode, errmsg
Tim Peters495ad3c2001-01-15 01:36:40 +0000421
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000422 def docmd(self, cmd, args=""):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000423 """Send a command, and return its response code."""
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000424 self.putcmd(cmd, args)
Guido van Rossum296e1431999-04-07 15:03:39 +0000425 return self.getreply()
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000426
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000427 # std smtp commands
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000428 def helo(self, name=''):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000429 """SMTP 'helo' command.
430 Hostname to send for this command defaults to the FQDN of the local
431 host.
432 """
Neil Schemenauer6730f262002-03-24 15:30:40 +0000433 self.putcmd("helo", name or self.local_hostname)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000434 (code, msg) = self.getreply()
435 self.helo_resp = msg
436 return (code, msg)
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000437
Guido van Rossum95e6f701998-06-25 02:15:50 +0000438 def ehlo(self, name=''):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000439 """ SMTP 'ehlo' command.
440 Hostname to send for this command defaults to the FQDN of the local
441 host.
442 """
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000443 self.esmtp_features = {}
Guido van Rossumd8faa362007-04-27 19:54:29 +0000444 self.putcmd(self.ehlo_msg, name or self.local_hostname)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000445 (code, msg) = self.getreply()
Tim Peters495ad3c2001-01-15 01:36:40 +0000446 # According to RFC1869 some (badly written)
447 # MTA's will disconnect on an ehlo. Toss an exception if
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000448 # that happens -ddm
449 if code == -1 and len(msg) == 0:
Barry Warsaw76750972001-12-14 20:34:20 +0000450 self.close()
Guido van Rossum40233ea1999-01-15 03:23:55 +0000451 raise SMTPServerDisconnected("Server not connected")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000452 self.ehlo_resp = msg
Fred Drake8152d322000-12-12 23:20:45 +0000453 if code != 250:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000454 return (code, msg)
455 self.does_esmtp = 1
Thomas Wouters7e474022000-07-16 12:04:32 +0000456 #parse the ehlo response -ddm
Guido van Rossum04110fb2007-08-24 16:32:05 +0000457 assert isinstance(self.ehlo_resp, bytes), repr(self.ehlo_resp)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000458 resp = self.ehlo_resp.decode("latin-1").split('\n')
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000459 del resp[0]
Guido van Rossum2880f6e1998-08-10 20:07:00 +0000460 for each in resp:
Piers Lauder385a77a2002-07-27 00:38:30 +0000461 # To be able to communicate with as many SMTP servers as possible,
462 # we have to take the old-style auth advertisement into account,
463 # because:
464 # 1) Else our SMTP feature parser gets confused.
465 # 2) There are some servers that only advertise the auth methods we
466 # support using the old style.
467 auth_match = OLDSTYLE_AUTH.match(each)
468 if auth_match:
469 # This doesn't remove duplicates, but that's no problem
470 self.esmtp_features["auth"] = self.esmtp_features.get("auth", "") \
471 + " " + auth_match.groups(0)[0]
472 continue
473
Barry Warsawbe22ae62002-04-15 20:03:30 +0000474 # RFC 1869 requires a space between ehlo keyword and parameters.
475 # It's actually stricter, in that only spaces are allowed between
476 # parameters, but were not going to check for that here. Note
477 # that the space isn't present if there are no parameters.
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000478 m = re.match(r'(?P<feature>[A-Za-z0-9][A-Za-z0-9\-]*) ?', each)
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000479 if m:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000480 feature = m.group("feature").lower()
481 params = m.string[m.end("feature"):].strip()
Piers Lauder385a77a2002-07-27 00:38:30 +0000482 if feature == "auth":
483 self.esmtp_features[feature] = self.esmtp_features.get(feature, "") \
484 + " " + params
485 else:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000486 self.esmtp_features[feature] = params
487 return (code, msg)
Guido van Rossum95e6f701998-06-25 02:15:50 +0000488
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000489 def has_extn(self, opt):
490 """Does the server support a given SMTP service extension?"""
Raymond Hettinger54f02222002-06-01 14:18:47 +0000491 return opt.lower() in self.esmtp_features
Guido van Rossum95e6f701998-06-25 02:15:50 +0000492
Guido van Rossum18586f41998-04-03 17:03:13 +0000493 def help(self, args=''):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000494 """SMTP 'help' command.
495 Returns help text from server."""
Guido van Rossum18586f41998-04-03 17:03:13 +0000496 self.putcmd("help", args)
Kurt B. Kaiser58bd1902005-06-26 18:27:36 +0000497 return self.getreply()[1]
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000498
499 def rset(self):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000500 """SMTP 'rset' command -- resets session."""
R David Murraycee7cf62015-05-16 13:58:14 -0400501 self.command_encoding = 'ascii'
Guido van Rossum296e1431999-04-07 15:03:39 +0000502 return self.docmd("rset")
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000503
R David Murrayafb151a2014-04-14 18:21:38 -0400504 def _rset(self):
505 """Internal 'rset' command which ignores any SMTPServerDisconnected error.
506
507 Used internally in the library, since the server disconnected error
508 should appear to the application when the *next* command is issued, if
509 we are doing an internal "safety" reset.
510 """
511 try:
512 self.rset()
513 except SMTPServerDisconnected:
514 pass
515
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000516 def noop(self):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000517 """SMTP 'noop' command -- doesn't do anything :>"""
Guido van Rossum296e1431999-04-07 15:03:39 +0000518 return self.docmd("noop")
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000519
Pablo Aguiard5fbe9b2018-09-08 00:04:48 +0200520 def mail(self, sender, options=()):
R David Murraycee7cf62015-05-16 13:58:14 -0400521 """SMTP 'mail' command -- begins mail xfer session.
522
523 This method may raise the following exceptions:
524
525 SMTPNotSupportedError The options parameter includes 'SMTPUTF8'
526 but the SMTPUTF8 extension is not supported by
527 the server.
528 """
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000529 optionlist = ''
530 if options and self.does_esmtp:
R David Murraycee7cf62015-05-16 13:58:14 -0400531 if any(x.lower()=='smtputf8' for x in options):
532 if self.has_extn('smtputf8'):
533 self.command_encoding = 'utf-8'
534 else:
535 raise SMTPNotSupportedError(
536 'SMTPUTF8 not supported by server')
Eric S. Raymondc013f302001-02-09 05:40:38 +0000537 optionlist = ' ' + ' '.join(options)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000538 self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000539 return self.getreply()
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000540
Pablo Aguiard5fbe9b2018-09-08 00:04:48 +0200541 def rcpt(self, recip, options=()):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000542 """SMTP 'rcpt' command -- indicates 1 recipient for this mail."""
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000543 optionlist = ''
544 if options and self.does_esmtp:
Eric S. Raymondc013f302001-02-09 05:40:38 +0000545 optionlist = ' ' + ' '.join(options)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000546 self.putcmd("rcpt", "TO:%s%s" % (quoteaddr(recip), optionlist))
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000547 return self.getreply()
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000548
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000549 def data(self, msg):
Tim Peters495ad3c2001-01-15 01:36:40 +0000550 """SMTP 'DATA' command -- sends message data to server.
Guido van Rossum296e1431999-04-07 15:03:39 +0000551
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000552 Automatically quotes lines beginning with a period per rfc821.
Guido van Rossum296e1431999-04-07 15:03:39 +0000553 Raises SMTPDataError if there is an unexpected reply to the
554 DATA command; the return value from this method is the final
R. David Murray7dff9e02010-11-08 17:15:13 +0000555 response code received when the all data is sent. If msg
Serhiy Storchaka9f8a8912015-04-03 18:12:41 +0300556 is a string, lone '\\r' and '\\n' characters are converted to
557 '\\r\\n' characters. If msg is bytes, it is transmitted as is.
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000558 """
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000559 self.putcmd("data")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000560 (code, repl) = self.getreply()
561 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400562 self._print_debug('data:', (code, repl))
Fred Drake8152d322000-12-12 23:20:45 +0000563 if code != 354:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000564 raise SMTPDataError(code, repl)
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000565 else:
R. David Murray7dff9e02010-11-08 17:15:13 +0000566 if isinstance(msg, str):
567 msg = _fix_eols(msg).encode('ascii')
568 q = _quote_periods(msg)
569 if q[-2:] != bCRLF:
570 q = q + bCRLF
571 q = q + b"." + bCRLF
Guido van Rossum20c92281999-04-21 16:52:20 +0000572 self.send(q)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000573 (code, msg) = self.getreply()
574 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -0400575 self._print_debug('data:', (code, msg))
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000576 return (code, msg)
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000577
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000578 def verify(self, address):
Barry Warsawa7d9bdf1998-12-22 03:24:27 +0000579 """SMTP 'verify' command -- checks for address validity."""
R David Murray46346762011-07-18 21:38:54 -0400580 self.putcmd("vrfy", _addr_only(address))
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000581 return self.getreply()
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000582 # a.k.a.
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000583 vrfy = verify
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000584
585 def expn(self, address):
Christian Heimes90c3d9b2008-02-23 13:18:03 +0000586 """SMTP 'expn' command -- expands a mailing list."""
R David Murray46346762011-07-18 21:38:54 -0400587 self.putcmd("expn", _addr_only(address))
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000588 return self.getreply()
589
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000590 # some useful methods
Guido van Rossumae010462001-09-11 15:57:46 +0000591
Christian Heimes679db4a2008-01-18 09:56:22 +0000592 def ehlo_or_helo_if_needed(self):
593 """Call self.ehlo() and/or self.helo() if needed.
594
595 If there has been no previous EHLO or HELO command this session, this
596 method tries ESMTP EHLO first.
597
598 This method may raise the following exceptions:
599
600 SMTPHeloError The server didn't reply properly to
601 the helo greeting.
602 """
603 if self.helo_resp is None and self.ehlo_resp is None:
604 if not (200 <= self.ehlo()[0] <= 299):
605 (code, resp) = self.helo()
606 if not (200 <= code <= 299):
607 raise SMTPHeloError(code, resp)
608
Barry Warsawc5ea7542015-07-09 10:39:55 -0400609 def auth(self, mechanism, authobject, *, initial_response_ok=True):
R David Murray76e13c12014-07-03 14:47:46 -0400610 """Authentication command - requires response processing.
611
612 'mechanism' specifies which authentication mechanism is to
613 be used - the valid values are those listed in the 'auth'
614 element of 'esmtp_features'.
615
616 'authobject' must be a callable object taking a single argument:
617
618 data = authobject(challenge)
619
620 It will be called to process the server's challenge response; the
621 challenge argument it is passed will be a bytes. It should return
Sebastian Rittau78deb7f2018-09-10 19:29:43 +0200622 an ASCII string that will be base64 encoded and sent to the server.
R David Murray76e13c12014-07-03 14:47:46 -0400623
Barry Warsawc5ea7542015-07-09 10:39:55 -0400624 Keyword arguments:
625 - initial_response_ok: Allow sending the RFC 4954 initial-response
626 to the AUTH command, if the authentication methods supports it.
627 """
628 # RFC 4954 allows auth methods to provide an initial response. Not all
629 # methods support it. By definition, if they return something other
630 # than None when challenge is None, then they do. See issue #15014.
R David Murray76e13c12014-07-03 14:47:46 -0400631 mechanism = mechanism.upper()
Barry Warsawc5ea7542015-07-09 10:39:55 -0400632 initial_response = (authobject() if initial_response_ok else None)
633 if initial_response is not None:
634 response = encode_base64(initial_response.encode('ascii'), eol='')
635 (code, resp) = self.docmd("AUTH", mechanism + " " + response)
636 else:
637 (code, resp) = self.docmd("AUTH", mechanism)
R David Murrayb0deeb42015-11-08 01:03:52 -0500638 # If server responds with a challenge, send the response.
639 if code == 334:
640 challenge = base64.decodebytes(resp)
641 response = encode_base64(
642 authobject(challenge).encode('ascii'), eol='')
643 (code, resp) = self.docmd(response)
Barry Warsawc5ea7542015-07-09 10:39:55 -0400644 if code in (235, 503):
645 return (code, resp)
R David Murray76e13c12014-07-03 14:47:46 -0400646 raise SMTPAuthenticationError(code, resp)
647
Barry Warsawc5ea7542015-07-09 10:39:55 -0400648 def auth_cram_md5(self, challenge=None):
R David Murray76e13c12014-07-03 14:47:46 -0400649 """ Authobject to use with CRAM-MD5 authentication. Requires self.user
650 and self.password to be set."""
Barry Warsawc5ea7542015-07-09 10:39:55 -0400651 # CRAM-MD5 does not support initial-response.
652 if challenge is None:
653 return None
R David Murray76e13c12014-07-03 14:47:46 -0400654 return self.user + " " + hmac.HMAC(
655 self.password.encode('ascii'), challenge, 'md5').hexdigest()
656
Barry Warsawc5ea7542015-07-09 10:39:55 -0400657 def auth_plain(self, challenge=None):
R David Murray76e13c12014-07-03 14:47:46 -0400658 """ Authobject to use with PLAIN authentication. Requires self.user and
659 self.password to be set."""
660 return "\0%s\0%s" % (self.user, self.password)
661
Barry Warsawc5ea7542015-07-09 10:39:55 -0400662 def auth_login(self, challenge=None):
R David Murray76e13c12014-07-03 14:47:46 -0400663 """ Authobject to use with LOGIN authentication. Requires self.user and
664 self.password to be set."""
R David Murrayb0deeb42015-11-08 01:03:52 -0500665 if challenge is None:
666 return self.user
667 else:
R David Murray76e13c12014-07-03 14:47:46 -0400668 return self.password
R David Murray76e13c12014-07-03 14:47:46 -0400669
Barry Warsawc5ea7542015-07-09 10:39:55 -0400670 def login(self, user, password, *, initial_response_ok=True):
Guido van Rossumae010462001-09-11 15:57:46 +0000671 """Log in on an SMTP server that requires authentication.
672
673 The arguments are:
R David Murray76e13c12014-07-03 14:47:46 -0400674 - user: The user name to authenticate with.
675 - password: The password for the authentication.
Guido van Rossumae010462001-09-11 15:57:46 +0000676
Barry Warsawc5ea7542015-07-09 10:39:55 -0400677 Keyword arguments:
678 - initial_response_ok: Allow sending the RFC 4954 initial-response
679 to the AUTH command, if the authentication methods supports it.
680
Guido van Rossumae010462001-09-11 15:57:46 +0000681 If there has been no previous EHLO or HELO command this session, this
682 method tries ESMTP EHLO first.
683
684 This method will return normally if the authentication was successful.
685
686 This method may raise the following exceptions:
687
688 SMTPHeloError The server didn't reply properly to
689 the helo greeting.
690 SMTPAuthenticationError The server didn't accept the username/
691 password combination.
R David Murraycee7cf62015-05-16 13:58:14 -0400692 SMTPNotSupportedError The AUTH command is not supported by the
693 server.
Fred Drake2f8f4d32001-10-13 18:35:32 +0000694 SMTPException No suitable authentication method was
Guido van Rossumae010462001-09-11 15:57:46 +0000695 found.
696 """
697
Christian Heimes679db4a2008-01-18 09:56:22 +0000698 self.ehlo_or_helo_if_needed()
Guido van Rossumae010462001-09-11 15:57:46 +0000699 if not self.has_extn("auth"):
R David Murraycee7cf62015-05-16 13:58:14 -0400700 raise SMTPNotSupportedError(
701 "SMTP AUTH extension not supported by server.")
Guido van Rossumae010462001-09-11 15:57:46 +0000702
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000703 # Authentication methods the server claims to support
704 advertised_authlist = self.esmtp_features["auth"].split()
Guido van Rossumae010462001-09-11 15:57:46 +0000705
R David Murray76e13c12014-07-03 14:47:46 -0400706 # Authentication methods we can handle in our preferred order:
707 preferred_auths = ['CRAM-MD5', 'PLAIN', 'LOGIN']
Guido van Rossumae010462001-09-11 15:57:46 +0000708
R David Murray76e13c12014-07-03 14:47:46 -0400709 # We try the supported authentications in our preferred order, if
710 # the server supports them.
711 authlist = [auth for auth in preferred_auths
712 if auth in advertised_authlist]
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000713 if not authlist:
Fred Drake2f8f4d32001-10-13 18:35:32 +0000714 raise SMTPException("No suitable authentication method found.")
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000715
716 # Some servers advertise authentication methods they don't really
717 # support, so if authentication fails, we continue until we've tried
718 # all methods.
R David Murray76e13c12014-07-03 14:47:46 -0400719 self.user, self.password = user, password
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000720 for authmethod in authlist:
R David Murray76e13c12014-07-03 14:47:46 -0400721 method_name = 'auth_' + authmethod.lower().replace('-', '_')
722 try:
Barry Warsawc5ea7542015-07-09 10:39:55 -0400723 (code, resp) = self.auth(
724 authmethod, getattr(self, method_name),
725 initial_response_ok=initial_response_ok)
R David Murray76e13c12014-07-03 14:47:46 -0400726 # 235 == 'Authentication successful'
727 # 503 == 'Error: already authenticated'
728 if code in (235, 503):
729 return (code, resp)
730 except SMTPAuthenticationError as e:
731 last_exception = e
Gerhard Häring1c5471f2010-08-05 14:08:44 +0000732
R David Murray76e13c12014-07-03 14:47:46 -0400733 # We could not login successfully. Return result of last attempt.
734 raise last_exception
Guido van Rossumae010462001-09-11 15:57:46 +0000735
Antoine Pitroue0650202011-05-18 18:03:09 +0200736 def starttls(self, keyfile=None, certfile=None, context=None):
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000737 """Puts the connection to the SMTP server into TLS mode.
Tim Petersb64bec32001-09-18 02:26:39 +0000738
Christian Heimes679db4a2008-01-18 09:56:22 +0000739 If there has been no previous EHLO or HELO command this session, this
740 method tries ESMTP EHLO first.
741
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000742 If the server supports TLS, this will encrypt the rest of the SMTP
743 session. If you provide the keyfile and certfile parameters,
744 the identity of the SMTP server and client can be checked. This,
745 however, depends on whether the socket module really checks the
746 certificates.
Christian Heimes679db4a2008-01-18 09:56:22 +0000747
748 This method may raise the following exceptions:
749
750 SMTPHeloError The server didn't reply properly to
751 the helo greeting.
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000752 """
Christian Heimes679db4a2008-01-18 09:56:22 +0000753 self.ehlo_or_helo_if_needed()
754 if not self.has_extn("starttls"):
R David Murraycee7cf62015-05-16 13:58:14 -0400755 raise SMTPNotSupportedError(
756 "STARTTLS extension not supported by server.")
Tim Petersb64bec32001-09-18 02:26:39 +0000757 (resp, reply) = self.docmd("STARTTLS")
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000758 if resp == 220:
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000759 if not _have_ssl:
760 raise RuntimeError("No SSL support included in this Python")
Antoine Pitroue0650202011-05-18 18:03:09 +0200761 if context is not None and keyfile is not None:
762 raise ValueError("context and keyfile arguments are mutually "
763 "exclusive")
764 if context is not None and certfile is not None:
765 raise ValueError("context and certfile arguments are mutually "
766 "exclusive")
Christian Heimesd0486372016-09-10 23:23:33 +0200767 if keyfile is not None or certfile is not None:
768 import warnings
Pablo Aguiar4b5e62d2018-11-01 11:33:35 +0100769 warnings.warn("keyfile and certfile are deprecated, use a "
Christian Heimesd0486372016-09-10 23:23:33 +0200770 "custom context instead", DeprecationWarning, 2)
Christian Heimes67986f92013-11-23 22:43:47 +0100771 if context is None:
772 context = ssl._create_stdlib_context(certfile=certfile,
773 keyfile=keyfile)
Christian Heimesa5768f72013-12-02 20:44:17 +0100774 self.sock = context.wrap_socket(self.sock,
Benjamin Peterson7243b572014-11-23 17:04:34 -0600775 server_hostname=self._host)
Antoine Pitrouf068ab82011-06-06 19:17:09 +0200776 self.file = None
Christian Heimes679db4a2008-01-18 09:56:22 +0000777 # RFC 3207:
778 # The client MUST discard any knowledge obtained from
779 # the server, such as the list of SMTP service extensions,
780 # which was not obtained from the TLS negotiation itself.
781 self.helo_resp = None
782 self.ehlo_resp = None
783 self.esmtp_features = {}
784 self.does_esmtp = 0
Benjamin Peterson46b32f32016-06-11 13:16:42 -0700785 else:
786 # RFC 3207:
787 # 501 Syntax error (no parameters allowed)
788 # 454 TLS not available due to temporary reason
789 raise SMTPResponseException(resp, reply)
Guido van Rossumf7fcf5e2001-09-14 16:08:44 +0000790 return (resp, reply)
Tim Petersb64bec32001-09-18 02:26:39 +0000791
Pablo Aguiard5fbe9b2018-09-08 00:04:48 +0200792 def sendmail(self, from_addr, to_addrs, msg, mail_options=(),
793 rcpt_options=()):
Tim Peters495ad3c2001-01-15 01:36:40 +0000794 """This command performs an entire mail transaction.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000795
Tim Peters495ad3c2001-01-15 01:36:40 +0000796 The arguments are:
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000797 - from_addr : The address sending this mail.
798 - to_addrs : A list of addresses to send this mail to. A bare
799 string will be treated as a list with 1 address.
Tim Peters495ad3c2001-01-15 01:36:40 +0000800 - msg : The message to send.
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000801 - mail_options : List of ESMTP options (such as 8bitmime) for the
802 mail command.
803 - rcpt_options : List of ESMTP options (such as DSN commands) for
804 all the rcpt commands.
805
R. David Murray7dff9e02010-11-08 17:15:13 +0000806 msg may be a string containing characters in the ASCII range, or a byte
807 string. A string is encoded to bytes using the ascii codec, and lone
R David Murrayac4e5ab2011-07-02 21:03:19 -0400808 \\r and \\n characters are converted to \\r\\n characters.
R. David Murray7dff9e02010-11-08 17:15:13 +0000809
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000810 If there has been no previous EHLO or HELO command this session, this
811 method tries ESMTP EHLO first. If the server does ESMTP, message size
812 and each of the specified options will be passed to it. If EHLO
813 fails, HELO will be tried and ESMTP options suppressed.
814
815 This method will return normally if the mail is accepted for at least
Barry Warsawd25c1b71999-11-28 17:11:06 +0000816 one recipient. It returns a dictionary, with one entry for each
817 recipient that was refused. Each entry contains a tuple of the SMTP
818 error code and the accompanying error message sent by the server.
Guido van Rossum296e1431999-04-07 15:03:39 +0000819
820 This method may raise the following exceptions:
821
822 SMTPHeloError The server didn't reply properly to
Tim Peters495ad3c2001-01-15 01:36:40 +0000823 the helo greeting.
Barry Warsawd25c1b71999-11-28 17:11:06 +0000824 SMTPRecipientsRefused The server rejected ALL recipients
Guido van Rossum296e1431999-04-07 15:03:39 +0000825 (no mail was sent).
826 SMTPSenderRefused The server didn't accept the from_addr.
827 SMTPDataError The server replied with an unexpected
828 error code (other than a refusal of
829 a recipient).
R David Murraycee7cf62015-05-16 13:58:14 -0400830 SMTPNotSupportedError The mail_options parameter includes 'SMTPUTF8'
831 but the SMTPUTF8 extension is not supported by
832 the server.
Guido van Rossum296e1431999-04-07 15:03:39 +0000833
834 Note: the connection will be open even after an exception is raised.
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000835
Guido van Rossum95e6f701998-06-25 02:15:50 +0000836 Example:
Tim Peters495ad3c2001-01-15 01:36:40 +0000837
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000838 >>> import smtplib
839 >>> s=smtplib.SMTP("localhost")
Guido van Rossumfc40a831998-01-29 17:26:45 +0000840 >>> tolist=["one@one.org","two@two.org","three@three.org","four@four.org"]
Martin v. Löwis301b1cd2002-07-28 16:52:01 +0000841 >>> msg = '''\\
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000842 ... From: Me@my.org
843 ... Subject: testin'...
844 ...
845 ... This is a test '''
846 >>> s.sendmail("me@my.org",tolist,msg)
847 { "three@three.org" : ( 550 ,"User unknown" ) }
848 >>> s.quit()
Tim Peters495ad3c2001-01-15 01:36:40 +0000849
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000850 In the above example, the message was accepted for delivery to three
851 of the four addresses, and one was rejected, with the error code
Barry Warsawd25c1b71999-11-28 17:11:06 +0000852 550. If all addresses are accepted, then the method will return an
Barry Warsaw4c4bec81998-12-22 03:02:20 +0000853 empty dictionary.
854
855 """
Christian Heimes679db4a2008-01-18 09:56:22 +0000856 self.ehlo_or_helo_if_needed()
Guido van Rossum95e6f701998-06-25 02:15:50 +0000857 esmtp_opts = []
R. David Murray7dff9e02010-11-08 17:15:13 +0000858 if isinstance(msg, str):
859 msg = _fix_eols(msg).encode('ascii')
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000860 if self.does_esmtp:
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000861 if self.has_extn('size'):
Walter Dörwald70a6b492004-02-12 17:35:32 +0000862 esmtp_opts.append("size=%d" % len(msg))
Guido van Rossumfcfb6321998-08-04 15:29:54 +0000863 for option in mail_options:
Guido van Rossum95e6f701998-06-25 02:15:50 +0000864 esmtp_opts.append(option)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000865 (code, resp) = self.mail(from_addr, esmtp_opts)
Fred Drake8152d322000-12-12 23:20:45 +0000866 if code != 250:
R David Murrayd312c742013-03-20 20:36:14 -0400867 if code == 421:
868 self.close()
869 else:
R David Murrayafb151a2014-04-14 18:21:38 -0400870 self._rset()
Guido van Rossum296e1431999-04-07 15:03:39 +0000871 raise SMTPSenderRefused(code, resp, from_addr)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000872 senderrs = {}
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000873 if isinstance(to_addrs, str):
Jeremy Hylton31bb8ce1998-08-13 19:57:46 +0000874 to_addrs = [to_addrs]
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000875 for each in to_addrs:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000876 (code, resp) = self.rcpt(each, rcpt_options)
Fred Drake8152d322000-12-12 23:20:45 +0000877 if (code != 250) and (code != 251):
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000878 senderrs[each] = (code, resp)
R David Murrayd312c742013-03-20 20:36:14 -0400879 if code == 421:
880 self.close()
881 raise SMTPRecipientsRefused(senderrs)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000882 if len(senderrs) == len(to_addrs):
Guido van Rossum95e6f701998-06-25 02:15:50 +0000883 # the server refused all our recipients
R David Murrayafb151a2014-04-14 18:21:38 -0400884 self._rset()
Guido van Rossum296e1431999-04-07 15:03:39 +0000885 raise SMTPRecipientsRefused(senderrs)
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +0000886 (code, resp) = self.data(msg)
Fred Drake8152d322000-12-12 23:20:45 +0000887 if code != 250:
R David Murrayd312c742013-03-20 20:36:14 -0400888 if code == 421:
889 self.close()
890 else:
R David Murrayafb151a2014-04-14 18:21:38 -0400891 self._rset()
Guido van Rossum296e1431999-04-07 15:03:39 +0000892 raise SMTPDataError(code, resp)
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000893 #if we got here then somebody got our mail
Tim Peters495ad3c2001-01-15 01:36:40 +0000894 return senderrs
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000895
R. David Murray7dff9e02010-11-08 17:15:13 +0000896 def send_message(self, msg, from_addr=None, to_addrs=None,
Pablo Aguiard5fbe9b2018-09-08 00:04:48 +0200897 mail_options=(), rcpt_options=()):
R. David Murray7dff9e02010-11-08 17:15:13 +0000898 """Converts message to a bytestring and passes it to sendmail.
899
900 The arguments are as for sendmail, except that msg is an
R David Murrayac4e5ab2011-07-02 21:03:19 -0400901 email.message.Message object. If from_addr is None or to_addrs is
902 None, these arguments are taken from the headers of the Message as
903 described in RFC 2822 (a ValueError is raised if there is more than
904 one set of 'Resent-' headers). Regardless of the values of from_addr and
905 to_addr, any Bcc field (or Resent-Bcc field, when the Message is a
906 resent) of the Message object won't be transmitted. The Message
907 object is then serialized using email.generator.BytesGenerator and
R David Murray83084442015-05-17 19:27:22 -0400908 sendmail is called to transmit the message. If the sender or any of
909 the recipient addresses contain non-ASCII and the server advertises the
910 SMTPUTF8 capability, the policy is cloned with utf8 set to True for the
911 serialization, and SMTPUTF8 and BODY=8BITMIME are asserted on the send.
Berker Peksage39682b2016-07-01 12:17:05 +0300912 If the server does not support SMTPUTF8, an SMTPNotSupported error is
R David Murray83084442015-05-17 19:27:22 -0400913 raised. Otherwise the generator is called without modifying the
914 policy.
R David Murrayac4e5ab2011-07-02 21:03:19 -0400915
R. David Murray7dff9e02010-11-08 17:15:13 +0000916 """
R David Murrayac4e5ab2011-07-02 21:03:19 -0400917 # 'Resent-Date' is a mandatory field if the Message is resent (RFC 2822
918 # Section 3.6.6). In such a case, we use the 'Resent-*' fields. However,
919 # if there is more than one 'Resent-' block there's no way to
920 # unambiguously determine which one is the most recent in all cases,
921 # so rather than guess we raise a ValueError in that case.
922 #
923 # TODO implement heuristics to guess the correct Resent-* block with an
924 # option allowing the user to enable the heuristics. (It should be
925 # possible to guess correctly almost all of the time.)
Senthil Kumaranb351a482011-07-31 09:14:17 +0800926
R David Murray83084442015-05-17 19:27:22 -0400927 self.ehlo_or_helo_if_needed()
Senthil Kumaranb351a482011-07-31 09:14:17 +0800928 resent = msg.get_all('Resent-Date')
R David Murrayac4e5ab2011-07-02 21:03:19 -0400929 if resent is None:
930 header_prefix = ''
931 elif len(resent) == 1:
932 header_prefix = 'Resent-'
933 else:
934 raise ValueError("message has more than one 'Resent-' header block")
R. David Murray7dff9e02010-11-08 17:15:13 +0000935 if from_addr is None:
R David Murrayac4e5ab2011-07-02 21:03:19 -0400936 # Prefer the sender field per RFC 2822:3.6.2.
Senthil Kumaranb351a482011-07-31 09:14:17 +0800937 from_addr = (msg[header_prefix + 'Sender']
938 if (header_prefix + 'Sender') in msg
939 else msg[header_prefix + 'From'])
Stéphane Wirtel8d83e4b2018-01-31 01:02:51 +0100940 from_addr = email.utils.getaddresses([from_addr])[0][1]
R. David Murray7dff9e02010-11-08 17:15:13 +0000941 if to_addrs is None:
Senthil Kumaranb351a482011-07-31 09:14:17 +0800942 addr_fields = [f for f in (msg[header_prefix + 'To'],
943 msg[header_prefix + 'Bcc'],
R David Murray83084442015-05-17 19:27:22 -0400944 msg[header_prefix + 'Cc'])
945 if f is not None]
R. David Murray7dff9e02010-11-08 17:15:13 +0000946 to_addrs = [a[1] for a in email.utils.getaddresses(addr_fields)]
R David Murrayac4e5ab2011-07-02 21:03:19 -0400947 # Make a local copy so we can delete the bcc headers.
948 msg_copy = copy.copy(msg)
949 del msg_copy['Bcc']
950 del msg_copy['Resent-Bcc']
R David Murray83084442015-05-17 19:27:22 -0400951 international = False
952 try:
953 ''.join([from_addr, *to_addrs]).encode('ascii')
954 except UnicodeEncodeError:
955 if not self.has_extn('smtputf8'):
956 raise SMTPNotSupportedError(
957 "One or more source or delivery addresses require"
958 " internationalized email support, but the server"
959 " does not advertise the required SMTPUTF8 capability")
960 international = True
R. David Murray7dff9e02010-11-08 17:15:13 +0000961 with io.BytesIO() as bytesmsg:
R David Murray83084442015-05-17 19:27:22 -0400962 if international:
963 g = email.generator.BytesGenerator(
964 bytesmsg, policy=msg.policy.clone(utf8=True))
Pablo Aguiard5fbe9b2018-09-08 00:04:48 +0200965 mail_options = (*mail_options, 'SMTPUTF8', 'BODY=8BITMIME')
R David Murray83084442015-05-17 19:27:22 -0400966 else:
967 g = email.generator.BytesGenerator(bytesmsg)
R David Murrayac4e5ab2011-07-02 21:03:19 -0400968 g.flatten(msg_copy, linesep='\r\n')
R. David Murray7dff9e02010-11-08 17:15:13 +0000969 flatmsg = bytesmsg.getvalue()
970 return self.sendmail(from_addr, to_addrs, flatmsg, mail_options,
971 rcpt_options)
972
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000973 def close(self):
974 """Close the connection to the SMTP server."""
Serhiy Storchaka7e7a3db2015-04-10 13:24:41 +0300975 try:
976 file = self.file
977 self.file = None
978 if file:
979 file.close()
980 finally:
981 sock = self.sock
982 self.sock = None
983 if sock:
984 sock.close()
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000985
Guido van Rossumbbe323e1998-01-29 17:24:40 +0000986 def quit(self):
Guido van Rossum95e6f701998-06-25 02:15:50 +0000987 """Terminate the SMTP session."""
Christian Heimesba4af492008-03-28 00:55:15 +0000988 res = self.docmd("quit")
R David Murray0cff49f2014-08-30 16:51:59 -0400989 # A new EHLO is required after reconnecting with connect()
990 self.ehlo_resp = self.helo_resp = None
991 self.esmtp_features = {}
992 self.does_esmtp = False
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000993 self.close()
Christian Heimesba4af492008-03-28 00:55:15 +0000994 return res
Guido van Rossum95e6f701998-06-25 02:15:50 +0000995
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000996if _have_ssl:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000997
Thomas Wouters47b49bf2007-08-30 22:15:33 +0000998 class SMTP_SSL(SMTP):
R David Murray021362d2013-06-23 16:05:44 -0400999 """ This is a subclass derived from SMTP that connects over an SSL
1000 encrypted socket (to use this class you need a socket module that was
1001 compiled with SSL support). If host is not specified, '' (the local
1002 host) is used. If port is omitted, the standard SMTP-over-SSL port
1003 (465) is used. local_hostname and source_address have the same meaning
1004 as they do in the SMTP class. keyfile and certfile are also optional -
1005 they can contain a PEM formatted private key and certificate chain file
1006 for the SSL connection. context also optional, can contain a
1007 SSLContext, and is an alternative to keyfile and certfile; If it is
1008 specified both keyfile and certfile must be None.
1009
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001010 """
Antoine Pitrouc1d52062011-05-07 19:39:37 +02001011
1012 default_port = SMTP_SSL_PORT
1013
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001014 def __init__(self, host='', port=0, local_hostname=None,
Georg Brandlf78e02b2008-06-10 17:40:04 +00001015 keyfile=None, certfile=None,
Senthil Kumaran3d23fd62011-07-30 10:56:50 +08001016 timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
1017 source_address=None, context=None):
Antoine Pitroue0650202011-05-18 18:03:09 +02001018 if context is not None and keyfile is not None:
1019 raise ValueError("context and keyfile arguments are mutually "
1020 "exclusive")
1021 if context is not None and certfile is not None:
1022 raise ValueError("context and certfile arguments are mutually "
1023 "exclusive")
Christian Heimesd0486372016-09-10 23:23:33 +02001024 if keyfile is not None or certfile is not None:
1025 import warnings
Pablo Aguiar4b5e62d2018-11-01 11:33:35 +01001026 warnings.warn("keyfile and certfile are deprecated, use a "
Christian Heimesd0486372016-09-10 23:23:33 +02001027 "custom context instead", DeprecationWarning, 2)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001028 self.keyfile = keyfile
1029 self.certfile = certfile
Christian Heimes67986f92013-11-23 22:43:47 +01001030 if context is None:
1031 context = ssl._create_stdlib_context(certfile=certfile,
1032 keyfile=keyfile)
Antoine Pitroue0650202011-05-18 18:03:09 +02001033 self.context = context
Senthil Kumaran3d23fd62011-07-30 10:56:50 +08001034 SMTP.__init__(self, host, port, local_hostname, timeout,
1035 source_address)
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001036
1037 def _get_socket(self, host, port, timeout):
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +00001038 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -04001039 self._print_debug('connect:', (host, port))
Senthil Kumaran3d23fd62011-07-30 10:56:50 +08001040 new_socket = socket.create_connection((host, port), timeout,
1041 self.source_address)
Christian Heimesa5768f72013-12-02 20:44:17 +01001042 new_socket = self.context.wrap_socket(new_socket,
Benjamin Peterson7243b572014-11-23 17:04:34 -06001043 server_hostname=self._host)
R. David Murray87e20742009-05-23 01:30:26 +00001044 return new_socket
Thomas Wouters47b49bf2007-08-30 22:15:33 +00001045
1046 __all__.append("SMTP_SSL")
Barry Warsaw4c4bec81998-12-22 03:02:20 +00001047
Guido van Rossumd8faa362007-04-27 19:54:29 +00001048#
1049# LMTP extension
1050#
1051LMTP_PORT = 2003
1052
1053class LMTP(SMTP):
1054 """LMTP - Local Mail Transfer Protocol
1055
1056 The LMTP protocol, which is very similar to ESMTP, is heavily based
R David Murray021362d2013-06-23 16:05:44 -04001057 on the standard SMTP client. It's common to use Unix sockets for
1058 LMTP, so our connect() method must support that as well as a regular
R David Murray36beb662013-06-23 15:47:50 -04001059 host:port server. local_hostname and source_address have the same
R David Murray021362d2013-06-23 16:05:44 -04001060 meaning as they do in the SMTP class. To specify a Unix socket,
1061 you must use an absolute path as the host, starting with a '/'.
Guido van Rossumd8faa362007-04-27 19:54:29 +00001062
1063 Authentication is supported, using the regular SMTP mechanism. When
1064 using a Unix socket, LMTP generally don't support or require any
1065 authentication, but your mileage might vary."""
1066
1067 ehlo_msg = "lhlo"
1068
Senthil Kumaran3d23fd62011-07-30 10:56:50 +08001069 def __init__(self, host='', port=LMTP_PORT, local_hostname=None,
1070 source_address=None):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001071 """Initialize a new instance."""
Senthil Kumaranb351a482011-07-31 09:14:17 +08001072 SMTP.__init__(self, host, port, local_hostname=local_hostname,
1073 source_address=source_address)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001074
Senthil Kumaran3d23fd62011-07-30 10:56:50 +08001075 def connect(self, host='localhost', port=0, source_address=None):
Guido van Rossumd8faa362007-04-27 19:54:29 +00001076 """Connect to the LMTP daemon, on either a Unix or a TCP socket."""
1077 if host[0] != '/':
Senthil Kumaranb351a482011-07-31 09:14:17 +08001078 return SMTP.connect(self, host, port, source_address=source_address)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001079
1080 # Handle Unix-domain sockets.
1081 try:
1082 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
Antoine Pitrouf068ab82011-06-06 19:17:09 +02001083 self.file = None
Guido van Rossumd8faa362007-04-27 19:54:29 +00001084 self.sock.connect(host)
Andrew Svetlov2ade6f22012-12-17 18:57:16 +02001085 except OSError:
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +00001086 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -04001087 self._print_debug('connect fail:', host)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001088 if self.sock:
1089 self.sock.close()
1090 self.sock = None
Andrew Svetlovb6693c42012-12-17 18:54:53 +02001091 raise
Guido van Rossumd8faa362007-04-27 19:54:29 +00001092 (code, msg) = self.getreply()
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +00001093 if self.debuglevel > 0:
R David Murray0c49b892015-04-16 17:14:42 -04001094 self._print_debug('connect:', msg)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001095 return (code, msg)
1096
1097
Guido van Rossum95e6f701998-06-25 02:15:50 +00001098# Test the sendmail method, which tests most of the others.
1099# Note: This always sends to localhost.
1100if __name__ == '__main__':
Guido van Rossum95e6f701998-06-25 02:15:50 +00001101 def prompt(prompt):
1102 sys.stdout.write(prompt + ": ")
Ezio Melotti6bfecd12011-10-18 13:20:07 +03001103 sys.stdout.flush()
Eric S. Raymondc013f302001-02-09 05:40:38 +00001104 return sys.stdin.readline().strip()
Guido van Rossum95e6f701998-06-25 02:15:50 +00001105
1106 fromaddr = prompt("From")
Giampaolo Rodolàbd258bd2011-02-22 15:56:20 +00001107 toaddrs = prompt("To").split(',')
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001108 print("Enter message, end with ^D:")
Guido van Rossum95e6f701998-06-25 02:15:50 +00001109 msg = ''
1110 while 1:
1111 line = sys.stdin.readline()
1112 if not line:
1113 break
1114 msg = msg + line
Guido van Rossumbe19ed72007-02-09 05:37:30 +00001115 print("Message length is %d" % len(msg))
Guido van Rossum95e6f701998-06-25 02:15:50 +00001116
1117 server = SMTP('localhost')
1118 server.set_debuglevel(1)
1119 server.sendmail(fromaddr, toaddrs, msg)
1120 server.quit()