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 |