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

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

Issue 9663017: net: add OCSP tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ... Created 8 years, 9 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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/FTP/SYNC/TCP/UDP/ server used for testing Chrome. 6 """This is a simple HTTP/FTP/SYNC/TCP/UDP/ 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
11 explicit port if necessary. 11 explicit port if necessary.
12 It can use https if you specify the flag --https=CERT where CERT is the path 12 It can use https if you specify the flag --https=CERT where CERT is the path
13 to a pem file containing the certificate and private key that should be used. 13 to a pem file containing the certificate and private key that should be used.
14 """ 14 """
15 15
16 import asyncore 16 import asyncore
17 import base64 17 import base64
18 import BaseHTTPServer 18 import BaseHTTPServer
19 import cgi 19 import cgi
20 import errno 20 import errno
21 import httplib 21 import httplib
22 import minica
22 import optparse 23 import optparse
23 import os 24 import os
24 import random 25 import random
25 import re 26 import re
26 import select 27 import select
28 import socket
27 import SocketServer 29 import SocketServer
28 import socket 30 import struct
29 import sys 31 import sys
30 import struct 32 import threading
31 import time 33 import time
32 import urllib 34 import urllib
33 import urlparse 35 import urlparse
34 import warnings 36 import warnings
35 import zlib 37 import zlib
36 38
37 # Ignore deprecation warnings, they make our output more cluttered. 39 # Ignore deprecation warnings, they make our output more cluttered.
38 warnings.filterwarnings("ignore", category=DeprecationWarning) 40 warnings.filterwarnings("ignore", category=DeprecationWarning)
39 41
40 import echo_message 42 import echo_message
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 100
99 def serve_forever(self): 101 def serve_forever(self):
100 self.stop = False 102 self.stop = False
101 self.nonce_time = None 103 self.nonce_time = None
102 while not self.stop: 104 while not self.stop:
103 self.handle_request() 105 self.handle_request()
104 self.socket.close() 106 self.socket.close()
105 107
106 108
107 class HTTPServer(ClientRestrictingServerMixIn, StoppableHTTPServer): 109 class HTTPServer(ClientRestrictingServerMixIn, StoppableHTTPServer):
108 """This is a specialization of StoppableHTTPerver that adds client 110 """This is a specialization of StoppableHTTPServer that adds client
109 verification.""" 111 verification."""
110 112
111 pass 113 pass
112 114
115 class OCSPServer(ClientRestrictingServerMixIn, BaseHTTPServer.HTTPServer):
116 """This is a specialization of HTTPServer that serves an
117 OCSP response"""
118
119 def serve_forever_on_thread(self):
120 self.thread = threading.Thread(target = self.serve_forever,
121 name = "OCSPServerThread")
122 self.thread.start()
123
124 def stop_serving(self):
125 self.shutdown()
126 self.thread.join()
113 127
114 class HTTPSServer(tlslite.api.TLSSocketServerMixIn, 128 class HTTPSServer(tlslite.api.TLSSocketServerMixIn,
115 ClientRestrictingServerMixIn, 129 ClientRestrictingServerMixIn,
116 StoppableHTTPServer): 130 StoppableHTTPServer):
117 """This is a specialization of StoppableHTTPerver that add https support and 131 """This is a specialization of StoppableHTTPServer that add https support and
118 client verification.""" 132 client verification."""
119 133
120 def __init__(self, server_address, request_hander_class, cert_path, 134 def __init__(self, server_address, request_hander_class, pem_cert_and_key,
121 ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers, 135 ssl_client_auth, ssl_client_cas, ssl_bulk_ciphers,
122 record_resume_info): 136 record_resume_info):
123 s = open(cert_path).read() 137 self.cert_chain = tlslite.api.X509CertChain().parseChain(pem_cert_and_key)
124 self.cert_chain = tlslite.api.X509CertChain().parseChain(s) 138 self.private_key = tlslite.api.parsePEMKey(pem_cert_and_key, private=True)
125 s = open(cert_path).read()
126 self.private_key = tlslite.api.parsePEMKey(s, private=True)
127 self.ssl_client_auth = ssl_client_auth 139 self.ssl_client_auth = ssl_client_auth
128 self.ssl_client_cas = [] 140 self.ssl_client_cas = []
129 for ca_file in ssl_client_cas: 141 for ca_file in ssl_client_cas:
130 s = open(ca_file).read() 142 s = open(ca_file).read()
131 x509 = tlslite.api.X509() 143 x509 = tlslite.api.X509()
132 x509.parse(s) 144 x509.parse(s)
133 self.ssl_client_cas.append(x509.subject) 145 self.ssl_client_cas.append(x509.subject)
134 self.ssl_handshake_settings = tlslite.api.HandshakeSettings() 146 self.ssl_handshake_settings = tlslite.api.HandshakeSettings()
135 if ssl_bulk_ciphers is not None: 147 if ssl_bulk_ciphers is not None:
136 self.ssl_handshake_settings.cipherNames = ssl_bulk_ciphers 148 self.ssl_handshake_settings.cipherNames = ssl_bulk_ciphers
(...skipping 1732 matching lines...) Expand 10 before | Expand all | Expand 10 after
1869 # Create the default path to our data dir, relative to the exe dir. 1881 # Create the default path to our data dir, relative to the exe dir.
1870 my_data_dir = os.path.dirname(sys.argv[0]) 1882 my_data_dir = os.path.dirname(sys.argv[0])
1871 my_data_dir = os.path.join(my_data_dir, "..", "..", "..", "..", 1883 my_data_dir = os.path.join(my_data_dir, "..", "..", "..", "..",
1872 "test", "data") 1884 "test", "data")
1873 1885
1874 #TODO(ibrar): Must use Find* funtion defined in google\tools 1886 #TODO(ibrar): Must use Find* funtion defined in google\tools
1875 #i.e my_data_dir = FindUpward(my_data_dir, "test", "data") 1887 #i.e my_data_dir = FindUpward(my_data_dir, "test", "data")
1876 1888
1877 return my_data_dir 1889 return my_data_dir
1878 1890
1891 class OCSPHandler(BasePageHandler):
1892 def __init__(self, request, client_address, socket_server):
1893 handlers = [self.OCSPResponse]
1894 self.ocsp_response = socket_server.ocsp_response
1895 BasePageHandler.__init__(self, request, client_address, socket_server,
1896 handlers, handlers, handlers,
1897 handlers, handlers)
1898
1899 def OCSPResponse(self):
1900 self.send_response(200)
1901 self.send_header('Content-Type', 'application/ocsp-response')
1902 self.send_header('Content-Length', str(len(self.ocsp_response)))
1903 self.end_headers()
1904
1905 self.wfile.write(self.ocsp_response)
1879 1906
1880 class TCPEchoHandler(SocketServer.BaseRequestHandler): 1907 class TCPEchoHandler(SocketServer.BaseRequestHandler):
1881 """The RequestHandler class for TCP echo server. 1908 """The RequestHandler class for TCP echo server.
1882 1909
1883 It is instantiated once per connection to the server, and overrides the 1910 It is instantiated once per connection to the server, and overrides the
1884 handle() method to implement communication to the client. 1911 handle() method to implement communication to the client.
1885 """ 1912 """
1886 1913
1887 def handle(self): 1914 def handle(self):
1888 """Handles the request from the client and constructs a response.""" 1915 """Handles the request from the client and constructs a response."""
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1949 sys.stdout = FileMultiplexer(sys.stdout, logfile) 1976 sys.stdout = FileMultiplexer(sys.stdout, logfile)
1950 else: 1977 else:
1951 sys.stdout = logfile 1978 sys.stdout = logfile
1952 1979
1953 port = options.port 1980 port = options.port
1954 host = options.host 1981 host = options.host
1955 1982
1956 server_data = {} 1983 server_data = {}
1957 server_data['host'] = host 1984 server_data['host'] = host
1958 1985
1986 ocsp_server = None
1987
1959 if options.server_type == SERVER_HTTP: 1988 if options.server_type == SERVER_HTTP:
1960 if options.cert: 1989 if options.cert:
1961 # let's make sure the cert file exists. 1990 pem_cert_and_key = None
1962 if not os.path.isfile(options.cert): 1991 if options.cert.startswith('__'):
1963 print 'specified server cert file not found: ' + options.cert + \ 1992 ocsp_server = OCSPServer((host, 0), OCSPHandler)
1964 ' exiting...' 1993 print 'OCSP server on port ' + str(ocsp_server.server_port)
1965 return 1994
1995 ocsp_der = None
1996 ocsp_revoked = False
1997 ocsp_invalid = False
1998
1999 if options.cert == '__ocsp_ok__':
2000 pass
2001 elif options.cert == '__ocsp_revoked__':
2002 ocsp_revoked = True
2003 elif options.cert == '__ocsp_invalid__':
2004 ocsp_invalid = True
2005 else:
2006 print 'unknown special certificate type: ' + options.cert
2007 return
2008
2009 (pem_cert_and_key, ocsp_der) = \
2010 minica.GenerateCertKeyAndOCSP(
2011 subject = "127.0.0.1",
2012 ocsp_url = "http://127.0.0.1:%d/ocsp" % ocsp_server.server_port,
2013 ocsp_revoked = ocsp_revoked)
2014
2015 if ocsp_invalid:
2016 ocsp_der = '3'
2017
2018 ocsp_server.ocsp_response = ocsp_der
2019 else:
2020 # options.cert is a filename. Let's make sure the cert file exists.
2021 if not os.path.isfile(options.cert):
2022 print 'specified server cert file not found: ' + options.cert + \
2023 ' exiting...'
2024 return
2025 pem_cert_and_key = file(options.cert, 'r').read()
2026
1966 for ca_cert in options.ssl_client_ca: 2027 for ca_cert in options.ssl_client_ca:
1967 if not os.path.isfile(ca_cert): 2028 if not os.path.isfile(ca_cert):
1968 print 'specified trusted client CA file not found: ' + ca_cert + \ 2029 print 'specified trusted client CA file not found: ' + ca_cert + \
1969 ' exiting...' 2030 ' exiting...'
1970 return 2031 return
1971 server = HTTPSServer((host, port), TestPageHandler, options.cert, 2032 server = HTTPSServer((host, port), TestPageHandler, pem_cert_and_key,
1972 options.ssl_client_auth, options.ssl_client_ca, 2033 options.ssl_client_auth, options.ssl_client_ca,
1973 options.ssl_bulk_cipher, options.record_resume) 2034 options.ssl_bulk_cipher, options.record_resume)
1974 print 'HTTPS server started on %s:%d...' % (host, server.server_port) 2035 print 'HTTPS server started on %s:%d...' % (host, server.server_port)
1975 else: 2036 else:
1976 server = HTTPServer((host, port), TestPageHandler) 2037 server = HTTPServer((host, port), TestPageHandler)
1977 print 'HTTP server started on %s:%d...' % (host, server.server_port) 2038 print 'HTTP server started on %s:%d...' % (host, server.server_port)
1978 2039
1979 server.data_dir = MakeDataDir() 2040 server.data_dir = MakeDataDir()
1980 server.file_root_url = options.file_root_url 2041 server.file_root_url = options.file_root_url
1981 server_data['port'] = server.server_port 2042 server_data['port'] = server.server_port
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2041 else: 2102 else:
2042 fd = options.startup_pipe 2103 fd = options.startup_pipe
2043 startup_pipe = os.fdopen(fd, "w") 2104 startup_pipe = os.fdopen(fd, "w")
2044 # First write the data length as an unsigned 4-byte value. This 2105 # First write the data length as an unsigned 4-byte value. This
2045 # is _not_ using network byte ordering since the other end of the 2106 # is _not_ using network byte ordering since the other end of the
2046 # pipe is on the same machine. 2107 # pipe is on the same machine.
2047 startup_pipe.write(struct.pack('=L', server_data_len)) 2108 startup_pipe.write(struct.pack('=L', server_data_len))
2048 startup_pipe.write(server_data_json) 2109 startup_pipe.write(server_data_json)
2049 startup_pipe.close() 2110 startup_pipe.close()
2050 2111
2112 if ocsp_server is not None:
2113 ocsp_server.serve_forever_on_thread()
2114
2051 try: 2115 try:
2052 server.serve_forever() 2116 server.serve_forever()
2053 except KeyboardInterrupt: 2117 except KeyboardInterrupt:
2054 print 'shutting down server' 2118 print 'shutting down server'
2119 if ocsp_server is not None:
2120 ocsp_server.stop_serving()
2055 server.stop = True 2121 server.stop = True
2056 2122
2057 if __name__ == '__main__': 2123 if __name__ == '__main__':
2058 option_parser = optparse.OptionParser() 2124 option_parser = optparse.OptionParser()
2059 option_parser.add_option("-f", '--ftp', action='store_const', 2125 option_parser.add_option("-f", '--ftp', action='store_const',
2060 const=SERVER_FTP, default=SERVER_HTTP, 2126 const=SERVER_FTP, default=SERVER_HTTP,
2061 dest='server_type', 2127 dest='server_type',
2062 help='start up an FTP server.') 2128 help='start up an FTP server.')
2063 option_parser.add_option('', '--sync', action='store_const', 2129 option_parser.add_option('', '--sync', action='store_const',
2064 const=SERVER_SYNC, default=SERVER_HTTP, 2130 const=SERVER_SYNC, default=SERVER_HTTP,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 dest='host', 2197 dest='host',
2132 help='Hostname or IP upon which the server will ' 2198 help='Hostname or IP upon which the server will '
2133 'listen. Client connections will also only be ' 2199 'listen. Client connections will also only be '
2134 'allowed from this address.') 2200 'allowed from this address.')
2135 option_parser.add_option('', '--auth-token', dest='auth_token', 2201 option_parser.add_option('', '--auth-token', dest='auth_token',
2136 help='Specify the auth token which should be used' 2202 help='Specify the auth token which should be used'
2137 'in the authorization header for GData.') 2203 'in the authorization header for GData.')
2138 options, args = option_parser.parse_args() 2204 options, args = option_parser.parse_args()
2139 2205
2140 sys.exit(main(options, args)) 2206 sys.exit(main(options, args))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698