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

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

Issue 464463003: Adding logging of offstore extensions state to user metrics. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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_verifier.h" 5 #include "chrome/browser/extensions/install_verifier.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 // the "MAX" item below should always be the last element. 121 // the "MAX" item below should always be the last element.
122 122
123 INIT_RESULT_MAX 123 INIT_RESULT_MAX
124 }; 124 };
125 125
126 void LogInitResultHistogram(InitResult result) { 126 void LogInitResultHistogram(InitResult result) {
127 UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.InitResult", 127 UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.InitResult",
128 result, INIT_RESULT_MAX); 128 result, INIT_RESULT_MAX);
129 } 129 }
130 130
131 bool FromStore(const Extension& extension) {
132 if (extension.from_webstore() || ManifestURL::UpdatesFromGallery(&extension))
133 return true;
134
135 // If an extension has no update url, our autoupdate code will ask the
136 // webstore about it (to aid in migrating to the webstore from self-hosting
137 // or sideloading based installs). So we want to do verification checks on
138 // such extensions too so that we don't accidentally disable old installs of
139 // extensions that did migrate to the webstore.
140 return (ManifestURL::GetUpdateURL(&extension).is_empty() &&
141 Manifest::IsAutoUpdateableLocation(extension.location()));
142 }
143
144 bool CanUseExtensionApis(const Extension& extension) { 131 bool CanUseExtensionApis(const Extension& extension) {
145 return extension.is_extension() || extension.is_legacy_packaged_app(); 132 return extension.is_extension() || extension.is_legacy_packaged_app();
146 } 133 }
147 134
148 enum VerifyAllSuccess { 135 enum VerifyAllSuccess {
149 VERIFY_ALL_BOOTSTRAP_SUCCESS = 0, 136 VERIFY_ALL_BOOTSTRAP_SUCCESS = 0,
150 VERIFY_ALL_BOOTSTRAP_FAILURE, 137 VERIFY_ALL_BOOTSTRAP_FAILURE,
151 VERIFY_ALL_NON_BOOTSTRAP_SUCCESS, 138 VERIFY_ALL_NON_BOOTSTRAP_SUCCESS,
152 VERIFY_ALL_NON_BOOTSTRAP_FAILURE, 139 VERIFY_ALL_NON_BOOTSTRAP_FAILURE,
153 140
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 : prefs_(prefs), 176 : prefs_(prefs),
190 context_(context), 177 context_(context),
191 bootstrap_check_complete_(false), 178 bootstrap_check_complete_(false),
192 weak_factory_(this) { 179 weak_factory_(this) {
193 } 180 }
194 181
195 InstallVerifier::~InstallVerifier() {} 182 InstallVerifier::~InstallVerifier() {}
196 183
197 // static 184 // static
198 bool InstallVerifier::NeedsVerification(const Extension& extension) { 185 bool InstallVerifier::NeedsVerification(const Extension& extension) {
199 return FromStore(extension) && CanUseExtensionApis(extension); 186 return IsFromStore(extension) && CanUseExtensionApis(extension);
187 }
188
189
190
191 // static
192 bool InstallVerifier::IsFromStore(const Extension& extension) {
193 if (extension.from_webstore() || ManifestURL::UpdatesFromGallery(&extension))
194 return true;
195
196 // If an extension has no update url, our autoupdate code will ask the
197 // webstore about it (to aid in migrating to the webstore from self-hosting
198 // or sideloading based installs). So we want to do verification checks on
199 // such extensions too so that we don't accidentally disable old installs of
200 // extensions that did migrate to the webstore.
201 return (ManifestURL::GetUpdateURL(&extension).is_empty() &&
202 Manifest::IsAutoUpdateableLocation(extension.location()));
200 } 203 }
201 204
202 void InstallVerifier::Init() { 205 void InstallVerifier::Init() {
203 UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ExperimentStatus", 206 UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ExperimentStatus",
204 GetExperimentStatus(), VERIFY_STATUS_MAX); 207 GetExperimentStatus(), VERIFY_STATUS_MAX);
205 UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ActualStatus", 208 UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ActualStatus",
206 GetStatus(), VERIFY_STATUS_MAX); 209 GetStatus(), VERIFY_STATUS_MAX);
207 210
208 const base::DictionaryValue* pref = prefs_->GetInstallSignature(); 211 const base::DictionaryValue* pref = prefs_->GetInstallSignature();
209 if (pref) { 212 if (pref) {
(...skipping 25 matching lines...) Expand all
235 AddMany(GetExtensionsToVerify(), ADD_ALL); 238 AddMany(GetExtensionsToVerify(), ADD_ALL);
236 } 239 }
237 240
238 base::Time InstallVerifier::SignatureTimestamp() { 241 base::Time InstallVerifier::SignatureTimestamp() {
239 if (signature_.get()) 242 if (signature_.get())
240 return signature_->timestamp; 243 return signature_->timestamp;
241 else 244 else
242 return base::Time(); 245 return base::Time();
243 } 246 }
244 247
245 bool InstallVerifier::IsKnownId(const std::string& id) { 248 bool InstallVerifier::IsKnownId(const std::string& id) const {
246 return signature_.get() && (ContainsKey(signature_->ids, id) || 249 return signature_.get() && (ContainsKey(signature_->ids, id) ||
247 ContainsKey(signature_->invalid_ids, id)); 250 ContainsKey(signature_->invalid_ids, id));
248 } 251 }
249 252
253 bool InstallVerifier::IsInvalid(const std::string& id) const {
254 return ((signature_.get() && ContainsKey(signature_->invalid_ids, id)));
255 }
256
250 void InstallVerifier::VerifyExtension(const std::string& extension_id) { 257 void InstallVerifier::VerifyExtension(const std::string& extension_id) {
251 ExtensionIdSet ids; 258 ExtensionIdSet ids;
252 ids.insert(extension_id); 259 ids.insert(extension_id);
253 AddMany(ids, ADD_SINGLE); 260 AddMany(ids, ADD_SINGLE);
254 } 261 }
255 262
256 void InstallVerifier::AddMany(const ExtensionIdSet& ids, OperationType type) { 263 void InstallVerifier::AddMany(const ExtensionIdSet& ids, OperationType type) {
257 if (!ShouldFetchSignature()) { 264 if (!ShouldFetchSignature()) {
258 OnVerificationComplete(true, type); // considered successful. 265 OnVerificationComplete(true, type); // considered successful.
259 return; 266 return;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 314
308 InstallVerifier::PendingOperation* operation = 315 InstallVerifier::PendingOperation* operation =
309 new InstallVerifier::PendingOperation(InstallVerifier::REMOVE); 316 new InstallVerifier::PendingOperation(InstallVerifier::REMOVE);
310 operation->ids = ids; 317 operation->ids = ids;
311 318
312 operation_queue_.push(linked_ptr<PendingOperation>(operation)); 319 operation_queue_.push(linked_ptr<PendingOperation>(operation));
313 if (operation_queue_.size() == 1) 320 if (operation_queue_.size() == 1)
314 BeginFetch(); 321 BeginFetch();
315 } 322 }
316 323
324 bool InstallVerifier::AllowedByEnterprisePolicy(const std::string& id) const {
325 PrefService* pref_service = prefs_->pref_service();
326 if (pref_service->IsManagedPreference(pref_names::kInstallAllowList)) {
327 const base::ListValue* whitelist =
328 pref_service->GetList(pref_names::kInstallAllowList);
329 base::StringValue id_value(id);
330 if (whitelist && whitelist->Find(id_value) != whitelist->end())
331 return true;
332 }
333 if (pref_service->IsManagedPreference(pref_names::kInstallForceList)) {
334 const base::DictionaryValue* forcelist =
335 pref_service->GetDictionary(pref_names::kInstallForceList);
336 if (forcelist && forcelist->HasKey(id))
337 return true;
338 }
339 return false;
340 }
341
317 std::string InstallVerifier::GetDebugPolicyProviderName() const { 342 std::string InstallVerifier::GetDebugPolicyProviderName() const {
318 return std::string("InstallVerifier"); 343 return std::string("InstallVerifier");
319 } 344 }
320 345
321 namespace { 346 namespace {
322 347
323 enum MustRemainDisabledOutcome { 348 enum MustRemainDisabledOutcome {
324 VERIFIED = 0, 349 VERIFIED = 0,
325 NOT_EXTENSION, 350 NOT_EXTENSION,
326 UNPACKED, 351 UNPACKED,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 if (AllowedByEnterprisePolicy(extension->id())) { 390 if (AllowedByEnterprisePolicy(extension->id())) {
366 MustRemainDisabledHistogram(ENTERPRISE_POLICY_ALLOWED); 391 MustRemainDisabledHistogram(ENTERPRISE_POLICY_ALLOWED);
367 return false; 392 return false;
368 } 393 }
369 394
370 bool verified = true; 395 bool verified = true;
371 MustRemainDisabledOutcome outcome = VERIFIED; 396 MustRemainDisabledOutcome outcome = VERIFIED;
372 if (ContainsKey(InstallSigner::GetForcedNotFromWebstore(), extension->id())) { 397 if (ContainsKey(InstallSigner::GetForcedNotFromWebstore(), extension->id())) {
373 verified = false; 398 verified = false;
374 outcome = FORCED_NOT_VERIFIED; 399 outcome = FORCED_NOT_VERIFIED;
375 } else if (!FromStore(*extension)) { 400 } else if (!IsFromStore(*extension)) {
376 verified = false; 401 verified = false;
377 outcome = NOT_FROM_STORE; 402 outcome = NOT_FROM_STORE;
378 } else if (signature_.get() == NULL && 403 } else if (signature_.get() == NULL &&
379 (!bootstrap_check_complete_ || GetStatus() < ENFORCE_STRICT)) { 404 (!bootstrap_check_complete_ || GetStatus() < ENFORCE_STRICT)) {
380 // If we don't have a signature yet, we'll temporarily consider every 405 // If we don't have a signature yet, we'll temporarily consider every
381 // extension from the webstore verified to avoid false positives on existing 406 // extension from the webstore verified to avoid false positives on existing
382 // profiles hitting this code for the first time. The InstallVerifier 407 // profiles hitting this code for the first time. The InstallVerifier
383 // will bootstrap itself once the ExtensionsSystem is ready. 408 // will bootstrap itself once the ExtensionsSystem is ready.
384 outcome = NO_SIGNATURE; 409 outcome = NO_SIGNATURE;
385 } else if (!IsVerified(extension->id())) { 410 } else if (!IsVerified(extension->id())) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 i != all_ids.end(); ++i) { 528 i != all_ids.end(); ++i) {
504 ExtensionIdSet::iterator found = leftovers.find(*i); 529 ExtensionIdSet::iterator found = leftovers.find(*i);
505 if (found != leftovers.end()) 530 if (found != leftovers.end())
506 leftovers.erase(found); 531 leftovers.erase(found);
507 } 532 }
508 if (!leftovers.empty()) { 533 if (!leftovers.empty()) {
509 RemoveMany(leftovers); 534 RemoveMany(leftovers);
510 } 535 }
511 } 536 }
512 537
513 bool InstallVerifier::AllowedByEnterprisePolicy(const std::string& id) const {
514 PrefService* pref_service = prefs_->pref_service();
515 if (pref_service->IsManagedPreference(pref_names::kInstallAllowList)) {
516 const base::ListValue* whitelist =
517 pref_service->GetList(pref_names::kInstallAllowList);
518 base::StringValue id_value(id);
519 if (whitelist && whitelist->Find(id_value) != whitelist->end())
520 return true;
521 }
522 if (pref_service->IsManagedPreference(pref_names::kInstallForceList)) {
523 const base::DictionaryValue* forcelist =
524 pref_service->GetDictionary(pref_names::kInstallForceList);
525 if (forcelist && forcelist->HasKey(id))
526 return true;
527 }
528 return false;
529 }
530
531 bool InstallVerifier::IsVerified(const std::string& id) const { 538 bool InstallVerifier::IsVerified(const std::string& id) const {
532 return ((signature_.get() && ContainsKey(signature_->ids, id)) || 539 return ((signature_.get() && ContainsKey(signature_->ids, id)) ||
533 ContainsKey(provisional_, id)); 540 ContainsKey(provisional_, id));
534 } 541 }
535 542
536 void InstallVerifier::BeginFetch() { 543 void InstallVerifier::BeginFetch() {
537 DCHECK(ShouldFetchSignature()); 544 DCHECK(ShouldFetchSignature());
538 545
539 // TODO(asargent) - It would be possible to coalesce all operations in the 546 // TODO(asargent) - It would be possible to coalesce all operations in the
540 // queue into one fetch - we'd probably just need to change the queue to 547 // queue into one fetch - we'd probably just need to change the queue to
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 } 642 }
636 643
637 OnVerificationComplete(success, operation->type); 644 OnVerificationComplete(success, operation->type);
638 } 645 }
639 646
640 if (!operation_queue_.empty()) 647 if (!operation_queue_.empty())
641 BeginFetch(); 648 BeginFetch();
642 } 649 }
643 650
644 } // namespace extensions 651 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698