2013-09-07 11 views
5

Hinweis: Dieser Code funktioniert gut auf Ubuntu, aber nicht auf Mac. Anstatt die Mac/Python-Einstellungen lokal zu ändern, versuche ich den Code so zu ändern, dass er überall funktioniert.Python httplib SSL23_GET_SERVER_HELLO: unbekanntes Protokoll

import ssl 
import httplib 
httplib.HTTPConnection(server, port, timeout) 

aber es wirft Fehler:

[Errno 1] _ssl.c:503: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

jetzt Code ist nicht mit urllib.request statt mit httplib

Ich möchte den Code ändern, so dass es SSLv3 als Standardprotokoll nehmen werden, etwa so:

ssl.SSLContext(ssl.PROTOCOL_SSLv3) 

Ich sah mich um und einige Links gefunden, aber nichts funktioniert!

this link is for ubuntu

link for python urllib and cURL

python bug fix, but again for urllib

Antwort

7

Hinweis: Der HTTPSConnection Konstruktor ermöglicht seit Python ein ssl context als Argument übergeben 2.7.9, die in diesem Fall verwendet werden soll.

Diese Antwort ist älter als diese Änderung und gilt daher nur für veraltete Versionen von Python.


httplib.HTTPSConnection.connect ruft nur ssl.wrap_socket auf der geöffneten Buchse eine https-Verbindung zu initialisieren, leider kann man keine Parameter in python2.7 angeben (python3 erlaubt passing the SSLContext).

Wenn Sie die Protokollversion angeben möchten, dann würden Sie auf Affen-Patch benötigen eine dieser beiden:

Methode 1: Patch httplib.HTTPSConnection.connect:

import httplib 
import socket 
import ssl 

def connect_patched(self): 
    "Connect to a host on a given (SSL) port." 

    sock = socket.create_connection((self.host, self.port), 
            self.timeout, self.source_address) 
    if self._tunnel_host: 
     self.sock = sock 
     self._tunnel() 
    self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, 
           ssl_version=ssl.PROTOCOL_SSLv3) 

httplib.HTTPSConnection.connect = connect_patched 

Dies ändert die Protokollversion für alle Verbindungen mit HTTPSConnection.

Methode 2: Patch ssl.wrap_socket:

import ssl 

wrap_socket_orig = ssl.wrap_socket 

def wrap_socket_patched(sock, keyfile=None, certfile=None, 
         server_side=False, cert_reqs=ssl.CERT_NONE, 
         ssl_version=ssl.PROTOCOL_SSLv3, ca_certs=None, 
         do_handshake_on_connect=True, 
         suppress_ragged_eofs=True, ciphers=None): 
    return wrap_socket_orig(sock, keyfile, certfile, server_side, 
          cert_reqs, ssl_version, ca_certs, 
          do_handshake_on_connect, 
          suppress_ragged_eofs, ciphers) 

ssl.wrap_socket = wrap_socket_patched 

Dies ändert die Standard-Protokollversion für alle Code, wrap_socket verwendet, wirkt sich daher auch andere Bibliotheken.

edit:

Methode 3: weil httplib eigentlich nur wrap_socket von ssl zugreift, können Sie auch einfach ersetzen httplib.ssl mit einer Klasse wrap_socket bietet.Mit functools.partial macht es sehr elegant, dies zu schreiben:

import httplib 
import ssl 
from functools import partial 

class fake_ssl: 
    wrap_socket = partial(ssl.wrap_socket, ssl_version=ssl.PROTOCOL_SSLv3) 

httplib.ssl = fake_ssl 
+1

Ich versuchte Methode 3 und jetzt seinen Wurf „SSL-Routinen: SSL3_GET_RECORD: falsche Versionsnummer“, aber wenn ich das Server-Protokoll überprüfen, indem Sie „openssl s_client -connect host: port | grep Protokoll "es gibt zurück" Protokoll: SSLv3 "! Ich werde versuchen, andere Methoden und lyk .. – Peter

+1

versucht alle 3 Methoden jetzt Fehler (für alle Methoden) "SSL-Routinen: SSL3_GET_RECORD: falsche Versionsnummer" – Peter

+0

Das Ergebnis sollte das gleiche sein, egal welche Methode der oben genannten Methoden Sie benutzen. Hast du verschiedene Protokollversoins ausprobiert? Ich bin nicht sicher, wie man den Fehler reproduziert, den Sie erhalten. Ich bekomme nur genau den gleichen Fehler bei der Verbindung zu einem SSLv3-Server mit einem TLSv1-Client ... – mata

Verwandte Themen