Python httplib SSL23_GET_SERVER_HELLO: protocolo desconocido

Nota: este código funciona bien en Ubuntu pero no en mac y, en lugar de cambiar la configuración de mac / python localmente, estoy intentando modificar el código para que funcione en todas partes.

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

pero arroja error:

[Errno 1] _ssl.c: 503: error: 140770FC: Rutinas SSL: SSL23_GET_SERVER_HELLO: protocolo desconocido

ahora el código no usa urllib.request en lugar de usar httplib

Quiero cambiar el código para que tome SSLv3 como protocolo predeterminado, algo como esto:

 ssl.SSLContext(ssl.PROTOCOL_SSLv3) 

Miré a mi alrededor y encontré algunos enlaces, ¡pero nada está funcionando!

este enlace es para ubuntu

enlace para python urllib y cURL

corrección de errores de Python, pero de nuevo para urllib

Nota: El constructor HTTPSConnection permite pasar un context ssl como argumento desde Python 2.7.9, que debe usarse en este caso.

Esta respuesta es anterior a ese cambio y, por lo tanto, solo se aplica a versiones desactualizadas de python.


httplib.HTTPSConnection.connect simplemente llama a ssl.wrap_socket en el socket abierto para iniciar una conexión https, desafortunadamente no puede especificar ningún parámetro en python2.7 (python3 permite pasar el SSLContext ).

Si desea especificar la versión del protocolo, deberá aplicar un parche a uno de estos dos:

Método 1 : parche 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 

Esto cambia la versión del protocolo para todas las conexiones realizadas con HTTPSConnection .

Método 2 : parche 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 

Esto cambia la versión predeterminada del protocolo para todo el código que usa wrap_socket , por lo tanto, también afecta a otras bibliotecas.

editar:

Método 3 : dado que httplib realmente accede solo a wrap_socket desde ssl , también podría reemplazar httplib.ssl con una clase que proporcione wrap_socket . El uso de functools.partial hace que sea muy elegante escribir esto:

 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