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 |