mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-27 02:24:18 +00:00
add reverseproxy mode, fix bugs
This commit is contained in:
parent
aac0ab23eb
commit
314e0f5839
@ -1,6 +1,7 @@
|
|||||||
from __future__ import (absolute_import, print_function, division)
|
from __future__ import (absolute_import, print_function, division)
|
||||||
from .layer import RootContext
|
from .layer import RootContext
|
||||||
from .socks import Socks5IncomingLayer
|
from .socks import Socks5IncomingLayer
|
||||||
|
from .reverse_proxy import ReverseProxy
|
||||||
from .rawtcp import TcpLayer
|
from .rawtcp import TcpLayer
|
||||||
from .auto import AutoLayer
|
from .auto import AutoLayer
|
||||||
__all__ = ["Socks5IncomingLayer", "TcpLayer", "AutoLayer", "RootContext"]
|
__all__ = ["Socks5IncomingLayer", "TcpLayer", "AutoLayer", "RootContext", "ReverseProxy"]
|
||||||
|
@ -176,7 +176,7 @@ def yield_from_callback(fun):
|
|||||||
"""
|
"""
|
||||||
yield_queue = Queue.Queue()
|
yield_queue = Queue.Queue()
|
||||||
|
|
||||||
def do_yield(self, msg):
|
def do_yield(msg):
|
||||||
yield_queue.put(msg)
|
yield_queue.put(msg)
|
||||||
yield_queue.get()
|
yield_queue.get()
|
||||||
|
|
||||||
@ -192,14 +192,14 @@ def yield_from_callback(fun):
|
|||||||
|
|
||||||
threading.Thread(target=run, name="YieldFromCallbackThread").start()
|
threading.Thread(target=run, name="YieldFromCallbackThread").start()
|
||||||
while True:
|
while True:
|
||||||
e = yield_queue.get()
|
msg = yield_queue.get()
|
||||||
if e is True:
|
if msg is True:
|
||||||
break
|
break
|
||||||
elif isinstance(e, Exception):
|
elif isinstance(msg, Exception):
|
||||||
# TODO: Include func name?
|
# TODO: Include func name?
|
||||||
raise ProxyError2("Error from callback: " + repr(e), e)
|
raise ProxyError2("Error in %s: %s" % (fun.__name__, repr(msg)), msg)
|
||||||
else:
|
else:
|
||||||
yield e
|
yield msg
|
||||||
yield_queue.put(None)
|
yield_queue.put(None)
|
||||||
|
|
||||||
self.yield_from_callback = None
|
self.yield_from_callback = None
|
||||||
|
19
libmproxy/protocol2/reverse_proxy.py
Normal file
19
libmproxy/protocol2/reverse_proxy.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from __future__ import (absolute_import, print_function, division)
|
||||||
|
|
||||||
|
from .layer import Layer, ServerConnectionMixin
|
||||||
|
from .ssl import SslLayer
|
||||||
|
|
||||||
|
|
||||||
|
class ReverseProxy(Layer, ServerConnectionMixin):
|
||||||
|
|
||||||
|
def __init__(self, ctx, server_address, client_ssl, server_ssl):
|
||||||
|
super(ReverseProxy, self).__init__(ctx)
|
||||||
|
self.server_address = server_address
|
||||||
|
self.client_ssl = client_ssl
|
||||||
|
self.server_ssl = server_ssl
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
layer = SslLayer(self, self.client_ssl, self.server_ssl)
|
||||||
|
for message in layer():
|
||||||
|
if not self._handle_server_message(message):
|
||||||
|
yield message
|
@ -14,7 +14,7 @@ class SslLayer(Layer):
|
|||||||
self._client_ssl = client_ssl
|
self._client_ssl = client_ssl
|
||||||
self._server_ssl = server_ssl
|
self._server_ssl = server_ssl
|
||||||
self._connected = False
|
self._connected = False
|
||||||
self._sni_from_handshake = None
|
self.client_sni = None
|
||||||
self._sni_from_server_change = None
|
self._sni_from_server_change = None
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
@ -74,7 +74,7 @@ class SslLayer(Layer):
|
|||||||
if self._sni_from_server_change is False:
|
if self._sni_from_server_change is False:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return self._sni_from_server_change or self._sni_from_handshake
|
return self._sni_from_server_change or self.client_sni
|
||||||
|
|
||||||
def _establish_ssl_with_client_and_server(self):
|
def _establish_ssl_with_client_and_server(self):
|
||||||
"""
|
"""
|
||||||
@ -97,7 +97,7 @@ class SslLayer(Layer):
|
|||||||
else:
|
else:
|
||||||
raise RuntimeError("Unexpected Message: %s" % message)
|
raise RuntimeError("Unexpected Message: %s" % message)
|
||||||
|
|
||||||
if server_err and not self._sni_from_handshake:
|
if server_err and not self.client_sni:
|
||||||
raise server_err
|
raise server_err
|
||||||
|
|
||||||
def handle_sni(self, connection):
|
def handle_sni(self, connection):
|
||||||
@ -111,14 +111,14 @@ class SslLayer(Layer):
|
|||||||
sn = connection.get_servername()
|
sn = connection.get_servername()
|
||||||
if not sn:
|
if not sn:
|
||||||
return
|
return
|
||||||
self._sni_from_handshake = sn.decode("utf8").encode("idna")
|
self.client_sni = sn.decode("utf8").encode("idna")
|
||||||
|
|
||||||
if old_upstream_sni != self.sni_for_upstream_connection:
|
if old_upstream_sni != self.sni_for_upstream_connection:
|
||||||
# Perform reconnect
|
# Perform reconnect
|
||||||
if self.server_ssl:
|
if self.server_ssl:
|
||||||
self.yield_from_callback(Reconnect())
|
self.yield_from_callback(Reconnect())
|
||||||
|
|
||||||
if self._sni_from_handshake:
|
if self.client_sni:
|
||||||
# Now, change client context to reflect possibly changed certificate:
|
# Now, change client context to reflect possibly changed certificate:
|
||||||
cert, key, chain_file = self.find_cert()
|
cert, key, chain_file = self.find_cert()
|
||||||
new_context = self.client_conn.create_ssl_context(
|
new_context = self.client_conn.create_ssl_context(
|
||||||
@ -195,8 +195,8 @@ class SslLayer(Layer):
|
|||||||
sans.add(host)
|
sans.add(host)
|
||||||
host = upstream_cert.cn.decode("utf8").encode("idna")
|
host = upstream_cert.cn.decode("utf8").encode("idna")
|
||||||
# Also add SNI values.
|
# Also add SNI values.
|
||||||
if self._sni_from_handshake:
|
if self.client_sni:
|
||||||
sans.add(self._sni_from_handshake)
|
sans.add(self.client_sni)
|
||||||
if self._sni_from_server_change:
|
if self._sni_from_server_change:
|
||||||
sans.add(self._sni_from_server_change)
|
sans.add(self._sni_from_server_change)
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ class ConnectionHandler2:
|
|||||||
self.config,
|
self.config,
|
||||||
self.channel
|
self.channel
|
||||||
)
|
)
|
||||||
root_layer = protocol2.Socks5IncomingLayer(root_context)
|
root_layer = protocol2.ReverseProxy(root_context, ("localhost", 5000), True, True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for message in root_layer():
|
for message in root_layer():
|
||||||
|
Loading…
Reference in New Issue
Block a user