| 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 |