Forcing Mechanize use SSLv3

How would you force mechanize to use SSLv3 for HTTPS URLs that require this? If I try to use the mechanization with all URLs for SSLv3 only, I get an error message:

URLError: <urlopen error [Errno 1] _ssl.c:504: error:140773E8:SSL routines:SSL23_GET_SERVER_HELLO:reason(1000)> 
+3
source share
3 answers

A dirty answer ... not requiring correction.

 import ssl from ssl import PROTOCOL_SSLv23, PROTOCOL_SSLv3, CERT_NONE, SSLSocket def monkey_wrap_socket(sock, keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version=PROTOCOL_SSLv23, ca_certs=None, do_handshake_on_connect=True, suppress_ragged_eofs=True, ciphers=None): ssl_version=PROTOCOL_SSLv3 return SSLSocket(sock, keyfile=keyfile, certfile=certfile, server_side=server_side, cert_reqs=cert_reqs, ssl_version=ssl_version, ca_certs=ca_certs, do_handshake_on_connect=do_handshake_on_connect, suppress_ragged_eofs=suppress_ragged_eofs, ciphers=ciphers) ssl.wrap_socket = monkey_wrap_socket 

... in front of your code.

+2
source

The last comment on the Python EiyrioΓΌ von Kauyf problem mentioned above is the solution that I implemented in my forked version of mechanization . The following is the difference in mechanization /_opener.py. It fixes mechanize.urlopen (), but does not mechanize the .Browser () open () method:

 diff --git a/mechanize/_opener.py b/mechanize/_opener.py index ad8412d..e6d1ebc 100644 --- a/mechanize/_opener.py +++ b/mechanize/_opener.py @@ -25,9 +25,27 @@ import _rfc3986 import _sockettimeout import _urllib2_fork from _util import isstringlike +import ssl, socket open_file = open +class HTTPSConnectionV3(httplib.HTTPSConnection): + def __init__(self, *args, **kwargs): + httplib.HTTPSConnection.__init__(self, *args, **kwargs) + + def connect(self): + sock = socket.create_connection((self.host, self.port), self.timeout) + if self._tunnel_host: + self.sock = sock + self._tunnel() + try: + self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv3) + except ssl.SSLError, e: + self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, ssl_version=ssl.PROTOCOL_SSLv23) + +class HTTPSHandlerV3(urllib2.HTTPSHandler): + def https_open(self, req): + return self.do_open(HTTPSConnectionV3, req) class ContentTooShortError(urllib2.URLError): def __init__(self, reason, result): @@ -370,7 +388,7 @@ class OpenerFactory: _urllib2_fork.HTTPErrorProcessor, ] if hasattr(httplib, 'HTTPS'): - default_classes.append(_urllib2_fork.HTTPSHandler) + default_classes.append(HTTPSHandlerV3) handlers = [] replacement_handlers = [] 
+1
source

You can use monkey-patch ssl.wrap_socket () to use TLSv1, which after the Poodle vulnerability seems to be the only viable. This will force all SSL connections to use TLSv1, regardless of the higher level library.

 import ssl from functools import wraps def sslwrap(func): @wraps(func) def bar(*args, **kw): kw['ssl_version'] = ssl.PROTOCOL_TLSv1 return func(*args, **kw) return bar ssl.wrap_socket = sslwrap(ssl.wrap_socket) 
0
source

Source: https://habr.com/ru/post/983117/


All Articles