OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2013 The Chromium Authors. All rights reserved. | 2 # Copyright 2013 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/TCP/UDP/BASIC_AUTH_PROXY/WEBSOCKET server used for | 6 """This is a simple HTTP/FTP/TCP/UDP/BASIC_AUTH_PROXY/WEBSOCKET server used for |
7 testing Chrome. | 7 testing Chrome. |
8 | 8 |
9 It supports several test URLs, as specified by the handlers in TestPageHandler. | 9 It supports several test URLs, as specified by the handlers in TestPageHandler. |
10 By default, it listens on an ephemeral port and sends the port number back to | 10 By default, it listens on an ephemeral port and sends the port number back to |
(...skipping 1665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 # called by chunked handling function | 1676 # called by chunked handling function |
1677 def sendChunkHelp(self, chunk): | 1677 def sendChunkHelp(self, chunk): |
1678 # Each chunk consists of: chunk size (hex), CRLF, chunk body, CRLF | 1678 # Each chunk consists of: chunk size (hex), CRLF, chunk body, CRLF |
1679 self.wfile.write('%X\r\n' % len(chunk)) | 1679 self.wfile.write('%X\r\n' % len(chunk)) |
1680 self.wfile.write(chunk) | 1680 self.wfile.write(chunk) |
1681 self.wfile.write('\r\n') | 1681 self.wfile.write('\r\n') |
1682 | 1682 |
1683 | 1683 |
1684 class OCSPHandler(testserver_base.BasePageHandler): | 1684 class OCSPHandler(testserver_base.BasePageHandler): |
1685 def __init__(self, request, client_address, socket_server): | 1685 def __init__(self, request, client_address, socket_server): |
1686 handlers = [self.OCSPResponse] | 1686 handlers = [self.OCSPResponse, self.CaIssuersResponse] |
1687 self.ocsp_response = socket_server.ocsp_response | 1687 self.ocsp_response = socket_server.ocsp_response |
| 1688 self.ca_issuers_response = socket_server.ca_issuers_response |
1688 testserver_base.BasePageHandler.__init__(self, request, client_address, | 1689 testserver_base.BasePageHandler.__init__(self, request, client_address, |
1689 socket_server, [], handlers, [], | 1690 socket_server, [], handlers, [], |
1690 handlers, []) | 1691 handlers, []) |
1691 | 1692 |
1692 def OCSPResponse(self): | 1693 def OCSPResponse(self): |
| 1694 if not self._ShouldHandleRequest("/ocsp"): |
| 1695 return False |
| 1696 print 'handling ocsp request' |
1693 self.send_response(200) | 1697 self.send_response(200) |
1694 self.send_header('Content-Type', 'application/ocsp-response') | 1698 self.send_header('Content-Type', 'application/ocsp-response') |
1695 self.send_header('Content-Length', str(len(self.ocsp_response))) | 1699 self.send_header('Content-Length', str(len(self.ocsp_response))) |
1696 self.end_headers() | 1700 self.end_headers() |
1697 | 1701 |
1698 self.wfile.write(self.ocsp_response) | 1702 self.wfile.write(self.ocsp_response) |
1699 | 1703 |
| 1704 def CaIssuersResponse(self): |
| 1705 if not self._ShouldHandleRequest("/ca_issuers"): |
| 1706 return False |
| 1707 print 'handling ca_issuers request' |
| 1708 self.send_response(200) |
| 1709 self.send_header('Content-Type', 'application/pkix-cert') |
| 1710 self.send_header('Content-Length', str(len(self.ca_issuers_response))) |
| 1711 self.end_headers() |
| 1712 |
| 1713 self.wfile.write(self.ca_issuers_response) |
| 1714 |
1700 | 1715 |
1701 class TCPEchoHandler(SocketServer.BaseRequestHandler): | 1716 class TCPEchoHandler(SocketServer.BaseRequestHandler): |
1702 """The RequestHandler class for TCP echo server. | 1717 """The RequestHandler class for TCP echo server. |
1703 | 1718 |
1704 It is instantiated once per connection to the server, and overrides the | 1719 It is instantiated once per connection to the server, and overrides the |
1705 handle() method to implement communication to the client. | 1720 handle() method to implement communication to the client. |
1706 """ | 1721 """ |
1707 | 1722 |
1708 def handle(self): | 1723 def handle(self): |
1709 """Handles the request from the client and constructs a response.""" | 1724 """Handles the request from the client and constructs a response.""" |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1891 if self.options.server_type == SERVER_HTTP: | 1906 if self.options.server_type == SERVER_HTTP: |
1892 if self.options.https: | 1907 if self.options.https: |
1893 pem_cert_and_key = None | 1908 pem_cert_and_key = None |
1894 ocsp_der = None | 1909 ocsp_der = None |
1895 if self.options.cert_and_key_file: | 1910 if self.options.cert_and_key_file: |
1896 if not os.path.isfile(self.options.cert_and_key_file): | 1911 if not os.path.isfile(self.options.cert_and_key_file): |
1897 raise testserver_base.OptionError( | 1912 raise testserver_base.OptionError( |
1898 'specified server cert file not found: ' + | 1913 'specified server cert file not found: ' + |
1899 self.options.cert_and_key_file + ' exiting...') | 1914 self.options.cert_and_key_file + ' exiting...') |
1900 pem_cert_and_key = file(self.options.cert_and_key_file, 'r').read() | 1915 pem_cert_and_key = file(self.options.cert_and_key_file, 'r').read() |
| 1916 elif self.options.aia_intermediate: |
| 1917 self.__ocsp_server = OCSPServer((host, 0), OCSPHandler) |
| 1918 print ('AIA server started on %s:%d...' % |
| 1919 (host, self.__ocsp_server.server_port)) |
| 1920 |
| 1921 (pem_cert_and_key, intermediate_cert_der) = \ |
| 1922 minica.GenerateCertKeyAndIntermediate( |
| 1923 subject = "127.0.0.1", |
| 1924 ca_issuers_url = ("http://%s:%d/ca_issuers" % |
| 1925 (host, self.__ocsp_server.server_port)), |
| 1926 serial = self.options.cert_serial) |
| 1927 |
| 1928 self.__ocsp_server.ocsp_response = None |
| 1929 self.__ocsp_server.ca_issuers_response = intermediate_cert_der |
1901 else: | 1930 else: |
1902 # generate a new certificate and run an OCSP server for it. | 1931 # generate a new certificate and run an OCSP server for it. |
1903 self.__ocsp_server = OCSPServer((host, 0), OCSPHandler) | 1932 self.__ocsp_server = OCSPServer((host, 0), OCSPHandler) |
1904 print ('OCSP server started on %s:%d...' % | 1933 print ('OCSP server started on %s:%d...' % |
1905 (host, self.__ocsp_server.server_port)) | 1934 (host, self.__ocsp_server.server_port)) |
1906 | 1935 |
1907 ocsp_states = list() | 1936 ocsp_states = list() |
1908 for ocsp_state_arg in self.options.ocsp.split(':'): | 1937 for ocsp_state_arg in self.options.ocsp.split(':'): |
1909 if ocsp_state_arg == 'ok': | 1938 if ocsp_state_arg == 'ok': |
1910 ocsp_state = minica.OCSP_STATE_GOOD | 1939 ocsp_state = minica.OCSP_STATE_GOOD |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1969 ocsp_states = ocsp_states, | 1998 ocsp_states = ocsp_states, |
1970 ocsp_dates = ocsp_dates, | 1999 ocsp_dates = ocsp_dates, |
1971 ocsp_produced = ocsp_produced, | 2000 ocsp_produced = ocsp_produced, |
1972 serial = self.options.cert_serial) | 2001 serial = self.options.cert_serial) |
1973 | 2002 |
1974 if self.options.ocsp_server_unavailable: | 2003 if self.options.ocsp_server_unavailable: |
1975 # SEQUENCE containing ENUMERATED with value 3 (tryLater). | 2004 # SEQUENCE containing ENUMERATED with value 3 (tryLater). |
1976 self.__ocsp_server.ocsp_response = '30030a0103'.decode('hex') | 2005 self.__ocsp_server.ocsp_response = '30030a0103'.decode('hex') |
1977 else: | 2006 else: |
1978 self.__ocsp_server.ocsp_response = ocsp_der | 2007 self.__ocsp_server.ocsp_response = ocsp_der |
| 2008 self.__ocsp_server.ca_issuers_response = None |
1979 | 2009 |
1980 for ca_cert in self.options.ssl_client_ca: | 2010 for ca_cert in self.options.ssl_client_ca: |
1981 if not os.path.isfile(ca_cert): | 2011 if not os.path.isfile(ca_cert): |
1982 raise testserver_base.OptionError( | 2012 raise testserver_base.OptionError( |
1983 'specified trusted client CA file not found: ' + ca_cert + | 2013 'specified trusted client CA file not found: ' + ca_cert + |
1984 ' exiting...') | 2014 ' exiting...') |
1985 | 2015 |
1986 stapled_ocsp_response = None | 2016 stapled_ocsp_response = None |
1987 if self.options.staple_ocsp_response: | 2017 if self.options.staple_ocsp_response: |
1988 stapled_ocsp_response = ocsp_der | 2018 stapled_ocsp_response = ocsp_der |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2130 dest='server_type', | 2160 dest='server_type', |
2131 help='start up a WebSocket server.') | 2161 help='start up a WebSocket server.') |
2132 self.option_parser.add_option('--https', action='store_true', | 2162 self.option_parser.add_option('--https', action='store_true', |
2133 dest='https', help='Specify that https ' | 2163 dest='https', help='Specify that https ' |
2134 'should be used.') | 2164 'should be used.') |
2135 self.option_parser.add_option('--cert-and-key-file', | 2165 self.option_parser.add_option('--cert-and-key-file', |
2136 dest='cert_and_key_file', help='specify the ' | 2166 dest='cert_and_key_file', help='specify the ' |
2137 'path to the file containing the certificate ' | 2167 'path to the file containing the certificate ' |
2138 'and private key for the server in PEM ' | 2168 'and private key for the server in PEM ' |
2139 'format') | 2169 'format') |
| 2170 self.option_parser.add_option('--aia-intermediate', action='store_true', |
| 2171 dest='aia_intermediate', |
| 2172 help='generate a certificate chain that ' |
| 2173 'requires AIA cert fetching, and run a ' |
| 2174 'server to respond to the AIA request.') |
2140 self.option_parser.add_option('--ocsp', dest='ocsp', default='ok', | 2175 self.option_parser.add_option('--ocsp', dest='ocsp', default='ok', |
2141 help='The type of OCSP response generated ' | 2176 help='The type of OCSP response generated ' |
2142 'for the automatically generated ' | 2177 'for the automatically generated ' |
2143 'certificate. One of [ok,revoked,invalid]') | 2178 'certificate. One of [ok,revoked,invalid]') |
2144 self.option_parser.add_option('--ocsp-date', dest='ocsp_date', | 2179 self.option_parser.add_option('--ocsp-date', dest='ocsp_date', |
2145 default='valid', help='The validity of the ' | 2180 default='valid', help='The validity of the ' |
2146 'range between thisUpdate and nextUpdate') | 2181 'range between thisUpdate and nextUpdate') |
2147 self.option_parser.add_option('--ocsp-produced', dest='ocsp_produced', | 2182 self.option_parser.add_option('--ocsp-produced', dest='ocsp_produced', |
2148 default='valid', help='producedAt relative ' | 2183 default='valid', help='producedAt relative ' |
2149 'to certificate expiry') | 2184 'to certificate expiry') |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2261 'an anonymous user.') | 2296 'an anonymous user.') |
2262 self.option_parser.add_option('--disable-channel-id', action='store_true') | 2297 self.option_parser.add_option('--disable-channel-id', action='store_true') |
2263 self.option_parser.add_option('--disable-extended-master-secret', | 2298 self.option_parser.add_option('--disable-extended-master-secret', |
2264 action='store_true') | 2299 action='store_true') |
2265 self.option_parser.add_option('--token-binding-params', action='append', | 2300 self.option_parser.add_option('--token-binding-params', action='append', |
2266 default=[], type='int') | 2301 default=[], type='int') |
2267 | 2302 |
2268 | 2303 |
2269 if __name__ == '__main__': | 2304 if __name__ == '__main__': |
2270 sys.exit(ServerRunner().main()) | 2305 sys.exit(ServerRunner().main()) |
OLD | NEW |