From d47eb7556a3e7afdc9343982a636bb7eaf9c749a Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Wed, 9 Jun 2021 23:59:44 +0200 Subject: [PATCH 1/2] fix #4630 --- mitmproxy/addons/tlsconfig.py | 2 +- test/helper_tools/loggrep.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mitmproxy/addons/tlsconfig.py b/mitmproxy/addons/tlsconfig.py index a05d63598..f46b7252a 100644 --- a/mitmproxy/addons/tlsconfig.py +++ b/mitmproxy/addons/tlsconfig.py @@ -172,7 +172,7 @@ class TlsConfig: server.alpn_offers = tuple(client.alpn_offers) else: server.alpn_offers = tuple(x for x in client.alpn_offers if x != b"h2") - elif client.tls_established: + elif client.tls: # We would perfectly support HTTP/1 -> HTTP/2, but we want to keep things on the same protocol version. # There are some edge cases where we want to mirror the regular server's behavior accurately, # for example header capitalization. diff --git a/test/helper_tools/loggrep.py b/test/helper_tools/loggrep.py index 005ca21b2..a986e47c4 100755 --- a/test/helper_tools/loggrep.py +++ b/test/helper_tools/loggrep.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import fileinput import sys +import re if __name__ == "__main__": if len(sys.argv) < 3: @@ -10,7 +11,7 @@ if __name__ == "__main__": port = sys.argv[1] matches = False for line in fileinput.input(sys.argv[2:]): - if line.startswith("["): + if re.match(r"^\[|(\d+\.){3}", line): matches = port in line if matches: print(line, end="") From 83a46b13b9876e4c8caf0697328c6c6c9a00b4e8 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Thu, 10 Jun 2021 00:18:37 +0200 Subject: [PATCH 2/2] further simplify ALPN selection --- mitmproxy/addons/tlsconfig.py | 17 +++++++++-------- test/mitmproxy/addons/test_tlsconfig.py | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/mitmproxy/addons/tlsconfig.py b/mitmproxy/addons/tlsconfig.py index f46b7252a..18d4fc73e 100644 --- a/mitmproxy/addons/tlsconfig.py +++ b/mitmproxy/addons/tlsconfig.py @@ -169,18 +169,19 @@ class TlsConfig: if not server.alpn_offers: if client.alpn_offers: if ctx.options.http2: + # We would perfectly support HTTP/1 -> HTTP/2, but we want to keep things on the same protocol + # version. There are some edge cases where we want to mirror the regular server's behavior + # accurately, for example header capitalization. server.alpn_offers = tuple(client.alpn_offers) else: server.alpn_offers = tuple(x for x in client.alpn_offers if x != b"h2") - elif client.tls: - # We would perfectly support HTTP/1 -> HTTP/2, but we want to keep things on the same protocol version. - # There are some edge cases where we want to mirror the regular server's behavior accurately, - # for example header capitalization. - server.alpn_offers = [] - elif ctx.options.http2: - server.alpn_offers = tls.HTTP_ALPNS else: - server.alpn_offers = tls.HTTP1_ALPNS + # We either have no client TLS or a client without ALPN. + # - If the client does use TLS but did not send an ALPN extension, we want to mirror that upstream. + # - If the client does not use TLS, there's no clear-cut answer. As a pragmatic approach, we also do + # not send any ALPN extension in this case, which defaults to whatever protocol we are speaking + # or falls back to HTTP. + server.alpn_offers = [] if not server.cipher_list and ctx.options.ciphers_server: server.cipher_list = ctx.options.ciphers_server.split(":") diff --git a/test/mitmproxy/addons/test_tlsconfig.py b/test/mitmproxy/addons/test_tlsconfig.py index 885b9410f..92237b67f 100644 --- a/test/mitmproxy/addons/test_tlsconfig.py +++ b/test/mitmproxy/addons/test_tlsconfig.py @@ -190,8 +190,8 @@ class TestTlsConfig: assert_alpn(True, tls.HTTP_ALPNS + (b"foo",), tls.HTTP_ALPNS + (b"foo",)) assert_alpn(False, tls.HTTP_ALPNS + (b"foo",), tls.HTTP1_ALPNS + (b"foo",)) - assert_alpn(True, [], tls.HTTP_ALPNS) - assert_alpn(False, [], tls.HTTP1_ALPNS) + assert_alpn(True, [], []) + assert_alpn(False, [], []) ctx.client.timestamp_tls_setup = time.time() # make sure that we don't upgrade h1 to h2, # see comment in tlsconfig.py