Ticket #254: custom.ssl_context.patch
| File custom.ssl_context.patch, 5.2 KB (added by s0undt3ch, 4 years ago) |
|---|
-
paste/httpserver.py
27 27 from itertools import count 28 28 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 29 29 from SocketServer import ThreadingMixIn 30 from paste.util import converters 30 from paste.util import converters, import_string 31 31 import logging 32 32 try: 33 33 from paste.util import killthread … … 430 430 # don't bother logging disconnects while handling a request 431 431 try: 432 432 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) 433 440 except SocketErrors, exce: 434 441 self.wsgi_connection_drop(exce) 435 442 … … 1127 1134 """ 1128 1135 1129 1136 def serve(application, host=None, port=None, handler=None, ssl_pem=None, 1130 ssl_context=None, s erver_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, 1133 1140 threadpool_options=None): 1134 1141 """ 1135 1142 Serves your ``application`` over HTTP(S) via WSGI interface … … 1171 1178 ``ssl_pem``. Supply this to use a context of your own 1172 1179 construction. 1173 1180 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 1174 1210 ``server_version`` 1175 1211 1176 1212 The version of the server as reported in HTTP response line. This … … 1226 1262 threadpool. See paste.httpserver.ThreadPool for specific 1227 1263 options (``threadpool_workers`` is a specific option that can 1228 1264 also go here). 1265 1229 1266 """ 1230 1267 is_ssl = False 1231 1268 if ssl_pem or ssl_context: … … 1239 1276 ssl_context = SSL.Context(SSL.SSLv23_METHOD) 1240 1277 ssl_context.use_privatekey_file(ssl_pem) 1241 1278 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) 1242 1289 1243 1290 host = host or '127.0.0.1' 1244 1291 if port is None: … … 1305 1352 for name in ['use_threadpool', 'daemon_threads']: 1306 1353 if name in kwargs: 1307 1354 kwargs[name] = asbool(kwargs[name]) 1355 ssl_context_options = {} 1356 if 'ssl_pem' in kwargs: 1357 ssl_context_options['ssl_pem'] = kwargs['ssl_pem'] 1308 1358 threadpool_options = {} 1309 1359 for name, value in kwargs.items(): 1310 1360 if name.startswith('threadpool_') and name != 'threadpool_workers': 1311 1361 threadpool_options[name[len('threadpool_'):]] = value 1312 1362 del kwargs[name] 1363 elif name.startswith('ssl_context_'): 1364 ssl_context_options[name[len('ssl_context_'):]] = value 1365 del kwargs[name] 1313 1366 if ('error_email' not in threadpool_options 1314 1367 and 'error_email' in global_conf): 1315 1368 threadpool_options['error_email'] = global_conf['error_email'] 1316 1369 kwargs['threadpool_options'] = threadpool_options 1370 kwargs['ssl_context_options'] = ssl_context_options 1317 1371 serve(wsgi_app, **kwargs) 1318 1372 1319 1373 server_runner.__doc__ = (serve.__doc__ or '') + """
