Uwaga: Konstruktor HTTPSConnection pozwala przekazać ssl context
jako argument od pytona 2.7.9, które powinny być stosowane w takim przypadku.
Ta odpowiedź poprzedza tę zmianę, a zatem dotyczy tylko nieaktualnych wersji Pythona.
httplib.HTTPSConnection.connect
po prostu wywołuje ssl.wrap_socket
na otwarciu gniazda do initalize połączenia https, niestety nie można określić żadnych parametrów w python2.7 (python3 pozwala passing the SSLContext
).
Jeśli chcesz określić wersję protokołu, trzeba by małpa plaster jeden z tych dwóch:
Metoda 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
Zmienia wersję protokołu do wszystkie połączenia wykonane z HTTPSConnection
.
Metoda 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
To zmienia domyślną wersję protokołu dla cały kod, który wykorzystuje wrap_socket
wpływa zatem także innych bibliotek.
edit:
Metoda 3: ponieważ httplib rzeczywiście ma dostęp tylko wrap_socket
z ssl
, można też po prostu zastąpić httplib.ssl
z klasą zapewniając wrap_socket
.Korzystanie functools.partial
sprawia, że bardzo elegancki napisać to:
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
Próbowałem metody 3, a teraz jego rzucanie „Procedury SSL: SSL3_GET_RECORD: błędny numer wersji”, ale jeśli mogę sprawdzić protokół serwera, „OpenSSL s_client -connect host: port | grep Protokół "zwraca" Protokół: SSLv3 "! Spróbuję innych metod i lyk .. – Peter
wypróbowałem wszystkie 3 metody teraz otrzymuję błąd (dla wszystkich metod) "Procedury SSL: SSL3_GET_RECORD: zły numer wersji" – Peter
Wynik powinien być taki sam, bez względu na metodę powyższych metod posługiwać się. Czy wypróbowałeś inny versoins protokołu? Nie jestem pewien, jak odtworzyć błąd, który otrzymujesz. Dostaję dokładnie taki sam błąd podczas łączenia się z serwerem SSLv3 za pomocą klienta TLSv1 ... – mata