Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / install_verifier.cc
index 7f06c68..1f6e824 100644 (file)
@@ -30,6 +30,11 @@ enum VerifyStatus {
   NONE = 0,   // Do not request install signatures, and do not enforce them.
   BOOTSTRAP,  // Request install signatures, but do not enforce them.
   ENFORCE,    // Request install signatures, and enforce them.
+
+  // This is used in histograms - do not remove or reorder entries above! Also
+  // the "MAX" item below should always be the last element.
+
+  VERIFY_STATUS_MAX
 };
 
 #if defined(GOOGLE_CHROME_BUILD)
@@ -49,7 +54,7 @@ VerifyStatus GetExperimentStatus() {
     return ENFORCE;
   }
 
-  VerifyStatus default_status = BOOTSTRAP;
+  VerifyStatus default_status = NONE;
 
   if (group == "Enforce")
     return ENFORCE;
@@ -141,6 +146,11 @@ bool InstallVerifier::NeedsVerification(const Extension& extension) {
 }
 
 void InstallVerifier::Init() {
+  UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ExperimentStatus",
+                            GetExperimentStatus(), VERIFY_STATUS_MAX);
+  UMA_HISTOGRAM_ENUMERATION("ExtensionInstallVerifier.ActualStatus",
+                            GetStatus(), VERIFY_STATUS_MAX);
+
   const base::DictionaryValue* pref = prefs_->GetInstallSignature();
   if (pref) {
     scoped_ptr<InstallSignature> signature_from_prefs =
@@ -166,6 +176,13 @@ bool InstallVerifier::NeedsBootstrap() {
   return signature_.get() == NULL && ShouldFetchSignature();
 }
 
+base::Time InstallVerifier::SignatureTimestamp() {
+  if (signature_.get())
+    return signature_->timestamp;
+  else
+    return base::Time();
+}
+
 void InstallVerifier::Add(const std::string& id,
                           const AddResultCallback& callback) {
   ExtensionIdSet ids;
@@ -255,10 +272,10 @@ enum MustRemainDisabledOutcome {
   NO_SIGNATURE,
   NOT_VERIFIED_BUT_NOT_ENFORCING,
   NOT_VERIFIED,
+  NOT_VERIFIED_BUT_INSTALL_TIME_NEWER_THAN_SIGNATURE,
 
   // This is used in histograms - do not remove or reorder entries above! Also
   // the "MAX" item below should always be the last element.
-
   MUST_REMAIN_DISABLED_OUTCOME_MAX
 };
 
@@ -302,8 +319,12 @@ bool InstallVerifier::MustRemainDisabled(const Extension* extension,
     // get a signature.
     outcome = NO_SIGNATURE;
   } else if (!IsVerified(extension->id())) {
-    verified = false;
-    outcome = NOT_VERIFIED;
+    if (WasInstalledAfterSignature(extension->id())) {
+      outcome = NOT_VERIFIED_BUT_INSTALL_TIME_NEWER_THAN_SIGNATURE;
+    } else {
+      verified = false;
+      outcome = NOT_VERIFIED;
+    }
   }
   if (!verified && !ShouldEnforce()) {
     verified = true;
@@ -371,6 +392,19 @@ bool InstallVerifier::IsVerified(const std::string& id) const {
           ContainsKey(provisional_, id));
 }
 
+bool InstallVerifier::WasInstalledAfterSignature(const std::string& id) const {
+  if (!signature_.get() || signature_->timestamp.is_null())
+    return true;
+
+  base::Time install_time = prefs_->GetInstallTime(id);
+  // If the extension install time is in the future, just assume it isn't
+  // newer than the signature. (Either the clock went backwards, or
+  // an attacker changed the install time in the preferences).
+  if (install_time >= base::Time::Now())
+    return false;
+  return install_time > signature_->timestamp;
+}
+
 void InstallVerifier::BeginFetch() {
   DCHECK(ShouldFetchSignature());