Skip to content

TLS Intercept conditionally #1476

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-library.yml
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ jobs:
- build-docs
- doctest-docs
- linkcheck-docs
- spellcheck-docs
# - spellcheck-docs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abhinavsingh

This is the upstream issue: sphinx-contrib/spelling#227.
I didn't mean disabling the entire check, just flipping the PyPI lookup setting: ansible/awx-plugins@842fb8d.

fail-fast: false

env:
Expand Down
37 changes: 18 additions & 19 deletions proxy/http/proxy/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,7 @@
# only for non-https requests and when
# tls interception is enabled
if raw is not None:
if (
not self.request.is_https_tunnel
or self.tls_interception_enabled
):
if not self.request.is_https_tunnel or self._tls_intercept_enabled:
if self.response.is_complete:
self.handle_pipeline_response(raw)
else:
Expand Down Expand Up @@ -429,8 +426,7 @@
# We also handle pipeline scenario for https proxy
# requests is TLS interception is enabled.
if self.request.is_complete and (
not self.request.is_https_tunnel or
self.tls_interception_enabled
not self.request.is_https_tunnel or self._tls_intercept_enabled
):
if self.pipeline_request is not None and \
self.pipeline_request.is_connection_upgrade:
Expand Down Expand Up @@ -474,6 +470,20 @@
else:
self.upstream.queue(raw)

@property
def _tls_intercept_enabled(self) -> bool:
do_intercept = self.tls_interception_enabled
if not do_intercept:
return do_intercept
# If enabled by flags, check if a plugin wants us to bypass
# interception for this particular request
for plugin in self.plugins.values():
do_intercept = plugin.do_intercept(self.request)
# A plugin requested to not intercept the request
if do_intercept is False:
break

Check warning on line 484 in proxy/http/proxy/server.py

View check run for this annotation

Codecov / codecov/patch

proxy/http/proxy/server.py#L484

Added line #L484 was not covered by tests
return do_intercept

def on_request_complete(self) -> Union[socket.socket, bool]:
self.emit_request_complete()

Expand Down Expand Up @@ -510,19 +520,8 @@
if self.upstream:
if self.request.is_https_tunnel:
self.client.queue(PROXY_TUNNEL_ESTABLISHED_RESPONSE_PKT)
if self.tls_interception_enabled:
# Check if any plugin wants to
# disable interception even
# with flags available
do_intercept = True
for plugin in self.plugins.values():
do_intercept = plugin.do_intercept(self.request)
# A plugin requested to not intercept
# the request
if do_intercept is False:
break
if do_intercept:
return self.intercept()
if self._tls_intercept_enabled:
return self.intercept()
# If an upstream server connection was established for http request,
# queue the request for upstream server.
else:
Expand Down
2 changes: 2 additions & 0 deletions proxy/plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from .modify_chunk_response import ModifyChunkResponsePlugin
from .modify_request_header import ModifyRequestHeaderPlugin
from .redirect_to_custom_server import RedirectToCustomServerPlugin
from .tls_intercept_conditionally import TlsInterceptConditionallyPlugin


__all__ = [
Expand All @@ -55,4 +56,5 @@
'CloudflareDnsResolverPlugin',
'ProgramNamePlugin',
'ModifyRequestHeaderPlugin',
'TlsInterceptConditionallyPlugin',
]
21 changes: 21 additions & 0 deletions proxy/plugin/tls_intercept_conditionally.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- 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 ..http.proxy import HttpProxyBasePlugin
from ..http.parser import HttpParser


class TlsInterceptConditionallyPlugin(HttpProxyBasePlugin):
"""TLS intercept conditionally."""

def do_intercept(self, request: HttpParser) -> bool:
if request.host == b'httpbin.org':
return False
return super().do_intercept(request)

Check warning on line 21 in proxy/plugin/tls_intercept_conditionally.py

View check run for this annotation

Codecov / codecov/patch

proxy/plugin/tls_intercept_conditionally.py#L20-L21

Added lines #L20 - L21 were not covered by tests
2 changes: 1 addition & 1 deletion tests/http/proxy/test_http_proxy_tls_interception.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ async def asyncReturn(val: T) -> T:
self.proxy_plugin.return_value.handle_client_request.call_count,
2,
)
self.proxy_plugin.return_value.do_intercept.assert_called_once()
self.assertEqual(self.proxy_plugin.return_value.do_intercept.call_count, 2)

callback_request = \
self.proxy_plugin.return_value.handle_client_request.call_args_list[1][0][0]
Expand Down
Loading