This commit is contained in:
Maximilian Hils 2016-03-20 23:39:57 +01:00
parent 403ac82a7d
commit 2d6eb28fd0
4 changed files with 30 additions and 22 deletions

View File

@ -423,7 +423,7 @@ class HTTPFlow(Flow):
def make_error_response(status_code, message, headers=None): def make_error_response(status_code, message, headers=None):
response = status_codes.RESPONSES.get(status_code, "Unknown") response = status_codes.RESPONSES.get(status_code, "Unknown").encode()
body = """ body = """
<html> <html>
<head> <head>
@ -432,6 +432,7 @@ def make_error_response(status_code, message, headers=None):
<body>%s</body> <body>%s</body>
</html> </html>
""".strip() % (status_code, response, message) """.strip() % (status_code, response, message)
body = body.encode("utf8", "replace")
if not headers: if not headers:
headers = Headers( headers = Headers(
@ -453,8 +454,8 @@ def make_error_response(status_code, message, headers=None):
def make_connect_request(address): def make_connect_request(address):
address = Address.wrap(address) address = Address.wrap(address)
return HTTPRequest( return HTTPRequest(
"authority", "CONNECT", None, address.host, address.port, None, b"HTTP/1.1", "authority", b"CONNECT", None, address.host, address.port, None, b"HTTP/1.1",
Headers(), "" Headers(), b""
) )
@ -464,9 +465,9 @@ def make_connect_response(http_version):
return HTTPResponse( return HTTPResponse(
http_version, http_version,
200, 200,
"Connection established", b"Connection established",
Headers(), Headers(),
"", b"",
) )
expect_continue_response = HTTPResponse(b"HTTP/1.1", 100, "Continue", Headers(), b"") expect_continue_response = HTTPResponse(b"HTTP/1.1", 100, b"Continue", Headers(), b"")

View File

@ -257,7 +257,7 @@ class HttpLayer(Layer):
def handle_regular_mode_connect(self, request): def handle_regular_mode_connect(self, request):
self.set_server((request.host, request.port)) self.set_server((request.host, request.port))
self.send_response(make_connect_response(request.http_version)) self.send_response(make_connect_response(request.data.http_version))
layer = self.ctx.next_layer(self) layer = self.ctx.next_layer(self)
layer() layer()

View File

@ -214,12 +214,20 @@ def is_tls_record_magic(d):
# TLS ClientHello magic, works for SSLv3, TLSv1.0, TLSv1.1, TLSv1.2 # TLS ClientHello magic, works for SSLv3, TLSv1.0, TLSv1.1, TLSv1.2
# http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html#client-hello # http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html#client-hello
if six.PY2:
return ( return (
len(d) == 3 and len(d) == 3 and
d[0] == '\x16' and d[0] == '\x16' and
d[1] == '\x03' and d[1] == '\x03' and
d[2] in ('\x00', '\x01', '\x02', '\x03') d[2] in ('\x00', '\x01', '\x02', '\x03')
) )
else:
return (
len(d) == 3 and
d[0] == 0x16 and
d[1] == 0x03 and
0x0 <= d[2] <= 0x03
)
def get_client_hello(client_conn): def get_client_hello(client_conn):
@ -232,7 +240,7 @@ def get_client_hello(client_conn):
Returns: Returns:
The raw handshake packet bytes, without TLS record header(s). The raw handshake packet bytes, without TLS record header(s).
""" """
client_hello = "" client_hello = b""
client_hello_size = 1 client_hello_size = 1
offset = 0 offset = 0
while len(client_hello) < client_hello_size: while len(client_hello) < client_hello_size:
@ -245,7 +253,7 @@ def get_client_hello(client_conn):
raise TlsProtocolException("Unexpected EOF in TLS handshake: %s" % record_body) raise TlsProtocolException("Unexpected EOF in TLS handshake: %s" % record_body)
client_hello += record_body client_hello += record_body
offset += record_size offset += record_size
client_hello_size = struct.unpack("!I", '\x00' + client_hello[1:4])[0] + 4 client_hello_size = struct.unpack("!I", b'\x00' + client_hello[1:4])[0] + 4
return client_hello return client_hello
@ -471,13 +479,13 @@ class TlsLayer(Layer):
# We only support http/1.1 and h2. # We only support http/1.1 and h2.
# If the server only supports spdy (next to http/1.1), it may select that # If the server only supports spdy (next to http/1.1), it may select that
# and mitmproxy would enter TCP passthrough mode, which we want to avoid. # and mitmproxy would enter TCP passthrough mode, which we want to avoid.
deprecated_http2_variant = lambda x: x.startswith("h2-") or x.startswith("spdy") deprecated_http2_variant = lambda x: x.startswith(b"h2-") or x.startswith(b"spdy")
if self.client_alpn_protocols: if self.client_alpn_protocols:
alpn = [x for x in self.client_alpn_protocols if not deprecated_http2_variant(x)] alpn = [x for x in self.client_alpn_protocols if not deprecated_http2_variant(x)]
else: else:
alpn = None alpn = None
if alpn and "h2" in alpn and not self.config.http2: if alpn and b"h2" in alpn and not self.config.http2:
alpn.remove("h2") alpn.remove(b"h2")
ciphers_server = self.config.ciphers_server ciphers_server = self.config.ciphers_server
if not ciphers_server: if not ciphers_server:
@ -546,7 +554,7 @@ class TlsLayer(Layer):
# However, we may just want to establish TLS so that we can send an error message to the client, # However, we may just want to establish TLS so that we can send an error message to the client,
# in which case the address can be None. # in which case the address can be None.
if self.server_conn.address: if self.server_conn.address:
host = self.server_conn.address.host host = self.server_conn.address.host.encode("idna")
# Should we incorporate information from the server certificate? # Should we incorporate information from the server certificate?
use_upstream_cert = ( use_upstream_cert = (

View File

@ -1,5 +1,4 @@
from __future__ import (absolute_import, print_function, division) from __future__ import (absolute_import, print_function, division)
import string
import sys import sys
import six import six
@ -102,8 +101,8 @@ class RootContext(object):
# 6. Check for raw tcp mode # 6. Check for raw tcp mode
is_ascii = ( is_ascii = (
len(d) == 3 and len(d) == 3 and
# better be safe here and don't expect uppercase... # expect A-Za-z
all(x in string.ascii_letters for x in d) all(65 <= x <= 90 and 97 <= x <= 122 for x in six.iterbytes(d))
) )
if self.config.rawtcp and not is_ascii: if self.config.rawtcp and not is_ascii:
return RawTCPLayer(top_layer) return RawTCPLayer(top_layer)