通过smtplib的STARTTLS方法登录到旧电子邮件服务器

8

我使用的是Python 2.7.15,OpenSSL 1.1.0h(2018年3月27日发布),MS Exchange 2007。

我的MS Exchange只允许在STARTTLS之后发送登录信息。

在Python中,我尝试连接服务器的方式如下:

from stmplib import SMTP
conn = SMTP(server,port)
conn.set_debuglevel(1)
conn.starttls()
conn.login(username, password)
conn.quit()

最后我在starttls中遇到了错误:

/python2.7/ssl.py",第847行,在do_handshake中 self._sslobj.do_handshake()

问题是Python尝试与TLS v1.2建立连接,但Exchange仅支持TLS v.1.0。 我尝试了25号和587号端口。
当我尝试通过控制台openssl应用程序连接并登录服务器时,对于使用TLS v.1.0的两个端口都可以正常工作: openssl s_client -connect sever:587 -starttls smtp -no_tls1_2 -no_tls1_1 -crlf 服务器回答:
SSL handshake has read 1481 bytes and written 530 bytes
--- New, TLSv1/SSLv3, Cipher is RC4-MD5 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-MD5
    Session-ID: xxxx
    Session-ID-ctx:
    Master-Key: xxxx
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1533874470
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
--- 250 CHUNKING ehlo 250-xxxxxxx Hello [xxxx] 250-SIZE 26214400 250-PIPELINING 250-DSN 250-ENHANCEDSTATUSCODES 250-AUTH GSSAPI NTLM LOGIN 250-8BITMIME 250-BINARYMIME 250 CHUNKING ^C

我尝试继承标准 SMTP 类以重载 starttls 方法,使用 context 选项,如下所示:

    # show only changes to standard `starttls` method
    def starttls(self, keyfile=None, certfile=None, context=None):
        ...
        if context is None:
            context = ssl._create_stdlib_context(certfile=certfile, keyfile=keyfile)                                        
        self.sock = context.wrap_socket(self.sock, server_hostname=self._hostname)
       ...

并在我的脚本中使用这个类:

context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.options |= ssl.OP_NO_TLSv1_2 | ssl.OP_NO_TLSv1_1

conn = mySMTP(server,port)
conn.set_debuglevel(1)
conn.starttls(context = context)
conn.login(username, password)
conn.quit()

但是错误仍然存在。 我做错了什么?也许上下文选项必须是其他的,或者我漏掉了某些内容? 在这种情况下如何设置smtplib和starttls方法以强制仅使用TLS v.1.0?
1个回答

1

在连接使用过时的SSL版本的旧邮件服务时,我过去成功的方法是使用stunnel或类似工具设置本地隧道,并通过localhost进行连接,您还可以设置本地sendmail实例作为代理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接