문제

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('_these_dont_matter@outlook.com', '_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

올바른 솔루션이 없습니다

다른 팁

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('now_your_real_login_data@outlook.com', '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('now_your_real_login_data@outlook.com', 'otherwise_SMTPServerDisconnect')

Sometimes you are not even required to login. Instead of the following line,

$ connection.login('now_your_real_login_data@outlook.com', 'otherwise_SMTPServerDisconnect')

You can directly send an email using your credentials.

$ sender_email = "senderemail@example.com"
$ receiver_email = "receiveremail@example.com"
$ msg = "Hello from python!"
$ connection.sendmail(sender_email, receiver_email, msg)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top