Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(252)

Side by Side Diff: chrome/browser/safe_browsing/certificate_reporting_service.cc

Issue 2503243003: Wire up CertificateReportingService to handle report uploads (Closed)
Patch Set: estark comments Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 5
5 #include "base/bind_helpers.h" 6 #include "base/bind_helpers.h"
7 #include "base/metrics/histogram_macros.h"
8 #include "base/metrics/sparse_histogram.h"
6 #include "base/time/clock.h" 9 #include "base/time/clock.h"
7 #include "base/time/default_clock.h" 10 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/safe_browsing/certificate_reporting_service.h" 11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
13 #include "components/prefs/pref_service.h"
14 #include "components/safe_browsing_db/safe_browsing_prefs.h"
9 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
10 16
11 namespace { 17 namespace {
12 18
13 // URL to upload invalid certificate chain reports. An HTTP URL is used because 19 // URL to upload invalid certificate chain reports. An HTTP URL is used because
14 // a client seeing an invalid cert might not be able to make an HTTPS connection 20 // a client seeing an invalid cert might not be able to make an HTTPS connection
15 // to report it. 21 // to report it.
16 const char kExtendedReportingUploadUrl[] = 22 const char kExtendedReportingUploadUrl[] =
17 "http://safebrowsing.googleusercontent.com/safebrowsing/clientreport/"; 23 "http://safebrowsing.googleusercontent.com/safebrowsing/clientreport/";
18 24
19 // Compare function that orders Reports in reverse chronological order (i.e. 25 // Compare function that orders Reports in reverse chronological order (i.e.
20 // oldest item is last). 26 // oldest item is last).
21 bool ReportCompareFunc(const CertificateReportingService::Report& item1, 27 bool ReportCompareFunc(const CertificateReportingService::Report& item1,
22 const CertificateReportingService::Report& item2) { 28 const CertificateReportingService::Report& item2) {
23 return item1.creation_time > item2.creation_time; 29 return item1.creation_time > item2.creation_time;
24 } 30 }
25 31
32 // Records an UMA histogram of the net errors when certificate reports
33 // fail to send.
34 void RecordUMAOnFailure(int net_error) {
35 UMA_HISTOGRAM_SPARSE_SLOWLY("SSL.CertificateErrorReportFailure", -net_error);
Ilya Sherman 2016/12/22 01:41:57 Is this a new histogram? Should it be added to hi
meacer 2016/12/22 18:50:04 It's an existing histogram being moved from SafeBr
Ilya Sherman 2016/12/22 22:00:08 Okay, thanks for the reassurance. And, yeah, code
36 }
37
26 } // namespace 38 } // namespace
27 39
28 CertificateReportingService::BoundedReportList::BoundedReportList( 40 CertificateReportingService::BoundedReportList::BoundedReportList(
29 size_t max_size) 41 size_t max_size)
30 : max_size_(max_size) { 42 : max_size_(max_size) {
31 CHECK(max_size <= 20) 43 CHECK(max_size <= 20)
32 << "Current implementation is not efficient for a large list."; 44 << "Current implementation is not efficient for a large list.";
33 DCHECK(thread_checker_.CalledOnValidThread()); 45 DCHECK(thread_checker_.CalledOnValidThread());
34 } 46 }
35 47
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 base::Bind(&CertificateReportingService::Reporter::SuccessCallback, 133 base::Bind(&CertificateReportingService::Reporter::SuccessCallback,
122 weak_factory_.GetWeakPtr(), report.report_id), 134 weak_factory_.GetWeakPtr(), report.report_id),
123 base::Bind(&CertificateReportingService::Reporter::ErrorCallback, 135 base::Bind(&CertificateReportingService::Reporter::ErrorCallback,
124 weak_factory_.GetWeakPtr(), report.report_id)); 136 weak_factory_.GetWeakPtr(), report.report_id));
125 } 137 }
126 138
127 void CertificateReportingService::Reporter::ErrorCallback(int report_id, 139 void CertificateReportingService::Reporter::ErrorCallback(int report_id,
128 const GURL& url, 140 const GURL& url,
129 int error) { 141 int error) {
130 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 142 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
143 RecordUMAOnFailure(error);
131 if (retries_enabled_) { 144 if (retries_enabled_) {
132 auto it = inflight_reports_.find(report_id); 145 auto it = inflight_reports_.find(report_id);
133 DCHECK(it != inflight_reports_.end()); 146 DCHECK(it != inflight_reports_.end());
134 retry_list_->Add(it->second); 147 retry_list_->Add(it->second);
135 } 148 }
136 CHECK_GT(inflight_reports_.erase(report_id), 0u); 149 CHECK_GT(inflight_reports_.erase(report_id), 0u);
137 } 150 }
138 151
139 void CertificateReportingService::Reporter::SuccessCallback(int report_id) { 152 void CertificateReportingService::Reporter::SuccessCallback(int report_id) {
140 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 153 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
141 CHECK_GT(inflight_reports_.erase(report_id), 0u); 154 CHECK_GT(inflight_reports_.erase(report_id), 0u);
142 } 155 }
143 156
144 CertificateReportingService::CertificateReportingService( 157 CertificateReportingService::CertificateReportingService(
158 safe_browsing::SafeBrowsingService* safe_browsing_service,
145 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, 159 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
160 Profile* profile,
146 uint8_t server_public_key[/* 32 */], 161 uint8_t server_public_key[/* 32 */],
147 uint32_t server_public_key_version, 162 uint32_t server_public_key_version,
148 size_t max_queued_report_count, 163 size_t max_queued_report_count,
149 base::TimeDelta max_report_age, 164 base::TimeDelta max_report_age,
150 std::unique_ptr<base::Clock> clock) 165 base::Clock* clock)
151 : enabled_(true), 166 : pref_service_(*profile->GetPrefs()),
167 enabled_(true),
152 url_request_context_(nullptr), 168 url_request_context_(nullptr),
153 max_queued_report_count_(max_queued_report_count), 169 max_queued_report_count_(max_queued_report_count),
154 max_report_age_(max_report_age), 170 max_report_age_(max_report_age),
155 clock_(std::move(clock)), 171 clock_(clock),
156 made_send_attempt_(false),
157 server_public_key_(server_public_key), 172 server_public_key_(server_public_key),
158 server_public_key_version_(server_public_key_version) { 173 server_public_key_version_(server_public_key_version) {
159 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 174 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
175 DCHECK(clock_);
176 // Subscribe to SafeBrowsing shutdown notifications.
177 safe_browsing_service_shutdown_subscription_ =
178 safe_browsing_service->RegisterShutdownCallback(base::Bind(
179 &CertificateReportingService::Shutdown, base::Unretained(this)));
180
181 // Subscribe to SafeBrowsing preference change notifications.
182 safe_browsing_state_subscription_ =
183 safe_browsing_service->RegisterStateCallback(
184 base::Bind(&CertificateReportingService::OnPreferenceChanged,
185 base::Unretained(this)));
186
160 content::BrowserThread::PostTask( 187 content::BrowserThread::PostTask(
161 content::BrowserThread::IO, FROM_HERE, 188 content::BrowserThread::IO, FROM_HERE,
162 base::Bind(&CertificateReportingService::InitializeOnIOThread, 189 base::Bind(&CertificateReportingService::InitializeOnIOThread,
163 base::Unretained(this), enabled_, url_request_context_getter, 190 base::Unretained(this), enabled_, url_request_context_getter,
164 max_queued_report_count_, max_report_age_, clock_.get(), 191 max_queued_report_count_, max_report_age_, clock_,
165 server_public_key_, server_public_key_version_)); 192 server_public_key_, server_public_key_version_));
166 } 193 }
167 194
168 CertificateReportingService::~CertificateReportingService() { 195 CertificateReportingService::~CertificateReportingService() {
169 DCHECK(!reporter_); 196 DCHECK(!reporter_);
170 } 197 }
171 198
172 void CertificateReportingService::Shutdown() { 199 void CertificateReportingService::Shutdown() {
173 // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once 200 // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once
174 // when all KeyedServices shut down. All calls after the first one are no-op. 201 // when all KeyedServices shut down. All calls after the first one are no-op.
175 enabled_ = false; 202 enabled_ = false;
176 Reset(); 203 Reset();
177 } 204 }
178 205
179 void CertificateReportingService::Send(const std::string& serialized_report) { 206 void CertificateReportingService::Send(const std::string& serialized_report) {
180 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 207 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
181 made_send_attempt_ = true;
182 if (!reporter_) { 208 if (!reporter_) {
183 return; 209 return;
184 } 210 }
185 content::BrowserThread::PostTask( 211 content::BrowserThread::PostTask(
186 content::BrowserThread::IO, FROM_HERE, 212 content::BrowserThread::IO, FROM_HERE,
187 base::Bind(&CertificateReportingService::Reporter::Send, 213 base::Bind(&CertificateReportingService::Reporter::Send,
188 base::Unretained(reporter_.get()), serialized_report)); 214 base::Unretained(reporter_.get()), serialized_report));
189 } 215 }
190 216
191 void CertificateReportingService::SendPending() { 217 void CertificateReportingService::SendPending() {
192 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 218 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
193 made_send_attempt_ = true;
194 if (!reporter_) { 219 if (!reporter_) {
195 return; 220 return;
196 } 221 }
197 content::BrowserThread::PostTask( 222 content::BrowserThread::PostTask(
198 content::BrowserThread::IO, FROM_HERE, 223 content::BrowserThread::IO, FROM_HERE,
199 base::Bind(&CertificateReportingService::Reporter::SendPending, 224 base::Bind(&CertificateReportingService::Reporter::SendPending,
200 base::Unretained(reporter_.get()))); 225 base::Unretained(reporter_.get())));
201 } 226 }
202 227
203 void CertificateReportingService::InitializeOnIOThread( 228 void CertificateReportingService::InitializeOnIOThread(
(...skipping 16 matching lines...) Expand all
220 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 245 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
221 enabled_ = enabled; 246 enabled_ = enabled;
222 Reset(); 247 Reset();
223 } 248 }
224 249
225 CertificateReportingService::Reporter* 250 CertificateReportingService::Reporter*
226 CertificateReportingService::GetReporterForTesting() const { 251 CertificateReportingService::GetReporterForTesting() const {
227 return reporter_.get(); 252 return reporter_.get();
228 } 253 }
229 254
230 void CertificateReportingService::SetMaxQueuedReportCountForTesting(
231 size_t count) {
232 DCHECK(!made_send_attempt_);
233 max_queued_report_count_ = count;
234 Reset();
235 }
236
237 void CertificateReportingService::SetClockForTesting(
238 std::unique_ptr<base::Clock> clock) {
239 DCHECK(!made_send_attempt_);
240 clock_ = std::move(clock);
241 Reset();
242 }
243
244 void CertificateReportingService::SetMaxReportAgeForTesting(
245 base::TimeDelta max_report_age) {
246 DCHECK(!made_send_attempt_);
247 max_report_age_ = max_report_age;
248 Reset();
249 }
250
251 // static 255 // static
252 GURL CertificateReportingService::GetReportingURLForTesting() { 256 GURL CertificateReportingService::GetReportingURLForTesting() {
253 return GURL(kExtendedReportingUploadUrl); 257 return GURL(kExtendedReportingUploadUrl);
254 } 258 }
255 259
256 void CertificateReportingService::Reset() { 260 void CertificateReportingService::Reset() {
257 content::BrowserThread::PostTask( 261 content::BrowserThread::PostTask(
258 content::BrowserThread::IO, FROM_HERE, 262 content::BrowserThread::IO, FROM_HERE,
259 base::Bind(&CertificateReportingService::ResetOnIOThread, 263 base::Bind(&CertificateReportingService::ResetOnIOThread,
260 base::Unretained(this), enabled_, url_request_context_, 264 base::Unretained(this), enabled_, url_request_context_,
261 max_queued_report_count_, max_report_age_, clock_.get(), 265 max_queued_report_count_, max_report_age_, clock_,
262 server_public_key_, server_public_key_version_)); 266 server_public_key_, server_public_key_version_));
263 } 267 }
264 268
265 void CertificateReportingService::ResetOnIOThread( 269 void CertificateReportingService::ResetOnIOThread(
266 bool enabled, 270 bool enabled,
267 net::URLRequestContext* url_request_context, 271 net::URLRequestContext* url_request_context,
268 size_t max_queued_report_count, 272 size_t max_queued_report_count,
269 base::TimeDelta max_report_age, 273 base::TimeDelta max_report_age,
270 base::Clock* clock, 274 base::Clock* clock,
271 uint8_t* const server_public_key, 275 uint8_t* const server_public_key,
(...skipping 17 matching lines...) Expand all
289 url_request_context, GURL(kExtendedReportingUploadUrl), 293 url_request_context, GURL(kExtendedReportingUploadUrl),
290 net::ReportSender::DO_NOT_SEND_COOKIES)); 294 net::ReportSender::DO_NOT_SEND_COOKIES));
291 } 295 }
292 296
293 reporter_.reset( 297 reporter_.reset(
294 new Reporter(std::move(error_reporter), 298 new Reporter(std::move(error_reporter),
295 std::unique_ptr<BoundedReportList>( 299 std::unique_ptr<BoundedReportList>(
296 new BoundedReportList(max_queued_report_count)), 300 new BoundedReportList(max_queued_report_count)),
297 clock, max_report_age, true /* retries_enabled */)); 301 clock, max_report_age, true /* retries_enabled */));
298 } 302 }
303
304 void CertificateReportingService::OnPreferenceChanged() {
305 safe_browsing::SafeBrowsingService* safe_browsing_service_ =
306 g_browser_process->safe_browsing_service();
307 const bool enabled = safe_browsing_service_ &&
308 safe_browsing_service_->enabled_by_prefs() &&
309 safe_browsing::IsExtendedReportingEnabled(pref_service_);
310 SetEnabled(enabled);
311 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698