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

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

Issue 266963003: Beginning of support for 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/extension_protocols.h ('k') | extensions/browser/extension_system.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/extension_protocols.h" 5 #include "extensions/browser/extension_protocols.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 15 matching lines...) Expand all
26 #include "base/strings/stringprintf.h" 26 #include "base/strings/stringprintf.h"
27 #include "base/strings/utf_string_conversions.h" 27 #include "base/strings/utf_string_conversions.h"
28 #include "base/threading/sequenced_worker_pool.h" 28 #include "base/threading/sequenced_worker_pool.h"
29 #include "base/threading/thread_restrictions.h" 29 #include "base/threading/thread_restrictions.h"
30 #include "base/timer/elapsed_timer.h" 30 #include "base/timer/elapsed_timer.h"
31 #include "build/build_config.h" 31 #include "build/build_config.h"
32 #include "content/public/browser/browser_thread.h" 32 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/resource_request_info.h" 33 #include "content/public/browser/resource_request_info.h"
34 #include "crypto/secure_hash.h" 34 #include "crypto/secure_hash.h"
35 #include "crypto/sha2.h" 35 #include "crypto/sha2.h"
36 #include "extensions/browser/content_verifier.h"
37 #include "extensions/browser/content_verify_job.h"
36 #include "extensions/browser/extensions_browser_client.h" 38 #include "extensions/browser/extensions_browser_client.h"
37 #include "extensions/browser/info_map.h" 39 #include "extensions/browser/info_map.h"
38 #include "extensions/common/constants.h" 40 #include "extensions/common/constants.h"
39 #include "extensions/common/extension.h" 41 #include "extensions/common/extension.h"
40 #include "extensions/common/extension_resource.h" 42 #include "extensions/common/extension_resource.h"
41 #include "extensions/common/file_util.h" 43 #include "extensions/common/file_util.h"
42 #include "extensions/common/manifest_handlers/background_info.h" 44 #include "extensions/common/manifest_handlers/background_info.h"
43 #include "extensions/common/manifest_handlers/csp_info.h" 45 #include "extensions/common/manifest_handlers/csp_info.h"
44 #include "extensions/common/manifest_handlers/icons_handler.h" 46 #include "extensions/common/manifest_handlers/icons_handler.h"
45 #include "extensions/common/manifest_handlers/incognito_info.h" 47 #include "extensions/common/manifest_handlers/incognito_info.h"
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 160
159 class URLRequestExtensionJob : public net::URLRequestFileJob { 161 class URLRequestExtensionJob : public net::URLRequestFileJob {
160 public: 162 public:
161 URLRequestExtensionJob(net::URLRequest* request, 163 URLRequestExtensionJob(net::URLRequest* request,
162 net::NetworkDelegate* network_delegate, 164 net::NetworkDelegate* network_delegate,
163 const std::string& extension_id, 165 const std::string& extension_id,
164 const base::FilePath& directory_path, 166 const base::FilePath& directory_path,
165 const base::FilePath& relative_path, 167 const base::FilePath& relative_path,
166 const std::string& content_security_policy, 168 const std::string& content_security_policy,
167 bool send_cors_header, 169 bool send_cors_header,
168 bool follow_symlinks_anywhere) 170 bool follow_symlinks_anywhere,
171 ContentVerifyJob* verify_job)
169 : net::URLRequestFileJob( 172 : net::URLRequestFileJob(
170 request, 173 request,
171 network_delegate, 174 network_delegate,
172 base::FilePath(), 175 base::FilePath(),
173 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( 176 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
174 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), 177 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
178 verify_job_(verify_job),
175 seek_position_(0), 179 seek_position_(0),
176 bytes_read_(0), 180 bytes_read_(0),
177 directory_path_(directory_path), 181 directory_path_(directory_path),
178 // TODO(tc): Move all of these files into resources.pak so we don't 182 // TODO(tc): Move all of these files into resources.pak so we don't
179 // break when updating on Linux. 183 // break when updating on Linux.
180 resource_(extension_id, directory_path, relative_path), 184 resource_(extension_id, directory_path, relative_path),
181 content_security_policy_(content_security_policy), 185 content_security_policy_(content_security_policy),
182 send_cors_header_(send_cors_header), 186 send_cors_header_(send_cors_header),
183 weak_factory_(this) { 187 weak_factory_(this) {
184 if (follow_symlinks_anywhere) { 188 if (follow_symlinks_anywhere) {
185 resource_.set_follow_symlinks_anywhere(); 189 resource_.set_follow_symlinks_anywhere();
186 } 190 }
187 const std::string& group =
188 base::FieldTrialList::FindFullName("ExtensionContentHashMeasurement");
189 if (group == "Yes") {
190 base::ElapsedTimer timer;
191 hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256));
192 hashing_time_ = timer.Elapsed();
193 }
194 } 191 }
195 192
196 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE { 193 virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE {
197 *info = response_info_; 194 *info = response_info_;
198 } 195 }
199 196
200 virtual void Start() OVERRIDE { 197 virtual void Start() OVERRIDE {
201 base::FilePath* read_file_path = new base::FilePath; 198 base::FilePath* read_file_path = new base::FilePath;
202 base::Time* last_modified_time = new base::Time(); 199 base::Time* last_modified_time = new base::Time();
203 bool posted = BrowserThread::PostBlockingPoolTaskAndReply( 200 bool posted = BrowserThread::PostBlockingPoolTaskAndReply(
204 FROM_HERE, 201 FROM_HERE,
205 base::Bind(&ReadResourceFilePathAndLastModifiedTime, 202 base::Bind(&ReadResourceFilePathAndLastModifiedTime,
206 resource_, 203 resource_,
207 directory_path_, 204 directory_path_,
208 base::Unretained(read_file_path), 205 base::Unretained(read_file_path),
209 base::Unretained(last_modified_time)), 206 base::Unretained(last_modified_time)),
210 base::Bind(&URLRequestExtensionJob::OnFilePathAndLastModifiedTimeRead, 207 base::Bind(&URLRequestExtensionJob::OnFilePathAndLastModifiedTimeRead,
211 weak_factory_.GetWeakPtr(), 208 weak_factory_.GetWeakPtr(),
212 base::Owned(read_file_path), 209 base::Owned(read_file_path),
213 base::Owned(last_modified_time))); 210 base::Owned(last_modified_time)));
214 DCHECK(posted); 211 DCHECK(posted);
215 } 212 }
216 213
214 virtual void SetExtraRequestHeaders(
215 const net::HttpRequestHeaders& headers) OVERRIDE {
216 // TODO(asargent) - we'll need to add proper support for range headers.
217 // crbug.com/369895.
218 std::string range_header;
219 if (headers.GetHeader(net::HttpRequestHeaders::kRange, &range_header)) {
220 if (verify_job_)
221 verify_job_ = NULL;
222 }
223 URLRequestFileJob::SetExtraRequestHeaders(headers);
224 }
225
217 virtual void OnSeekComplete(int64 result) OVERRIDE { 226 virtual void OnSeekComplete(int64 result) OVERRIDE {
218 DCHECK_EQ(seek_position_, 0); 227 DCHECK_EQ(seek_position_, 0);
219 seek_position_ = result; 228 seek_position_ = result;
229 // TODO(asargent) - we'll need to add proper support for range headers.
230 // crbug.com/369895.
231 if (result > 0 && verify_job_)
232 verify_job_ = NULL;
220 } 233 }
221 234
222 virtual void OnReadComplete(net::IOBuffer* buffer, int result) OVERRIDE { 235 virtual void OnReadComplete(net::IOBuffer* buffer, int result) OVERRIDE {
223 if (result >= 0) 236 if (result >= 0)
224 UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.OnReadCompleteResult", result); 237 UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.OnReadCompleteResult", result);
225 else 238 else
226 UMA_HISTOGRAM_SPARSE_SLOWLY("ExtensionUrlRequest.OnReadCompleteError", 239 UMA_HISTOGRAM_SPARSE_SLOWLY("ExtensionUrlRequest.OnReadCompleteError",
227 -result); 240 -result);
228 if (result > 0) { 241 if (result > 0) {
229 bytes_read_ += result; 242 bytes_read_ += result;
230 if (hash_.get()) { 243 if (verify_job_) {
231 base::ElapsedTimer timer; 244 verify_job_->BytesRead(result, buffer->data());
232 hash_->Update(buffer->data(), result); 245 if (!remaining_bytes())
233 hashing_time_ += timer.Elapsed(); 246 verify_job_->DoneReading();
234 } 247 }
235 } 248 }
236 } 249 }
237 250
238 private: 251 private:
239 virtual ~URLRequestExtensionJob() { 252 virtual ~URLRequestExtensionJob() {
240 if (hash_.get()) {
241 base::ElapsedTimer timer;
242 std::string hash_bytes(crypto::kSHA256Length, 0);
243 hash_->Finish(string_as_array(&hash_bytes), hash_bytes.size());
244 hashing_time_ += timer.Elapsed();
245 UMA_HISTOGRAM_TIMES("ExtensionUrlRequest.HashTimeMs", hashing_time_);
246 }
247 UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.TotalKbRead", bytes_read_ / 1024); 253 UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.TotalKbRead", bytes_read_ / 1024);
248 UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.SeekPosition", seek_position_); 254 UMA_HISTOGRAM_COUNTS("ExtensionUrlRequest.SeekPosition", seek_position_);
249 } 255 }
250 256
251 void OnFilePathAndLastModifiedTimeRead(base::FilePath* read_file_path, 257 void OnFilePathAndLastModifiedTimeRead(base::FilePath* read_file_path,
252 base::Time* last_modified_time) { 258 base::Time* last_modified_time) {
253 file_path_ = *read_file_path; 259 file_path_ = *read_file_path;
254 response_info_.headers = BuildHttpHeaders( 260 response_info_.headers = BuildHttpHeaders(
255 content_security_policy_, 261 content_security_policy_,
256 send_cors_header_, 262 send_cors_header_,
257 *last_modified_time); 263 *last_modified_time);
258 URLRequestFileJob::Start(); 264 URLRequestFileJob::Start();
259 } 265 }
260 266
261 // A hash of the contents we've read from the file. 267 scoped_refptr<ContentVerifyJob> verify_job_;
262 scoped_ptr<crypto::SecureHash> hash_;
263 268
264 // The position we seeked to in the file. 269 // The position we seeked to in the file.
265 int64 seek_position_; 270 int64 seek_position_;
266 271
267 // The number of bytes of content we read from the file. 272 // The number of bytes of content we read from the file.
268 int bytes_read_; 273 int bytes_read_;
269 274
270 // Used to count the total time it takes to do hashing operations.
271 base::TimeDelta hashing_time_;
272
273 net::HttpResponseInfo response_info_; 275 net::HttpResponseInfo response_info_;
274 base::FilePath directory_path_; 276 base::FilePath directory_path_;
275 extensions::ExtensionResource resource_; 277 extensions::ExtensionResource resource_;
276 std::string content_security_policy_; 278 std::string content_security_policy_;
277 bool send_cors_header_; 279 bool send_cors_header_;
278 base::WeakPtrFactory<URLRequestExtensionJob> weak_factory_; 280 base::WeakPtrFactory<URLRequestExtensionJob> weak_factory_;
279 }; 281 };
280 282
281 bool ExtensionCanLoadInIncognito(const ResourceRequestInfo* info, 283 bool ExtensionCanLoadInIncognito(const ResourceRequestInfo* info,
282 const std::string& extension_id, 284 const std::string& extension_id,
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 new_extension && 494 new_extension &&
493 (first_party_in_import || 495 (first_party_in_import ||
494 SharedModuleInfo::IsExportAllowed(new_extension, new_relative_path))) { 496 SharedModuleInfo::IsExportAllowed(new_extension, new_relative_path))) {
495 directory_path = new_extension->path(); 497 directory_path = new_extension->path();
496 extension_id = new_extension_id; 498 extension_id = new_extension_id;
497 relative_path = base::FilePath::FromUTF8Unsafe(new_relative_path); 499 relative_path = base::FilePath::FromUTF8Unsafe(new_relative_path);
498 } else { 500 } else {
499 return NULL; 501 return NULL;
500 } 502 }
501 } 503 }
504 ContentVerifyJob* verify_job = NULL;
505 ContentVerifier* verifier = extension_info_map_->content_verifier();
506 if (verifier) {
507 verify_job =
508 verifier->CreateJobFor(extension_id, directory_path, relative_path);
509 if (verify_job)
510 verify_job->Start();
511 }
502 512
503 return new URLRequestExtensionJob(request, 513 return new URLRequestExtensionJob(request,
504 network_delegate, 514 network_delegate,
505 extension_id, 515 extension_id,
506 directory_path, 516 directory_path,
507 relative_path, 517 relative_path,
508 content_security_policy, 518 content_security_policy,
509 send_cors_header, 519 send_cors_header,
510 follow_symlinks_anywhere); 520 follow_symlinks_anywhere,
521 verify_job);
511 } 522 }
512 523
513 } // namespace 524 } // namespace
514 525
515 net::HttpResponseHeaders* BuildHttpHeaders( 526 net::HttpResponseHeaders* BuildHttpHeaders(
516 const std::string& content_security_policy, 527 const std::string& content_security_policy,
517 bool send_cors_header, 528 bool send_cors_header,
518 const base::Time& last_modified_time) { 529 const base::Time& last_modified_time) {
519 std::string raw_headers; 530 std::string raw_headers;
520 raw_headers.append("HTTP/1.1 200 OK"); 531 raw_headers.append("HTTP/1.1 200 OK");
(...skipping 29 matching lines...) Expand all
550 return new net::HttpResponseHeaders(raw_headers); 561 return new net::HttpResponseHeaders(raw_headers);
551 } 562 }
552 563
553 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler( 564 net::URLRequestJobFactory::ProtocolHandler* CreateExtensionProtocolHandler(
554 bool is_incognito, 565 bool is_incognito,
555 extensions::InfoMap* extension_info_map) { 566 extensions::InfoMap* extension_info_map) {
556 return new ExtensionProtocolHandler(is_incognito, extension_info_map); 567 return new ExtensionProtocolHandler(is_incognito, extension_info_map);
557 } 568 }
558 569
559 } // namespace extensions 570 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/extension_protocols.h ('k') | extensions/browser/extension_system.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698