OLD | NEW |
---|---|
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 10 matching lines...) Expand all Loading... | |
21 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
22 #include "extensions/common/manifest.h" | 22 #include "extensions/common/manifest.h" |
23 #include "grit/generated_resources.h" | 23 #include "grit/generated_resources.h" |
24 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 enum VerifyStatus { | 28 enum VerifyStatus { |
29 NONE = 0, // Do not request install signatures, and do not enforce them. | 29 NONE = 0, // Do not request install signatures, and do not enforce them. |
30 BOOTSTRAP = 1, // Request install signatures, but do not enforce them. | 30 BOOTSTRAP = 1, // Request install signatures, but do not enforce them. |
31 ENFORCE = 2 // Request install signatures, and enforce them. | 31 ENFORCE = 2 // Request install signatures, and enforce them. |
Finnur
2013/12/16 21:42:08
Usually =0 is specified but we leave out the rest.
asargent_no_longer_on_chrome
2013/12/16 22:01:59
Done.
| |
32 }; | 32 }; |
33 | 33 |
34 #if defined(GOOGLE_CHROME_BUILD) | 34 #if defined(GOOGLE_CHROME_BUILD) |
35 const char kExperimentName[] = "ExtensionInstallVerification"; | 35 const char kExperimentName[] = "ExtensionInstallVerification"; |
36 #endif // defined(GOOGLE_CHROME_BUILD) | 36 #endif // defined(GOOGLE_CHROME_BUILD) |
37 | 37 |
38 VerifyStatus GetExperimentStatus() { | 38 VerifyStatus GetExperimentStatus() { |
39 #if defined(GOOGLE_CHROME_BUILD) | 39 #if defined(GOOGLE_CHROME_BUILD) |
40 const std::string group = base::FieldTrialList::FindFullName( | 40 const std::string group = base::FieldTrialList::FindFullName( |
41 kExperimentName); | 41 kExperimentName); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 DVLOG(1) << "Init - ignoring invalid signature"; | 116 DVLOG(1) << "Init - ignoring invalid signature"; |
117 } else { | 117 } else { |
118 signature_ = signature_from_prefs.Pass(); | 118 signature_ = signature_from_prefs.Pass(); |
119 UMA_HISTOGRAM_COUNTS("InstallVerifier.InitGoodSignature", | 119 UMA_HISTOGRAM_COUNTS("InstallVerifier.InitGoodSignature", |
120 signature_->ids.size()); | 120 signature_->ids.size()); |
121 GarbageCollect(); | 121 GarbageCollect(); |
122 } | 122 } |
123 } else { | 123 } else { |
124 UMA_HISTOGRAM_BOOLEAN("InstallVerifier.InitNoSignature", true); | 124 UMA_HISTOGRAM_BOOLEAN("InstallVerifier.InitNoSignature", true); |
125 } | 125 } |
126 } | |
126 | 127 |
127 if (!signature_.get() && ShouldFetchSignature()) { | 128 bool InstallVerifier::NeedsBootstrap() { |
128 // We didn't have any signature but are in fetch mode, so do a request for | 129 return signature_.get() == NULL && ShouldFetchSignature(); |
129 // a signature if needed. | |
130 scoped_ptr<ExtensionPrefs::ExtensionsInfo> all_info = | |
131 prefs_->GetInstalledExtensionsInfo(); | |
132 ExtensionIdSet to_add; | |
133 if (all_info.get()) { | |
134 for (ExtensionPrefs::ExtensionsInfo::const_iterator i = all_info->begin(); | |
135 i != all_info->end(); ++i) { | |
136 const ExtensionInfo& info = **i; | |
137 const base::DictionaryValue* dictionary = info.extension_manifest.get(); | |
138 if (dictionary && ManifestURL::UpdatesFromGallery(dictionary)) { | |
139 Manifest manifest(info.extension_location, | |
140 scoped_ptr<DictionaryValue>( | |
141 dictionary->DeepCopy())); | |
142 if (manifest.is_extension()) | |
143 to_add.insert(info.extension_id); | |
144 } | |
145 } | |
146 } | |
147 if (to_add.empty()) { | |
148 // Write an empty signature so we don't have to redo this at next Init. | |
149 signature_.reset(new InstallSignature()); | |
150 SaveToPrefs(); | |
151 } else { | |
152 AddMany(to_add, AddResultCallback()); | |
153 } | |
154 } | |
155 } | 130 } |
156 | 131 |
157 void InstallVerifier::Add(const std::string& id, | 132 void InstallVerifier::Add(const std::string& id, |
158 const AddResultCallback& callback) { | 133 const AddResultCallback& callback) { |
159 ExtensionIdSet ids; | 134 ExtensionIdSet ids; |
160 ids.insert(id); | 135 ids.insert(id); |
161 AddMany(ids, callback); | 136 AddMany(ids, callback); |
162 } | 137 } |
163 | 138 |
164 void InstallVerifier::AddMany(const ExtensionIdSet& ids, | 139 void InstallVerifier::AddMany(const ExtensionIdSet& ids, |
165 const AddResultCallback& callback) { | 140 const AddResultCallback& callback) { |
166 if (!ShouldFetchSignature()) | 141 if (!ShouldFetchSignature()) { |
142 if (!callback.is_null()) | |
143 callback.Run(true); | |
167 return; | 144 return; |
145 } | |
168 | 146 |
169 if (signature_.get()) { | 147 if (signature_.get()) { |
170 ExtensionIdSet not_allowed_yet = | 148 ExtensionIdSet not_allowed_yet = |
171 base::STLSetDifference<ExtensionIdSet>(ids, signature_->ids); | 149 base::STLSetDifference<ExtensionIdSet>(ids, signature_->ids); |
172 if (not_allowed_yet.empty()) { | 150 if (not_allowed_yet.empty()) { |
173 if (!callback.is_null()) | 151 if (!callback.is_null()) |
174 callback.Run(true); | 152 callback.Run(true); |
175 return; | 153 return; |
176 } | 154 } |
177 } | 155 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
234 } | 212 } |
235 | 213 |
236 bool InstallVerifier::MustRemainDisabled(const Extension* extension, | 214 bool InstallVerifier::MustRemainDisabled(const Extension* extension, |
237 Extension::DisableReason* reason, | 215 Extension::DisableReason* reason, |
238 base::string16* error) const { | 216 base::string16* error) const { |
239 if (!extension->is_extension() || | 217 if (!extension->is_extension() || |
240 Manifest::IsUnpackedLocation(extension->location()) || | 218 Manifest::IsUnpackedLocation(extension->location()) || |
241 AllowedByEnterprisePolicy(extension->id())) | 219 AllowedByEnterprisePolicy(extension->id())) |
242 return false; | 220 return false; |
243 | 221 |
222 // If we don't have a signature yet, we'll temporarily consider every | |
223 // extension from the webstore verified to avoid false positives on existing | |
224 // profiles hitting this code for the first time, and rely on consumers of | |
225 // this class to check NeedsBootstrap() and schedule a first check so we can | |
226 // get a signature. | |
244 bool verified = | 227 bool verified = |
245 FromStore(extension) && | 228 FromStore(extension) && |
246 IsVerified(extension->id()) && | 229 (signature_.get() == NULL || IsVerified(extension->id())) && |
247 !ContainsKey(InstallSigner::GetForcedNotFromWebstore(), extension->id()); | 230 !ContainsKey(InstallSigner::GetForcedNotFromWebstore(), extension->id()); |
248 | 231 |
249 if (!verified && !ShouldEnforce()) { | 232 if (!verified && !ShouldEnforce()) { |
250 if (signature_.get()) | 233 if (signature_.get()) |
251 UMA_HISTOGRAM_BOOLEAN("InstallVerifier.SignatureFailedButNotEnforcing", | 234 UMA_HISTOGRAM_BOOLEAN("InstallVerifier.SignatureFailedButNotEnforcing", |
252 true); | 235 true); |
253 return false; | 236 return false; |
254 } | 237 } |
255 | 238 |
256 if (!verified) { | 239 if (!verified) { |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 } else { | 371 } else { |
389 signature_ = signature.Pass(); | 372 signature_ = signature.Pass(); |
390 SaveToPrefs(); | 373 SaveToPrefs(); |
391 | 374 |
392 if (!provisional_.empty()) { | 375 if (!provisional_.empty()) { |
393 // Update |provisional_| to remove ids that were successfully signed. | 376 // Update |provisional_| to remove ids that were successfully signed. |
394 provisional_ = base::STLSetDifference<ExtensionIdSet>( | 377 provisional_ = base::STLSetDifference<ExtensionIdSet>( |
395 provisional_, signature_->ids); | 378 provisional_, signature_->ids); |
396 } | 379 } |
397 | 380 |
398 // See if we were able to sign all of |ids|. | |
399 ExtensionIdSet not_allowed = | |
400 base::STLSetDifference<ExtensionIdSet>(operation->ids, | |
401 signature_->ids); | |
402 | |
403 UMA_HISTOGRAM_COUNTS_100("InstallVerifier.CallbackNotAllowed", | |
404 not_allowed.size()); | |
405 | |
406 if (!operation->callback.is_null()) | 381 if (!operation->callback.is_null()) |
407 operation->callback.Run(not_allowed.empty()); | 382 operation->callback.Run(success); |
408 } | 383 } |
409 | 384 |
410 if (!operation_queue_.empty()) | 385 if (!operation_queue_.empty()) |
411 BeginFetch(); | 386 BeginFetch(); |
412 } | 387 } |
413 | 388 |
414 | 389 |
415 } // namespace extensions | 390 } // namespace extensions |
OLD | NEW |