apply fixes from proxy-refactor-cb branch
This commit is contained in:
parent
531ca4a356
commit
c46e3f90bb
|
@ -1,4 +1,4 @@
|
|||
from __future__ import (absolute_import, print_function, division, unicode_literals)
|
||||
from __future__ import (absolute_import, print_function, division)
|
||||
from .layer import RootContext
|
||||
from .socks import Socks5IncomingLayer
|
||||
from .rawtcp import TcpLayer
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from __future__ import (absolute_import, print_function, division, unicode_literals)
|
||||
from __future__ import (absolute_import, print_function, division)
|
||||
from .layer import Layer
|
||||
|
||||
|
||||
|
@ -6,6 +6,8 @@ class AutoLayer(Layer):
|
|||
def __call__(self):
|
||||
d = self.client_conn.rfile.peek(1)
|
||||
|
||||
if not d:
|
||||
return
|
||||
# TLS ClientHello magic, see http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html#client-hello
|
||||
if d[0] == "\x16":
|
||||
layer = SslLayer(self, True, True)
|
||||
|
|
|
@ -31,7 +31,7 @@ Further goals:
|
|||
- Upstream connections should be established as late as possible;
|
||||
inline scripts shall have a chance to handle everything locally.
|
||||
"""
|
||||
from __future__ import (absolute_import, print_function, division, unicode_literals)
|
||||
from __future__ import (absolute_import, print_function, division)
|
||||
from netlib import tcp
|
||||
from ..proxy import ProxyError2, Log
|
||||
from ..proxy.connection import ServerConnection
|
||||
|
@ -49,12 +49,6 @@ class RootContext(object):
|
|||
self.channel = channel # provides .ask() method to communicate with FlowMaster
|
||||
self.config = config # Proxy Configuration
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""
|
||||
Accessing a nonexisting attribute does not throw an error but returns None instead.
|
||||
"""
|
||||
return None
|
||||
|
||||
|
||||
class _LayerCodeCompletion(object):
|
||||
"""
|
||||
|
@ -113,7 +107,7 @@ class ServerConnectionMixin(object):
|
|||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.server_address = None
|
||||
self._server_address = None
|
||||
self.server_conn = None
|
||||
|
||||
def _handle_server_message(self, message):
|
||||
|
@ -128,6 +122,16 @@ class ServerConnectionMixin(object):
|
|||
raise NotImplementedError
|
||||
return False
|
||||
|
||||
@property
|
||||
def server_address(self):
|
||||
return self._server_address
|
||||
|
||||
@server_address.setter
|
||||
def server_address(self, address):
|
||||
self._server_address = tcp.Address.wrap(address)
|
||||
self.log("Set new server address: " + repr(self.server_address), "debug")
|
||||
|
||||
|
||||
def _disconnect(self):
|
||||
"""
|
||||
Deletes (and closes) an existing server connection.
|
||||
|
@ -145,8 +149,3 @@ class ServerConnectionMixin(object):
|
|||
self.server_conn.connect()
|
||||
except tcp.NetLibError as e:
|
||||
raise ProxyError2("Server connection to '%s' failed: %s" % (self.server_address, e), e)
|
||||
|
||||
def _set_address(self, address):
|
||||
a = tcp.Address.wrap(address)
|
||||
self.log("Set new server address: " + repr(a), "debug")
|
||||
self.server_address = address
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
This module contains all valid messages layers can send to the underlying layers.
|
||||
"""
|
||||
from __future__ import (absolute_import, print_function, division, unicode_literals)
|
||||
from __future__ import (absolute_import, print_function, division)
|
||||
|
||||
|
||||
class _Message(object):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from __future__ import (absolute_import, print_function, division, unicode_literals)
|
||||
from __future__ import (absolute_import, print_function, division)
|
||||
from ..protocol.tcp import TCPHandler
|
||||
from .layer import Layer
|
||||
from .messages import Connect
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from __future__ import (absolute_import, print_function, division, unicode_literals)
|
||||
from __future__ import (absolute_import, print_function, division)
|
||||
|
||||
from ..proxy import ProxyError, Socks5ProxyMode, ProxyError2
|
||||
from .layer import Layer, ServerConnectionMixin
|
||||
|
@ -14,7 +14,7 @@ class Socks5IncomingLayer(Layer, ServerConnectionMixin):
|
|||
# TODO: Unmonkeypatch
|
||||
raise ProxyError2(str(e), e)
|
||||
|
||||
self._set_address(address)
|
||||
self.server_address = address
|
||||
|
||||
layer = AutoLayer(self)
|
||||
for message in layer():
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from __future__ import (absolute_import, print_function, division, unicode_literals)
|
||||
from __future__ import (absolute_import, print_function, division)
|
||||
import Queue
|
||||
import threading
|
||||
import traceback
|
||||
|
@ -76,7 +76,7 @@ class SslLayer(Layer):
|
|||
self._establish_ssl_with_server()
|
||||
|
||||
@property
|
||||
def sni(self):
|
||||
def sni_for_upstream_connection(self):
|
||||
if self._sni_from_server_change is False:
|
||||
return None
|
||||
else:
|
||||
|
@ -132,21 +132,22 @@ class SslLayer(Layer):
|
|||
The client has just sent the Sever Name Indication (SNI).
|
||||
"""
|
||||
try:
|
||||
old_upstream_sni = self.sni_for_upstream_connection
|
||||
|
||||
sn = connection.get_servername()
|
||||
if not sn:
|
||||
return
|
||||
sni = sn.decode("utf8").encode("idna")
|
||||
|
||||
if sni != self.sni:
|
||||
self._sni_from_handshake = sni
|
||||
self._sni_from_handshake = sn.decode("utf8").encode("idna")
|
||||
|
||||
if old_upstream_sni != self.sni_for_upstream_connection:
|
||||
# Perform reconnect
|
||||
if self.server_ssl:
|
||||
reconnect = ReconnectRequest()
|
||||
self.__client_ssl_queue.put()
|
||||
self.__client_ssl_queue.put(reconnect)
|
||||
reconnect.done.wait()
|
||||
|
||||
# Now, change client context to reflect changed certificate:
|
||||
if self._sni_from_handshake:
|
||||
# Now, change client context to reflect possibly changed certificate:
|
||||
cert, key, chain_file = self.find_cert()
|
||||
new_context = self.client_conn.create_ssl_context(
|
||||
cert, key,
|
||||
|
@ -183,7 +184,7 @@ class SslLayer(Layer):
|
|||
try:
|
||||
self.server_conn.establish_ssl(
|
||||
self.config.clientcerts,
|
||||
self.sni,
|
||||
self.sni_for_upstream_connection,
|
||||
method=self.config.openssl_method_server,
|
||||
options=self.config.openssl_options_server,
|
||||
verify_options=self.config.openssl_verification_mode_server,
|
||||
|
@ -206,23 +207,24 @@ class SslLayer(Layer):
|
|||
"error")
|
||||
self.log("Aborting connection attempt", "error")
|
||||
raise ProxyError2(repr(e), e)
|
||||
except Exception as e:
|
||||
except tcp.NetLibError as e:
|
||||
raise ProxyError2(repr(e), e)
|
||||
|
||||
def find_cert(self):
|
||||
host = self.server_conn.address.host
|
||||
sans = []
|
||||
# TODO: Better use an OrderedSet here
|
||||
sans = set()
|
||||
# Incorporate upstream certificate
|
||||
if self.server_conn.ssl_established and (not self.config.no_upstream_cert):
|
||||
upstream_cert = self.server_conn.cert
|
||||
sans.extend(upstream_cert.altnames)
|
||||
sans.update(upstream_cert.altnames)
|
||||
if upstream_cert.cn:
|
||||
sans.append(host)
|
||||
sans.add(host)
|
||||
host = upstream_cert.cn.decode("utf8").encode("idna")
|
||||
# Also add SNI values.
|
||||
if self._sni_from_handshake:
|
||||
sans.append(self._sni_from_handshake)
|
||||
sans.add(self._sni_from_handshake)
|
||||
if self._sni_from_server_change:
|
||||
sans.append(self._sni_from_server_change)
|
||||
sans.add(self._sni_from_server_change)
|
||||
|
||||
return self.config.certstore.get_cert(host, sans)
|
||||
return self.config.certstore.get_cert(host, list(sans))
|
Loading…
Reference in New Issue