diff options
| -rw-r--r-- | libmproxy/protocol2/http_proxy.py | 1 | ||||
| -rw-r--r-- | libmproxy/protocol2/layer.py | 2 | ||||
| -rw-r--r-- | libmproxy/protocol2/tls.py | 33 | ||||
| -rw-r--r-- | libmproxy/proxy/connection.py | 9 | 
4 files changed, 29 insertions, 16 deletions
diff --git a/libmproxy/protocol2/http_proxy.py b/libmproxy/protocol2/http_proxy.py index ca70b012..9488e367 100644 --- a/libmproxy/protocol2/http_proxy.py +++ b/libmproxy/protocol2/http_proxy.py @@ -1,7 +1,6 @@  from __future__ import (absolute_import, print_function, division)  from .layer import Layer, ServerConnectionMixin -from .http import HttpLayer  class HttpProxy(Layer, ServerConnectionMixin): diff --git a/libmproxy/protocol2/layer.py b/libmproxy/protocol2/layer.py index ca297c0e..c1648a62 100644 --- a/libmproxy/protocol2/layer.py +++ b/libmproxy/protocol2/layer.py @@ -207,4 +207,4 @@ def yield_from_callback(fun):          self.yield_from_callback = None -    return wrapper
\ No newline at end of file +    return wrapper diff --git a/libmproxy/protocol2/tls.py b/libmproxy/protocol2/tls.py index 9ef72a78..fcc12f18 100644 --- a/libmproxy/protocol2/tls.py +++ b/libmproxy/protocol2/tls.py @@ -17,6 +17,9 @@ class TlsLayer(Layer):          self._server_tls = server_tls          self.client_sni = None          self._sni_from_server_change = None +        self.client_alpn_protos = None + +        # foo alpn protos = [netlib.http.http1.HTTP1Protocol.ALPN_PROTO_HTTP1, netlib.http.http2.HTTP2Protocol.ALPN_PROTO_H2],  # TODO: read this from client_conn first      def __call__(self):          """ @@ -133,7 +136,8 @@ class TlsLayer(Layer):                      options=self.config.openssl_options_client,                      cipher_list=self.config.ciphers_client,                      dhparams=self.config.certstore.dhparams, -                    chain_file=chain_file +                    chain_file=chain_file, +                    alpn_select_callback=self.__handle_alpn_select,                  )                  connection.set_context(new_context)          # An unhandled exception in this method will core dump PyOpenSSL, so @@ -141,10 +145,30 @@ class TlsLayer(Layer):          except:  # pragma: no cover              self.log("Error in handle_sni:\r\n" + traceback.format_exc(), "error") +    def __handle_alpn_select(self, conn_, options): +        # TODO: change to something meaningful? +        alpn_preference = netlib.http.http1.HTTP1Protocol.ALPN_PROTO_HTTP1 +        alpn_preference = netlib.http.http2.HTTP2Protocol.ALPN_PROTO_H2 +        ### + +        if self.client_alpn_protos != options: +            # Perform reconnect +            if self._server_tls: +                self.yield_from_callback(Reconnect()) + +        self.client_alpn_protos = options +        print("foo: %s" % options) + +        if alpn_preference in options: +            return bytes(alpn_preference) +        else:  # pragma no cover +            return options[0] +      @yield_from_callback      def _establish_tls_with_client(self):          self.log("Establish TLS with client", "debug")          cert, key, chain_file = self._find_cert() +          try:              self.client_conn.convert_to_ssl(                  cert, key, @@ -154,9 +178,10 @@ class TlsLayer(Layer):                  cipher_list=self.config.ciphers_client,                  dhparams=self.config.certstore.dhparams,                  chain_file=chain_file, -                alpn_select=netlib.http.http2.HTTP2Protocol.ALPN_PROTO_H2,  # TODO: check if server is capable of h2 first +                alpn_select_callback=self.__handle_alpn_select,              )          except tcp.NetLibError as e: +            print("alpn: %s" % self.client_alpn_protos)              raise ProtocolException(repr(e), e)      def _establish_tls_with_server(self): @@ -171,9 +196,7 @@ class TlsLayer(Layer):                  ca_path=self.config.openssl_trusted_cadir_server,                  ca_pemfile=self.config.openssl_trusted_ca_server,                  cipher_list=self.config.ciphers_server, -                alpn_protos=[ -                    netlib.http.http1.HTTP1Protocol.ALPN_PROTO_HTTP1, -                    netlib.http.http2.HTTP2Protocol.ALPN_PROTO_H2],  # TODO: read this from client_conn first +                alpn_protos=self.client_alpn_protos,              )              tls_cert_err = self.server_conn.ssl_verification_error              if tls_cert_err is not None: diff --git a/libmproxy/proxy/connection.py b/libmproxy/proxy/connection.py index d2b956f3..f33e84cd 100644 --- a/libmproxy/proxy/connection.py +++ b/libmproxy/proxy/connection.py @@ -77,15 +77,6 @@ class ClientConnection(tcp.BaseHandler, stateobject.StateObject):          return f      def convert_to_ssl(self, *args, **kwargs): -        if 'alpn_select' in kwargs: -            alpn_select = kwargs['alpn_select'] -            def alpn_select_callback(conn_, options): -                if alpn_select in options: -                    return bytes(alpn_select) -                else:  # pragma no cover -                    return options[0] -            kwargs['alpn_select'] = alpn_select_callback -          tcp.BaseHandler.convert_to_ssl(self, *args, **kwargs)          self.timestamp_ssl_setup = utils.timestamp()  | 
