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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 } | 169 } |
170 } else { | 170 } else { |
171 LogInitResultHistogram(INIT_NO_PREF); | 171 LogInitResultHistogram(INIT_NO_PREF); |
172 } | 172 } |
173 } | 173 } |
174 | 174 |
175 bool InstallVerifier::NeedsBootstrap() { | 175 bool InstallVerifier::NeedsBootstrap() { |
176 return signature_.get() == NULL && ShouldFetchSignature(); | 176 return signature_.get() == NULL && ShouldFetchSignature(); |
177 } | 177 } |
178 | 178 |
| 179 base::Time InstallVerifier::SignatureTimestamp() { |
| 180 if (signature_.get()) |
| 181 return signature_->timestamp; |
| 182 else |
| 183 return base::Time(); |
| 184 } |
| 185 |
179 void InstallVerifier::Add(const std::string& id, | 186 void InstallVerifier::Add(const std::string& id, |
180 const AddResultCallback& callback) { | 187 const AddResultCallback& callback) { |
181 ExtensionIdSet ids; | 188 ExtensionIdSet ids; |
182 ids.insert(id); | 189 ids.insert(id); |
183 AddMany(ids, callback); | 190 AddMany(ids, callback); |
184 } | 191 } |
185 | 192 |
186 void InstallVerifier::AddMany(const ExtensionIdSet& ids, | 193 void InstallVerifier::AddMany(const ExtensionIdSet& ids, |
187 const AddResultCallback& callback) { | 194 const AddResultCallback& callback) { |
188 if (!ShouldFetchSignature()) { | 195 if (!ShouldFetchSignature()) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 enum MustRemainDisabledOutcome { | 265 enum MustRemainDisabledOutcome { |
259 VERIFIED = 0, | 266 VERIFIED = 0, |
260 NOT_EXTENSION, | 267 NOT_EXTENSION, |
261 UNPACKED, | 268 UNPACKED, |
262 ENTERPRISE_POLICY_ALLOWED, | 269 ENTERPRISE_POLICY_ALLOWED, |
263 FORCED_NOT_VERIFIED, | 270 FORCED_NOT_VERIFIED, |
264 NOT_FROM_STORE, | 271 NOT_FROM_STORE, |
265 NO_SIGNATURE, | 272 NO_SIGNATURE, |
266 NOT_VERIFIED_BUT_NOT_ENFORCING, | 273 NOT_VERIFIED_BUT_NOT_ENFORCING, |
267 NOT_VERIFIED, | 274 NOT_VERIFIED, |
| 275 NOT_VERIFIED_BUT_INSTALL_TIME_NEWER_THAN_SIGNATURE, |
268 | 276 |
269 // This is used in histograms - do not remove or reorder entries above! Also | 277 // This is used in histograms - do not remove or reorder entries above! Also |
270 // the "MAX" item below should always be the last element. | 278 // the "MAX" item below should always be the last element. |
271 | |
272 MUST_REMAIN_DISABLED_OUTCOME_MAX | 279 MUST_REMAIN_DISABLED_OUTCOME_MAX |
273 }; | 280 }; |
274 | 281 |
275 void MustRemainDisabledHistogram(MustRemainDisabledOutcome outcome) { | 282 void MustRemainDisabledHistogram(MustRemainDisabledOutcome outcome) { |
276 UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.MustRemainDisabled", | 283 UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.MustRemainDisabled", |
277 outcome, MUST_REMAIN_DISABLED_OUTCOME_MAX); | 284 outcome, MUST_REMAIN_DISABLED_OUTCOME_MAX); |
278 } | 285 } |
279 | 286 |
280 } // namespace | 287 } // namespace |
281 | 288 |
(...skipping 23 matching lines...) Expand all Loading... |
305 verified = false; | 312 verified = false; |
306 outcome = NOT_FROM_STORE; | 313 outcome = NOT_FROM_STORE; |
307 } else if (signature_.get() == NULL) { | 314 } else if (signature_.get() == NULL) { |
308 // If we don't have a signature yet, we'll temporarily consider every | 315 // If we don't have a signature yet, we'll temporarily consider every |
309 // extension from the webstore verified to avoid false positives on existing | 316 // extension from the webstore verified to avoid false positives on existing |
310 // profiles hitting this code for the first time, and rely on consumers of | 317 // profiles hitting this code for the first time, and rely on consumers of |
311 // this class to check NeedsBootstrap() and schedule a first check so we can | 318 // this class to check NeedsBootstrap() and schedule a first check so we can |
312 // get a signature. | 319 // get a signature. |
313 outcome = NO_SIGNATURE; | 320 outcome = NO_SIGNATURE; |
314 } else if (!IsVerified(extension->id())) { | 321 } else if (!IsVerified(extension->id())) { |
315 verified = false; | 322 if (WasInstalledAfterSignature(extension->id())) { |
316 outcome = NOT_VERIFIED; | 323 outcome = NOT_VERIFIED_BUT_INSTALL_TIME_NEWER_THAN_SIGNATURE; |
| 324 } else { |
| 325 verified = false; |
| 326 outcome = NOT_VERIFIED; |
| 327 } |
317 } | 328 } |
318 if (!verified && !ShouldEnforce()) { | 329 if (!verified && !ShouldEnforce()) { |
319 verified = true; | 330 verified = true; |
320 outcome = NOT_VERIFIED_BUT_NOT_ENFORCING; | 331 outcome = NOT_VERIFIED_BUT_NOT_ENFORCING; |
321 } | 332 } |
322 MustRemainDisabledHistogram(outcome); | 333 MustRemainDisabledHistogram(outcome); |
323 | 334 |
324 if (!verified) { | 335 if (!verified) { |
325 if (reason) | 336 if (reason) |
326 *reason = Extension::DISABLE_NOT_VERIFIED; | 337 *reason = Extension::DISABLE_NOT_VERIFIED; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 return true; | 385 return true; |
375 } | 386 } |
376 return false; | 387 return false; |
377 } | 388 } |
378 | 389 |
379 bool InstallVerifier::IsVerified(const std::string& id) const { | 390 bool InstallVerifier::IsVerified(const std::string& id) const { |
380 return ((signature_.get() && ContainsKey(signature_->ids, id)) || | 391 return ((signature_.get() && ContainsKey(signature_->ids, id)) || |
381 ContainsKey(provisional_, id)); | 392 ContainsKey(provisional_, id)); |
382 } | 393 } |
383 | 394 |
| 395 bool InstallVerifier::WasInstalledAfterSignature(const std::string& id) const { |
| 396 if (!signature_.get() || signature_->timestamp.is_null()) |
| 397 return true; |
| 398 |
| 399 base::Time install_time = prefs_->GetInstallTime(id); |
| 400 // If the extension install time is in the future, just assume it isn't |
| 401 // newer than the signature. (Either the clock went backwards, or |
| 402 // an attacker changed the install time in the preferences). |
| 403 if (install_time >= base::Time::Now()) |
| 404 return false; |
| 405 return install_time > signature_->timestamp; |
| 406 } |
| 407 |
384 void InstallVerifier::BeginFetch() { | 408 void InstallVerifier::BeginFetch() { |
385 DCHECK(ShouldFetchSignature()); | 409 DCHECK(ShouldFetchSignature()); |
386 | 410 |
387 // TODO(asargent) - It would be possible to coalesce all operations in the | 411 // TODO(asargent) - It would be possible to coalesce all operations in the |
388 // queue into one fetch - we'd probably just need to change the queue to | 412 // queue into one fetch - we'd probably just need to change the queue to |
389 // hold (set of ids, list of callbacks) pairs. | 413 // hold (set of ids, list of callbacks) pairs. |
390 CHECK(!operation_queue_.empty()); | 414 CHECK(!operation_queue_.empty()); |
391 const PendingOperation& operation = *operation_queue_.front(); | 415 const PendingOperation& operation = *operation_queue_.front(); |
392 | 416 |
393 ExtensionIdSet ids_to_sign; | 417 ExtensionIdSet ids_to_sign; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 if (!operation->callback.is_null()) | 510 if (!operation->callback.is_null()) |
487 operation->callback.Run(success); | 511 operation->callback.Run(success); |
488 } | 512 } |
489 | 513 |
490 if (!operation_queue_.empty()) | 514 if (!operation_queue_.empty()) |
491 BeginFetch(); | 515 BeginFetch(); |
492 } | 516 } |
493 | 517 |
494 | 518 |
495 } // namespace extensions | 519 } // namespace extensions |
OLD | NEW |