mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2025-02-01 15:55:28 +00:00
fix bugs, make https work
This commit is contained in:
parent
0dd243c5e4
commit
2a15479cdb
@ -4,7 +4,7 @@ from .. import version
|
|||||||
from ..exceptions import InvalidCredentials, HttpException, ProtocolException
|
from ..exceptions import InvalidCredentials, HttpException, ProtocolException
|
||||||
from .layer import Layer, ServerConnectionMixin
|
from .layer import Layer, ServerConnectionMixin
|
||||||
from libmproxy import utils
|
from libmproxy import utils
|
||||||
from .messages import ChangeServer, Connect, Reconnect, Kill
|
from .messages import SetServer, Connect, Reconnect, Kill
|
||||||
from libmproxy.protocol import KILL
|
from libmproxy.protocol import KILL
|
||||||
|
|
||||||
from libmproxy.protocol.http import HTTPFlow
|
from libmproxy.protocol.http import HTTPFlow
|
||||||
@ -71,19 +71,9 @@ class HttpLayer(Layer):
|
|||||||
HTTP 1 Layer
|
HTTP 1 Layer
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, ctx):
|
def __init__(self, ctx, mode):
|
||||||
super(HttpLayer, self).__init__(ctx)
|
super(HttpLayer, self).__init__(ctx)
|
||||||
|
self.mode = mode
|
||||||
# FIXME: Imports
|
|
||||||
from .http_proxy import HttpProxy, HttpUpstreamProxy
|
|
||||||
|
|
||||||
if any(isinstance(l, HttpProxy) for l in self.layers):
|
|
||||||
self.mode = "regular"
|
|
||||||
elif any(isinstance(l, HttpUpstreamProxy) for l in self.layers):
|
|
||||||
self.mode = "upstream"
|
|
||||||
else:
|
|
||||||
# also includes socks or reverse mode, which are handled similarly on this layer.
|
|
||||||
self.mode = "transparent"
|
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
while True:
|
while True:
|
||||||
@ -104,7 +94,7 @@ class HttpLayer(Layer):
|
|||||||
|
|
||||||
# Regular Proxy Mode: Handle CONNECT
|
# Regular Proxy Mode: Handle CONNECT
|
||||||
if self.mode == "regular" and request.form_in == "authority":
|
if self.mode == "regular" and request.form_in == "authority":
|
||||||
self.server_address = (request.host, request.port)
|
yield SetServer((request.host, request.port), False, None)
|
||||||
self.send_to_client(make_connect_response(request.httpversion))
|
self.send_to_client(make_connect_response(request.httpversion))
|
||||||
layer = self.ctx.next_layer(self)
|
layer = self.ctx.next_layer(self)
|
||||||
for message in layer():
|
for message in layer():
|
||||||
@ -255,7 +245,7 @@ class HttpLayer(Layer):
|
|||||||
else:
|
else:
|
||||||
flow.request.host = self.ctx.server_address.host
|
flow.request.host = self.ctx.server_address.host
|
||||||
flow.request.port = self.ctx.server_address.port
|
flow.request.port = self.ctx.server_address.port
|
||||||
flow.request.scheme = self.server_conn.tls_established
|
flow.request.scheme = "https" if self.server_conn.tls_established else "http"
|
||||||
|
|
||||||
# TODO: Expose ChangeServer functionality to inline scripts somehow? (yield_from_callback?)
|
# TODO: Expose ChangeServer functionality to inline scripts somehow? (yield_from_callback?)
|
||||||
request_reply = self.channel.ask("request", flow)
|
request_reply = self.channel.ask("request", flow)
|
||||||
@ -271,8 +261,8 @@ class HttpLayer(Layer):
|
|||||||
tls = (flow.request.scheme == "https")
|
tls = (flow.request.scheme == "https")
|
||||||
if self.mode == "regular" or self.mode == "transparent":
|
if self.mode == "regular" or self.mode == "transparent":
|
||||||
# If there's an existing connection that doesn't match our expectations, kill it.
|
# If there's an existing connection that doesn't match our expectations, kill it.
|
||||||
if self.server_address != address or tls != self.server_address.ssl_established:
|
if self.server_address != address or tls != self.server_conn.ssl_established:
|
||||||
yield ChangeServer(address, tls, address.host)
|
yield SetServer(address, tls, address.host)
|
||||||
# Establish connection is neccessary.
|
# Establish connection is neccessary.
|
||||||
if not self.server_conn:
|
if not self.server_conn:
|
||||||
yield Connect()
|
yield Connect()
|
||||||
|
@ -6,7 +6,7 @@ from .http import HttpLayer
|
|||||||
|
|
||||||
class HttpProxy(Layer, ServerConnectionMixin):
|
class HttpProxy(Layer, ServerConnectionMixin):
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
layer = HttpLayer(self)
|
layer = HttpLayer(self, "regular")
|
||||||
for message in layer():
|
for message in layer():
|
||||||
if not self._handle_server_message(message):
|
if not self._handle_server_message(message):
|
||||||
yield message
|
yield message
|
||||||
@ -18,7 +18,7 @@ class HttpUpstreamProxy(Layer, ServerConnectionMixin):
|
|||||||
self.server_address = server_address
|
self.server_address = server_address
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
layer = HttpLayer(self)
|
layer = HttpLayer(self, "upstream")
|
||||||
for message in layer():
|
for message in layer():
|
||||||
if not self._handle_server_message(message):
|
if not self._handle_server_message(message):
|
||||||
yield message
|
yield message
|
||||||
|
@ -35,7 +35,7 @@ import threading
|
|||||||
from netlib import tcp
|
from netlib import tcp
|
||||||
from ..proxy import Log
|
from ..proxy import Log
|
||||||
from ..proxy.connection import ServerConnection
|
from ..proxy.connection import ServerConnection
|
||||||
from .messages import Connect, Reconnect, ChangeServer, Kill
|
from .messages import Connect, Reconnect, SetServer, Kill
|
||||||
from ..exceptions import ProtocolException
|
from ..exceptions import ProtocolException
|
||||||
|
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ class ServerConnectionMixin(object):
|
|||||||
elif message == Connect:
|
elif message == Connect:
|
||||||
self._connect()
|
self._connect()
|
||||||
return True
|
return True
|
||||||
elif message == ChangeServer and message.depth == 1:
|
elif message == SetServer and message.depth == 1:
|
||||||
if self.server_conn:
|
if self.server_conn:
|
||||||
self._disconnect()
|
self._disconnect()
|
||||||
self.server_address = message.address
|
self.server_address = message.address
|
||||||
|
@ -27,7 +27,7 @@ class Reconnect(_Message):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class ChangeServer(_Message):
|
class SetServer(_Message):
|
||||||
"""
|
"""
|
||||||
Change the upstream server.
|
Change the upstream server.
|
||||||
"""
|
"""
|
||||||
|
@ -2,7 +2,7 @@ from __future__ import (absolute_import, print_function, division)
|
|||||||
|
|
||||||
from .rawtcp import RawTcpLayer
|
from .rawtcp import RawTcpLayer
|
||||||
from .tls import TlsLayer
|
from .tls import TlsLayer
|
||||||
|
from .http import HttpLayer
|
||||||
|
|
||||||
class RootContext(object):
|
class RootContext(object):
|
||||||
"""
|
"""
|
||||||
@ -38,10 +38,12 @@ class RootContext(object):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if is_tls_client_hello:
|
if is_tls_client_hello:
|
||||||
layer = TlsLayer(top_layer, True, True)
|
return TlsLayer(top_layer, True, True)
|
||||||
|
elif isinstance(top_layer, TlsLayer) and isinstance(top_layer.ctx, HttpLayer):
|
||||||
|
return HttpLayer(top_layer, "transparent")
|
||||||
else:
|
else:
|
||||||
layer = RawTcpLayer(top_layer)
|
return RawTcpLayer(top_layer)
|
||||||
return layer
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def layers(self):
|
def layers(self):
|
||||||
|
@ -5,7 +5,7 @@ from netlib import tcp
|
|||||||
|
|
||||||
from ..exceptions import ProtocolException
|
from ..exceptions import ProtocolException
|
||||||
from .layer import Layer, yield_from_callback
|
from .layer import Layer, yield_from_callback
|
||||||
from .messages import Connect, Reconnect, ChangeServer
|
from .messages import Connect, Reconnect, SetServer
|
||||||
|
|
||||||
|
|
||||||
class TlsLayer(Layer):
|
class TlsLayer(Layer):
|
||||||
@ -13,7 +13,6 @@ class TlsLayer(Layer):
|
|||||||
super(TlsLayer, self).__init__(ctx)
|
super(TlsLayer, self).__init__(ctx)
|
||||||
self._client_tls = client_tls
|
self._client_tls = client_tls
|
||||||
self._server_tls = server_tls
|
self._server_tls = server_tls
|
||||||
self._connected = False
|
|
||||||
self.client_sni = None
|
self.client_sni = None
|
||||||
self._sni_from_server_change = None
|
self._sni_from_server_change = None
|
||||||
|
|
||||||
@ -44,9 +43,6 @@ class TlsLayer(Layer):
|
|||||||
client_tls_requires_server_cert = (
|
client_tls_requires_server_cert = (
|
||||||
self._client_tls and self._server_tls and not self.config.no_upstream_cert
|
self._client_tls and self._server_tls and not self.config.no_upstream_cert
|
||||||
)
|
)
|
||||||
lazy_server_tls = (
|
|
||||||
self._server_tls and not client_tls_requires_server_cert
|
|
||||||
)
|
|
||||||
|
|
||||||
if client_tls_requires_server_cert:
|
if client_tls_requires_server_cert:
|
||||||
for m in self._establish_tls_with_client_and_server():
|
for m in self._establish_tls_with_client_and_server():
|
||||||
@ -56,18 +52,27 @@ class TlsLayer(Layer):
|
|||||||
yield m
|
yield m
|
||||||
|
|
||||||
layer = self.ctx.next_layer(self)
|
layer = self.ctx.next_layer(self)
|
||||||
|
|
||||||
for message in layer():
|
for message in layer():
|
||||||
if message != Connect or not self._connected:
|
self.log("TlsLayer: %s" % message,"debug")
|
||||||
|
if not (message == Connect and self._connected):
|
||||||
yield message
|
yield message
|
||||||
if message == Connect:
|
|
||||||
if lazy_server_tls:
|
if message == Connect or message == Reconnect:
|
||||||
self._establish_tls_with_server()
|
if self._server_tls and not self._server_tls_established:
|
||||||
if message == ChangeServer and message.depth == 1:
|
|
||||||
self._server_tls = message.server_tls
|
|
||||||
self._sni_from_server_change = message.sni
|
|
||||||
if message == Reconnect or message == ChangeServer:
|
|
||||||
if self._server_tls:
|
|
||||||
self._establish_tls_with_server()
|
self._establish_tls_with_server()
|
||||||
|
if message == SetServer and message.depth == 1:
|
||||||
|
if message.server_tls is not None:
|
||||||
|
self._sni_from_server_change = message.sni
|
||||||
|
self._server_tls = message.server_tls
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _server_tls_established(self):
|
||||||
|
return self.server_conn and self.server_conn.tls_established
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _connected(self):
|
||||||
|
return bool(self.server_conn)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sni_for_upstream_connection(self):
|
def sni_for_upstream_connection(self):
|
||||||
@ -83,7 +88,6 @@ class TlsLayer(Layer):
|
|||||||
|
|
||||||
# First, try to connect to the server.
|
# First, try to connect to the server.
|
||||||
yield Connect()
|
yield Connect()
|
||||||
self._connected = True
|
|
||||||
server_err = None
|
server_err = None
|
||||||
try:
|
try:
|
||||||
self._establish_tls_with_server()
|
self._establish_tls_with_server()
|
||||||
|
Loading…
Reference in New Issue
Block a user