2014-05-12 7 views
5

Ich stieß heute auf das folgende seltsame Verhalten.smtplib.SMTP starttls schlägt fehl mit tlsv1 alert decode Fehler

Der folgende Code auf Python funktioniert 3.3:

smtp = smtplib.SMTP() 
smtp.connect(host="smtp.gmail.com", port=587) 
smtp.ehlo() 
smtp.starttls() 

In Pyhton 3.4 der obige Code funktioniert nicht, stattdessen wird der folgende Fehler aufgetreten:

File "smtp_test.py", line 10, in <module> 
    smtp.starttls() 
    File "/usr/lib/python3.4/smtplib.py", line 676, in starttls 
    server_hostname=server_hostname) 
    File "/usr/lib/python3.4/ssl.py", line 344, in wrap_socket 
    _context=self) 
    File "/usr/lib/python3.4/ssl.py", line 540, in __init__ 
    self.do_handshake() 
    File "/usr/lib/python3.4/ssl.py", line 767, in do_handshake 
    self._sslobj.do_handshake() 
    ssl.SSLError: [SSL: TLSV1_ALERT_DECODE_ERROR] tlsv1 alert decode error (_ssl.c:598) 

Wenn der obige Code geändert wird Um den Host und den Port im Konstruktor anzugeben und nicht wie im folgenden Code die Methode connect zu verwenden, funktioniert es.

smtp = smtplib.SMTP(host="smtp.gmail.com", port=587) 
smtp.ehlo() 
smtp.starttls() 

Das obige Verhalten tritt mit OpenSSL Version 1.0.1f und OpenSSL 1.0.1g

Könnte jemand dieses Verhalten mir das erklären?

Antwort

4

Laut einem tcpdump sendet der Code in 3.4 SNI-Erweiterung mit einem leeren Zielnamen. SNI (Server Name Indication) wird verwendet, wenn verschiedene Zertifikate hinter derselben IP-Adresse stehen. Ich betrachte dies als einen Fehler: Wenn es keinen Namen hat, sollte es nicht die SNI-Erweiterung senden, anstatt eine Erweiterung mit einem Namen der Länge 0 darin zu senden.

+1

Warum funktioniert das zweite Stück Code, das im Konstruktor die gleiche connect-Methode verwendet, dann? – Burmudar

+1

, weil es wahrscheinlich den Host im Konstruktor speichert und für die SNI-Erweiterung wiederverwendet. Und die Verbindung speichert den Host wahrscheinlich nicht. –