| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/sandboxed_unpacker.h" | 5 #include "chrome/browser/extensions/sandboxed_unpacker.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 UtilityProcessHost::Create(this, unpacker_io_task_runner_.get()); | 347 UtilityProcessHost::Create(this, unpacker_io_task_runner_.get()); |
| 348 // Grant the subprocess access to the entire subdir the extension file is | 348 // Grant the subprocess access to the entire subdir the extension file is |
| 349 // in, so that it can unpack to that dir. | 349 // in, so that it can unpack to that dir. |
| 350 host->SetExposedDir(temp_crx_path.DirName()); | 350 host->SetExposedDir(temp_crx_path.DirName()); |
| 351 host->Send( | 351 host->Send( |
| 352 new ChromeUtilityMsg_UnpackExtension( | 352 new ChromeUtilityMsg_UnpackExtension( |
| 353 temp_crx_path, extension_id_, location_, creation_flags_)); | 353 temp_crx_path, extension_id_, location_, creation_flags_)); |
| 354 } | 354 } |
| 355 | 355 |
| 356 void SandboxedUnpacker::OnUnpackExtensionSucceeded( | 356 void SandboxedUnpacker::OnUnpackExtensionSucceeded( |
| 357 const DictionaryValue& manifest) { | 357 const base::DictionaryValue& manifest) { |
| 358 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); | 358 CHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); |
| 359 got_response_ = true; | 359 got_response_ = true; |
| 360 | 360 |
| 361 scoped_ptr<DictionaryValue> final_manifest(RewriteManifestFile(manifest)); | 361 scoped_ptr<base::DictionaryValue> final_manifest( |
| 362 RewriteManifestFile(manifest)); |
| 362 if (!final_manifest) | 363 if (!final_manifest) |
| 363 return; | 364 return; |
| 364 | 365 |
| 365 // Create an extension object that refers to the temporary location the | 366 // Create an extension object that refers to the temporary location the |
| 366 // extension was unpacked to. We use this until the extension is finally | 367 // extension was unpacked to. We use this until the extension is finally |
| 367 // installed. For example, the install UI shows images from inside the | 368 // installed. For example, the install UI shows images from inside the |
| 368 // extension. | 369 // extension. |
| 369 | 370 |
| 370 // Localize manifest now, so confirm UI gets correct extension name. | 371 // Localize manifest now, so confirm UI gets correct extension name. |
| 371 | 372 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 const base::string16& error) { | 583 const base::string16& error) { |
| 583 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", | 584 UMA_HISTOGRAM_ENUMERATION("Extensions.SandboxUnpackFailureReason", |
| 584 reason, NUM_FAILURE_REASONS); | 585 reason, NUM_FAILURE_REASONS); |
| 585 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime", | 586 UMA_HISTOGRAM_TIMES("Extensions.SandboxUnpackFailureTime", |
| 586 base::TimeTicks::Now() - unpack_start_time_); | 587 base::TimeTicks::Now() - unpack_start_time_); |
| 587 Cleanup(); | 588 Cleanup(); |
| 588 client_->OnUnpackFailure(error); | 589 client_->OnUnpackFailure(error); |
| 589 } | 590 } |
| 590 | 591 |
| 591 void SandboxedUnpacker::ReportSuccess( | 592 void SandboxedUnpacker::ReportSuccess( |
| 592 const DictionaryValue& original_manifest, | 593 const base::DictionaryValue& original_manifest, |
| 593 const SkBitmap& install_icon) { | 594 const SkBitmap& install_icon) { |
| 594 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1); | 595 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1); |
| 595 | 596 |
| 596 RecordSuccessfulUnpackTimeHistograms( | 597 RecordSuccessfulUnpackTimeHistograms( |
| 597 crx_path_, base::TimeTicks::Now() - unpack_start_time_); | 598 crx_path_, base::TimeTicks::Now() - unpack_start_time_); |
| 598 | 599 |
| 599 // Client takes ownership of temporary directory and extension. | 600 // Client takes ownership of temporary directory and extension. |
| 600 client_->OnUnpackSuccess( | 601 client_->OnUnpackSuccess( |
| 601 temp_dir_.Take(), extension_root_, &original_manifest, extension_.get(), | 602 temp_dir_.Take(), extension_root_, &original_manifest, extension_.get(), |
| 602 install_icon); | 603 install_icon); |
| 603 extension_ = NULL; | 604 extension_ = NULL; |
| 604 } | 605 } |
| 605 | 606 |
| 606 DictionaryValue* SandboxedUnpacker::RewriteManifestFile( | 607 base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile( |
| 607 const DictionaryValue& manifest) { | 608 const base::DictionaryValue& manifest) { |
| 608 // Add the public key extracted earlier to the parsed manifest and overwrite | 609 // Add the public key extracted earlier to the parsed manifest and overwrite |
| 609 // the original manifest. We do this to ensure the manifest doesn't contain an | 610 // the original manifest. We do this to ensure the manifest doesn't contain an |
| 610 // exploitable bug that could be used to compromise the browser. | 611 // exploitable bug that could be used to compromise the browser. |
| 611 scoped_ptr<DictionaryValue> final_manifest(manifest.DeepCopy()); | 612 scoped_ptr<base::DictionaryValue> final_manifest(manifest.DeepCopy()); |
| 612 final_manifest->SetString(manifest_keys::kPublicKey, public_key_); | 613 final_manifest->SetString(manifest_keys::kPublicKey, public_key_); |
| 613 | 614 |
| 614 std::string manifest_json; | 615 std::string manifest_json; |
| 615 JSONStringValueSerializer serializer(&manifest_json); | 616 JSONStringValueSerializer serializer(&manifest_json); |
| 616 serializer.set_pretty_print(true); | 617 serializer.set_pretty_print(true); |
| 617 if (!serializer.Serialize(*final_manifest)) { | 618 if (!serializer.Serialize(*final_manifest)) { |
| 618 // Error serializing manifest.json. | 619 // Error serializing manifest.json. |
| 619 ReportFailure( | 620 ReportFailure( |
| 620 ERROR_SERIALIZING_MANIFEST_JSON, | 621 ERROR_SERIALIZING_MANIFEST_JSON, |
| 621 l10n_util::GetStringFUTF16( | 622 l10n_util::GetStringFUTF16( |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 749 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 749 ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE"))); | 750 ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE"))); |
| 750 return false; | 751 return false; |
| 751 } | 752 } |
| 752 } | 753 } |
| 753 | 754 |
| 754 return true; | 755 return true; |
| 755 } | 756 } |
| 756 | 757 |
| 757 bool SandboxedUnpacker::RewriteCatalogFiles() { | 758 bool SandboxedUnpacker::RewriteCatalogFiles() { |
| 758 DictionaryValue catalogs; | 759 base::DictionaryValue catalogs; |
| 759 if (!ReadMessageCatalogsFromFile(temp_dir_.path(), &catalogs)) { | 760 if (!ReadMessageCatalogsFromFile(temp_dir_.path(), &catalogs)) { |
| 760 // Could not read catalog data from disk. | 761 // Could not read catalog data from disk. |
| 761 ReportFailure( | 762 ReportFailure( |
| 762 COULD_NOT_READ_CATALOG_DATA_FROM_DISK, | 763 COULD_NOT_READ_CATALOG_DATA_FROM_DISK, |
| 763 l10n_util::GetStringFUTF16( | 764 l10n_util::GetStringFUTF16( |
| 764 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 765 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 765 ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK"))); | 766 ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK"))); |
| 766 return false; | 767 return false; |
| 767 } | 768 } |
| 768 | 769 |
| 769 // Write our parsed catalogs back to disk. | 770 // Write our parsed catalogs back to disk. |
| 770 for (DictionaryValue::Iterator it(catalogs); !it.IsAtEnd(); it.Advance()) { | 771 for (base::DictionaryValue::Iterator it(catalogs); |
| 771 const DictionaryValue* catalog = NULL; | 772 !it.IsAtEnd(); it.Advance()) { |
| 773 const base::DictionaryValue* catalog = NULL; |
| 772 if (!it.value().GetAsDictionary(&catalog)) { | 774 if (!it.value().GetAsDictionary(&catalog)) { |
| 773 // Invalid catalog data. | 775 // Invalid catalog data. |
| 774 ReportFailure( | 776 ReportFailure( |
| 775 INVALID_CATALOG_DATA, | 777 INVALID_CATALOG_DATA, |
| 776 l10n_util::GetStringFUTF16( | 778 l10n_util::GetStringFUTF16( |
| 777 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 779 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 778 ASCIIToUTF16("INVALID_CATALOG_DATA"))); | 780 ASCIIToUTF16("INVALID_CATALOG_DATA"))); |
| 779 return false; | 781 return false; |
| 780 } | 782 } |
| 781 | 783 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 | 826 |
| 825 void SandboxedUnpacker::Cleanup() { | 827 void SandboxedUnpacker::Cleanup() { |
| 826 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); | 828 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); |
| 827 if (!temp_dir_.Delete()) { | 829 if (!temp_dir_.Delete()) { |
| 828 LOG(WARNING) << "Can not delete temp directory at " | 830 LOG(WARNING) << "Can not delete temp directory at " |
| 829 << temp_dir_.path().value(); | 831 << temp_dir_.path().value(); |
| 830 } | 832 } |
| 831 } | 833 } |
| 832 | 834 |
| 833 } // namespace extensions | 835 } // namespace extensions |
| OLD | NEW |