Ticket #315 (new defect)

Opened 3 years ago

Last modified 3 years ago

SSL Handshake failure results in an exception using paste.httpserver

Reported by: jkp Owned by: ianb
Priority: normal Milestone: 1.4.1
Component: paste Version: svn-trunk
Severity: normal Keywords:
Cc:

Description

If I make a call against an httpserver started with a temporary certificate using Firefox I get the following exception on the server when the client responds saying it doesn't recognise the signing authority:

KidA% python main.py
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 52268)
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/Paste-1.7.2-py2.6.egg/paste/httpserver.py", line 1068, in process_request_in_thread
    self.finish_request(request, client_address)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/SocketServer.py", line 320, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/SocketServer.py", line 615, in __init__
    self.handle()
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/Paste-1.7.2-py2.6.egg/paste/httpserver.py", line 442, in handle
    BaseHTTPRequestHandler.handle(self)
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/BaseHTTPServer.py", line 329, in handle
    self.handle_one_request()
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/Paste-1.7.2-py2.6.egg/paste/httpserver.py", line 431, in handle_one_request
    self.raw_requestline = self.rfile.readline()
  File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/socket.py", line 404, in readline
    data = self._sock.recv(self._rbufsize)
Error: [('SSL routines', 'SSL3_READ_BYTES', 'tlsv1 alert unknown ca'), ('SSL routines', 'SSL23_READ', 'ssl handshake failure')]
----------------------------------------

Surely this is a normal part of the nevgociation process and should be handled more gracefully? Once I accept the certificate in the client requests go through normally but it seems that this shouldn't be an "exceptional" situation.

Thoughts?

Attachments

httpserver.py Download (56.6 KB) - added by jkp 3 years ago.
Revised SSL Implementation

Change History

Changed 3 years ago by jkp

OK, I've spent some time looking at this and a pretty hacky patch follows:

class WSGIHandler(WSGIHandlerMixin, BaseHTTPRequestHandler):
    """
    A WSGI handler that overrides POST, GET and HEAD to delegate
    requests to the server's ``wsgi_application``.
    """
    server_version = 'PasteWSGIServer/' + __version__

    def handle_one_request(self):
        """Handle a single HTTP request.

        You normally don't need to override this method; see the class
        __doc__ string for information on how to handle specific HTTP
        commands such as GET and POST.

        """
        
        try:
            # catch SSL handshake errors which are normal when
            # using self-signed certificates
            from OpenSSL.SSL import Error as SSLError
            try:
                self.raw_requestline = self.rfile.readline()
            except SSLError, exce:
                return
        except:
            self.raw_requestline = self.rfile.readline()
        if not self.raw_requestline:
            self.close_connection = 1
            return
        if not self.parse_request(): # An error code has been sent, just exit
            return
        self.wsgi_execute()

The issue is that the client sends back some data to the server on a handshake failure which results in an exception being raised. I've added code to conditionally catch such exceptions if the SSL module is present, but it would probably be nicer if the RequestHandler? class could know whether or not SSL was enabled and do the Right Thing based on that.

That said, there isn't any overhead in this way really. Perhaps it will do - it works OK.

As an aside, there is SSL support in 2.6, but only if you supply a certificate / key (or just a cert if the key is embedded). It might be nice to provide a way to support this so people don't have to have the OpenSSL module in just to get this kind of functionality.

Perhaps that needs a seperate ticket.

Changed 3 years ago by jkp

I spent some more time on this morning and completely reworked the SSL code to fix both the error above and to allow more intelligent usage of the possible SSL modules.

The new code has the following features:

• All SSL setup code is delegated to a new class SSLStrategy. • SSLStrategy will attempt to use the built-in ssl module in Python 2.6+ if it is there and if the user has not either requested a certificate to be generated, or passed in an OpenSSL context. • The error that occurred above is now more elegantly handled by adding SSL.Error to the list of exceptions that are already treated as normal by the code in the RequestHandler?'s handle() method.

I've tested the code using Firefox and Safari and all the various combinations of options that are now allowed. I found that while Firefox could cope with SSLv3 supported in the new ssl module, Safari couldn't so for now I've left it at v2 or v3.

Would appreciate if you could review this code for inclusion: documentation would need updating if it was included.

Changed 3 years ago by jkp

Revised SSL Implementation

Note: See TracTickets for help on using tickets.