install_verifier.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/install_verifier.h" 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <algorithm> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <string> 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/command_line.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/field_trial.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/histogram.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/prefs/pref_service.h" 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/stl_util.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/extensions/extension_service.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/install_signer.h" 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h" 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/pref_names.h" 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "content/public/browser/browser_context.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/content_switches.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/browser/extension_registry.h" 25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/browser/extension_system.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/pref_names.h" 27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/extension_set.h" 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest.h" 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "extensions/common/one_shot_event.h" 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "grit/generated_resources.h" 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace extensions { 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace { 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)enum VerifyStatus { 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NONE = 0, // Do not request install signatures, and do not enforce them. 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BOOTSTRAP, // Request install signatures, but do not enforce them. 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ENFORCE, // Request install signatures, and enforce them. 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ENFORCE_STRICT, // Same as ENFORCE, but hard fail if we can't fetch 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // signatures. 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is used in histograms - do not remove or reorder entries above! Also 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the "MAX" item below should always be the last element. 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VERIFY_STATUS_MAX 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kExperimentName[] = "ExtensionInstallVerification"; 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // defined(GOOGLE_CHROME_BUILD) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)VerifyStatus GetExperimentStatus() { 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string group = base::FieldTrialList::FindFullName( 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kExperimentName); 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string forced_trials = CommandLine::ForCurrentProcess()-> 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSwitchValueASCII(switches::kForceFieldTrials); 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (forced_trials.find(kExperimentName) != std::string::npos) { 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We don't want to allow turning off enforcement by forcing the field 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // trial group to something other than enforcement. 63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ENFORCE_STRICT; 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VerifyStatus default_status = NONE; 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (group == "EnforceStrict") 69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ENFORCE_STRICT; 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else if (group == "Enforce") 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ENFORCE; 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (group == "Bootstrap") 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return BOOTSTRAP; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (group == "None" || group == "Control") 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NONE; 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return default_status; 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // defined(GOOGLE_CHROME_BUILD) 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NONE; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)VerifyStatus GetCommandLineStatus() { 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const CommandLine* cmdline = CommandLine::ForCurrentProcess(); 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!InstallSigner::GetForcedNotFromWebstore().empty()) 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ENFORCE; 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (cmdline->HasSwitch(switches::kExtensionsInstallVerification)) { 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string value = cmdline->GetSwitchValueASCII( 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switches::kExtensionsInstallVerification); 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (value == "bootstrap") 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return BOOTSTRAP; 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else if (value == "enforce_strict") 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return ENFORCE_STRICT; 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ENFORCE; 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NONE; 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)VerifyStatus GetStatus() { 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return std::max(GetExperimentStatus(), GetCommandLineStatus()); 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ShouldFetchSignature() { 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return GetStatus() >= BOOTSTRAP; 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool ShouldEnforce() { 111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return GetStatus() >= ENFORCE; 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum InitResult { 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_NO_PREF = 0, 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_UNPARSEABLE_PREF, 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_INVALID_SIGNATURE, 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_VALID_SIGNATURE, 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is used in histograms - do not remove or reorder entries above! Also 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the "MAX" item below should always be the last element. 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) INIT_RESULT_MAX 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void LogInitResultHistogram(InitResult result) { 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.InitResult", 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result, INIT_RESULT_MAX); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool FromStore(const Extension& extension) { 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (extension.from_webstore() || ManifestURL::UpdatesFromGallery(&extension)) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If an extension has no update url, our autoupdate code will ask the 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // webstore about it (to aid in migrating to the webstore from self-hosting 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // or sideloading based installs). So we want to do verification checks on 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // such extensions too so that we don't accidentally disable old installs of 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // extensions that did migrate to the webstore. 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return (ManifestURL::GetUpdateURL(&extension).is_empty() && 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Manifest::IsAutoUpdateableLocation(extension.location())); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CanUseExtensionApis(const Extension& extension) { 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return extension.is_extension() || extension.is_legacy_packaged_app(); 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochenum VerifyAllSuccess { 149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_BOOTSTRAP_SUCCESS = 0, 150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_BOOTSTRAP_FAILURE, 151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_NON_BOOTSTRAP_SUCCESS, 152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_NON_BOOTSTRAP_FAILURE, 153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Used in histograms. Do not remove/reorder any entries above, and the below 155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // MAX entry should always come last. 156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VERIFY_ALL_SUCCESS_MAX 157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Record the success or failure of verifying all extensions, and whether or 160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// not it was a bootstrapping. 161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid LogVerifyAllSuccessHistogram(bool bootstrap, bool success) { 162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch VerifyAllSuccess result; 163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (bootstrap && success) 164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = VERIFY_ALL_BOOTSTRAP_SUCCESS; 165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else if (bootstrap && !success) 166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = VERIFY_ALL_BOOTSTRAP_FAILURE; 167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else if (!bootstrap && success) 168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = VERIFY_ALL_NON_BOOTSTRAP_SUCCESS; 169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = VERIFY_ALL_NON_BOOTSTRAP_FAILURE; 171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // This used to be part of ExtensionService, but moved here. In order to keep 173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // our histograms accurate, the name is unchanged. 174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_ENUMERATION( 175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "ExtensionService.VerifyAllSuccess", result, VERIFY_ALL_SUCCESS_MAX); 176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Record the success or failure of a single verification. 179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid LogAddVerifiedSuccess(bool success) { 180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // This used to be part of ExtensionService, but moved here. In order to keep 181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // our histograms accurate, the name is unchanged. 182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch UMA_HISTOGRAM_BOOLEAN("ExtensionService.AddVerified", success); 183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 187effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochInstallVerifier::InstallVerifier(ExtensionPrefs* prefs, 188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch content::BrowserContext* context) 189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : prefs_(prefs), 190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) context_(context), 191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bootstrap_check_complete_(false), 192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) weak_factory_(this) { 193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 195effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochInstallVerifier::~InstallVerifier() {} 196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool InstallVerifier::NeedsVerification(const Extension& extension) { 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return FromStore(extension) && CanUseExtensionApis(extension); 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::Init() { 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ExperimentStatus", 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetExperimentStatus(), VERIFY_STATUS_MAX); 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ActualStatus", 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetStatus(), VERIFY_STATUS_MAX); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::DictionaryValue* pref = prefs_->GetInstallSignature(); 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (pref) { 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<InstallSignature> signature_from_prefs = 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InstallSignature::FromValue(*pref); 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!signature_from_prefs.get()) { 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LogInitResultHistogram(INIT_UNPARSEABLE_PREF); 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (!InstallSigner::VerifySignature(*signature_from_prefs.get())) { 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LogInitResultHistogram(INIT_INVALID_SIGNATURE); 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "Init - ignoring invalid signature"; 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) signature_ = signature_from_prefs.Pass(); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LogInitResultHistogram(INIT_VALID_SIGNATURE); 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("ExtensionInstallVerifier.InitSignatureCount", 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) signature_->ids.size()); 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GarbageCollect(); 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LogInitResultHistogram(INIT_NO_PREF); 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 227effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 228effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionSystem::Get(context_)->ready().Post( 229effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch FROM_HERE, 230effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(&InstallVerifier::MaybeBootstrapSelf, 231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_factory_.GetWeakPtr())); 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 234effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InstallVerifier::VerifyAllExtensions() { 235effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddMany(GetExtensionsToVerify(), ADD_ALL); 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Time InstallVerifier::SignatureTimestamp() { 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (signature_.get()) 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return signature_->timestamp; 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::Time(); 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool InstallVerifier::IsKnownId(const std::string& id) { 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return signature_.get() && (ContainsKey(signature_->ids, id) || 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ContainsKey(signature_->invalid_ids, id)); 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 250effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InstallVerifier::VerifyExtension(const std::string& extension_id) { 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet ids; 252effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ids.insert(extension_id); 253effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddMany(ids, ADD_SINGLE); 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 256effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InstallVerifier::AddMany(const ExtensionIdSet& ids, OperationType type) { 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ShouldFetchSignature()) { 258effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnVerificationComplete(true, type); // considered successful. 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (signature_.get()) { 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet not_allowed_yet = 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::STLSetDifference<ExtensionIdSet>(ids, signature_->ids); 265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (not_allowed_yet.empty()) { 266effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnVerificationComplete(true, type); // considered successful. 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InstallVerifier::PendingOperation* operation = 272effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new InstallVerifier::PendingOperation(type); 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation->ids.insert(ids.begin(), ids.end()); 274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation_queue_.push(linked_ptr<PendingOperation>(operation)); 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If there are no ongoing pending requests, we need to kick one off. 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (operation_queue_.size() == 1) 279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BeginFetch(); 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::AddProvisional(const ExtensionIdSet& ids) { 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) provisional_.insert(ids.begin(), ids.end()); 284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddMany(ids, ADD_PROVISIONAL); 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::Remove(const std::string& id) { 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet ids; 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ids.insert(id); 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RemoveMany(ids); 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::RemoveMany(const ExtensionIdSet& ids) { 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!signature_.get() || !ShouldFetchSignature()) 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool found_any = false; 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (ExtensionIdSet::const_iterator i = ids.begin(); i != ids.end(); ++i) { 299a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (ContainsKey(signature_->ids, *i) || 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ContainsKey(signature_->invalid_ids, *i)) { 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) found_any = true; 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!found_any) 306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InstallVerifier::PendingOperation* operation = 309effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new InstallVerifier::PendingOperation(InstallVerifier::REMOVE); 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation->ids = ids; 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation_queue_.push(linked_ptr<PendingOperation>(operation)); 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (operation_queue_.size() == 1) 314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BeginFetch(); 315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string InstallVerifier::GetDebugPolicyProviderName() const { 318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return std::string("InstallVerifier"); 319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum MustRemainDisabledOutcome { 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VERIFIED = 0, 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_EXTENSION, 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UNPACKED, 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ENTERPRISE_POLICY_ALLOWED, 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FORCED_NOT_VERIFIED, 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_FROM_STORE, 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NO_SIGNATURE, 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_VERIFIED_BUT_NOT_ENFORCING, 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_VERIFIED, 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOT_VERIFIED_BUT_INSTALL_TIME_NEWER_THAN_SIGNATURE, 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOT_VERIFIED_BUT_UNKNOWN_ID, 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) COMPONENT, 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is used in histograms - do not remove or reorder entries above! Also 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the "MAX" item below should always be the last element. 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MUST_REMAIN_DISABLED_OUTCOME_MAX 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MustRemainDisabledHistogram(MustRemainDisabledOutcome outcome) { 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.MustRemainDisabled", 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome, MUST_REMAIN_DISABLED_OUTCOME_MAX); 345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool InstallVerifier::MustRemainDisabled(const Extension* extension, 350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Extension::DisableReason* reason, 351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16* error) const { 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CHECK(extension); 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!CanUseExtensionApis(*extension)) { 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledHistogram(NOT_EXTENSION); 355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (Manifest::IsUnpackedLocation(extension->location())) { 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledHistogram(UNPACKED); 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (extension->location() == Manifest::COMPONENT) { 362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MustRemainDisabledHistogram(COMPONENT); 363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (AllowedByEnterprisePolicy(extension->id())) { 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledHistogram(ENTERPRISE_POLICY_ALLOWED); 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool verified = true; 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledOutcome outcome = VERIFIED; 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ContainsKey(InstallSigner::GetForcedNotFromWebstore(), extension->id())) { 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verified = false; 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = FORCED_NOT_VERIFIED; 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (!FromStore(*extension)) { 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verified = false; 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = NOT_FROM_STORE; 378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } else if (signature_.get() == NULL && 379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) (!bootstrap_check_complete_ || GetStatus() < ENFORCE_STRICT)) { 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we don't have a signature yet, we'll temporarily consider every 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // extension from the webstore verified to avoid false positives on existing 382effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // profiles hitting this code for the first time. The InstallVerifier 383effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // will bootstrap itself once the ExtensionsSystem is ready. 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = NO_SIGNATURE; 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (!IsVerified(extension->id())) { 386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (signature_.get() && 387f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) !ContainsKey(signature_->invalid_ids, extension->id())) { 388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) outcome = NOT_VERIFIED_BUT_UNKNOWN_ID; 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verified = false; 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = NOT_VERIFIED; 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!verified && !ShouldEnforce()) { 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) verified = true; 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) outcome = NOT_VERIFIED_BUT_NOT_ENFORCING; 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MustRemainDisabledHistogram(outcome); 399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!verified) { 401f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (reason) 402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *reason = Extension::DISABLE_NOT_VERIFIED; 403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (error) 404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) *error = l10n_util::GetStringFUTF16( 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IDS_EXTENSIONS_ADDED_WITHOUT_KNOWLEDGE, 406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)); 407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return !verified; 409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 411effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochInstallVerifier::PendingOperation::PendingOperation(OperationType type) 412effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : type(type) {} 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)InstallVerifier::PendingOperation::~PendingOperation() { 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 417effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochExtensionIdSet InstallVerifier::GetExtensionsToVerify() const { 418effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionIdSet result; 419effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch scoped_ptr<ExtensionSet> extensions = 420effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionRegistry::Get(context_)->GenerateInstalledExtensionsSet(); 421effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (ExtensionSet::const_iterator iter = extensions->begin(); 422effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iter != extensions->end(); 423effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++iter) { 424effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (NeedsVerification(**iter)) 425effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result.insert((*iter)->id()); 426effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 427effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return result; 428effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 429effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 430effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid InstallVerifier::MaybeBootstrapSelf() { 431effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool needs_bootstrap = false; 432effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 433effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionIdSet extension_ids = GetExtensionsToVerify(); 434effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (signature_.get() == NULL && ShouldFetchSignature()) { 435effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch needs_bootstrap = true; 436effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 437effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (ExtensionIdSet::const_iterator iter = extension_ids.begin(); 438effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iter != extension_ids.end(); 439effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++iter) { 440effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!IsKnownId(*iter)) { 441effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch needs_bootstrap = true; 442effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 443effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 444effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 445effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 446effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 447effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (needs_bootstrap) 448effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddMany(extension_ids, ADD_ALL_BOOTSTRAP); 449f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) else 450f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bootstrap_check_complete_ = true; 451effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 452effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void InstallVerifier::OnVerificationComplete(bool success, OperationType type) { 454effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch switch (type) { 455effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case ADD_SINGLE: 456effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogAddVerifiedSuccess(success); 457effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 458effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case ADD_ALL: 459effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case ADD_ALL_BOOTSTRAP: 460effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch LogVerifyAllSuccessHistogram(type == ADD_ALL_BOOTSTRAP, success); 461f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bootstrap_check_complete_ = true; 462effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (success) { 463effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Iterate through the extensions and, if any are newly-verified and 464effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // should have the DISABLE_NOT_VERIFIED reason lifted, do so. 465effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const ExtensionSet& disabled_extensions = 466effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionRegistry::Get(context_)->disabled_extensions(); 467effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (ExtensionSet::const_iterator iter = disabled_extensions.begin(); 468effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iter != disabled_extensions.end(); 469effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ++iter) { 470effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int disable_reasons = prefs_->GetDisableReasons((*iter)->id()); 471effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (disable_reasons & Extension::DISABLE_NOT_VERIFIED && 472effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch !MustRemainDisabled(*iter, NULL, NULL)) { 473effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch prefs_->RemoveDisableReason((*iter)->id(), 474effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Extension::DISABLE_NOT_VERIFIED); 475effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 476effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 477f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 478f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (success || GetStatus() == ENFORCE_STRICT) { 479effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ExtensionSystem::Get(context_) 480effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ->extension_service() 481effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ->CheckManagementPolicy(); 482effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 483effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 484effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // We don't need to check disable reasons or report UMA stats for 485effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // provisional adds or removals. 486effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case ADD_PROVISIONAL: 487effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch case REMOVE: 488effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 489effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 490effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 491effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::GarbageCollect() { 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ShouldFetchSignature()) { 494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CHECK(signature_.get()); 497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet leftovers = signature_->ids; 498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) leftovers.insert(signature_->invalid_ids.begin(), 499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) signature_->invalid_ids.end()); 500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdList all_ids; 501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prefs_->GetExtensions(&all_ids); 502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (ExtensionIdList::const_iterator i = all_ids.begin(); 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) i != all_ids.end(); ++i) { 504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet::iterator found = leftovers.find(*i); 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (found != leftovers.end()) 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) leftovers.erase(found); 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!leftovers.empty()) { 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RemoveMany(leftovers); 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool InstallVerifier::AllowedByEnterprisePolicy(const std::string& id) const { 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) PrefService* pref_service = prefs_->pref_service(); 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pref_service->IsManagedPreference(pref_names::kInstallAllowList)) { 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const base::ListValue* whitelist = 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service->GetList(pref_names::kInstallAllowList); 518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::StringValue id_value(id); 519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (whitelist && whitelist->Find(id_value) != whitelist->end()) 520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (pref_service->IsManagedPreference(pref_names::kInstallForceList)) { 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const base::DictionaryValue* forcelist = 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_service->GetDictionary(pref_names::kInstallForceList); 525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (forcelist && forcelist->HasKey(id)) 526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool InstallVerifier::IsVerified(const std::string& id) const { 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return ((signature_.get() && ContainsKey(signature_->ids, id)) || 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ContainsKey(provisional_, id)); 534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::BeginFetch() { 537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(ShouldFetchSignature()); 538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(asargent) - It would be possible to coalesce all operations in the 540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // queue into one fetch - we'd probably just need to change the queue to 541effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // hold (set of ids, list of operation type) pairs. 542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CHECK(!operation_queue_.empty()); 543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const PendingOperation& operation = *operation_queue_.front(); 544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ExtensionIdSet ids_to_sign; 546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (signature_.get()) { 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ids_to_sign.insert(signature_->ids.begin(), signature_->ids.end()); 548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 549effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (operation.type == InstallVerifier::REMOVE) { 550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (ExtensionIdSet::const_iterator i = operation.ids.begin(); 551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) i != operation.ids.end(); ++i) { 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (ContainsKey(ids_to_sign, *i)) 553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ids_to_sign.erase(*i); 554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 555effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { // All other operation types are some form of "ADD". 556effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ids_to_sign.insert(operation.ids.begin(), operation.ids.end()); 557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 559effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch signer_.reset(new InstallSigner(context_->GetRequestContext(), ids_to_sign)); 560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) signer_->GetSignature(base::Bind(&InstallVerifier::SignatureCallback, 561effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch weak_factory_.GetWeakPtr())); 562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::SaveToPrefs() { 565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (signature_.get()) 566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(InstallSigner::VerifySignature(*signature_)); 567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!signature_.get() || signature_->ids.empty()) { 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "SaveToPrefs - saving NULL"; 570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prefs_->SetInstallSignature(NULL); 571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 5725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue pref; 573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) signature_->ToValue(&pref); 574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (VLOG_IS_ON(1)) { 575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DVLOG(1) << "SaveToPrefs - saving"; 576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(InstallSigner::VerifySignature(*signature_.get())); 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<InstallSignature> rehydrated = 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) InstallSignature::FromValue(pref); 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(InstallSigner::VerifySignature(*rehydrated.get())); 581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) prefs_->SetInstallSignature(&pref); 583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum CallbackResult { 5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CALLBACK_NO_SIGNATURE = 0, 5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CALLBACK_INVALID_SIGNATURE, 5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CALLBACK_VALID_SIGNATURE, 5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is used in histograms - do not remove or reorder entries above! Also 5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the "MAX" item below should always be the last element. 5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CALLBACK_RESULT_MAX 5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GetSignatureResultHistogram(CallbackResult result) { 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.GetSignatureResult", 6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result, CALLBACK_RESULT_MAX); 6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 6055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void InstallVerifier::SignatureCallback( 607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<InstallSignature> signature) { 608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) linked_ptr<PendingOperation> operation = operation_queue_.front(); 610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) operation_queue_.pop(); 611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool success = false; 613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!signature.get()) { 6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSignatureResultHistogram(CALLBACK_NO_SIGNATURE); 615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else if (!InstallSigner::VerifySignature(*signature)) { 6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSignatureResultHistogram(CALLBACK_INVALID_SIGNATURE); 617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetSignatureResultHistogram(CALLBACK_VALID_SIGNATURE); 619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) success = true; 620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!success) { 623effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnVerificationComplete(false, operation->type); 624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(asargent) - if this was something like a network error, we need to 626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // do retries with exponential back off. 627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) signature_ = signature.Pass(); 629f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SaveToPrefs(); 630f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 631f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!provisional_.empty()) { 632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Update |provisional_| to remove ids that were successfully signed. 633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) provisional_ = base::STLSetDifference<ExtensionIdSet>( 634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) provisional_, signature_->ids); 635f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 637effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch OnVerificationComplete(success, operation->type); 638f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 639f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 640f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!operation_queue_.empty()) 641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BeginFetch(); 642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 643f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace extensions 645