1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/login/test/https_forwarder.h"
9 #include "base/base_paths.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/path_service.h"
13 #include "base/values.h"
14 #include "net/cert/test_root_certs.h"
15 #include "net/cert/x509_certificate.h"
16 #include "net/test/python_utils.h"
17 #include "net/test/spawned_test_server/base_test_server.h"
18 #include "net/test/spawned_test_server/local_test_server.h"
19 #include "url/third_party/mozilla/url_parse.h"
20 #include "url/url_canon.h"
26 // The root certificate used by net/tools/testserver/minica.py.
27 const char kMinicaRootCert
[] =
28 "-----BEGIN CERTIFICATE-----\n"
29 "MIIB0TCCATqgAwIBAgIBATANBgkqhkiG9w0BAQUFADAVMRMwEQYDVQQDEwpUZXN0aW5nIENBMB"
30 "4XDTEwMDEwMTA2MDAwMFoXDTMyMTIwMTA2MDAwMFowFTETMBEGA1UEAxMKVGVzdGluZyBDQTCB"
31 "nTANBgkqhkiG9w0BAQEFAAOBiwAwgYcCgYEApxmY8pML/nPQMah/Ez0vN47u7tUqd+RND8n/bw"
32 "f/Msvz2pmd5O1lgyr8sIB/mHh1BlOdJYoM48LHeWdlMJmpA0qbEVqHbDmoxOTtSs0MZAlZRvs5"
33 "7utHoHBNuwGKz0jDocS4lfxAn7SjQKmGsa/EVRmrnspHwwGFx3HGSqXs8H0CAQOjMzAxMBIGA1"
34 "UdEwEB/wQIMAYBAf8CAQAwGwYDVR0gAQEABBEwDzANBgsrBgEEAdZ5AgHODzANBgkqhkiG9w0B"
35 "AQUFAAOBgQA/STb40A6D+93jMfLGQzXc997IsaJZdoPt7tYa8PqGJBL62EiTj+erd/H5pDZx/2"
36 "/bcpOG4m9J56ygwOohbllw2TM+oeEd8syzV6X+1SIPnGI56JRrm3UXcHYx1Rq5loM9WKAiz/Wm"
37 "IWmskljsEQ7+542pq0pkHjs8nuXovSkUYA==\n"
38 "-----END CERTIFICATE-----";
42 // A net::LocalTestServer that handles the actual forwarding to another server.
43 // Requires that the root certificate used by minica.py be marked as trusted
45 class ForwardingServer
: public net::LocalTestServer
{
47 ForwardingServer(const std::string
& ssl_host
, const GURL
& forward_target
);
49 // net::LocalTestServer:
50 bool SetPythonPath() const override
;
51 bool GetTestServerPath(base::FilePath
* testserver_path
) const override
;
52 bool GenerateAdditionalArguments(
53 base::DictionaryValue
* arguments
) const override
;
56 const std::string ssl_host_
;
57 const GURL forward_target_
;
59 DISALLOW_COPY_AND_ASSIGN(ForwardingServer
);
62 ForwardingServer::ForwardingServer(const std::string
& ssl_host
,
63 const GURL
& forward_target
)
64 : net::LocalTestServer(net::LocalTestServer::TYPE_HTTPS
,
65 SSLOptions(SSLOptions::CERT_AUTO
),
68 forward_target_(forward_target
) {
71 bool ForwardingServer::SetPythonPath() const {
72 if (!net::LocalTestServer::SetPythonPath())
75 base::FilePath net_testserver_path
;
76 if (!LocalTestServer::GetTestServerPath(&net_testserver_path
))
78 AppendToPythonPath(net_testserver_path
.DirName());
83 bool ForwardingServer::GetTestServerPath(
84 base::FilePath
* testserver_path
) const {
85 base::FilePath source_root_dir
;
86 if (!PathService::Get(base::DIR_SOURCE_ROOT
, &source_root_dir
))
89 *testserver_path
= source_root_dir
.Append("chrome")
94 .Append("https_forwarder.py");
98 bool ForwardingServer::GenerateAdditionalArguments(
99 base::DictionaryValue
* arguments
) const {
100 base::FilePath source_root_dir
;
101 if (!net::LocalTestServer::GenerateAdditionalArguments(arguments
) ||
102 !PathService::Get(base::DIR_SOURCE_ROOT
, &source_root_dir
))
105 arguments
->SetString("ssl-host", ssl_host_
);
106 arguments
->SetString("forward-target", forward_target_
.spec());
111 HTTPSForwarder::HTTPSForwarder() {
114 HTTPSForwarder::~HTTPSForwarder() {
117 GURL
HTTPSForwarder::GetURLForSSLHost(const std::string
& path
) const {
118 CHECK(forwarding_server_
);
119 url::Replacements
<char> replacements
;
120 replacements
.SetHost(ssl_host_
.c_str(), url::Component(0, ssl_host_
.size()));
121 return forwarding_server_
->GetURL(path
).ReplaceComponents(replacements
);
124 bool HTTPSForwarder::Initialize(const std::string
& ssl_host
,
125 const GURL
& forward_target
) {
126 // Mark the root certificate used by minica.py as trusted. This will be used
127 // by the Python part of the HTTPSForwarder to generate a certificate for
129 net::TestRootCerts
* root_certs
= net::TestRootCerts::GetInstance();
132 net::CertificateList certs
=
133 net::X509Certificate::CreateCertificateListFromBytes(
134 kMinicaRootCert
, strlen(kMinicaRootCert
),
135 net::X509Certificate::FORMAT_AUTO
);
136 if (certs
.size() != 1)
138 root_certs
->Add(certs
.front().get());
140 ssl_host_
= ssl_host
;
141 forwarding_server_
.reset(new ForwardingServer(ssl_host
, forward_target
));
142 return forwarding_server_
->Start();
145 } // namespace chromeos