Skip to content

Commit

Permalink
TLS intercept self-signed servers using --insecure-tls-interception (
Browse files Browse the repository at this point in the history
…#1446)

* Disable mandatory TLS verification with --insecure

* Fix lint issues

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix type issues with `cert_der_to_dict`

* Flake8 exception

* Fix `cert_der_to_dict` where file may not be writter before it is gets used by `_test_decode_cert`

* Silence lint issue due to pylint bug

* Rename flag to `--insecure-tls-interception`

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Reuse `DEFAULT_SSL_CONTEXT_OPTIONS`

* # noqa: WPS436

---------

Co-authored-by: d4x <d_4xfe@proton.me>
Co-authored-by: d4xfe <168460626+d4xfe@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Aug 10, 2024
1 parent 39854e1 commit 50046d3
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 47 deletions.
75 changes: 42 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
- [Plugin Ordering](#plugin-ordering)
- [End-to-End Encryption](#end-to-end-encryption)
- [TLS Interception](#tls-interception)
- [Insecure TLS Interception](#insecure-tls-interception)
- [TLS Interception With Docker](#tls-interception-with-docker)
- [GROUT (NGROK Alternative)](#grout-ngrok-alternative)
- [Grout Usage](#grout-usage)
Expand Down Expand Up @@ -1241,6 +1242,13 @@ cached file instead of plain text.
Now use CA flags with other
[plugin examples](#plugin-examples) to see them work with `https` traffic.

## Insecure TLS Interception

To intercept TLS traffic from a server using a self-signed certificate
add the `--insecure-tls-interception` flag to disable mandatory TLS certificate validation.

NOTE: This flag disables certificate check for all servers.

## TLS Interception With Docker

Important notes about TLS Interception with Docker container:
Expand Down Expand Up @@ -2510,17 +2518,16 @@ To run standalone benchmark for `proxy.py`, use the following command from repo

```console
proxy -h
usage: -m [-h] [--enable-proxy-protocol] [--threadless] [--threaded]
[--num-workers NUM_WORKERS] [--enable-events] [--enable-conn-pool]
[--key-file KEY_FILE] [--cert-file CERT_FILE]
[--client-recvbuf-size CLIENT_RECVBUF_SIZE]
[--server-recvbuf-size SERVER_RECVBUF_SIZE]
[--max-sendbuf-size MAX_SENDBUF_SIZE] [--timeout TIMEOUT]
[--tunnel-hostname TUNNEL_HOSTNAME] [--tunnel-port TUNNEL_PORT]
usage: -m [-h] [--tunnel-hostname TUNNEL_HOSTNAME] [--tunnel-port TUNNEL_PORT]
[--tunnel-username TUNNEL_USERNAME]
[--tunnel-ssh-key TUNNEL_SSH_KEY]
[--tunnel-ssh-key-passphrase TUNNEL_SSH_KEY_PASSPHRASE]
[--tunnel-remote-port TUNNEL_REMOTE_PORT]
[--tunnel-remote-port TUNNEL_REMOTE_PORT] [--threadless]
[--threaded] [--num-workers NUM_WORKERS] [--enable-events]
[--enable-proxy-protocol] [--enable-conn-pool] [--key-file KEY_FILE]
[--cert-file CERT_FILE] [--client-recvbuf-size CLIENT_RECVBUF_SIZE]
[--server-recvbuf-size SERVER_RECVBUF_SIZE]
[--max-sendbuf-size MAX_SENDBUF_SIZE] [--timeout TIMEOUT]
[--local-executor LOCAL_EXECUTOR] [--backlog BACKLOG]
[--hostname HOSTNAME] [--hostnames HOSTNAMES [HOSTNAMES ...]]
[--port PORT] [--ports PORTS [PORTS ...]] [--port-file PORT_FILE]
Expand All @@ -2533,9 +2540,9 @@ usage: -m [-h] [--enable-proxy-protocol] [--threadless] [--threaded]
[--work-klass WORK_KLASS] [--pid-file PID_FILE] [--openssl OPENSSL]
[--data-dir DATA_DIR] [--ssh-listener-klass SSH_LISTENER_KLASS]
[--disable-http-proxy] [--disable-headers DISABLE_HEADERS]
[--ca-key-file CA_KEY_FILE] [--ca-cert-dir CA_CERT_DIR]
[--ca-cert-file CA_CERT_FILE] [--ca-file CA_FILE]
[--ca-signing-key-file CA_SIGNING_KEY_FILE]
[--ca-key-file CA_KEY_FILE] [--insecure-tls-interception]
[--ca-cert-dir CA_CERT_DIR] [--ca-cert-file CA_CERT_FILE]
[--ca-file CA_FILE] [--ca-signing-key-file CA_SIGNING_KEY_FILE]
[--auth-plugin AUTH_PLUGIN] [--cache-requests]
[--cache-by-content-type] [--cache-dir CACHE_DIR]
[--proxy-pool PROXY_POOL] [--enable-web-server]
Expand All @@ -2549,13 +2556,25 @@ usage: -m [-h] [--enable-proxy-protocol] [--threadless] [--threaded]
[--filtered-client-ips FILTERED_CLIENT_IPS]
[--filtered-url-regex-config FILTERED_URL_REGEX_CONFIG]

proxy.py v2.4.4rc6.dev191+gef5a8922
proxy.py v2.4.5

options:
-h, --help show this help message and exit
--enable-proxy-protocol
Default: False. If used, will enable proxy protocol.
Only version 1 is currently supported.
--tunnel-hostname TUNNEL_HOSTNAME
Default: None. Remote hostname or IP address to which
SSH tunnel will be established.
--tunnel-port TUNNEL_PORT
Default: 22. SSH port of the remote host.
--tunnel-username TUNNEL_USERNAME
Default: None. Username to use for establishing SSH
tunnel.
--tunnel-ssh-key TUNNEL_SSH_KEY
Default: None. Private key path in pem format
--tunnel-ssh-key-passphrase TUNNEL_SSH_KEY_PASSPHRASE
Default: None. Private key passphrase
--tunnel-remote-port TUNNEL_REMOTE_PORT
Default: 8899. Remote port which will be forwarded
locally for proxy.
--threadless Default: True. Enabled by default on Python 3.8+ (mac,
linux). When disabled a new thread is spawned to
handle each client connection.
Expand All @@ -2567,6 +2586,9 @@ options:
--enable-events Default: False. Enables core to dispatch lifecycle
events. Plugins can be used to subscribe for core
events.
--enable-proxy-protocol
Default: False. If used, will enable proxy protocol.
Only version 1 is currently supported.
--enable-conn-pool Default: False. (WIP) Enable upstream connection
pooling.
--key-file KEY_FILE Default: None. Server key file to enable end-to-end
Expand All @@ -2588,21 +2610,6 @@ options:
--timeout TIMEOUT Default: 10.0. Number of seconds after which an
inactive connection must be dropped. Inactivity is
defined by no data sent or received by the client.
--tunnel-hostname TUNNEL_HOSTNAME
Default: None. Remote hostname or IP address to which
SSH tunnel will be established.
--tunnel-port TUNNEL_PORT
Default: 22. SSH port of the remote host.
--tunnel-username TUNNEL_USERNAME
Default: None. Username to use for establishing SSH
tunnel.
--tunnel-ssh-key TUNNEL_SSH_KEY
Default: None. Private key path in pem format
--tunnel-ssh-key-passphrase TUNNEL_SSH_KEY_PASSPHRASE
Default: None. Private key passphrase
--tunnel-remote-port TUNNEL_REMOTE_PORT
Default: 8899. Remote port which will be forwarded
locally for proxy.
--local-executor LOCAL_EXECUTOR
Default: 1. Enabled by default. Use 0 to disable. When
enabled acceptors will make use of local (same
Expand Down Expand Up @@ -2668,6 +2675,8 @@ options:
Default: None. CA key to use for signing dynamically
generated HTTPS certificates. If used, must also pass
--ca-cert-file and --ca-signing-key-file
--insecure-tls-interception
Default: False. Disables certificate verification
--ca-cert-dir CA_CERT_DIR
Default: ~/.proxy/certificates. Directory to store
dynamically generated certificates. Also see --ca-key-
Expand All @@ -2676,9 +2685,9 @@ options:
Default: None. Signing certificate to use for signing
dynamically generated HTTPS certificates. If used,
must also pass --ca-key-file and --ca-signing-key-file
--ca-file CA_FILE Default: /Users/abhinavsingh/Dev/proxy.py/.venv31013/l
ib/python3.10/site-packages/certifi/cacert.pem.
Provide path to custom CA bundle for peer certificate
--ca-file CA_FILE Default: /Users/abhinavsingh/Dev/proxy.py/.venv3118/li
b/python3.11/site-packages/certifi/cacert.pem. Provide
path to custom CA bundle for peer certificate
verification
--ca-signing-key-file CA_SIGNING_KEY_FILE
Default: None. CA signing key to use for dynamic
Expand Down
1 change: 1 addition & 0 deletions proxy/common/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def _env_threadless_compliant() -> bool:
DEFAULT_MAX_SEND_SIZE = 64 * 1024
DEFAULT_BUFFER_SIZE = 128 * 1024
DEFAULT_CA_CERT_DIR = None
DEFAULT_INSECURE_TLS_INTERCEPTION = False
DEFAULT_CA_CERT_FILE = None
DEFAULT_CA_KEY_FILE = None
DEFAULT_CA_SIGNING_KEY_FILE = None
Expand Down
21 changes: 21 additions & 0 deletions proxy/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@
utils
"""
import os
import ssl
import sys
import socket
import logging
import argparse
import tempfile
import functools
import ipaddress
import contextlib
from types import TracebackType
from typing import Any, Dict, List, Type, Tuple, Callable, Optional

import _ssl # noqa: WPS436

from .types import HostPort
from .constants import (
CRLF, COLON, HTTP_1_1, IS_WINDOWS, WHITESPACE, DEFAULT_TIMEOUT,
Expand All @@ -36,6 +40,23 @@
logger = logging.getLogger(__name__)


def cert_der_to_dict(der: Optional[bytes]) -> Dict[str, Any]:
"""Parse a DER formatted certificate to a python dict"""
if not der:
return {}
with tempfile.NamedTemporaryFile(delete=False) as cert_file:
pem = ssl.DER_cert_to_PEM_cert(der)
cert_file.write(pem.encode())
cert_file.flush()
cert_file.seek(0)
try:
certificate = _ssl._test_decode_cert(cert_file.name)
finally:
cert_file.close()
os.remove(cert_file.name)
return certificate or {}


def tls_interception_enabled(flags: argparse.Namespace) -> bool:
return flags.ca_key_file is not None and \
flags.ca_cert_dir is not None and \
Expand Down
11 changes: 6 additions & 5 deletions proxy/core/connection/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from .connection import TcpConnection, TcpConnectionUninitializedException
from ...common.types import HostPort, TcpOrTlsSocket
from ...common.utils import new_socket_connection
from ...common.constants import DEFAULT_SSL_CONTEXT_OPTIONS


class TcpServerConnection(TcpConnection):
Expand Down Expand Up @@ -51,12 +52,12 @@ def wrap(
# Ref https://github.com/PyCQA/pylint/issues/3691
verify_mode: ssl.VerifyMode = ssl.VerifyMode.CERT_REQUIRED, # pylint: disable=E1101
) -> None:
ctx = ssl.create_default_context(
ssl.Purpose.SERVER_AUTH,
cafile=ca_file,
ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=ca_file)
ctx.options |= DEFAULT_SSL_CONTEXT_OPTIONS
# pylint: disable=E1101
ctx.check_hostname = (
False if verify_mode == ssl.VerifyMode.CERT_NONE else hostname is not None
)
ctx.options |= ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
ctx.check_hostname = hostname is not None
ctx.verify_mode = verify_mode
self.connection.setblocking(True)
self._conn = ctx.wrap_socket(
Expand Down
23 changes: 19 additions & 4 deletions proxy/http/proxy/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import logging
import threading
import subprocess
from typing import Any, Dict, List, Union, Optional, cast
from typing import Any, Dict, List, Union, Optional

from .plugin import HttpProxyBasePlugin
from ..parser import HttpParser, httpParserTypes, httpParserStates
Expand All @@ -35,15 +35,16 @@
from ...core.event import eventNames
from ...common.flag import flags
from ...common.types import Readables, Writables, Descriptors
from ...common.utils import text_
from ...common.utils import text_, cert_der_to_dict
from ...core.connection import (
TcpServerConnection, TcpConnectionUninitializedException,
)
from ...common.constants import (
COMMA, DEFAULT_CA_FILE, PLUGIN_PROXY_AUTH, DEFAULT_CA_CERT_DIR,
DEFAULT_CA_KEY_FILE, DEFAULT_CA_CERT_FILE, DEFAULT_DISABLE_HEADERS,
PROXY_AGENT_HEADER_VALUE, DEFAULT_DISABLE_HTTP_PROXY,
DEFAULT_CA_SIGNING_KEY_FILE, DEFAULT_HTTP_PROXY_ACCESS_LOG_FORMAT,
DEFAULT_CA_SIGNING_KEY_FILE, DEFAULT_INSECURE_TLS_INTERCEPTION,
DEFAULT_HTTP_PROXY_ACCESS_LOG_FORMAT,
DEFAULT_HTTPS_PROXY_ACCESS_LOG_FORMAT,
)

Expand Down Expand Up @@ -74,6 +75,13 @@
'HTTPS certificates. If used, must also pass --ca-cert-file and --ca-signing-key-file',
)

flags.add_argument(
'--insecure-tls-interception',
action='store_true',
default=DEFAULT_INSECURE_TLS_INTERCEPTION,
help='Default: False. Disables certificate verification',
)

flags.add_argument(
'--ca-cert-dir',
type=str,
Expand Down Expand Up @@ -760,10 +768,17 @@ def wrap_server(self) -> bool:
assert isinstance(self.upstream.connection, socket.socket)
do_close = False
try:
# pylint: disable=E1101
verify_mode = (
ssl.VerifyMode.CERT_NONE
if self.flags.insecure_tls_interception
else ssl.VerifyMode.CERT_REQUIRED
)
self.upstream.wrap(
text_(self.request.host),
self.flags.ca_file,
as_non_blocking=True,
verify_mode=verify_mode,
)
except ssl.SSLCertVerificationError: # Server raised certificate verification error
# When --disable-interception-on-ssl-cert-verification-error flag is on,
Expand Down Expand Up @@ -802,7 +817,7 @@ def wrap_client(self) -> bool:
try:
# TODO: Perform async certificate generation
generated_cert = self.generate_upstream_certificate(
cast(Dict[str, Any], self.upstream.connection.getpeercert()),
cert_der_to_dict(self.upstream.connection.getpeercert(True)),
)
self.client.wrap(self.flags.ca_signing_key_file, generated_cert)
except subprocess.TimeoutExpired as e: # Popen communicate timeout
Expand Down
45 changes: 45 additions & 0 deletions tests/certificates/test_cert_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
"""
proxy.py
~~~~~~~~
⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on
Network monitoring, controls & Application development, testing, debugging.
:copyright: (c) 2013-present by Abhinav Singh and contributors.
:license: BSD, see LICENSE for more details.
"""
from typing import Any


# pylint: disable=line-too-long
test_cert_bytes = b"0\x82\x03\xa30\x82\x02\x8b\xa0\x03\x02\x01\x02\x02\x14PE\x01\x8c\xa6\xea\xd8#\xcf\x90\xb0D\xc7\x04\xde\x9b9Y\xf3 0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x000a1\x0b0\t\x06\x03U\x04\x06\x13\x02as1\x0b0\t\x06\x03U\x04\x08\x0c\x02as1\x0b0\t\x06\x03U\x04\x07\x0c\x02as1\x0b0\t\x06\x03U\x04\n\x0c\x02as1\x0b0\t\x06\x03U\x04\x0b\x0c\x02as1\x0b0\t\x06\x03U\x04\x03\x0c\x02as1\x110\x0f\x06\t*\x86H\x86\xf7\r\x01\t\x01\x16\x02as0\x1e\x17\r240429125057Z\x17\r250429125057Z0a1\x0b0\t\x06\x03U\x04\x06\x13\x02as1\x0b0\t\x06\x03U\x04\x08\x0c\x02as1\x0b0\t\x06\x03U\x04\x07\x0c\x02as1\x0b0\t\x06\x03U\x04\n\x0c\x02as1\x0b0\t\x06\x03U\x04\x0b\x0c\x02as1\x0b0\t\x06\x03U\x04\x03\x0c\x02as1\x110\x0f\x06\t*\x86H\x86\xf7\r\x01\t\x01\x16\x02as0\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xee\xcbU\xe3\xc4]\x83\xb9\x9d\xb1(v0\x18\x18\xc3\x00\x96\xc0\x0f\xc29\x84\xe7/W\xc7\x0b\xec\xdf\x9d-\xec\xd9\x876\xe5m\xda\x96\xea\xb0\xc6\x00\x7f\xb6\x93;\xd6\x1bK`\xd4Hc<\xa0g\xe5Q[\xe3\xe1\xd1DD5\x9b\x12\xdf\xd0\xd0\xc6X\xc9\x98\xc9\xb1\x81\xf5\xa2\x12\xaa\xc1\xb0\x80\xe8)R\xa7\xed\xe3P6\x82\x05\xbcA4\x91\xbcs?\xc2\xf2\xfd-\xe65'};\xa7E\xb2yN\x0fiO7\x82-`CX\xdb\xe0\x9c\xd7\x8e\x00N\nAu\xac/\xb3o\xcaG;\xa4\x8d\xca\x92\xe3F\x96\xe5\xbd\x1dq\xf6\xa5\x9f\xc5@I=\xfc\x1cl\x81\xb3y\x93FaPa^\x08\x0f\x80t\xb8J\xfd\xb8]\xd52\xf5\x9bE\xe8J:\x08\x8c\x98m0\xba\x85\x1b\xb6\x97\xe5\xba4\xe3nU\xa5\xc7\xeb\xde_z\x1a(j\xa7\xeb\x8a\xb4\xe1'?\x91\x80MhG=y\xc7\xf1|\xcaJ@\xae\xc4'\xd6\xd6}L\xf4\x91NV`\x98\x80\xef%\xa2hq\x05s\x02\x03\x01\x00\x01\xa3S0Q0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xc6\xa4,\xe5\xe3\x15j\x18\x15@Xw!\xdd\xbf\xc6\xe5\xf0vG0\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14\xc6\xa4,\xe5\xe3\x15j\x18\x15@Xw!\xdd\xbf\xc6\xe5\xf0vG0\x0f\x06\x03U\x1d\x13\x01\x01\xff\x04\x050\x03\x01\x01\xff0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\xacx\xeb\x02\x8a\xd3\x966\xb73\xfb\n\x1eb\ng\xda\x84\x18\x97P\xb4\x7f\x8a\xbd\x82\xf3\x1b\xe8k%\xcc\x0f\xbd\x7fB\xb9\x1df|-k\x01\xf3\x89\x08r\xb9\x93\xf5?Z\x16\xff\x0f\x97\x91b#\xef$I\x11\x9e\x16\xb2J\x97\xd1\x0e\xd6\xabD\xca@\xe7\xb3\xbe\x84S\x1e\xdb;\x9b\xc4\xf4\x18\xf4\x9a\x1b\xcej\xe0qmx\xe4N?K\n.p\xa8\xa6\xfa\xb0\xf7y\xe8\x0f\xbd\x0c216\xb0\xa1d\x1f\x7f3\xa1l?\xbe\x9a\x06\xed]\x1a\x00\xab\xb4e\x13:\x17\x1b\x88\x8e\xcaqp\"\x8f\xa6\xf7\x06J?`\xe0\xf7\xce\xf8K\x08\x15\x18\xa1\xc4\xb5\xd9hB\xb0\xc6\\\xae?\xa9\x83FL\x8cm\xd1\xad^\xf0\xa5:\x8e\x97\x07\xd2\xd0l\x0e\x9d\x01\xa00c)\xae\xd0@\xefr\xe7,\xb7[\xd3H\xfe1\xfb\xa9|\xd0\xac\xc6i\x98\xe5\xd5\xd1\xf2\x97<\xf9\xe1?=\x93\xfaM\x86\xa2\x9dy\xdeZj\x93&\xa6\x84d\x07a\xbf\xd6\xdde\xaa)\t\xd6\x0e\x99\x85K" # noqa: WPS342, E501


def mock_cert(_: Any) -> Any:
return test_cert_bytes


cert_dict = {
'subject': (
(('countryName', 'as'),),
(('stateOrProvinceName', 'as'),),
(('localityName', 'as'),),
(('organizationName', 'as'),),
(('organizationalUnitName', 'as'),),
(('commonName', 'as'),),
(('emailAddress', 'as'),),
),
'issuer': (
(('countryName', 'as'),),
(('stateOrProvinceName', 'as'),),
(('localityName', 'as'),),
(('organizationName', 'as'),),
(('organizationalUnitName', 'as'),),
(('commonName', 'as'),),
(('emailAddress', 'as'),),
),
'version': 3,
'serialNumber': '5045018CA6EAD823CF90B044C704DE9B3959F320',
'notBefore': 'Apr 29 12:50:57 2024 GMT',
'notAfter': 'Apr 29 12:50:57 2025 GMT',
}
6 changes: 4 additions & 2 deletions tests/http/proxy/test_http_proxy_tls_interception.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from proxy.core.connection import TcpServerConnection
from proxy.common.constants import DEFAULT_CA_FILE
from ...test_assertions import Assertions
from ...certificates.test_cert_data import mock_cert


class TestHttpProxyTlsInterception(Assertions):
Expand Down Expand Up @@ -59,6 +60,7 @@ async def test_e2e(self, mocker: MockerFixture) -> None:
# Used for server side wrapping
self.mock_ssl_context = mocker.patch('ssl.create_default_context')
upstream_tls_sock = mock.MagicMock(spec=ssl.SSLSocket)
upstream_tls_sock.getpeercert = mock_cert
self.mock_ssl_context.return_value.wrap_socket.return_value = upstream_tls_sock

# Used for client wrapping
Expand All @@ -75,8 +77,8 @@ def mock_connection() -> Any:

# Do not mock the original wrap method
self.mock_server_conn.return_value.wrap.side_effect = \
lambda x, y, as_non_blocking: TcpServerConnection.wrap(
self.mock_server_conn.return_value, x, y, as_non_blocking=as_non_blocking,
lambda x, y, as_non_blocking, verify_mode: TcpServerConnection.wrap(
self.mock_server_conn.return_value, x, y, as_non_blocking=as_non_blocking, verify_mode=verify_mode,
)

type(self.mock_server_conn.return_value).connection = \
Expand Down
7 changes: 4 additions & 3 deletions tests/plugin/test_http_proxy_plugins_with_tls_interception.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from proxy.core.connection import TcpServerConnection
from .utils import get_plugin_by_test_name
from ..test_assertions import Assertions
from ..certificates.test_cert_data import mock_cert


class TestHttpProxyPluginExamplesWithTlsInterception(Assertions):
Expand Down Expand Up @@ -78,8 +79,8 @@ def _setUp(self, request: Any, mocker: MockerFixture) -> None:
self.protocol_handler.initialize()

self.server = self.mock_server_conn.return_value

self.server_ssl_connection = mocker.MagicMock(spec=ssl.SSLSocket)
self.server_ssl_connection.getpeercert = mock_cert
self.mock_ssl_context.return_value.wrap_socket.return_value = self.server_ssl_connection
self.client_ssl_connection = mocker.MagicMock(spec=ssl.SSLSocket)
self.mock_ssl_wrap.return_value.wrap_socket.return_value = self.client_ssl_connection
Expand All @@ -97,8 +98,8 @@ def mock_connection() -> Any:

# Do not mock the original wrap method
self.server.wrap.side_effect = \
lambda x, y, as_non_blocking: TcpServerConnection.wrap(
self.server, x, y, as_non_blocking=as_non_blocking,
lambda x, y, as_non_blocking, verify_mode: TcpServerConnection.wrap(
self.server, x, y, as_non_blocking=as_non_blocking, verify_mode=verify_mode,
)

self.server.has_buffer.side_effect = has_buffer
Expand Down

0 comments on commit 50046d3

Please sign in to comment.