Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Side by Side Diff: net/tools/testserver/testserver.py

Issue 6804032: Add TLS-SRP (RFC 5054) support Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: remove "httpsv" scheme, minor NSS/OpenSSL changes Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/third_party/nss/ssl/sslt.h ('k') | net/url_request/url_request.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python2.4 1 #!/usr/bin/python2.4
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """This is a simple HTTP server used for testing Chrome. 6 """This is a simple HTTP server used for testing Chrome.
7 7
8 It supports several test URLs, as specified by the handlers in TestPageHandler. 8 It supports several test URLs, as specified by the handlers in TestPageHandler.
9 By default, it listens on an ephemeral port and sends the port number back to 9 By default, it listens on an ephemeral port and sends the port number back to
10 the originating process over a pipe. The originating process can specify an 10 the originating process over a pipe. The originating process can specify an
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 self.stop = False 66 self.stop = False
67 self.nonce_time = None 67 self.nonce_time = None
68 while not self.stop: 68 while not self.stop:
69 self.handle_request() 69 self.handle_request()
70 self.socket.close() 70 self.socket.close()
71 71
72 class HTTPSServer(tlslite.api.TLSSocketServerMixIn, StoppableHTTPServer): 72 class HTTPSServer(tlslite.api.TLSSocketServerMixIn, StoppableHTTPServer):
73 """This is a specialization of StoppableHTTPerver that add https support.""" 73 """This is a specialization of StoppableHTTPerver that add https support."""
74 74
75 def __init__(self, server_address, request_hander_class, cert_path, 75 def __init__(self, server_address, request_hander_class, cert_path,
76 ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers): 76 ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers,
77 use_tls_srp, only_tls_srp):
77 s = open(cert_path).read() 78 s = open(cert_path).read()
78 x509 = tlslite.api.X509() 79 x509 = tlslite.api.X509()
79 x509.parse(s) 80 x509.parse(s)
80 self.cert_chain = tlslite.api.X509CertChain([x509]) 81 self.cert_chain = tlslite.api.X509CertChain([x509])
81 s = open(cert_path).read() 82 s = open(cert_path).read()
82 self.private_key = tlslite.api.parsePEMKey(s, private=True) 83 self.private_key = tlslite.api.parsePEMKey(s, private=True)
83 self.ssl_client_auth = ssl_client_auth 84 self.ssl_client_auth = ssl_client_auth
84 self.ssl_client_cas = [] 85 self.ssl_client_cas = []
85 for ca_file in ssl_client_cas: 86 for ca_file in ssl_client_cas:
86 s = open(ca_file).read() 87 s = open(ca_file).read()
87 x509 = tlslite.api.X509() 88 x509 = tlslite.api.X509()
88 x509.parse(s) 89 x509.parse(s)
89 self.ssl_client_cas.append(x509.subject) 90 self.ssl_client_cas.append(x509.subject)
90 self.ssl_handshake_settings = tlslite.api.HandshakeSettings() 91 self.ssl_handshake_settings = tlslite.api.HandshakeSettings()
91 if ssl_bulk_ciphers is not None: 92 if ssl_bulk_ciphers is not None:
92 self.ssl_handshake_settings.cipherNames = ssl_bulk_ciphers 93 self.ssl_handshake_settings.cipherNames = ssl_bulk_ciphers
94 self.only_tls_srp = only_tls_srp
95 self.srp_verifier_db = None
96 if use_tls_srp:
97 # Make dummy SRP verifier database
98 self.srp_verifier_db = tlslite.api.VerifierDB()
99 self.srp_verifier_db.create()
100 entry = tlslite.api.VerifierDB.makeVerifier('user', 'secret', 1536)
101 self.srp_verifier_db['user'] = entry
93 102
94 self.session_cache = tlslite.api.SessionCache() 103 self.session_cache = tlslite.api.SessionCache()
95 StoppableHTTPServer.__init__(self, server_address, request_hander_class) 104 StoppableHTTPServer.__init__(self, server_address, request_hander_class)
96 105
97 def handshake(self, tlsConnection): 106 def handshake(self, tlsConnection):
98 """Creates the SSL connection.""" 107 """Creates the SSL connection."""
99 try: 108 try:
100 tlsConnection.handshakeServer(certChain=self.cert_chain, 109 if not self.only_tls_srp:
101 privateKey=self.private_key, 110 tlsConnection.handshakeServer(certChain=self.cert_chain,
102 sessionCache=self.session_cache, 111 privateKey=self.private_key,
103 reqCert=self.ssl_client_auth, 112 sessionCache=self.session_cache,
104 settings=self.ssl_handshake_settings, 113 reqCert=self.ssl_client_auth,
105 reqCAs=self.ssl_client_cas) 114 settings=self.ssl_handshake_settings,
115 reqCAs=self.ssl_client_cas,
116 verifierDB=self.srp_verifier_db)
117 else:
118 tlsConnection.handshakeServer(verifierDB=self.srp_verifier_db)
106 tlsConnection.ignoreAbruptClose = True 119 tlsConnection.ignoreAbruptClose = True
120 self.tlsConnection = tlsConnection
107 return True 121 return True
108 except tlslite.api.TLSAbruptCloseError: 122 except tlslite.api.TLSAbruptCloseError:
109 # Ignore abrupt close. 123 # Ignore abrupt close.
110 return True 124 return True
111 except tlslite.api.TLSError, error: 125 except tlslite.api.TLSError, error:
112 print "Handshake failure:", str(error) 126 print "Handshake failure:", str(error)
113 return False 127 return False
114 128
115 129
116 class SyncHTTPServer(StoppableHTTPServer): 130 class SyncHTTPServer(StoppableHTTPServer):
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 asyncore.dispatcher.handle_write_event) 218 asyncore.dispatcher.handle_write_event)
205 219
206 for fd in exceptional_fds: 220 for fd in exceptional_fds:
207 HandleXmppSocket(fd, self._xmpp_socket_map, 221 HandleXmppSocket(fd, self._xmpp_socket_map,
208 asyncore.dispatcher.handle_expt_event) 222 asyncore.dispatcher.handle_expt_event)
209 223
210 224
211 class BasePageHandler(BaseHTTPServer.BaseHTTPRequestHandler): 225 class BasePageHandler(BaseHTTPServer.BaseHTTPRequestHandler):
212 226
213 def __init__(self, request, client_address, socket_server, 227 def __init__(self, request, client_address, socket_server,
214 connect_handlers, get_handlers, post_handlers, put_handlers): 228 connect_handlers, get_handlers, get_with_socket_handlers,
229 post_handlers, put_handlers):
215 self._connect_handlers = connect_handlers 230 self._connect_handlers = connect_handlers
216 self._get_handlers = get_handlers 231 self._get_handlers = get_handlers
232 self._get_with_socket_handlers = get_with_socket_handlers
217 self._post_handlers = post_handlers 233 self._post_handlers = post_handlers
218 self._put_handlers = put_handlers 234 self._put_handlers = put_handlers
235 self._socket_server = socket_server
219 BaseHTTPServer.BaseHTTPRequestHandler.__init__( 236 BaseHTTPServer.BaseHTTPRequestHandler.__init__(
220 self, request, client_address, socket_server) 237 self, request, client_address, socket_server)
221 238
222 def log_request(self, *args, **kwargs): 239 def log_request(self, *args, **kwargs):
223 # Disable request logging to declutter test log output. 240 # Disable request logging to declutter test log output.
224 pass 241 pass
225 242
226 def _ShouldHandleRequest(self, handler_name): 243 def _ShouldHandleRequest(self, handler_name):
227 """Determines if the path can be handled by the handler. 244 """Determines if the path can be handled by the handler.
228 245
229 We consider a handler valid if the path begins with the 246 We consider a handler valid if the path begins with the
230 handler name. It can optionally be followed by "?*", "/*". 247 handler name. It can optionally be followed by "?*", "/*".
231 """ 248 """
232 249
233 pattern = re.compile('%s($|\?|/).*' % handler_name) 250 pattern = re.compile('%s($|\?|/).*' % handler_name)
234 return pattern.match(self.path) 251 return pattern.match(self.path)
235 252
236 def do_CONNECT(self): 253 def do_CONNECT(self):
237 for handler in self._connect_handlers: 254 for handler in self._connect_handlers:
238 if handler(): 255 if handler():
239 return 256 return
240 257
241 def do_GET(self): 258 def do_GET(self):
259 for handler in self._get_with_socket_handlers:
260 if handler(self._socket_server):
261 return
242 for handler in self._get_handlers: 262 for handler in self._get_handlers:
243 if handler(): 263 if handler():
244 return 264 return
245 265
246 def do_POST(self): 266 def do_POST(self):
247 for handler in self._post_handlers: 267 for handler in self._post_handlers:
248 if handler(): 268 if handler():
249 return 269 return
250 270
251 def do_PUT(self): 271 def do_PUT(self):
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 self.RealBZ2FileWithCommonHeaderHandler, 305 self.RealBZ2FileWithCommonHeaderHandler,
286 self.SetCookieHandler, 306 self.SetCookieHandler,
287 self.AuthBasicHandler, 307 self.AuthBasicHandler,
288 self.AuthDigestHandler, 308 self.AuthDigestHandler,
289 self.SlowServerHandler, 309 self.SlowServerHandler,
290 self.ContentTypeHandler, 310 self.ContentTypeHandler,
291 self.ServerRedirectHandler, 311 self.ServerRedirectHandler,
292 self.ClientRedirectHandler, 312 self.ClientRedirectHandler,
293 self.MultipartHandler, 313 self.MultipartHandler,
294 self.DefaultResponseHandler] 314 self.DefaultResponseHandler]
315 get_with_socket_handlers = [
316 self.TLSLoginInfoHandler]
295 post_handlers = [ 317 post_handlers = [
296 self.EchoTitleHandler, 318 self.EchoTitleHandler,
297 self.EchoAllHandler, 319 self.EchoAllHandler,
298 self.EchoHandler, 320 self.EchoHandler,
299 self.DeviceManagementHandler] + get_handlers 321 self.DeviceManagementHandler] + get_handlers
300 put_handlers = [ 322 put_handlers = [
301 self.EchoTitleHandler, 323 self.EchoTitleHandler,
302 self.EchoAllHandler, 324 self.EchoAllHandler,
303 self.EchoHandler] + get_handlers 325 self.EchoHandler] + get_handlers
304 326
305 self._mime_types = { 327 self._mime_types = {
306 'crx' : 'application/x-chrome-extension', 328 'crx' : 'application/x-chrome-extension',
307 'exe' : 'application/octet-stream', 329 'exe' : 'application/octet-stream',
308 'gif': 'image/gif', 330 'gif': 'image/gif',
309 'jpeg' : 'image/jpeg', 331 'jpeg' : 'image/jpeg',
310 'jpg' : 'image/jpeg', 332 'jpg' : 'image/jpeg',
311 'pdf' : 'application/pdf', 333 'pdf' : 'application/pdf',
312 'xml' : 'text/xml' 334 'xml' : 'text/xml'
313 } 335 }
314 self._default_mime_type = 'text/html' 336 self._default_mime_type = 'text/html'
315 337
316 BasePageHandler.__init__(self, request, client_address, socket_server, 338 BasePageHandler.__init__(self, request, client_address, socket_server,
317 connect_handlers, get_handlers, post_handlers, 339 connect_handlers, get_handlers,
340 get_with_socket_handlers, post_handlers,
318 put_handlers) 341 put_handlers)
319 342
320 def GetMIMETypeFromName(self, file_name): 343 def GetMIMETypeFromName(self, file_name):
321 """Returns the mime type for the specified file_name. So far it only looks 344 """Returns the mime type for the specified file_name. So far it only looks
322 at the file extension.""" 345 at the file extension."""
323 346
324 (shortname, extension) = os.path.splitext(file_name.split("?")[0]) 347 (shortname, extension) = os.path.splitext(file_name.split("?")[0])
325 if len(extension) == 0: 348 if len(extension) == 0:
326 # no extension. 349 # no extension.
327 return self._default_mime_type 350 return self._default_mime_type
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 while True: 629 while True:
607 line = self.rfile.readline() 630 line = self.rfile.readline()
608 length = int(line, 16) 631 length = int(line, 16)
609 if length == 0: 632 if length == 0:
610 self.rfile.readline() 633 self.rfile.readline()
611 break 634 break
612 body += self.rfile.read(length) 635 body += self.rfile.read(length)
613 self.rfile.read(2) 636 self.rfile.read(2)
614 return body 637 return body
615 638
639 def TLSLoginInfoHandler(self, socket_server):
640 """This handler echoes back the username used to log in via TLS."""
641
642 if not self._ShouldHandleRequest("/tlslogininfo"):
643 return False
644
645 self.send_response(200)
646 self.send_header('Content-type', 'text/html')
647 self.end_headers()
648
649 srp_user = socket_server.tlsConnection.session.srpUsername
650 if srp_user:
651 self.wfile.write('username: ' + srp_user)
652 else:
653 self.wfile.write('not using TLS-SRP')
654 return True
655
616 def EchoHandler(self): 656 def EchoHandler(self):
617 """This handler just echoes back the payload of the request, for testing 657 """This handler just echoes back the payload of the request, for testing
618 form submission.""" 658 form submission."""
619 659
620 if not self._ShouldHandleRequest("/echo"): 660 if not self._ShouldHandleRequest("/echo"):
621 return False 661 return False
622 662
623 self.send_response(200) 663 self.send_response(200)
624 self.send_header('Content-type', 'text/html') 664 self.send_header('Content-type', 'text/html')
625 self.end_headers() 665 self.end_headers()
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 print 'specified server cert file not found: ' + options.cert + \ 1446 print 'specified server cert file not found: ' + options.cert + \
1407 ' exiting...' 1447 ' exiting...'
1408 return 1448 return
1409 for ca_cert in options.ssl_client_ca: 1449 for ca_cert in options.ssl_client_ca:
1410 if not os.path.isfile(ca_cert): 1450 if not os.path.isfile(ca_cert):
1411 print 'specified trusted client CA file not found: ' + ca_cert + \ 1451 print 'specified trusted client CA file not found: ' + ca_cert + \
1412 ' exiting...' 1452 ' exiting...'
1413 return 1453 return
1414 server = HTTPSServer(('127.0.0.1', port), TestPageHandler, options.cert, 1454 server = HTTPSServer(('127.0.0.1', port), TestPageHandler, options.cert,
1415 options.ssl_client_auth, options.ssl_client_ca, 1455 options.ssl_client_auth, options.ssl_client_ca,
1416 options.ssl_bulk_cipher) 1456 options.ssl_bulk_cipher, options.use_tls_srp,
1457 options.only_tls_srp)
1417 print 'HTTPS server started on port %d...' % server.server_port 1458 print 'HTTPS server started on port %d...' % server.server_port
1418 else: 1459 else:
1419 server = StoppableHTTPServer(('127.0.0.1', port), TestPageHandler) 1460 server = StoppableHTTPServer(('127.0.0.1', port), TestPageHandler)
1420 print 'HTTP server started on port %d...' % server.server_port 1461 print 'HTTP server started on port %d...' % server.server_port
1421 1462
1422 server.data_dir = MakeDataDir() 1463 server.data_dir = MakeDataDir()
1423 server.file_root_url = options.file_root_url 1464 server.file_root_url = options.file_root_url
1424 server_data['port'] = server.server_port 1465 server_data['port'] = server.server_port
1425 server._device_management_handler = None 1466 server._device_management_handler = None
1426 server.policy_cert_chain = options.policy_cert_chain 1467 server.policy_cert_chain = options.policy_cert_chain
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 'specified file. This option may appear multiple ' 1556 'specified file. This option may appear multiple '
1516 'times, indicating multiple CA names should be ' 1557 'times, indicating multiple CA names should be '
1517 'sent in the request.') 1558 'sent in the request.')
1518 option_parser.add_option('', '--ssl-bulk-cipher', action='append', 1559 option_parser.add_option('', '--ssl-bulk-cipher', action='append',
1519 help='Specify the bulk encryption algorithm(s)' 1560 help='Specify the bulk encryption algorithm(s)'
1520 'that will be accepted by the SSL server. Valid ' 1561 'that will be accepted by the SSL server. Valid '
1521 'values are "aes256", "aes128", "3des", "rc4". If ' 1562 'values are "aes256", "aes128", "3des", "rc4". If '
1522 'omitted, all algorithms will be used. This ' 1563 'omitted, all algorithms will be used. This '
1523 'option may appear multiple times, indicating ' 1564 'option may appear multiple times, indicating '
1524 'multiple algorithms should be enabled.'); 1565 'multiple algorithms should be enabled.');
1566 option_parser.add_option('', '--use-tls-srp', action='store_true',
1567 help='Allow TLS authentication using TLS-SRP'
1568 ' (user jsmith, password asdf)')
1569 option_parser.add_option('', '--only-tls-srp', action='store_true',
1570 help='Only allow connections using TLS-SRP')
1525 option_parser.add_option('', '--file-root-url', default='/files/', 1571 option_parser.add_option('', '--file-root-url', default='/files/',
1526 help='Specify a root URL for files served.') 1572 help='Specify a root URL for files served.')
1527 option_parser.add_option('', '--startup-pipe', type='int', 1573 option_parser.add_option('', '--startup-pipe', type='int',
1528 dest='startup_pipe', 1574 dest='startup_pipe',
1529 help='File handle of pipe to parent process') 1575 help='File handle of pipe to parent process')
1530 option_parser.add_option('', '--policy-cert-chain', action='append', 1576 option_parser.add_option('', '--policy-cert-chain', action='append',
1531 help='Specify a path to a certificate file to sign ' 1577 help='Specify a path to a certificate file to sign '
1532 'policy responses. This option may be used ' 1578 'policy responses. This option may be used '
1533 'multiple times to define a certificate chain. ' 1579 'multiple times to define a certificate chain. '
1534 'The first element will be used for signing, ' 1580 'The first element will be used for signing, '
1535 'the last element should be the root ' 1581 'the last element should be the root '
1536 'certificate.') 1582 'certificate.')
1537 options, args = option_parser.parse_args() 1583 options, args = option_parser.parse_args()
1538 1584
1539 sys.exit(main(options, args)) 1585 sys.exit(main(options, args))
OLDNEW
« no previous file with comments | « net/third_party/nss/ssl/sslt.h ('k') | net/url_request/url_request.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698