【问题标题】:Why Do I Keep getting SSL Error on Simple Mail Client Program? [duplicate]为什么我在简单邮件客户端程序上不断收到 SSL 错误? [复制]
【发布时间】:2012-09-15 00:39:41
【问题描述】:

可能重复:
Implementing Transport Layer Security in Python - Simple Mail Client

我不断收到此错误...

ssl.SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib

...在一个简单的邮件客户端分配中,即打开与 google smtp 服务器的连接。几乎可以肯定,问题似乎在于我在这里形成 ssl.wrap_socket() 方法的方式......

 clientSocket = socket(AF_INET, SOCK_STREAM)
  ssl_clientSocket = ssl.wrap_socket(clientSocket,
          ca_certs = '/etc/ssl/certs/ca.pm',
          cert_reqs = ssl.CERT_REQUIRED)
  ssl_clientSocket.connect((mailserver, port))

.. 但我无法真正弄清楚问题出在哪里,而且我真的不确定在 /etc/ssl/certs 中使用哪个 .pm 文件。我正在使用 ca.pm,因为我已经在一些教程中看到它是这样做的。这是用于衡量的其余代码....

from socket import *
import certifi
import ssl

msg = "\r\n I love computer networks!"
endmsg = "\r\n.\r\n"

# Choose a mail server (e.g. Google mail server) and call it mailserver
mailserver = "smtp.gmail.com"
port = 587

# Create socket called clientSocket and establish a TCP connection with mailserver
clientSocket = socket(AF_INET, SOCK_STREAM)
ssl_clientSocket = ssl.wrap_socket(clientSocket, 
        ca_certs = '/etc/ssl/certs/ca.pm',
        cert_reqs = ssl.CERT_REQUIRED) 
ssl_clientSocket.connect((mailserver, port))

###################################################################
print "got to here 1"
###############################################################

recv = ssl_clientSocket.recv(1024)
print
print recv

# If the first three numbers of what we receive from the SMTP server are not
# '220', we have a problem
if recv[:3] != '220':
    print '220 reply not received from server.'

# Send HELO command and print server response.
heloCommand = 'HELO Alice\r\n'
ssl_clientSocket.send(heloCommand)
recv1 = ssl_clientSocket.recv(1024)
print recv1

######################################################################
print "Got to here 2"
#####################################################################

# If the first three numbers of the response from the server are not
# '250', we have a problem
if recv1[:3] != '250':
    print '250 reply not received from server.'

# Send MAIL FROM command and print server response.
mailFromCommand = 'MAIL From: wgimson@gmail.com\r\n'
ssl_clientSocket.send(mailFromCommand)
recv2 = ssl_clientSocket.recv(1024)
print recv2

# If the first three numbers of the response from the server are not
# '250', we have a problem
if recv2[:3] != '250':
    print '250 reply not received from server.'

# Send RCPT TO command and print server response.
rcptToCommand = 'RCPT To: macyali@gmail.com\r\n'
ssl_clientSocket.send(rcptToCommand)
recv3 = ssl_clientSocket.recv(1024)
print recv3

# If the first three numbers of the response from the server are not
# '250', we have a problem
if recv3[:3] != '250':
    print '250 reply not received from server.'

# Send DATA command and print server response.
dataCommand = 'DATA\r\n'
ssl_clientSocket.send(dataCommand)
recv4 = ssl_clientSocket.recv(1024)
print recv4

# If the first three numbers of the response from the server are not
# '250', we have a problem
if recv4[:3] != '250':
    print '250 reply not received from server.'

# Send message data.
ssl_clientSocket.send(msg)

# Message ends with a single period.
ssl_clientSocket.send(endmsg)

# Send QUIT command and get server response.
quitCommand = 'QUIT\r\n'
ssl_clientSocket.send(quitCommand)
recv5 = ssl_clientSocket.recv(I1024)
print recv5

# If the first three numbers of the response from the server are not
# '250', we have a problem
if recv5[:3] != '221':
    print '221 reply not received from server.'

【问题讨论】:

    标签: python sockets ssl smtp certificate


    【解决方案1】:
    • 错误可能是由拼写错误引起的:'/etc/ssl/certs/ca.pm' -> '/etc/ssl/certs/ca.pem' 即系统找不到ca.pm文件
    • '/etc/ssl/certs/ca.pem' 不包含必要的 CA 证书。

    您可以从http://curl.haxx.se/ca/cacert.pem 下载cacert.pem(它是最新的)或使用ca_certs = certifi.where()(我在您的代码中看到import certifi),例如:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import smtplib
    import socket
    import ssl
    import sys
    from email.header    import Header
    from email.mime.text import MIMEText
    from getpass         import getpass
    
    import certifi # $ pip install certifi
    
    login, password = 'user@gmail.com', getpass('Gmail password:')
    ca_certs = certifi.where()
    ##ca_certs = 'cacert.pem' # $ wget http://curl.haxx.se/ca/cacert.pem
    
    
    class SMTP_SSL(smtplib.SMTP_SSL):
        """Add support for additional ssl options."""
        def __init__(self, host, port=0, **kwargs):
            self.ssl_kwargs = kwargs.pop('ssl_kwargs', {})
            self.ssl_kwargs['keyfile'] = kwargs.pop('keyfile', None)
            self.ssl_kwargs['certfile'] = kwargs.pop('certfile', None)
            smtplib.SMTP_SSL.__init__(self, host, port, **kwargs)
    
        def _get_socket(self, host, port, timeout):
            if self.debuglevel > 0:
                print>>sys.stderr, 'connect:', (host, port)
            new_socket = socket.create_connection((host, port), timeout)
            new_socket = ssl.wrap_socket(new_socket, **self.ssl_kwargs)
            self.file = smtplib.SSLFakeFile(new_socket)
            return new_socket
    
    # create message
    msg = MIMEText('message body…', _charset='utf-8')
    msg['Subject'] = Header('subject…', 'utf-8')
    msg['From'] = login
    msg['To'] = login
    
    # send it via gmail
    s = SMTP_SSL('smtp.gmail.com', timeout=10,
                 ssl_kwargs=dict(cert_reqs=ssl.CERT_REQUIRED,
                                 ssl_version=ssl.PROTOCOL_SSLv3,
                                 ca_certs=ca_certs))
    s.set_debuglevel(1) # enable debug output
    try:
        s.login(login, password)
        s.sendmail(msg['From'], msg['To'], msg.as_string())
    finally:
        s.quit()
    

    【讨论】:

      猜你喜欢
      • 2020-07-11
      • 2021-06-06
      • 1970-01-01
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多