better exception handling

This commit is contained in:
Maximilian Hils 2015-09-11 01:39:33 +02:00
parent c159c8ca13
commit ffdf143be4
5 changed files with 58 additions and 17 deletions

View File

@ -33,6 +33,11 @@ class TlsException(ProtocolException):
pass
class ClientHandshakeException(TlsException):
# This subclass is quite useful to give hints about cert errors.
pass
class Socks5Exception(ProtocolException):
pass

View File

@ -1,4 +1,6 @@
from __future__ import (absolute_import, print_function, division)
import six
import sys
from netlib import tcp
from ..models import ServerConnection
from ..exceptions import ProtocolException
@ -172,8 +174,12 @@ class ServerConnectionMixin(object):
try:
self.server_conn.connect()
except tcp.NetLibError as e:
raise ProtocolException(
"Server connection to %s failed: %s" % (repr(self.server_conn.address), e), e)
six.reraise(
ProtocolException,
ProtocolException("Server connection to %s failed: %s" %
(repr(self.server_conn.address), e), e),
sys.exc_info()[2]
)
class Kill(Exception):

View File

@ -1,6 +1,8 @@
from __future__ import (absolute_import, print_function, division)
import socket
import select
import six
import sys
from OpenSSL import SSL
@ -63,4 +65,8 @@ class RawTCPLayer(Layer):
)
except (socket.error, NetLibError, SSL.Error) as e:
raise ProtocolException("TCP connection closed unexpectedly: {}".format(repr(e)), e)
six.reraise(
ProtocolException,
ProtocolException("TCP connection closed unexpectedly: {}".format(repr(e)), e),
sys.exc_info()[2]
)

View File

@ -1,18 +1,19 @@
from __future__ import (absolute_import, print_function, division)
import struct
import sys
from construct import ConstructError
import six
import sys
from netlib.tcp import NetLibError, NetLibInvalidCertificateError
from netlib.http.http1 import HTTP1Protocol
from ..contrib.tls._constructs import ClientHello
from ..exceptions import ProtocolException, TlsException
from ..exceptions import ProtocolException, TlsException, ClientHandshakeException
from .base import Layer
# taken from https://testssl.sh/openssl-rfc.mappping.html
CIPHER_ID_NAME_MAP = {
0x00: 'NULL-MD5',
@ -407,8 +408,17 @@ class TlsLayer(Layer):
chain_file=chain_file,
alpn_select_callback=self.__alpn_select_callback,
)
# Some TLS clients will not fail the handshake,
# but will immediately throw an "unexpected eof" error on the first read.
# The reason for this might be difficult to find, so we try to peek here to see if it
# raises ann error.
self.client_conn.rfile.peek(0)
except NetLibError as e:
raise TlsException("Cannot establish TLS with client: %s" % repr(e), e)
six.reraise(
ClientHandshakeException,
ClientHandshakeException("Cannot establish TLS with client: %s" % repr(e), e),
sys.exc_info()[2]
)
def _establish_tls_with_server(self):
self.log("Establish TLS with server", "debug")
@ -457,17 +467,25 @@ class TlsLayer(Layer):
(tls_cert_err['depth'], tls_cert_err['errno']),
"error")
self.log("Aborting connection attempt", "error")
raise TlsException("Cannot establish TLS with {address} (sni: {sni}): {e}".format(
address=repr(self.server_conn.address),
sni=self.sni_for_server_connection,
e=repr(e),
), e)
six.reraise(
TlsException,
TlsException("Cannot establish TLS with {address} (sni: {sni}): {e}".format(
address=repr(self.server_conn.address),
sni=self.sni_for_server_connection,
e=repr(e),
), e),
sys.exc_info()[2]
)
except NetLibError as e:
raise TlsException("Cannot establish TLS with {address} (sni: {sni}): {e}".format(
address=repr(self.server_conn.address),
sni=self.sni_for_server_connection,
e=repr(e),
), e)
six.reraise(
TlsException,
TlsException("Cannot establish TLS with {address} (sni: {sni}): {e}".format(
address=repr(self.server_conn.address),
sni=self.sni_for_server_connection,
e=repr(e),
), e),
sys.exc_info()[2]
)
self.log("ALPN selected by server: %s" % self.alpn_for_client_connection, "debug")

View File

@ -3,6 +3,7 @@ from __future__ import (absolute_import, print_function, division)
import traceback
import sys
import socket
import six
from netlib import tcp
from netlib.http.http1 import HTTP1Protocol
@ -39,7 +40,11 @@ class ProxyServer(tcp.TCPServer):
try:
super(ProxyServer, self).__init__((config.host, config.port))
except socket.error as e:
raise ServerException('Error starting proxy server: ' + repr(e), e)
six.reraise(
ServerException,
ServerException('Error starting proxy server: ' + repr(e), e),
sys.exc_info()[2]
)
self.channel = None
def start_slave(self, klass, channel):
@ -117,6 +122,7 @@ class ConnectionHandler(object):
self.log("Connection killed", "info")
except ProtocolException as e:
self.log(repr(e), "info")
self.log(traceback.format_exc(), "debug")
# If an error propagates to the topmost level,
# we send an HTTP error response, which is both
# understandable by HTTP clients and humans.