Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/net/certificate_error_reporter.h" | 5 #include "chrome/browser/net/certificate_error_reporter.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 DCHECK(!upload_url.is_empty()); | 30 DCHECK(!upload_url.is_empty()); |
| 31 } | 31 } |
| 32 | 32 |
| 33 CertificateErrorReporter::~CertificateErrorReporter() { | 33 CertificateErrorReporter::~CertificateErrorReporter() { |
| 34 STLDeleteElements(&inflight_requests_); | 34 STLDeleteElements(&inflight_requests_); |
| 35 } | 35 } |
| 36 | 36 |
| 37 void CertificateErrorReporter::SendReport(ReportType type, | 37 void CertificateErrorReporter::SendReport(ReportType type, |
| 38 const std::string& hostname, | 38 const std::string& hostname, |
| 39 const net::SSLInfo& ssl_info) { | 39 const net::SSLInfo& ssl_info) { |
| 40 CertLoggerRequest request; | 40 CertLoggerRequest report; |
| 41 std::string out; | 41 BuildReport(hostname, ssl_info, &report); |
| 42 | 42 SendReport(type, report); |
| 43 BuildReport(hostname, ssl_info, &request); | |
| 44 | |
| 45 switch (type) { | |
| 46 case REPORT_TYPE_PINNING_VIOLATION: | |
| 47 SendCertLoggerRequest(request); | |
| 48 break; | |
| 49 case REPORT_TYPE_EXTENDED_REPORTING: | |
| 50 // TODO(estark): Encrypt the report if not sending over HTTPS | |
| 51 DCHECK(upload_url_.SchemeIsSecure()); | |
| 52 SendCertLoggerRequest(request); | |
| 53 break; | |
| 54 default: | |
| 55 NOTREACHED(); | |
| 56 } | |
| 57 } | 43 } |
| 58 | 44 |
| 59 void CertificateErrorReporter::OnResponseStarted(net::URLRequest* request) { | 45 void CertificateErrorReporter::SendReport(ReportType type, |
| 60 const net::URLRequestStatus& status(request->status()); | 46 const CertLoggerRequest& report) { |
| 61 if (!status.is_success()) { | 47 if (type == REPORT_TYPE_EXTENDED_REPORTING) { |
| 62 LOG(WARNING) << "Certificate upload failed" | 48 // TODO(estark): Encrypt the report if not sending over HTTPS |
|
Ryan Sleevi
2015/04/16 01:44:10
FWIW, a tracking bug for this is handy, even if it
| |
| 63 << " status:" << status.status() | 49 DCHECK(upload_url_.SchemeIsSecure()); |
| 64 << " error:" << status.error(); | |
| 65 } else if (request->GetResponseCode() != 200) { | |
| 66 LOG(WARNING) << "Certificate upload HTTP status: " | |
| 67 << request->GetResponseCode(); | |
| 68 } | |
| 69 RequestComplete(request); | |
| 70 } | 50 } |
| 71 | 51 |
| 72 void CertificateErrorReporter::OnReadCompleted(net::URLRequest* request, | 52 std::string serialized_report; |
| 73 int bytes_read) { | 53 report.SerializeToString(&serialized_report); |
| 74 } | |
| 75 | |
| 76 scoped_ptr<net::URLRequest> CertificateErrorReporter::CreateURLRequest( | |
| 77 net::URLRequestContext* context) { | |
| 78 scoped_ptr<net::URLRequest> request = | |
| 79 context->CreateRequest(upload_url_, net::DEFAULT_PRIORITY, this); | |
| 80 if (cookies_preference_ != SEND_COOKIES) { | |
| 81 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | |
| 82 net::LOAD_DO_NOT_SAVE_COOKIES); | |
| 83 } | |
| 84 return request.Pass(); | |
| 85 } | |
| 86 | |
| 87 void CertificateErrorReporter::SendCertLoggerRequest( | |
| 88 const CertLoggerRequest& request) { | |
| 89 std::string serialized_request; | |
| 90 request.SerializeToString(&serialized_request); | |
| 91 | 54 |
| 92 scoped_ptr<net::URLRequest> url_request = CreateURLRequest(request_context_); | 55 scoped_ptr<net::URLRequest> url_request = CreateURLRequest(request_context_); |
| 93 url_request->set_method("POST"); | 56 url_request->set_method("POST"); |
| 94 | 57 |
| 95 scoped_ptr<net::UploadElementReader> reader( | 58 scoped_ptr<net::UploadElementReader> reader( |
| 96 net::UploadOwnedBytesElementReader::CreateWithString(serialized_request)); | 59 net::UploadOwnedBytesElementReader::CreateWithString(serialized_report)); |
| 97 url_request->set_upload( | 60 url_request->set_upload( |
| 98 net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0)); | 61 net::ElementsUploadDataStream::CreateWithReader(reader.Pass(), 0)); |
| 99 | 62 |
| 100 net::HttpRequestHeaders headers; | 63 net::HttpRequestHeaders headers; |
| 101 headers.SetHeader(net::HttpRequestHeaders::kContentType, | 64 headers.SetHeader(net::HttpRequestHeaders::kContentType, |
| 102 "x-application/chrome-fraudulent-cert-report"); | 65 "x-application/chrome-fraudulent-cert-report"); |
| 103 url_request->SetExtraRequestHeaders(headers); | 66 url_request->SetExtraRequestHeaders(headers); |
| 104 | 67 |
| 105 net::URLRequest* raw_url_request = url_request.get(); | 68 net::URLRequest* raw_url_request = url_request.get(); |
| 106 inflight_requests_.insert(url_request.release()); | 69 inflight_requests_.insert(url_request.release()); |
| 107 raw_url_request->Start(); | 70 raw_url_request->Start(); |
| 108 } | 71 } |
| 109 | 72 |
| 73 void CertificateErrorReporter::OnResponseStarted(net::URLRequest* request) { | |
| 74 const net::URLRequestStatus& status(request->status()); | |
| 75 if (!status.is_success()) { | |
| 76 LOG(WARNING) << "Certificate upload failed" | |
| 77 << " status:" << status.status() | |
| 78 << " error:" << status.error(); | |
| 79 } else if (request->GetResponseCode() != 200) { | |
| 80 LOG(WARNING) << "Certificate upload HTTP status: " | |
| 81 << request->GetResponseCode(); | |
| 82 } | |
| 83 RequestComplete(request); | |
| 84 } | |
| 85 | |
| 86 void CertificateErrorReporter::OnReadCompleted(net::URLRequest* request, | |
| 87 int bytes_read) { | |
| 88 } | |
| 89 | |
| 90 void CertificateErrorReporter::BuildReport(const std::string& hostname, | |
| 91 const net::SSLInfo& ssl_info, | |
| 92 uint32 validation_result, | |
| 93 uint32 interstitial_reason, | |
| 94 ProceedDecision proceed_decision, | |
| 95 Overridable overridable, | |
| 96 CertLoggerRequest* out_request) { | |
| 97 BuildReport(hostname, ssl_info, out_request); | |
| 98 out_request->mutable_interstitial_info()->set_validation_result( | |
| 99 validation_result); | |
| 100 out_request->mutable_interstitial_info()->set_interstitial_reason( | |
| 101 interstitial_reason); | |
| 102 out_request->mutable_interstitial_info()->set_user_proceeded( | |
| 103 proceed_decision == USER_PROCEEDED); | |
| 104 out_request->mutable_interstitial_info()->set_overridable(overridable == | |
| 105 OVERRIDABLE); | |
| 106 } | |
| 107 | |
| 110 void CertificateErrorReporter::BuildReport(const std::string& hostname, | 108 void CertificateErrorReporter::BuildReport(const std::string& hostname, |
| 111 const net::SSLInfo& ssl_info, | 109 const net::SSLInfo& ssl_info, |
| 112 CertLoggerRequest* out_request) { | 110 CertLoggerRequest* out_request) { |
| 113 base::Time now = base::Time::Now(); | 111 base::Time now = base::Time::Now(); |
| 114 out_request->set_time_usec(now.ToInternalValue()); | 112 out_request->set_time_usec(now.ToInternalValue()); |
| 115 out_request->set_hostname(hostname); | 113 out_request->set_hostname(hostname); |
| 116 | 114 |
| 117 std::vector<std::string> pem_encoded_chain; | 115 std::vector<std::string> pem_encoded_chain; |
| 118 if (!ssl_info.cert->GetPEMEncodedChain(&pem_encoded_chain)) | 116 if (!ssl_info.cert->GetPEMEncodedChain(&pem_encoded_chain)) |
| 119 LOG(ERROR) << "Could not get PEM encoded chain."; | 117 LOG(ERROR) << "Could not get PEM encoded chain."; |
| 120 | 118 |
| 121 std::string* cert_chain = out_request->mutable_cert_chain(); | 119 std::string* cert_chain = out_request->mutable_cert_chain(); |
| 122 for (size_t i = 0; i < pem_encoded_chain.size(); ++i) | 120 for (size_t i = 0; i < pem_encoded_chain.size(); ++i) |
| 123 *cert_chain += pem_encoded_chain[i]; | 121 *cert_chain += pem_encoded_chain[i]; |
| 124 | 122 |
| 125 out_request->add_pin(ssl_info.pinning_failure_log); | 123 out_request->add_pin(ssl_info.pinning_failure_log); |
| 126 } | 124 } |
| 127 | 125 |
| 126 scoped_ptr<net::URLRequest> CertificateErrorReporter::CreateURLRequest( | |
| 127 net::URLRequestContext* context) { | |
| 128 scoped_ptr<net::URLRequest> request = | |
| 129 context->CreateRequest(upload_url_, net::DEFAULT_PRIORITY, this); | |
| 130 if (cookies_preference_ != SEND_COOKIES) { | |
| 131 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | |
| 132 net::LOAD_DO_NOT_SAVE_COOKIES); | |
| 133 } | |
| 134 return request.Pass(); | |
| 135 } | |
| 136 | |
| 137 void CertificateErrorReporter::SendCertLoggerRequest( | |
| 138 const CertLoggerRequest& request) { | |
| 139 } | |
|
Ryan Sleevi
2015/04/16 01:44:10
Dead code? Broken?
| |
| 140 | |
| 128 void CertificateErrorReporter::RequestComplete(net::URLRequest* request) { | 141 void CertificateErrorReporter::RequestComplete(net::URLRequest* request) { |
| 129 std::set<net::URLRequest*>::iterator i = inflight_requests_.find(request); | 142 std::set<net::URLRequest*>::iterator i = inflight_requests_.find(request); |
| 130 DCHECK(i != inflight_requests_.end()); | 143 DCHECK(i != inflight_requests_.end()); |
| 131 scoped_ptr<net::URLRequest> url_request(*i); | 144 scoped_ptr<net::URLRequest> url_request(*i); |
| 132 inflight_requests_.erase(i); | 145 inflight_requests_.erase(i); |
| 133 } | 146 } |
| 134 | 147 |
| 135 } // namespace chrome_browser_net | 148 } // namespace chrome_browser_net |
| OLD | NEW |