Ticket #254: custom.ssl_context.patch

File custom.ssl_context.patch, 5.2 KB (added by s0undt3ch, 4 years ago)

more source code comments

  • paste/httpserver.py

     
    2727from itertools import count 
    2828from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 
    2929from SocketServer import ThreadingMixIn 
    30 from paste.util import converters 
     30from paste.util import converters, import_string 
    3131import logging 
    3232try: 
    3333    from paste.util import killthread 
     
    430430        # don't bother logging disconnects while handling a request 
    431431        try: 
    432432            BaseHTTPRequestHandler.handle(self) 
     433        except (SSL.WantReadError, SSL.WantWriteError, 
     434                SSL.WantX509LookupError), error: 
     435            self.wsgi_connection_drop(error) 
     436        except SSL.ZeroReturnError, error: 
     437            self.wsgi_connection_drop(error) 
     438        except SSL.Error, error: 
     439            self.wsgi_connection_drop(error) 
    433440        except SocketErrors, exce: 
    434441            self.wsgi_connection_drop(exce) 
    435442 
     
    11271134    """ 
    11281135 
    11291136def serve(application, host=None, port=None, handler=None, ssl_pem=None, 
    1130           ssl_context=None, server_version=None, protocol_version=None, 
    1131           start_loop=True, daemon_threads=None, socket_timeout=None, 
    1132           use_threadpool=None, threadpool_workers=10, 
     1137          ssl_context=None, ssl_context_options=None, server_version=None, 
     1138          protocol_version=None, start_loop=True, daemon_threads=None, 
     1139          socket_timeout=None, use_threadpool=None, threadpool_workers=10, 
    11331140          threadpool_options=None): 
    11341141    """ 
    11351142    Serves your ``application`` over HTTP(S) via WSGI interface 
     
    11711178        ``ssl_pem``.  Supply this to use a context of your own 
    11721179        construction. 
    11731180 
     1181        If you set a module path on the config file, that module will be loaded, 
     1182        and on that module you must have a function ``get_ssl_context`` where 
     1183        you setup your custom context and then return in. All options will be 
     1184        passed to that function for your convenience. 
     1185        For example:: 
     1186 
     1187            def ssl_verify_callback_stub(ssl_ctx_ptr, x509_ptr, errnum, 
     1188                                         errdepth, ok): 
     1189                print 'Got Client Certificate: ', x509_ptr.get_subject() 
     1190                return ok 
     1191 
     1192            def get_ssl_context(**ssl_context_options): 
     1193                ctx = SSL.Context(SSL.SSLv3_METHOD) 
     1194                ctx.use_privatekey_file(ssl_context_options.get('ssl_key')) 
     1195                ctx.use_certificate_file(ssl_context_options.get('ssl_cert')) 
     1196                ctx.load_verify_locations(ssl_context_options.get('ssl_ca_cert')) 
     1197                ctx.set_verify( 
     1198                    SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, 
     1199                    ssl_verify_callback_stub) # Demand a certificate 
     1200                return ctx 
     1201 
     1202        Then, on your config file you would have something like:: 
     1203 
     1204            ssl_context = myapp.lib.custom_ssl_context 
     1205 
     1206    ``ssl_context_options`` 
     1207 
     1208        These are extra options passed to the custom ssl_context. 
     1209 
    11741210    ``server_version`` 
    11751211 
    11761212        The version of the server as reported in HTTP response line. This 
     
    12261262        threadpool.  See paste.httpserver.ThreadPool for specific 
    12271263        options (``threadpool_workers`` is a specific option that can 
    12281264        also go here). 
     1265 
    12291266    """ 
    12301267    is_ssl = False 
    12311268    if ssl_pem or ssl_context: 
     
    12391276                ssl_context = SSL.Context(SSL.SSLv23_METHOD) 
    12401277                ssl_context.use_privatekey_file(ssl_pem) 
    12411278                ssl_context.use_certificate_chain_file(ssl_pem) 
     1279        else: 
     1280            if isinstance(ssl_context, basestring): 
     1281                # Is this a module path from the config file 
     1282                module = import_string.try_import_module(ssl_context) 
     1283                # module has the necessary function to setup ssl_context? 
     1284                if not hasattr(module, 'get_ssl_context'): 
     1285                    raise SystemExit, "'%s' does not " % module + \ 
     1286                                      "have a get_ssl_context() function" 
     1287                # Get the ssl_context all configured 
     1288                ssl_context = module.get_ssl_context(**ssl_context_options) 
    12421289 
    12431290    host = host or '127.0.0.1' 
    12441291    if port is None: 
     
    13051352    for name in ['use_threadpool', 'daemon_threads']: 
    13061353        if name in kwargs: 
    13071354            kwargs[name] = asbool(kwargs[name]) 
     1355    ssl_context_options = {} 
     1356    if 'ssl_pem' in kwargs: 
     1357        ssl_context_options['ssl_pem'] = kwargs['ssl_pem'] 
    13081358    threadpool_options = {} 
    13091359    for name, value in kwargs.items(): 
    13101360        if name.startswith('threadpool_') and name != 'threadpool_workers': 
    13111361            threadpool_options[name[len('threadpool_'):]] = value 
    13121362            del kwargs[name] 
     1363        elif name.startswith('ssl_context_'): 
     1364            ssl_context_options[name[len('ssl_context_'):]] = value 
     1365            del kwargs[name] 
    13131366    if ('error_email' not in threadpool_options 
    13141367        and 'error_email' in global_conf): 
    13151368        threadpool_options['error_email'] = global_conf['error_email'] 
    13161369    kwargs['threadpool_options'] = threadpool_options 
     1370    kwargs['ssl_context_options'] = ssl_context_options 
    13171371    serve(wsgi_app, **kwargs) 
    13181372 
    13191373server_runner.__doc__ = (serve.__doc__ or '') + """