| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #include "chrome/browser/safe_browsing/certificate_reporting_service.h" | 4 #include "chrome/browser/safe_browsing/certificate_reporting_service.h" |
| 5 | 5 |
| 6 #include "base/bind_helpers.h" | 6 #include "base/bind_helpers.h" |
| 7 #include "base/metrics/histogram_macros.h" | 7 #include "base/metrics/histogram_macros.h" |
| 8 #include "base/metrics/sparse_histogram.h" | 8 #include "base/metrics/sparse_histogram.h" |
| 9 #include "base/time/clock.h" | 9 #include "base/time/clock.h" |
| 10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 const CertificateReportingService::Report& item2) { | 28 const CertificateReportingService::Report& item2) { |
| 29 return item1.creation_time > item2.creation_time; | 29 return item1.creation_time > item2.creation_time; |
| 30 } | 30 } |
| 31 | 31 |
| 32 // Records an UMA histogram of the net errors when certificate reports | 32 // Records an UMA histogram of the net errors when certificate reports |
| 33 // fail to send. | 33 // fail to send. |
| 34 void RecordUMAOnFailure(int net_error) { | 34 void RecordUMAOnFailure(int net_error) { |
| 35 UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.CertificateErrorReportFailure", -net_error); | 35 UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.CertificateErrorReportFailure", -net_error); |
| 36 } | 36 } |
| 37 | 37 |
| 38 void CleanupOnIOThread( |
| 39 std::unique_ptr<CertificateReportingService::Reporter> reporter) { |
| 40 reporter.reset(); |
| 41 } |
| 42 |
| 38 } // namespace | 43 } // namespace |
| 39 | 44 |
| 40 CertificateReportingService::BoundedReportList::BoundedReportList( | 45 CertificateReportingService::BoundedReportList::BoundedReportList( |
| 41 size_t max_size) | 46 size_t max_size) |
| 42 : max_size_(max_size) { | 47 : max_size_(max_size) { |
| 43 CHECK(max_size <= 20) | 48 CHECK(max_size <= 20) |
| 44 << "Current implementation is not efficient for a large list."; | 49 << "Current implementation is not efficient for a large list."; |
| 45 DCHECK(thread_checker_.CalledOnValidThread()); | 50 DCHECK(thread_checker_.CalledOnValidThread()); |
| 46 } | 51 } |
| 47 | 52 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 CertificateReportingService::CertificateReportingService( | 162 CertificateReportingService::CertificateReportingService( |
| 158 safe_browsing::SafeBrowsingService* safe_browsing_service, | 163 safe_browsing::SafeBrowsingService* safe_browsing_service, |
| 159 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, | 164 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, |
| 160 Profile* profile, | 165 Profile* profile, |
| 161 uint8_t server_public_key[/* 32 */], | 166 uint8_t server_public_key[/* 32 */], |
| 162 uint32_t server_public_key_version, | 167 uint32_t server_public_key_version, |
| 163 size_t max_queued_report_count, | 168 size_t max_queued_report_count, |
| 164 base::TimeDelta max_report_age, | 169 base::TimeDelta max_report_age, |
| 165 base::Clock* clock) | 170 base::Clock* clock) |
| 166 : pref_service_(*profile->GetPrefs()), | 171 : pref_service_(*profile->GetPrefs()), |
| 167 enabled_(true), | |
| 168 url_request_context_(nullptr), | 172 url_request_context_(nullptr), |
| 169 max_queued_report_count_(max_queued_report_count), | 173 max_queued_report_count_(max_queued_report_count), |
| 170 max_report_age_(max_report_age), | 174 max_report_age_(max_report_age), |
| 171 clock_(clock), | 175 clock_(clock), |
| 172 server_public_key_(server_public_key), | 176 server_public_key_(server_public_key), |
| 173 server_public_key_version_(server_public_key_version) { | 177 server_public_key_version_(server_public_key_version) { |
| 174 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 178 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 175 DCHECK(clock_); | 179 DCHECK(clock_); |
| 176 // Subscribe to SafeBrowsing shutdown notifications. | 180 // Subscribe to SafeBrowsing shutdown notifications. |
| 177 safe_browsing_service_shutdown_subscription_ = | 181 safe_browsing_service_shutdown_subscription_ = |
| 178 safe_browsing_service->RegisterShutdownCallback(base::Bind( | 182 safe_browsing_service->RegisterShutdownCallback(base::Bind( |
| 179 &CertificateReportingService::Shutdown, base::Unretained(this))); | 183 &CertificateReportingService::Shutdown, base::Unretained(this))); |
| 180 | 184 |
| 181 // Subscribe to SafeBrowsing preference change notifications. | 185 // Subscribe to SafeBrowsing preference change notifications. |
| 182 safe_browsing_state_subscription_ = | 186 safe_browsing_state_subscription_ = |
| 183 safe_browsing_service->RegisterStateCallback( | 187 safe_browsing_service->RegisterStateCallback( |
| 184 base::Bind(&CertificateReportingService::OnPreferenceChanged, | 188 base::Bind(&CertificateReportingService::OnPreferenceChanged, |
| 185 base::Unretained(this))); | 189 base::Unretained(this))); |
| 186 | 190 |
| 187 content::BrowserThread::PostTask( | 191 content::BrowserThread::PostTask( |
| 188 content::BrowserThread::IO, FROM_HERE, | 192 content::BrowserThread::IO, FROM_HERE, |
| 189 base::Bind(&CertificateReportingService::InitializeOnIOThread, | 193 base::Bind(&CertificateReportingService::InitializeOnIOThread, |
| 190 base::Unretained(this), enabled_, url_request_context_getter, | 194 base::Unretained(this), true, url_request_context_getter, |
| 191 max_queued_report_count_, max_report_age_, clock_, | 195 max_queued_report_count_, max_report_age_, clock_, |
| 192 server_public_key_, server_public_key_version_)); | 196 server_public_key_, server_public_key_version_)); |
| 193 } | 197 } |
| 194 | 198 |
| 195 CertificateReportingService::~CertificateReportingService() { | 199 CertificateReportingService::~CertificateReportingService() { |
| 196 DCHECK(!reporter_); | 200 DCHECK(!reporter_); |
| 197 } | 201 } |
| 198 | 202 |
| 199 void CertificateReportingService::Shutdown() { | 203 void CertificateReportingService::Shutdown() { |
| 200 // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once | 204 // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once |
| 201 // when all KeyedServices shut down. All calls after the first one are no-op. | 205 // when all KeyedServices shut down. All calls after the first one are no-op. |
| 202 enabled_ = false; | 206 url_request_context_ = nullptr; |
| 203 Reset(); | 207 content::BrowserThread::PostTask( |
| 208 content::BrowserThread::IO, FROM_HERE, |
| 209 base::Bind(&CleanupOnIOThread, base::Passed(std::move(reporter_)))); |
| 204 } | 210 } |
| 205 | 211 |
| 206 void CertificateReportingService::Send(const std::string& serialized_report) { | 212 void CertificateReportingService::Send(const std::string& serialized_report) { |
| 207 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 213 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 208 if (!reporter_) { | 214 if (!reporter_) { |
| 209 return; | 215 return; |
| 210 } | 216 } |
| 211 content::BrowserThread::PostTask( | 217 content::BrowserThread::PostTask( |
| 212 content::BrowserThread::IO, FROM_HERE, | 218 content::BrowserThread::IO, FROM_HERE, |
| 213 base::Bind(&CertificateReportingService::Reporter::Send, | 219 base::Bind(&CertificateReportingService::Reporter::Send, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 236 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 242 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 237 DCHECK(!url_request_context_); | 243 DCHECK(!url_request_context_); |
| 238 url_request_context_ = url_request_context_getter->GetURLRequestContext(); | 244 url_request_context_ = url_request_context_getter->GetURLRequestContext(); |
| 239 ResetOnIOThread(enabled, url_request_context_, max_queued_report_count, | 245 ResetOnIOThread(enabled, url_request_context_, max_queued_report_count, |
| 240 max_report_age, clock, server_public_key, | 246 max_report_age, clock, server_public_key, |
| 241 server_public_key_version); | 247 server_public_key_version); |
| 242 } | 248 } |
| 243 | 249 |
| 244 void CertificateReportingService::SetEnabled(bool enabled) { | 250 void CertificateReportingService::SetEnabled(bool enabled) { |
| 245 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 251 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 246 enabled_ = enabled; | 252 // Don't reset if the service is already shut down. |
| 247 Reset(); | 253 if (!url_request_context_) |
| 254 return; |
| 255 |
| 256 content::BrowserThread::PostTask( |
| 257 content::BrowserThread::IO, FROM_HERE, |
| 258 base::Bind(&CertificateReportingService::ResetOnIOThread, |
| 259 base::Unretained(this), enabled, url_request_context_, |
| 260 max_queued_report_count_, max_report_age_, clock_, |
| 261 server_public_key_, server_public_key_version_)); |
| 248 } | 262 } |
| 249 | 263 |
| 250 CertificateReportingService::Reporter* | 264 CertificateReportingService::Reporter* |
| 251 CertificateReportingService::GetReporterForTesting() const { | 265 CertificateReportingService::GetReporterForTesting() const { |
| 252 return reporter_.get(); | 266 return reporter_.get(); |
| 253 } | 267 } |
| 254 | 268 |
| 255 // static | 269 // static |
| 256 GURL CertificateReportingService::GetReportingURLForTesting() { | 270 GURL CertificateReportingService::GetReportingURLForTesting() { |
| 257 return GURL(kExtendedReportingUploadUrl); | 271 return GURL(kExtendedReportingUploadUrl); |
| 258 } | 272 } |
| 259 | 273 |
| 260 void CertificateReportingService::Reset() { | |
| 261 content::BrowserThread::PostTask( | |
| 262 content::BrowserThread::IO, FROM_HERE, | |
| 263 base::Bind(&CertificateReportingService::ResetOnIOThread, | |
| 264 base::Unretained(this), enabled_, url_request_context_, | |
| 265 max_queued_report_count_, max_report_age_, clock_, | |
| 266 server_public_key_, server_public_key_version_)); | |
| 267 } | |
| 268 | |
| 269 void CertificateReportingService::ResetOnIOThread( | 274 void CertificateReportingService::ResetOnIOThread( |
| 270 bool enabled, | 275 bool enabled, |
| 271 net::URLRequestContext* url_request_context, | 276 net::URLRequestContext* url_request_context, |
| 272 size_t max_queued_report_count, | 277 size_t max_queued_report_count, |
| 273 base::TimeDelta max_report_age, | 278 base::TimeDelta max_report_age, |
| 274 base::Clock* clock, | 279 base::Clock* clock, |
| 275 uint8_t* const server_public_key, | 280 uint8_t* const server_public_key, |
| 276 uint32_t server_public_key_version) { | 281 uint32_t server_public_key_version) { |
| 277 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 282 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 278 // url_request_context_ is null during shutdown. | 283 // url_request_context_ is null during shutdown. |
| 279 if (!enabled || !url_request_context) { | 284 if (!enabled || !url_request_context) { |
| 280 reporter_.reset(nullptr); | 285 reporter_.reset(); |
| 281 return; | 286 return; |
| 282 } | 287 } |
| 283 std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter; | 288 std::unique_ptr<certificate_reporting::ErrorReporter> error_reporter; |
| 284 if (server_public_key) { | 289 if (server_public_key) { |
| 285 // Only used in tests. | 290 // Only used in tests. |
| 286 std::unique_ptr<net::ReportSender> report_sender(new net::ReportSender( | 291 std::unique_ptr<net::ReportSender> report_sender(new net::ReportSender( |
| 287 url_request_context, net::ReportSender::DO_NOT_SEND_COOKIES)); | 292 url_request_context, net::ReportSender::DO_NOT_SEND_COOKIES)); |
| 288 error_reporter.reset(new certificate_reporting::ErrorReporter( | 293 error_reporter.reset(new certificate_reporting::ErrorReporter( |
| 289 GURL(kExtendedReportingUploadUrl), server_public_key, | 294 GURL(kExtendedReportingUploadUrl), server_public_key, |
| 290 server_public_key_version, std::move(report_sender))); | 295 server_public_key_version, std::move(report_sender))); |
| 291 } else { | 296 } else { |
| 292 error_reporter.reset(new certificate_reporting::ErrorReporter( | 297 error_reporter.reset(new certificate_reporting::ErrorReporter( |
| 293 url_request_context, GURL(kExtendedReportingUploadUrl), | 298 url_request_context, GURL(kExtendedReportingUploadUrl), |
| 294 net::ReportSender::DO_NOT_SEND_COOKIES)); | 299 net::ReportSender::DO_NOT_SEND_COOKIES)); |
| 295 } | 300 } |
| 296 | |
| 297 reporter_.reset( | 301 reporter_.reset( |
| 298 new Reporter(std::move(error_reporter), | 302 new Reporter(std::move(error_reporter), |
| 299 std::unique_ptr<BoundedReportList>( | 303 std::unique_ptr<BoundedReportList>( |
| 300 new BoundedReportList(max_queued_report_count)), | 304 new BoundedReportList(max_queued_report_count)), |
| 301 clock, max_report_age, true /* retries_enabled */)); | 305 clock, max_report_age, true /* retries_enabled */)); |
| 302 } | 306 } |
| 303 | 307 |
| 304 void CertificateReportingService::OnPreferenceChanged() { | 308 void CertificateReportingService::OnPreferenceChanged() { |
| 305 safe_browsing::SafeBrowsingService* safe_browsing_service_ = | 309 safe_browsing::SafeBrowsingService* safe_browsing_service_ = |
| 306 g_browser_process->safe_browsing_service(); | 310 g_browser_process->safe_browsing_service(); |
| 307 const bool enabled = safe_browsing_service_ && | 311 const bool enabled = safe_browsing_service_ && |
| 308 safe_browsing_service_->enabled_by_prefs() && | 312 safe_browsing_service_->enabled_by_prefs() && |
| 309 safe_browsing::IsExtendedReportingEnabled(pref_service_); | 313 safe_browsing::IsExtendedReportingEnabled(pref_service_); |
| 310 SetEnabled(enabled); | 314 SetEnabled(enabled); |
| 311 } | 315 } |
| OLD | NEW |