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

Side by Side Diff: chrome/browser/extensions/install_signer.cc

Issue 149353002: Change default mode of extension install verification (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged with latest trunk Created 6 years, 10 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/extensions/install_signer.h" 5 #include "chrome/browser/extensions/install_signer.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
11 #include "base/json/json_writer.h" 11 #include "base/json/json_writer.h"
12 #include "base/lazy_instance.h"
12 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
13 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
15 #include "base/process/process_info.h"
14 #include "base/stl_util.h" 16 #include "base/stl_util.h"
15 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_split.h" 18 #include "base/strings/string_split.h"
17 #include "base/strings/string_util.h" 19 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h" 20 #include "base/strings/stringprintf.h"
21 #include "base/time/time.h"
19 #include "base/values.h" 22 #include "base/values.h"
20 #include "chrome/common/chrome_switches.h" 23 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/extensions/extension_constants.h" 24 #include "chrome/common/extensions/extension_constants.h"
22 #include "crypto/random.h" 25 #include "crypto/random.h"
23 #include "crypto/secure_hash.h" 26 #include "crypto/secure_hash.h"
24 #include "crypto/sha2.h" 27 #include "crypto/sha2.h"
25 #include "crypto/signature_verifier.h" 28 #include "crypto/signature_verifier.h"
26 #include "net/url_request/url_fetcher.h" 29 #include "net/url_request/url_fetcher.h"
27 #include "net/url_request/url_fetcher_delegate.h" 30 #include "net/url_request/url_fetcher_delegate.h"
28 #include "net/url_request/url_request_context_getter.h" 31 #include "net/url_request/url_request_context_getter.h"
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 std::string value = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 239 std::string value = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
237 switches::kExtensionsNotWebstore); 240 switches::kExtensionsNotWebstore);
238 if (value.empty()) 241 if (value.empty())
239 return ExtensionIdSet(); 242 return ExtensionIdSet();
240 243
241 std::vector<std::string> ids; 244 std::vector<std::string> ids;
242 base::SplitString(value, ',', &ids); 245 base::SplitString(value, ',', &ids);
243 return ExtensionIdSet(ids.begin(), ids.end()); 246 return ExtensionIdSet(ids.begin(), ids.end());
244 } 247 }
245 248
249 namespace {
250
251 static int g_request_count = 0;
252
253 base::LazyInstance<base::TimeTicks> g_last_request_time =
254 LAZY_INSTANCE_INITIALIZER;
255
256 base::LazyInstance<base::ThreadChecker> g_single_thread_checker =
257 LAZY_INSTANCE_INITIALIZER;
258
259 void LogRequestStartHistograms() {
260 // Make sure we only ever call this from one thread, so that we don't have to
261 // worry about race conditions setting g_last_request_time.
262 DCHECK(g_single_thread_checker.Get().CalledOnValidThread());
263
264 const base::Time process_creation_time =
265 base::CurrentProcessInfo::CreationTime();
266 UMA_HISTOGRAM_COUNTS("ExtensionInstallSigner.UptimeAtTimeOfRequest",
267 (base::Time::Now() - process_creation_time).InSeconds());
268
269 base::TimeDelta delta;
270 base::TimeTicks now = base::TimeTicks::Now();
271 if (!g_last_request_time.Get().is_null())
272 delta = now - g_last_request_time.Get();
273 g_last_request_time.Get() = now;
274 UMA_HISTOGRAM_COUNTS("ExtensionInstallSigner.SecondsSinceLastRequest",
275 delta.InSeconds());
276
277 g_request_count += 1;
278 UMA_HISTOGRAM_COUNTS_100("ExtensionInstallSigner.RequestCount",
279 g_request_count);
280 }
281
282 } // namespace
283
246 void InstallSigner::GetSignature(const SignatureCallback& callback) { 284 void InstallSigner::GetSignature(const SignatureCallback& callback) {
247 CHECK(!url_fetcher_.get()); 285 CHECK(!url_fetcher_.get());
248 CHECK(callback_.is_null()); 286 CHECK(callback_.is_null());
249 CHECK(salt_.empty()); 287 CHECK(salt_.empty());
250 callback_ = callback; 288 callback_ = callback;
251 289
252 // If the set of ids is empty, just return an empty signature and skip the 290 // If the set of ids is empty, just return an empty signature and skip the
253 // call to the server. 291 // call to the server.
254 if (ids_.empty()) { 292 if (ids_.empty()) {
255 if (!callback_.is_null()) 293 if (!callback_.is_null())
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 id_list->AppendString(*i); 332 id_list->AppendString(*i);
295 } 333 }
296 dictionary.Set(kIdsKey, id_list.release()); 334 dictionary.Set(kIdsKey, id_list.release());
297 std::string json; 335 std::string json;
298 base::JSONWriter::Write(&dictionary, &json); 336 base::JSONWriter::Write(&dictionary, &json);
299 if (json.empty()) { 337 if (json.empty()) {
300 ReportErrorViaCallback(); 338 ReportErrorViaCallback();
301 return; 339 return;
302 } 340 }
303 url_fetcher_->SetUploadData("application/json", json); 341 url_fetcher_->SetUploadData("application/json", json);
342 LogRequestStartHistograms();
304 url_fetcher_->Start(); 343 url_fetcher_->Start();
305 } 344 }
306 345
307 void InstallSigner::ReportErrorViaCallback() { 346 void InstallSigner::ReportErrorViaCallback() {
308 InstallSignature* null_signature = NULL; 347 InstallSignature* null_signature = NULL;
309 if (!callback_.is_null()) 348 if (!callback_.is_null())
310 callback_.Run(scoped_ptr<InstallSignature>(null_signature)); 349 callback_.Run(scoped_ptr<InstallSignature>(null_signature));
311 } 350 }
312 351
313 void InstallSigner::ParseFetchResponse() { 352 void InstallSigner::ParseFetchResponse() {
353 bool fetch_success = url_fetcher_->GetStatus().is_success();
354 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.FetchSuccess", fetch_success);
355
314 std::string response; 356 std::string response;
315 if (!url_fetcher_->GetStatus().is_success() || 357 if (fetch_success) {
316 !url_fetcher_->GetResponseAsString(&response) || 358 if (!url_fetcher_->GetResponseAsString(&response))
317 response.empty()) { 359 response.clear();
360 }
361 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.GetResponseSuccess",
362 !response.empty());
363 if (!fetch_success || response.empty()) {
318 ReportErrorViaCallback(); 364 ReportErrorViaCallback();
319 return; 365 return;
320 } 366 }
321 367
322 // The response is JSON of the form: 368 // The response is JSON of the form:
323 // { 369 // {
324 // "protocol_version": "1", 370 // "protocol_version": "1",
325 // "signature": "<base64-encoded signature>", 371 // "signature": "<base64-encoded signature>",
326 // "expiry": "<date in YYYY-MM-DD form>", 372 // "expiry": "<date in YYYY-MM-DD form>",
327 // "invalid_ids": [ "<id3>", "<id4>" ] 373 // "invalid_ids": [ "<id3>", "<id4>" ]
328 // } 374 // }
329 // where |invalid_ids| is a list of ids from the original request that 375 // where |invalid_ids| is a list of ids from the original request that
330 // could not be verified to be in the webstore. 376 // could not be verified to be in the webstore.
331 377
332 base::DictionaryValue* dictionary = NULL; 378 base::DictionaryValue* dictionary = NULL;
333 scoped_ptr<base::Value> parsed(base::JSONReader::Read(response)); 379 scoped_ptr<base::Value> parsed(base::JSONReader::Read(response));
334 if (!parsed.get() || !parsed->GetAsDictionary(&dictionary)) { 380 bool json_success = parsed.get() && parsed->GetAsDictionary(&dictionary);
381 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ParseJsonSuccess",
382 json_success);
383 if (!json_success) {
335 ReportErrorViaCallback(); 384 ReportErrorViaCallback();
336 return; 385 return;
337 } 386 }
338 387
339 int protocol_version = 0; 388 int protocol_version = 0;
340 std::string signature_base64; 389 std::string signature_base64;
341 std::string signature; 390 std::string signature;
342 std::string expire_date; 391 std::string expire_date;
343 392
344 dictionary->GetInteger(kProtocolVersionKey, &protocol_version); 393 dictionary->GetInteger(kProtocolVersionKey, &protocol_version);
345 dictionary->GetString(kSignatureKey, &signature_base64); 394 dictionary->GetString(kSignatureKey, &signature_base64);
346 dictionary->GetString(kExpiryKey, &expire_date); 395 dictionary->GetString(kExpiryKey, &expire_date);
347 396
348 if (protocol_version != 1 || signature_base64.empty() || 397 bool fields_success =
349 !ValidateExpireDateFormat(expire_date) || 398 protocol_version == 1 && !signature_base64.empty() &&
350 !base::Base64Decode(signature_base64, &signature)) { 399 ValidateExpireDateFormat(expire_date) &&
400 base::Base64Decode(signature_base64, &signature);
401 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ParseFieldsSuccess",
402 fields_success);
403 if (!fields_success) {
351 ReportErrorViaCallback(); 404 ReportErrorViaCallback();
352 return; 405 return;
353 } 406 }
354 407
355 ExtensionIdSet invalid_ids; 408 ExtensionIdSet invalid_ids;
356 const base::ListValue* invalid_ids_list = NULL; 409 const base::ListValue* invalid_ids_list = NULL;
357 if (dictionary->GetList(kInvalidIdsKey, &invalid_ids_list)) { 410 if (dictionary->GetList(kInvalidIdsKey, &invalid_ids_list)) {
358 for (size_t i = 0; i < invalid_ids_list->GetSize(); i++) { 411 for (size_t i = 0; i < invalid_ids_list->GetSize(); i++) {
359 std::string id; 412 std::string id;
360 if (!invalid_ids_list->GetString(i, &id)) { 413 if (!invalid_ids_list->GetString(i, &id)) {
(...skipping 27 matching lines...) Expand all
388 if (!verified) 441 if (!verified)
389 result.reset(); 442 result.reset();
390 } 443 }
391 444
392 if (!callback_.is_null()) 445 if (!callback_.is_null())
393 callback_.Run(result.Pass()); 446 callback_.Run(result.Pass());
394 } 447 }
395 448
396 449
397 } // namespace extensions 450 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_service.cc ('k') | chrome/browser/extensions/install_verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698