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

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

Issue 150093002: Change default mode of extension install verification (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: compile fix 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 // CurrentProcessInfo::CreationTime is only defined on some platforms.
265 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX)
266 const base::Time process_creation_time =
267 base::CurrentProcessInfo::CreationTime();
268 UMA_HISTOGRAM_COUNTS("ExtensionInstallSigner.UptimeAtTimeOfRequest",
269 (base::Time::Now() - process_creation_time).InSeconds());
270 #endif // defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX)
271
272 base::TimeDelta delta;
273 base::TimeTicks now = base::TimeTicks::Now();
274 if (!g_last_request_time.Get().is_null())
275 delta = now - g_last_request_time.Get();
276 g_last_request_time.Get() = now;
277 UMA_HISTOGRAM_COUNTS("ExtensionInstallSigner.SecondsSinceLastRequest",
278 delta.InSeconds());
279
280 g_request_count += 1;
281 UMA_HISTOGRAM_COUNTS_100("ExtensionInstallSigner.RequestCount",
282 g_request_count);
283 }
284
285 } // namespace
286
246 void InstallSigner::GetSignature(const SignatureCallback& callback) { 287 void InstallSigner::GetSignature(const SignatureCallback& callback) {
247 CHECK(!url_fetcher_.get()); 288 CHECK(!url_fetcher_.get());
248 CHECK(callback_.is_null()); 289 CHECK(callback_.is_null());
249 CHECK(salt_.empty()); 290 CHECK(salt_.empty());
250 callback_ = callback; 291 callback_ = callback;
251 292
252 // If the set of ids is empty, just return an empty signature and skip the 293 // If the set of ids is empty, just return an empty signature and skip the
253 // call to the server. 294 // call to the server.
254 if (ids_.empty()) { 295 if (ids_.empty()) {
255 if (!callback_.is_null()) 296 if (!callback_.is_null())
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 id_list->AppendString(*i); 335 id_list->AppendString(*i);
295 } 336 }
296 dictionary.Set(kIdsKey, id_list.release()); 337 dictionary.Set(kIdsKey, id_list.release());
297 std::string json; 338 std::string json;
298 base::JSONWriter::Write(&dictionary, &json); 339 base::JSONWriter::Write(&dictionary, &json);
299 if (json.empty()) { 340 if (json.empty()) {
300 ReportErrorViaCallback(); 341 ReportErrorViaCallback();
301 return; 342 return;
302 } 343 }
303 url_fetcher_->SetUploadData("application/json", json); 344 url_fetcher_->SetUploadData("application/json", json);
345 LogRequestStartHistograms();
304 url_fetcher_->Start(); 346 url_fetcher_->Start();
305 } 347 }
306 348
307 void InstallSigner::ReportErrorViaCallback() { 349 void InstallSigner::ReportErrorViaCallback() {
308 InstallSignature* null_signature = NULL; 350 InstallSignature* null_signature = NULL;
309 if (!callback_.is_null()) 351 if (!callback_.is_null())
310 callback_.Run(scoped_ptr<InstallSignature>(null_signature)); 352 callback_.Run(scoped_ptr<InstallSignature>(null_signature));
311 } 353 }
312 354
313 void InstallSigner::ParseFetchResponse() { 355 void InstallSigner::ParseFetchResponse() {
356 bool fetch_success = url_fetcher_->GetStatus().is_success();
357 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.FetchSuccess", fetch_success);
358
314 std::string response; 359 std::string response;
315 if (!url_fetcher_->GetStatus().is_success() || 360 if (fetch_success) {
316 !url_fetcher_->GetResponseAsString(&response) || 361 if (!url_fetcher_->GetResponseAsString(&response))
317 response.empty()) { 362 response.clear();
363 }
364 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.GetResponseSuccess",
365 !response.empty());
366 if (!fetch_success || response.empty()) {
318 ReportErrorViaCallback(); 367 ReportErrorViaCallback();
319 return; 368 return;
320 } 369 }
321 370
322 // The response is JSON of the form: 371 // The response is JSON of the form:
323 // { 372 // {
324 // "protocol_version": "1", 373 // "protocol_version": "1",
325 // "signature": "<base64-encoded signature>", 374 // "signature": "<base64-encoded signature>",
326 // "expiry": "<date in YYYY-MM-DD form>", 375 // "expiry": "<date in YYYY-MM-DD form>",
327 // "invalid_ids": [ "<id3>", "<id4>" ] 376 // "invalid_ids": [ "<id3>", "<id4>" ]
328 // } 377 // }
329 // where |invalid_ids| is a list of ids from the original request that 378 // where |invalid_ids| is a list of ids from the original request that
330 // could not be verified to be in the webstore. 379 // could not be verified to be in the webstore.
331 380
332 base::DictionaryValue* dictionary = NULL; 381 base::DictionaryValue* dictionary = NULL;
333 scoped_ptr<base::Value> parsed(base::JSONReader::Read(response)); 382 scoped_ptr<base::Value> parsed(base::JSONReader::Read(response));
334 if (!parsed.get() || !parsed->GetAsDictionary(&dictionary)) { 383 bool json_success = parsed.get() && parsed->GetAsDictionary(&dictionary);
384 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ParseJsonSuccess",
385 json_success);
386 if (!json_success) {
335 ReportErrorViaCallback(); 387 ReportErrorViaCallback();
336 return; 388 return;
337 } 389 }
338 390
339 int protocol_version = 0; 391 int protocol_version = 0;
340 std::string signature_base64; 392 std::string signature_base64;
341 std::string signature; 393 std::string signature;
342 std::string expire_date; 394 std::string expire_date;
343 395
344 dictionary->GetInteger(kProtocolVersionKey, &protocol_version); 396 dictionary->GetInteger(kProtocolVersionKey, &protocol_version);
345 dictionary->GetString(kSignatureKey, &signature_base64); 397 dictionary->GetString(kSignatureKey, &signature_base64);
346 dictionary->GetString(kExpiryKey, &expire_date); 398 dictionary->GetString(kExpiryKey, &expire_date);
347 399
348 if (protocol_version != 1 || signature_base64.empty() || 400 bool fields_success =
349 !ValidateExpireDateFormat(expire_date) || 401 protocol_version == 1 && !signature_base64.empty() &&
350 !base::Base64Decode(signature_base64, &signature)) { 402 ValidateExpireDateFormat(expire_date) &&
403 base::Base64Decode(signature_base64, &signature);
404 UMA_HISTOGRAM_BOOLEAN("ExtensionInstallSigner.ParseFieldsSuccess",
405 fields_success);
406 if (!fields_success) {
351 ReportErrorViaCallback(); 407 ReportErrorViaCallback();
352 return; 408 return;
353 } 409 }
354 410
355 ExtensionIdSet invalid_ids; 411 ExtensionIdSet invalid_ids;
356 const base::ListValue* invalid_ids_list = NULL; 412 const base::ListValue* invalid_ids_list = NULL;
357 if (dictionary->GetList(kInvalidIdsKey, &invalid_ids_list)) { 413 if (dictionary->GetList(kInvalidIdsKey, &invalid_ids_list)) {
358 for (size_t i = 0; i < invalid_ids_list->GetSize(); i++) { 414 for (size_t i = 0; i < invalid_ids_list->GetSize(); i++) {
359 std::string id; 415 std::string id;
360 if (!invalid_ids_list->GetString(i, &id)) { 416 if (!invalid_ids_list->GetString(i, &id)) {
(...skipping 27 matching lines...) Expand all
388 if (!verified) 444 if (!verified)
389 result.reset(); 445 result.reset();
390 } 446 }
391 447
392 if (!callback_.is_null()) 448 if (!callback_.is_null())
393 callback_.Run(result.Pass()); 449 callback_.Run(result.Pass());
394 } 450 }
395 451
396 452
397 } // namespace extensions 453 } // 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