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

Side by Side Diff: extensions/browser/content_verifier.cc

Issue 280013003: More implementation details of extension content verification (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged latest trunk Created 6 years, 7 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
« no previous file with comments | « extensions/browser/content_verifier.h ('k') | extensions/browser/content_verifier_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/browser/content_verifier.h" 5 #include "extensions/browser/content_verifier.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/metrics/field_trial.h" 11 #include "base/metrics/field_trial.h"
12 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
13 #include "extensions/browser/content_hash_fetcher.h"
14 #include "extensions/browser/content_hash_reader.h"
15 #include "extensions/browser/content_verifier_delegate.h"
13 #include "extensions/browser/extension_registry.h" 16 #include "extensions/browser/extension_registry.h"
14 #include "extensions/common/switches.h" 17 #include "extensions/common/switches.h"
15 18
16 namespace { 19 namespace {
17 20
18 const char kExperimentName[] = "ExtensionContentVerification"; 21 const char kExperimentName[] = "ExtensionContentVerification";
19 22
20 } // namespace 23 } // namespace
21 24
22 namespace extensions { 25 namespace extensions {
23 26
24 ContentVerifier::ContentVerifier(content::BrowserContext* context, 27 ContentVerifier::ContentVerifier(content::BrowserContext* context,
25 const ContentVerifierFilter& filter) 28 ContentVerifierDelegate* delegate)
26 : mode_(GetMode()), 29 : mode_(GetMode()),
27 filter_(filter),
28 context_(context), 30 context_(context),
29 observers_(new ObserverListThreadSafe<ContentVerifierObserver>) { 31 delegate_(delegate),
32 fetcher_(new ContentHashFetcher(context, delegate)) {
30 } 33 }
31 34
32 ContentVerifier::~ContentVerifier() { 35 ContentVerifier::~ContentVerifier() {
33 } 36 }
34 37
35 void ContentVerifier::Start() { 38 void ContentVerifier::Start() {
39 if (mode_ >= BOOTSTRAP)
40 fetcher_->Start();
36 } 41 }
37 42
38 void ContentVerifier::Shutdown() { 43 void ContentVerifier::Shutdown() {
39 filter_.Reset(); 44 fetcher_.reset();
45 delegate_.reset();
40 } 46 }
41 47
42 ContentVerifyJob* ContentVerifier::CreateJobFor( 48 ContentVerifyJob* ContentVerifier::CreateJobFor(
43 const std::string& extension_id, 49 const std::string& extension_id,
44 const base::FilePath& extension_root, 50 const base::FilePath& extension_root,
45 const base::FilePath& relative_path) { 51 const base::FilePath& relative_path) {
46 if (filter_.is_null()) 52 if (!delegate_)
47 return NULL; 53 return NULL;
48 54
49 ExtensionRegistry* registry = ExtensionRegistry::Get(context_); 55 ExtensionRegistry* registry = ExtensionRegistry::Get(context_);
50 const Extension* extension = 56 const Extension* extension =
51 registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); 57 registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
52 58
53 if (!extension || !filter_.Run(extension)) 59 if (!extension || !delegate_->ShouldBeVerified(*extension) ||
60 !extension->version())
54 return NULL; 61 return NULL;
55 62
56 return new ContentVerifyJob( 63 return new ContentVerifyJob(
57 extension_id, 64 new ContentHashReader(extension_id,
65 *extension->version(),
66 extension_root,
67 relative_path,
68 delegate_->PublicKey()),
58 base::Bind(&ContentVerifier::VerifyFailed, this, extension->id())); 69 base::Bind(&ContentVerifier::VerifyFailed, this, extension->id()));
59 } 70 }
60 71
61 void ContentVerifier::VerifyFailed(const std::string& extension_id, 72 void ContentVerifier::VerifyFailed(const std::string& extension_id,
62 ContentVerifyJob::FailureReason reason) { 73 ContentVerifyJob::FailureReason reason) {
63 if (mode_ < ENFORCE) 74 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
64 return;
65
66 if (reason == ContentVerifyJob::NO_HASHES && mode_ < ENFORCE_STRICT) {
67 content::BrowserThread::PostTask( 75 content::BrowserThread::PostTask(
68 content::BrowserThread::UI, 76 content::BrowserThread::UI,
69 FROM_HERE, 77 FROM_HERE,
70 base::Bind(&ContentVerifier::RequestFetch, this, extension_id)); 78 base::Bind(&ContentVerifier::VerifyFailed, this, extension_id, reason));
71 return; 79 return;
72 } 80 }
73 81
74 // The magic of ObserverListThreadSafe will make sure that observers get 82 if (!delegate_ || mode_ < ENFORCE)
75 // called on the same threads that they called AddObserver on. 83 return;
76 observers_->Notify(&ContentVerifierObserver::ContentVerifyFailed,
77 extension_id);
78 }
79 84
80 void ContentVerifier::AddObserver(ContentVerifierObserver* observer) { 85 if (reason == ContentVerifyJob::NO_HASHES && mode_ < ENFORCE_STRICT &&
81 observers_->AddObserver(observer); 86 fetcher_.get()) {
82 } 87 // If we failed because there were no hashes yet for this extension, just
83 88 // request some.
84 void ContentVerifier::RemoveObserver(ContentVerifierObserver* observer) { 89 ExtensionRegistry* registry = ExtensionRegistry::Get(context_);
85 observers_->RemoveObserver(observer); 90 const Extension* extension =
86 } 91 registry->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING);
87 92 if (extension)
88 void ContentVerifier::RequestFetch(const std::string& extension_id) { 93 fetcher_->DoFetch(extension);
94 return;
95 }
96 delegate_->VerifyFailed(extension_id);
89 } 97 }
90 98
91 // static 99 // static
92 ContentVerifier::Mode ContentVerifier::GetMode() { 100 ContentVerifier::Mode ContentVerifier::GetMode() {
93 Mode experiment_value = NONE; 101 Mode experiment_value = NONE;
94 const std::string group = base::FieldTrialList::FindFullName(kExperimentName); 102 const std::string group = base::FieldTrialList::FindFullName(kExperimentName);
95 if (group == "EnforceStrict") 103 if (group == "EnforceStrict")
96 experiment_value = ENFORCE_STRICT; 104 experiment_value = ENFORCE_STRICT;
97 else if (group == "Enforce") 105 else if (group == "Enforce")
98 experiment_value = ENFORCE; 106 experiment_value = ENFORCE;
(...skipping 17 matching lines...) Expand all
116 cmdline_value = ENFORCE; 124 cmdline_value = ENFORCE;
117 } 125 }
118 126
119 // We don't want to allow the command-line flags to eg disable enforcement if 127 // We don't want to allow the command-line flags to eg disable enforcement if
120 // the experiment group says it should be on, or malware may just modify the 128 // the experiment group says it should be on, or malware may just modify the
121 // command line flags. So return the more restrictive of the 2 values. 129 // command line flags. So return the more restrictive of the 2 values.
122 return std::max(experiment_value, cmdline_value); 130 return std::max(experiment_value, cmdline_value);
123 } 131 }
124 132
125 } // namespace extensions 133 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/content_verifier.h ('k') | extensions/browser/content_verifier_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698