我 Python 尝试通过 Gmail 通过 SMTP 发送邮件有什么问题? SSL 包装器似乎不起作用

What's wrong with my Python attempt at sending mail via SMTP through Gmail? The SSL wrapper doesn't seem to work

我有以下非常简单的 Python 代码,源自 here:

import ssl
import base64
from socket import *

cc = socket(AF_INET, SOCK_STREAM)
cc.connect(("smtp.gmail.com", 587))

cc.send('helo tester.com\r\n')
cc.send('starttls\r\n')

scc = ssl.wrap_socket(cc, ssl_version=ssl.PROTOCOL_SSLv23)
scc.send('AUTH LOGIN\r\n')

scc.send(base64.b64encode('myBase64EncodedUsernameAndPassword==')+'\r\n')
scc.send

但是在 运行 之后我得到:

Traceback (most recent call last):
  File "Untitled 2.py", line 16, in <module>
    scc = ssl.wrap_socket(cc, ssl_version=ssl.PROTOCOL_SSLv23)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 387, in wrap_socket
    ciphers=ciphers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 143, in __init__
    self.do_handshake()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ssl.py", line 305, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [Errno 1] _ssl.c:507: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

我做错了什么?

您盲目地将数据发送到服务器,而没有尝试从服务器读取和检查答案。但这是必需的,因为只有在成功响应 STARTTLS 命令后,您才能将套接字升级到 SSL。

由于您不读取服务器的响应并尝试盲目地将套接字升级到 SSL,它将通过发送 ClientHello 开始 SSL 握手,但随后会发出 unknown protocol 的声音,因为相反读取 ServerHello 它将从服务器读取纯文本数据,您应该早先读取它。

有关如何正确处理 SMTP 的详细信息,请参阅标准,即 RFC 5321 and RFC 3207