The following code in python 3 raises an error on my computer, and I don't know how to log in properly:
import smtplib
connection = smtplib.SMTP('smtp-mail.outlook.com', 587)
connection.ehlo()
connection.starttls()
connection.ehlo()
connection.login('[email protected]', '_the_error_persists_')
The last line produces the following output:
Traceback (most recent call last):
File "/usr/lib/python3.3/smtplib.py", line 366, in getreply
line = self.file.readline()
File "/usr/lib/python3.3/socket.py", line 297, in readinto
return self._sock.recv_into(b)
File "/usr/lib/python3.3/ssl.py", line 460, in recv_into
return self.read(nbytes, buffer)
File "/usr/lib/python3.3/ssl.py", line 334, in read
v = self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1504)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/smtplib.py", line 621, in login
AUTH_PLAIN + " " + encode_plain(user, password))
File "/usr/lib/python3.3/smtplib.py", line 398, in docmd
return self.getreply()
File "/usr/lib/python3.3/smtplib.py", line 370, in getreply
+ str(e))
smtplib.SMTPServerDisconnected: Connection unexpectedly closed: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1504)
The SMTP information (port, etc) I used is from a microsoft help site, other ports or domains for outlook I've tried result in the same error.
The output of openssl version
is 1.0.1e 11 Feb 2013
Source code: Lib/smtplib.py The smtplib module defines an SMTP client session object that can be used to send mail to any internet machine with an SMTP or ESMTP listener daemon. For details of SMTP and ESMTP operation, consult RFC 821 (Simple Mail Transfer Protocol) and RFC 1869 (SMTP Service Extensions).
exception smtplib. SMTPResponseException ¶ Base class for all exceptions that include an SMTP error code. These exceptions are generated in some instances when the SMTP server returns an error code. The error code is stored in the smtp_code attribute of the error, and the smtp_error attribute is set to the error message.
Python has provisional and experimental support for TLS 1.3 with OpenSSL 1.1.1. The new protocol behaves slightly differently than previous version of TLS/SSL. Some new TLS 1.3 features are not yet available. TLS 1.3 uses a
If this method does not raise an exception, it returns a dictionary, with one entry for each recipient that was refused. Each entry contains a tuple of the SMTP error code and the accompanying error message sent by the server.
To answer my own question:
beginning with python 3.3, you don't have to hack the smtplib as in this answer, but instead you can pass a SSLContext
object when using starttls
.
However, be aware: if the login data is wrong, it will still raise an error. If the login data is right, everything works fine if using the following code:
import smtplib
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
connection = smtplib.SMTP('smtp-mail.outlook.com', 587)
connection.ehlo()
connection.starttls(context=context)
connection.ehlo()
connection.login('[email protected]', 'otherwise_SMTPServerDisconnect')
The answer of @user2884042 is almost right.
According to https://docs.python.org/3/library/ssl.html:
Changed in version 3.5: The default ssl_version is changed from PROTOCOL_SSLv3 to PROTOCOL_TLS for maximum compatibility with modern servers.
So, you need to replace 'PROTOCOL_SSLv3' by 'PROTOCOL_TLS', which leaves the code something like:
import smtplib
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
connection = smtplib.SMTP('smtp-mail.outlook.com', 587)
connection.ehlo()
connection.starttls(context=context)
connection.ehlo()
connection.login('[email protected]', 'otherwise_SMTPServerDisconnect')
Sometimes you are not even required to login. Instead of the following line,
$ connection.login('[email protected]', 'otherwise_SMTPServerDisconnect')
You can directly send an email using your credentials.
$ sender_email = "[email protected]"
$ receiver_email = "[email protected]"
$ msg = "Hello from python!"
$ connection.sendmail(sender_email, receiver_email, msg)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With