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

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

Issue 2336403002: Fix extension content verification out-of-band hash fetching (Closed)
Patch Set: Created 4 years, 3 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
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_hash_fetcher.h" 5 #include "extensions/browser/content_hash_fetcher.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <memory>
11 #include <vector>
10 12
11 #include "base/base64.h" 13 #include "base/base64.h"
12 #include "base/files/file_enumerator.h" 14 #include "base/files/file_enumerator.h"
13 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
14 #include "base/json/json_reader.h" 16 #include "base/json/json_reader.h"
15 #include "base/macros.h" 17 #include "base/macros.h"
16 #include "base/memory/ref_counted.h" 18 #include "base/memory/ref_counted.h"
17 #include "base/metrics/histogram.h" 19 #include "base/metrics/histogram.h"
18 #include "base/synchronization/lock.h" 20 #include "base/synchronization/lock.h"
19 #include "base/task_runner_util.h" 21 #include "base/task_runner_util.h"
20 #include "base/timer/elapsed_timer.h" 22 #include "base/timer/elapsed_timer.h"
21 #include "base/version.h" 23 #include "base/version.h"
22 #include "content/public/browser/browser_context.h"
23 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/storage_partition.h"
25 #include "crypto/sha2.h" 25 #include "crypto/sha2.h"
26 #include "extensions/browser/computed_hashes.h" 26 #include "extensions/browser/computed_hashes.h"
27 #include "extensions/browser/content_hash_tree.h" 27 #include "extensions/browser/content_hash_tree.h"
28 #include "extensions/browser/content_verifier_delegate.h" 28 #include "extensions/browser/content_verifier_delegate.h"
29 #include "extensions/browser/verified_contents.h" 29 #include "extensions/browser/verified_contents.h"
30 #include "extensions/common/constants.h" 30 #include "extensions/common/constants.h"
31 #include "extensions/common/extension.h" 31 #include "extensions/common/extension.h"
32 #include "extensions/common/file_util.h" 32 #include "extensions/common/file_util.h"
33 #include "net/base/load_flags.h" 33 #include "net/base/load_flags.h"
34 #include "net/url_request/url_fetcher.h" 34 #include "net/url_request/url_fetcher.h"
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 url_fetcher_->Start(); 251 url_fetcher_->Start();
252 } 252 }
253 } 253 }
254 254
255 // Helper function to let us pass ownership of a string via base::Bind with the 255 // Helper function to let us pass ownership of a string via base::Bind with the
256 // contents to be written into a file. Also ensures that the directory for 256 // contents to be written into a file. Also ensures that the directory for
257 // |path| exists, creating it if needed. 257 // |path| exists, creating it if needed.
258 static int WriteFileHelper(const base::FilePath& path, 258 static int WriteFileHelper(const base::FilePath& path,
259 std::unique_ptr<std::string> content) { 259 std::unique_ptr<std::string> content) {
260 base::FilePath dir = path.DirName(); 260 base::FilePath dir = path.DirName();
261 return (base::CreateDirectoryAndGetError(dir, NULL) && 261 if (!base::CreateDirectoryAndGetError(dir, NULL))
lazyboy 2016/09/14 22:23:20 nit: change to nullptr
asargent_no_longer_on_chrome 2016/09/14 23:26:24 Done.
262 base::WriteFile(path, content->data(), content->size())); 262 return -1;
263 return base::WriteFile(path, content->data(), content->size());
263 } 264 }
264 265
265 void ContentHashFetcherJob::OnURLFetchComplete(const net::URLFetcher* source) { 266 void ContentHashFetcherJob::OnURLFetchComplete(const net::URLFetcher* source) {
266 VLOG(1) << "URLFetchComplete for " << extension_id_ 267 VLOG(1) << "URLFetchComplete for " << extension_id_
267 << " is_success:" << url_fetcher_->GetStatus().is_success() << " " 268 << " is_success:" << url_fetcher_->GetStatus().is_success() << " "
268 << fetch_url_.possibly_invalid_spec(); 269 << fetch_url_.possibly_invalid_spec();
269 if (IsCancelled()) 270 if (IsCancelled())
270 return; 271 return;
271 std::unique_ptr<std::string> response(new std::string); 272 std::unique_ptr<std::string> response(new std::string);
272 if (!url_fetcher_->GetStatus().is_success() || 273 if (!url_fetcher_->GetStatus().is_success() ||
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 if (IsCancelled()) 346 if (IsCancelled())
346 return false; 347 return false;
347 // Make sure the directory exists. 348 // Make sure the directory exists.
348 if (!base::CreateDirectoryAndGetError(hashes_file.DirName(), NULL)) 349 if (!base::CreateDirectoryAndGetError(hashes_file.DirName(), NULL))
349 return false; 350 return false;
350 351
351 if (!verified_contents_.get()) { 352 if (!verified_contents_.get()) {
352 base::FilePath verified_contents_path = 353 base::FilePath verified_contents_path =
353 file_util::GetVerifiedContentsPath(extension_path_); 354 file_util::GetVerifiedContentsPath(extension_path_);
354 verified_contents_.reset(new VerifiedContents(key_.data, key_.size)); 355 verified_contents_.reset(new VerifiedContents(key_.data, key_.size));
355 if (!verified_contents_->InitFrom(verified_contents_path, false)) 356 if (!verified_contents_->InitFrom(verified_contents_path, false)) {
357 verified_contents_.reset();
356 return false; 358 return false;
357 verified_contents_.reset(); 359 }
358 } 360 }
359 361
360 base::FileEnumerator enumerator(extension_path_, 362 base::FileEnumerator enumerator(extension_path_,
361 true, /* recursive */ 363 true, /* recursive */
362 base::FileEnumerator::FILES); 364 base::FileEnumerator::FILES);
363 // First discover all the file paths and put them in a sorted set. 365 // First discover all the file paths and put them in a sorted set.
364 SortedFilePathSet paths; 366 SortedFilePathSet paths;
365 for (;;) { 367 for (;;) {
366 if (IsCancelled()) 368 if (IsCancelled())
367 return false; 369 return false;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 { 418 {
417 base::AutoLock autolock(cancelled_lock_); 419 base::AutoLock autolock(cancelled_lock_);
418 if (cancelled_) 420 if (cancelled_)
419 return; 421 return;
420 } 422 }
421 callback_.Run(this); 423 callback_.Run(this);
422 } 424 }
423 425
424 // ---- 426 // ----
425 427
426 ContentHashFetcher::ContentHashFetcher(content::BrowserContext* context, 428 ContentHashFetcher::ContentHashFetcher(
427 ContentVerifierDelegate* delegate, 429 net::URLRequestContextGetter* context_getter,
428 const FetchCallback& callback) 430 ContentVerifierDelegate* delegate,
429 : context_(context), 431 const FetchCallback& callback)
432 : context_getter_(context_getter),
430 delegate_(delegate), 433 delegate_(delegate),
431 fetch_callback_(callback), 434 fetch_callback_(callback),
432 weak_ptr_factory_(this) { 435 weak_ptr_factory_(this) {}
433 }
434 436
435 ContentHashFetcher::~ContentHashFetcher() { 437 ContentHashFetcher::~ContentHashFetcher() {
436 for (JobMap::iterator i = jobs_.begin(); i != jobs_.end(); ++i) { 438 for (JobMap::iterator i = jobs_.begin(); i != jobs_.end(); ++i) {
437 i->second->Cancel(); 439 i->second->Cancel();
438 } 440 }
439 } 441 }
440 442
441 void ContentHashFetcher::DoFetch(const Extension* extension, bool force) { 443 void ContentHashFetcher::DoFetch(const Extension* extension, bool force) {
442 DCHECK(extension); 444 DCHECK(extension);
443 445
(...skipping 11 matching lines...) Expand all
455 } 457 }
456 458
457 // TODO(asargent) - we should do something here to remember recent attempts 459 // TODO(asargent) - we should do something here to remember recent attempts
458 // to fetch signatures by extension id, and use exponential backoff to avoid 460 // to fetch signatures by extension id, and use exponential backoff to avoid
459 // hammering the server when we aren't successful in getting them. 461 // hammering the server when we aren't successful in getting them.
460 // crbug.com/373397 462 // crbug.com/373397
461 463
462 DCHECK(extension->version()); 464 DCHECK(extension->version());
463 GURL url = 465 GURL url =
464 delegate_->GetSignatureFetchUrl(extension->id(), *extension->version()); 466 delegate_->GetSignatureFetchUrl(extension->id(), *extension->version());
465 ContentHashFetcherJob* job = new ContentHashFetcherJob( 467 ContentHashFetcherJob* job =
466 content::BrowserContext::GetDefaultStoragePartition(context_)-> 468 new ContentHashFetcherJob(context_getter_, delegate_->GetPublicKey(),
467 GetURLRequestContext(), 469 extension->id(), extension->path(), url, force,
468 delegate_->GetPublicKey(), extension->id(), 470 base::Bind(&ContentHashFetcher::JobFinished,
469 extension->path(), url, force, 471 weak_ptr_factory_.GetWeakPtr()));
470 base::Bind(&ContentHashFetcher::JobFinished,
471 weak_ptr_factory_.GetWeakPtr()));
472 jobs_.insert(std::make_pair(key, job)); 472 jobs_.insert(std::make_pair(key, job));
473 job->Start(); 473 job->Start();
474 } 474 }
475 475
476 void ContentHashFetcher::ExtensionLoaded(const Extension* extension) { 476 void ContentHashFetcher::ExtensionLoaded(const Extension* extension) {
477 CHECK(extension); 477 CHECK(extension);
478 DoFetch(extension, false); 478 DoFetch(extension, false);
479 } 479 }
480 480
481 void ContentHashFetcher::ExtensionUnloaded(const Extension* extension) { 481 void ContentHashFetcher::ExtensionUnloaded(const Extension* extension) {
(...skipping 16 matching lines...) Expand all
498 498
499 for (JobMap::iterator i = jobs_.begin(); i != jobs_.end(); ++i) { 499 for (JobMap::iterator i = jobs_.begin(); i != jobs_.end(); ++i) {
500 if (i->second.get() == job) { 500 if (i->second.get() == job) {
501 jobs_.erase(i); 501 jobs_.erase(i);
502 break; 502 break;
503 } 503 }
504 } 504 }
505 } 505 }
506 506
507 } // namespace extensions 507 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698