Python httplib SSL23_GET_SERVER_HELLO: неизвестный протокол

Примечание: этот код отлично работает в Ubuntu, но не на Mac, и вместо локального изменения настроек Mac/python я пытаюсь внести изменения в код, чтобы он работал везде.

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

но выдает ошибку:

[Errno 1] _ssl.c:503: ошибка: 140770FC: подпрограммы SSL: SSL23_GET_SERVER_HELLO: неизвестный протокол

теперь код использует не urllib.request, а httplib

Я хочу изменить код, чтобы он использовал SSLv3 в качестве протокола по умолчанию, примерно так:

ssl.SSLContext(ssl.PROTOCOL_SSLv3)

Я огляделся и нашел несколько ссылок, но ничего не работает!

эта ссылка для Ubuntu

ссылка на python urllib и cURL

исправление ошибки Python, но опять же для urllib


person Peter    schedule 07.09.2013    source источник


Ответы (1)


Примечание. Конструктор HTTPSConnection позволяет передать ssl context в качестве аргумента, начиная с python 2.7.9, который следует использовать в этом случае.

Этот ответ предшествует этому изменению и поэтому применим только к устаревшим версиям Python.


httplib.HTTPSConnection.connect просто вызывает ssl.wrap_socket в открытом сокете для инициализации соединения https, к сожалению, вы не можете указать какие-либо параметры в python2.7 (python3 позволяет передавать SSLContext).

Если вы хотите указать версию протокола, вам нужно пропатчить одну из этих двух:

Метод 1: исправление 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

Это изменяет версию протокола для всех соединений, выполненных с помощью HTTPSConnection.

Метод 2: исправление 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

Это изменяет версию протокола по умолчанию для всего кода, который использует wrap_socket, поэтому также влияет на другие библиотеки.

редактировать:

Способ 3: поскольку httplib на самом деле обращается только к wrap_socket из ssl, вы также можете просто заменить httplib.ssl классом, предоставляющим wrap_socket. Использование functools.partial позволяет очень элегантно написать это:

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
person mata    schedule 07.09.2013
comment
Я попробовал метод 3, и теперь он выдает подпрограммы SSL: SSL3_GET_RECORD: неверный номер версии, но если я проверю протокол сервера с помощью openssl s_client -connect host:port | grep Протокол, который он возвращает Протокол: SSLv3! Попробую другие способы и лык.. - person Peter; 08.09.2013
comment
попробовал все 3 метода, теперь получаю ошибку (для всех методов) Процедуры SSL: SSL3_GET_RECORD: неправильный номер версии - person Peter; 12.09.2013
comment
Результат должен быть одинаковым, независимо от того, какой метод из вышеперечисленных методов вы используете. Вы пробовали разные версии протокола? Я не уверен, как воспроизвести ошибку, которую вы получаете. Я получаю точно такую ​​же ошибку только при подключении к серверу SSLv3 с использованием клиента TLSv1... - person mata; 12.09.2013
comment
Да, я пробовал все протоколы с SSLv3 и TLSv1, он говорит неправильный номер версии, с SSLv23 он говорит, что неизвестный протокол, а SSLv2 просто тайм-ауты. Я считаю, что это проблема с моей env, но ваш код решает первоначальную проблему. - person Peter; 12.09.2013