mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-11-08 02:18:13 -10:00
110 lines
3.7 KiB
Python
110 lines
3.7 KiB
Python
#!/usr/bin/env python
|
|
|
|
"""
|
|
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
|
|
See the file 'LICENSE' for copying permission
|
|
|
|
Unit tests for lib/request/httpshandler.py, exercising the SSL protocol
|
|
candidate selection.
|
|
|
|
No network is involved: the module is reimported with chosen ssl.PROTOCOL_*
|
|
constants removed, mimicking OpenSSL builds that have those protocol versions
|
|
compiled out (e.g. OPENSSL_NO_TLS1), as the constants are conditional there.
|
|
"""
|
|
|
|
import os
|
|
import ssl
|
|
import sys
|
|
import unittest
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from _testutils import bootstrap
|
|
|
|
bootstrap()
|
|
|
|
from lib.core.data import conf
|
|
import lib.request.httpshandler as hmod
|
|
from thirdparty.six.moves import reload_module as _reload_module
|
|
|
|
class TestProtocolSelection(unittest.TestCase):
|
|
def tearDown(self):
|
|
hmod.socket.create_connection = self._createConnection
|
|
hmod.ssl.SSLContext = self._sslContext
|
|
hmod._contexts.clear()
|
|
|
|
for name, value in self._removed.items():
|
|
setattr(ssl, name, value)
|
|
_reload_module(hmod)
|
|
|
|
def _reload_without(self, *names):
|
|
"""Reloads the module with `names` missing from ssl (as on builds lacking those protocols)"""
|
|
|
|
self._removed = {}
|
|
self._createConnection = hmod.socket.create_connection
|
|
self._sslContext = hmod.ssl.SSLContext
|
|
|
|
for name in names:
|
|
if hasattr(ssl, name):
|
|
self._removed[name] = getattr(ssl, name)
|
|
delattr(ssl, name)
|
|
|
|
_reload_module(hmod)
|
|
|
|
return [hmod._lut.get(_, _) for _ in hmod._protocols if _ in hmod._tlsProtocols]
|
|
|
|
def test_only_tls_protocols_are_used_with_sni(self):
|
|
# Note: SSL era protocols stay in _protocols for the non-SNI fallback, but carry no server_hostname
|
|
selected = self._reload_without()
|
|
self.assertTrue(selected)
|
|
for name in ("PROTOCOL_SSLv3", "PROTOCOL_SSLv23", "PROTOCOL_SSLv2"):
|
|
if hasattr(ssl, name):
|
|
self.assertIn(getattr(ssl, name), hmod._protocols)
|
|
self.assertNotIn(getattr(ssl, name), hmod._tlsProtocols)
|
|
|
|
def test_missing_tlsv1_does_not_raise(self):
|
|
# Note: ssl.PROTOCOL_TLSv1 is compiled in only '#ifndef OPENSSL_NO_TLS1' (used to raise an AttributeError here)
|
|
selected = self._reload_without("PROTOCOL_TLSv1")
|
|
self.assertTrue(selected)
|
|
self.assertNotIn("PROTOCOL_TLSv1", selected)
|
|
|
|
def test_missing_all_legacy_tls_does_not_raise(self):
|
|
selected = self._reload_without("PROTOCOL_TLSv1", "PROTOCOL_TLSv1_1")
|
|
self.assertTrue(selected)
|
|
self.assertNotIn("PROTOCOL_TLSv1_1", selected)
|
|
|
|
def test_connect_without_tlsv1(self):
|
|
"""Drives the real connect() loop, which used to reference ssl.PROTOCOL_TLSv1 directly"""
|
|
|
|
selected = self._reload_without("PROTOCOL_TLSv1")
|
|
|
|
conf.host = None
|
|
conf.httpHeaders = []
|
|
|
|
class _Context(object):
|
|
def __init__(self, protocol):
|
|
self.protocol = protocol
|
|
|
|
def set_ciphers(self, _):
|
|
pass
|
|
|
|
def wrap_socket(self, sock, **kwargs):
|
|
return "wrapped:%s" % hmod._lut.get(self.protocol, self.protocol)
|
|
|
|
connection = hmod.HTTPSConnection("example.com", 443)
|
|
|
|
# Note: stubbed only after the instantiation, as that one resolves the default context through ssl itself
|
|
hmod.socket.create_connection = lambda *args, **kwargs: _Socket()
|
|
hmod.ssl.SSLContext = _Context
|
|
hmod._contexts.clear()
|
|
|
|
connection.connect()
|
|
|
|
self.assertEqual(connection.sock, "wrapped:%s" % selected[0])
|
|
|
|
class _Socket(object):
|
|
def close(self):
|
|
pass
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|