diff options
author | Maximilian Hils <git@maximilianhils.com> | 2016-11-21 02:16:20 +0100 |
---|---|---|
committer | Maximilian Hils <git@maximilianhils.com> | 2016-11-21 02:28:10 +0100 |
commit | 9af8f4bb31c94a25780a4189bffa406906249626 (patch) | |
tree | cf52f1c312b7bac3d83d796d6b03bb33b4556f26 /examples/tls_passthrough.py | |
parent | f74e561524d04c93cd7953f34e78ebe67eaa58a8 (diff) | |
download | mitmproxy-9af8f4bb31c94a25780a4189bffa406906249626.tar.gz mitmproxy-9af8f4bb31c94a25780a4189bffa406906249626.tar.bz2 mitmproxy-9af8f4bb31c94a25780a4189bffa406906249626.zip |
organize examples
This commit is largely based on work by Thiago Arrais (@thiagoarrais)
and Shane Bradfield (@l33tLumberjack). I wasn't really able to get their
PR reasonably merged onto the latest master, so I reapplied their changes
manually here and did some further improvements on that.
Diffstat (limited to 'examples/tls_passthrough.py')
-rw-r--r-- | examples/tls_passthrough.py | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/examples/tls_passthrough.py b/examples/tls_passthrough.py deleted file mode 100644 index 40c1051d..00000000 --- a/examples/tls_passthrough.py +++ /dev/null @@ -1,140 +0,0 @@ -""" -This inline script allows conditional TLS Interception based -on a user-defined strategy. - -Example: - - > mitmdump -s tls_passthrough.py - - 1. curl --proxy http://localhost:8080 https://example.com --insecure - // works - we'll also see the contents in mitmproxy - - 2. curl --proxy http://localhost:8080 https://example.com --insecure - // still works - we'll also see the contents in mitmproxy - - 3. curl --proxy http://localhost:8080 https://example.com - // fails with a certificate error, which we will also see in mitmproxy - - 4. curl --proxy http://localhost:8080 https://example.com - // works again, but mitmproxy does not intercept and we do *not* see the contents - -Authors: Maximilian Hils, Matthew Tuusberg -""" -import collections -import random - -import sys -from enum import Enum - -import mitmproxy -from mitmproxy.exceptions import TlsProtocolException -from mitmproxy.proxy.protocol import TlsLayer, RawTCPLayer - - -class InterceptionResult(Enum): - success = True - failure = False - skipped = None - - -class _TlsStrategy: - """ - Abstract base class for interception strategies. - """ - - def __init__(self): - # A server_address -> interception results mapping - self.history = collections.defaultdict(lambda: collections.deque(maxlen=200)) - - def should_intercept(self, server_address): - """ - Returns: - True, if we should attempt to intercept the connection. - False, if we want to employ pass-through instead. - """ - raise NotImplementedError() - - def record_success(self, server_address): - self.history[server_address].append(InterceptionResult.success) - - def record_failure(self, server_address): - self.history[server_address].append(InterceptionResult.failure) - - def record_skipped(self, server_address): - self.history[server_address].append(InterceptionResult.skipped) - - -class ConservativeStrategy(_TlsStrategy): - """ - Conservative Interception Strategy - only intercept if there haven't been any failed attempts - in the history. - """ - - def should_intercept(self, server_address): - if InterceptionResult.failure in self.history[server_address]: - return False - return True - - -class ProbabilisticStrategy(_TlsStrategy): - """ - Fixed probability that we intercept a given connection. - """ - - def __init__(self, p): - self.p = p - super(ProbabilisticStrategy, self).__init__() - - def should_intercept(self, server_address): - return random.uniform(0, 1) < self.p - - -class TlsFeedback(TlsLayer): - """ - Monkey-patch _establish_tls_with_client to get feedback if TLS could be established - successfully on the client connection (which may fail due to cert pinning). - """ - - def _establish_tls_with_client(self): - server_address = self.server_conn.address - - try: - super(TlsFeedback, self)._establish_tls_with_client() - except TlsProtocolException as e: - tls_strategy.record_failure(server_address) - raise e - else: - tls_strategy.record_success(server_address) - - -# inline script hooks below. - -tls_strategy = None - - -def start(): - global tls_strategy - if len(sys.argv) == 2: - tls_strategy = ProbabilisticStrategy(float(sys.argv[1])) - else: - tls_strategy = ConservativeStrategy() - - -def next_layer(next_layer): - """ - This hook does the actual magic - if the next layer is planned to be a TLS layer, - we check if we want to enter pass-through mode instead. - """ - if isinstance(next_layer, TlsLayer) and next_layer._client_tls: - server_address = next_layer.server_conn.address - - if tls_strategy.should_intercept(server_address): - # We try to intercept. - # Monkey-Patch the layer to get feedback from the TLSLayer if interception worked. - next_layer.__class__ = TlsFeedback - else: - # We don't intercept - reply with a pass-through layer and add a "skipped" entry. - mitmproxy.ctx.log("TLS passthrough for %s" % repr(next_layer.server_conn.address), "info") - next_layer_replacement = RawTCPLayer(next_layer.ctx, ignore=True) - next_layer.reply.send(next_layer_replacement) - tls_strategy.record_skipped(server_address) |