diff options
Diffstat (limited to 'libmproxy/protocol2/ssl.py')
-rw-r--r-- | libmproxy/protocol2/ssl.py | 51 |
1 files changed, 12 insertions, 39 deletions
diff --git a/libmproxy/protocol2/ssl.py b/libmproxy/protocol2/ssl.py index c21956b7..32798e72 100644 --- a/libmproxy/protocol2/ssl.py +++ b/libmproxy/protocol2/ssl.py @@ -1,20 +1,13 @@ from __future__ import (absolute_import, print_function, division) -import Queue -import threading import traceback from netlib import tcp from ..proxy import ProxyError2 -from .layer import Layer +from .layer import Layer, yield_from_callback from .messages import Connect, Reconnect, ChangeServer from .auto import AutoLayer -class ReconnectRequest(object): - def __init__(self): - self.done = threading.Event() - - class SslLayer(Layer): def __init__(self, ctx, client_ssl, server_ssl): super(SslLayer, self).__init__(ctx) @@ -59,7 +52,8 @@ class SslLayer(Layer): for m in self._establish_ssl_with_client_and_server(): yield m elif self.client_ssl: - self._establish_ssl_with_client() + for m in self._establish_ssl_with_client(): + yield m layer = AutoLayer(self) for message in layer(): @@ -96,32 +90,12 @@ class SslLayer(Layer): except ProxyError2 as e: server_err = e - # The part below is a bit ugly as we cannot yield from the handle_sni callback. - # The workaround is to do that in a separate thread and yield from the main thread. - - # client_ssl_queue may contain the following elements - # - True, if ssl was successfully established - # - An Exception thrown by self._establish_ssl_with_client() - # - A threading.Event, which singnifies a request for a reconnect from the sni callback - self.__client_ssl_queue = Queue.Queue() - - def establish_client_ssl(): - try: - self._establish_ssl_with_client() - self.__client_ssl_queue.put(True) - except Exception as client_err: - self.__client_ssl_queue.put(client_err) - - threading.Thread(target=establish_client_ssl, name="ClientSSLThread").start() - e = self.__client_ssl_queue.get() - if isinstance(e, ReconnectRequest): - yield Reconnect() - self._establish_ssl_with_server() - e.done.set() - e = self.__client_ssl_queue.get() - if e is not True: - raise ProxyError2("Error when establish client SSL: " + repr(e), e) - self.__client_ssl_queue = None + for message in self._establish_ssl_with_client(): + if message == Reconnect: + yield message + self._establish_ssl_with_server() + else: + raise RuntimeError("Unexpected Message: %s" % message) if server_err and not self._sni_from_handshake: raise server_err @@ -142,9 +116,7 @@ class SslLayer(Layer): if old_upstream_sni != self.sni_for_upstream_connection: # Perform reconnect if self.server_ssl: - reconnect = ReconnectRequest() - self.__client_ssl_queue.put(reconnect) - reconnect.done.wait() + self.yield_from_callback(Reconnect()) if self._sni_from_handshake: # Now, change client context to reflect possibly changed certificate: @@ -163,6 +135,7 @@ class SslLayer(Layer): except: # pragma: no cover self.log("Error in handle_sni:\r\n" + traceback.format_exc(), "error") + @yield_from_callback def _establish_ssl_with_client(self): self.log("Establish SSL with client", "debug") cert, key, chain_file = self.find_cert() @@ -227,4 +200,4 @@ class SslLayer(Layer): if self._sni_from_server_change: sans.add(self._sni_from_server_change) - return self.config.certstore.get_cert(host, list(sans))
\ No newline at end of file + return self.config.certstore.get_cert(host, list(sans)) |