| 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 "extensions/browser/sandboxed_unpacker.h" | 5 #include "extensions/browser/sandboxed_unpacker.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <set> | 10 #include <set> |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 extensions::switches::kEnableCrxHashCheck)) { | 265 extensions::switches::kEnableCrxHashCheck)) { |
| 266 expected_hash = base::ToLowerASCII(crx_info.expected_hash); | 266 expected_hash = base::ToLowerASCII(crx_info.expected_hash); |
| 267 } | 267 } |
| 268 | 268 |
| 269 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackInitialCrxPathLength", | 269 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackInitialCrxPathLength", |
| 270 crx_info.path); | 270 crx_info.path); |
| 271 if (!CreateTempDirectory()) | 271 if (!CreateTempDirectory()) |
| 272 return; // ReportFailure() already called. | 272 return; // ReportFailure() already called. |
| 273 | 273 |
| 274 // Initialize the path that will eventually contain the unpacked extension. | 274 // Initialize the path that will eventually contain the unpacked extension. |
| 275 extension_root_ = temp_dir_.path().AppendASCII(kTempExtensionName); | 275 extension_root_ = temp_dir_.GetPath().AppendASCII(kTempExtensionName); |
| 276 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackUnpackedCrxPathLength", | 276 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackUnpackedCrxPathLength", |
| 277 extension_root_); | 277 extension_root_); |
| 278 | 278 |
| 279 // Extract the public key and validate the package. | 279 // Extract the public key and validate the package. |
| 280 if (!ValidateSignature(crx_info.path, expected_hash)) | 280 if (!ValidateSignature(crx_info.path, expected_hash)) |
| 281 return; // ValidateSignature() already reported the error. | 281 return; // ValidateSignature() already reported the error. |
| 282 | 282 |
| 283 // Copy the crx file into our working directory. | 283 // Copy the crx file into our working directory. |
| 284 base::FilePath temp_crx_path = | 284 base::FilePath temp_crx_path = |
| 285 temp_dir_.path().Append(crx_info.path.BaseName()); | 285 temp_dir_.GetPath().Append(crx_info.path.BaseName()); |
| 286 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackTempCrxPathLength", | 286 PATH_LENGTH_HISTOGRAM("Extensions.SandboxUnpackTempCrxPathLength", |
| 287 temp_crx_path); | 287 temp_crx_path); |
| 288 | 288 |
| 289 if (!base::CopyFile(crx_info.path, temp_crx_path)) { | 289 if (!base::CopyFile(crx_info.path, temp_crx_path)) { |
| 290 // Failed to copy extension file to temporary directory. | 290 // Failed to copy extension file to temporary directory. |
| 291 ReportFailure( | 291 ReportFailure( |
| 292 FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY, | 292 FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY, |
| 293 l10n_util::GetStringFUTF16( | 293 l10n_util::GetStringFUTF16( |
| 294 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 294 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 295 ASCIIToUTF16("FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY"))); | 295 ASCIIToUTF16("FAILED_TO_COPY_EXTENSION_FILE_TO_TEMP_DIRECTORY"))); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 318 } | 318 } |
| 319 | 319 |
| 320 void SandboxedUnpacker::StartWithDirectory(const std::string& extension_id, | 320 void SandboxedUnpacker::StartWithDirectory(const std::string& extension_id, |
| 321 const std::string& public_key, | 321 const std::string& public_key, |
| 322 const base::FilePath& directory) { | 322 const base::FilePath& directory) { |
| 323 extension_id_ = extension_id; | 323 extension_id_ = extension_id; |
| 324 public_key_ = public_key; | 324 public_key_ = public_key; |
| 325 if (!CreateTempDirectory()) | 325 if (!CreateTempDirectory()) |
| 326 return; // ReportFailure() already called. | 326 return; // ReportFailure() already called. |
| 327 | 327 |
| 328 extension_root_ = temp_dir_.path().AppendASCII(kTempExtensionName); | 328 extension_root_ = temp_dir_.GetPath().AppendASCII(kTempExtensionName); |
| 329 | 329 |
| 330 if (!base::Move(directory, extension_root_)) { | 330 if (!base::Move(directory, extension_root_)) { |
| 331 LOG(ERROR) << "Could not move " << directory.value() << " to " | 331 LOG(ERROR) << "Could not move " << directory.value() << " to " |
| 332 << extension_root_.value(); | 332 << extension_root_.value(); |
| 333 ReportFailure( | 333 ReportFailure( |
| 334 DIRECTORY_MOVE_FAILED, | 334 DIRECTORY_MOVE_FAILED, |
| 335 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 335 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 336 ASCIIToUTF16("DIRECTORY_MOVE_FAILED"))); | 336 ASCIIToUTF16("DIRECTORY_MOVE_FAILED"))); |
| 337 return; | 337 return; |
| 338 } | 338 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 ReportFailure( | 373 ReportFailure( |
| 374 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL, | 374 UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL, |
| 375 l10n_util::GetStringFUTF16( | 375 l10n_util::GetStringFUTF16( |
| 376 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 376 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 377 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) + | 377 ASCIIToUTF16("UTILITY_PROCESS_CRASHED_WHILE_TRYING_TO_INSTALL")) + |
| 378 ASCIIToUTF16(". ") + | 378 ASCIIToUTF16(". ") + |
| 379 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED)); | 379 l10n_util::GetStringUTF16(IDS_EXTENSION_INSTALL_PROCESS_CRASHED)); |
| 380 } | 380 } |
| 381 | 381 |
| 382 void SandboxedUnpacker::StartUnzipOnIOThread(const base::FilePath& crx_path) { | 382 void SandboxedUnpacker::StartUnzipOnIOThread(const base::FilePath& crx_path) { |
| 383 if (!utility_wrapper_->StartIfNeeded(temp_dir_.path(), this, | 383 if (!utility_wrapper_->StartIfNeeded(temp_dir_.GetPath(), this, |
| 384 unpacker_io_task_runner_)) { | 384 unpacker_io_task_runner_)) { |
| 385 ReportFailure( | 385 ReportFailure( |
| 386 COULD_NOT_START_UTILITY_PROCESS, | 386 COULD_NOT_START_UTILITY_PROCESS, |
| 387 l10n_util::GetStringFUTF16( | 387 l10n_util::GetStringFUTF16( |
| 388 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 388 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 389 FailureReasonToString16(COULD_NOT_START_UTILITY_PROCESS))); | 389 FailureReasonToString16(COULD_NOT_START_UTILITY_PROCESS))); |
| 390 return; | 390 return; |
| 391 } | 391 } |
| 392 DCHECK(crx_path.DirName() == temp_dir_.path()); | 392 DCHECK(crx_path.DirName() == temp_dir_.GetPath()); |
| 393 base::FilePath unzipped_dir = | 393 base::FilePath unzipped_dir = |
| 394 crx_path.DirName().AppendASCII(kTempExtensionName); | 394 crx_path.DirName().AppendASCII(kTempExtensionName); |
| 395 utility_wrapper_->host()->Send( | 395 utility_wrapper_->host()->Send( |
| 396 new ExtensionUtilityMsg_UnzipToDir(crx_path, unzipped_dir)); | 396 new ExtensionUtilityMsg_UnzipToDir(crx_path, unzipped_dir)); |
| 397 } | 397 } |
| 398 | 398 |
| 399 void SandboxedUnpacker::StartUnpackOnIOThread( | 399 void SandboxedUnpacker::StartUnpackOnIOThread( |
| 400 const base::FilePath& directory_path) { | 400 const base::FilePath& directory_path) { |
| 401 if (!utility_wrapper_->StartIfNeeded(temp_dir_.path(), this, | 401 if (!utility_wrapper_->StartIfNeeded(temp_dir_.GetPath(), this, |
| 402 unpacker_io_task_runner_)) { | 402 unpacker_io_task_runner_)) { |
| 403 ReportFailure( | 403 ReportFailure( |
| 404 COULD_NOT_START_UTILITY_PROCESS, | 404 COULD_NOT_START_UTILITY_PROCESS, |
| 405 l10n_util::GetStringFUTF16( | 405 l10n_util::GetStringFUTF16( |
| 406 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 406 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 407 FailureReasonToString16(COULD_NOT_START_UTILITY_PROCESS))); | 407 FailureReasonToString16(COULD_NOT_START_UTILITY_PROCESS))); |
| 408 return; | 408 return; |
| 409 } | 409 } |
| 410 DCHECK(directory_path.DirName() == temp_dir_.path()); | 410 DCHECK(directory_path.DirName() == temp_dir_.GetPath()); |
| 411 utility_wrapper_->host()->Send(new ExtensionUtilityMsg_UnpackExtension( | 411 utility_wrapper_->host()->Send(new ExtensionUtilityMsg_UnpackExtension( |
| 412 directory_path, extension_id_, location_, creation_flags_)); | 412 directory_path, extension_id_, location_, creation_flags_)); |
| 413 } | 413 } |
| 414 | 414 |
| 415 void SandboxedUnpacker::OnUnzipToDirSucceeded(const base::FilePath& directory) { | 415 void SandboxedUnpacker::OnUnzipToDirSucceeded(const base::FilePath& directory) { |
| 416 BrowserThread::PostTask( | 416 BrowserThread::PostTask( |
| 417 BrowserThread::IO, FROM_HERE, | 417 BrowserThread::IO, FROM_HERE, |
| 418 base::Bind(&SandboxedUnpacker::StartUnpackOnIOThread, this, directory)); | 418 base::Bind(&SandboxedUnpacker::StartUnpackOnIOThread, this, directory)); |
| 419 } | 419 } |
| 420 | 420 |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 662 void SandboxedUnpacker::ReportSuccess( | 662 void SandboxedUnpacker::ReportSuccess( |
| 663 const base::DictionaryValue& original_manifest, | 663 const base::DictionaryValue& original_manifest, |
| 664 const SkBitmap& install_icon) { | 664 const SkBitmap& install_icon) { |
| 665 utility_wrapper_ = nullptr; | 665 utility_wrapper_ = nullptr; |
| 666 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1); | 666 UMA_HISTOGRAM_COUNTS("Extensions.SandboxUnpackSuccess", 1); |
| 667 | 667 |
| 668 if (!crx_unpack_start_time_.is_null()) | 668 if (!crx_unpack_start_time_.is_null()) |
| 669 RecordSuccessfulUnpackTimeHistograms( | 669 RecordSuccessfulUnpackTimeHistograms( |
| 670 crx_path_for_histograms_, | 670 crx_path_for_histograms_, |
| 671 base::TimeTicks::Now() - crx_unpack_start_time_); | 671 base::TimeTicks::Now() - crx_unpack_start_time_); |
| 672 DCHECK(!temp_dir_.path().empty()); | 672 DCHECK(!temp_dir_.GetPath().empty()); |
| 673 | 673 |
| 674 // Client takes ownership of temporary directory and extension. | 674 // Client takes ownership of temporary directory and extension. |
| 675 client_->OnUnpackSuccess(temp_dir_.Take(), extension_root_, | 675 client_->OnUnpackSuccess(temp_dir_.Take(), extension_root_, |
| 676 &original_manifest, extension_.get(), install_icon); | 676 &original_manifest, extension_.get(), install_icon); |
| 677 extension_ = NULL; | 677 extension_ = NULL; |
| 678 } | 678 } |
| 679 | 679 |
| 680 base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile( | 680 base::DictionaryValue* SandboxedUnpacker::RewriteManifestFile( |
| 681 const base::DictionaryValue& manifest) { | 681 const base::DictionaryValue& manifest) { |
| 682 // Add the public key extracted earlier to the parsed manifest and overwrite | 682 // Add the public key extracted earlier to the parsed manifest and overwrite |
| (...skipping 23 matching lines...) Expand all Loading... |
| 706 ERROR_SAVING_MANIFEST_JSON, | 706 ERROR_SAVING_MANIFEST_JSON, |
| 707 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 707 l10n_util::GetStringFUTF16(IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 708 ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON"))); | 708 ASCIIToUTF16("ERROR_SAVING_MANIFEST_JSON"))); |
| 709 return NULL; | 709 return NULL; |
| 710 } | 710 } |
| 711 | 711 |
| 712 return final_manifest.release(); | 712 return final_manifest.release(); |
| 713 } | 713 } |
| 714 | 714 |
| 715 bool SandboxedUnpacker::RewriteImageFiles(SkBitmap* install_icon) { | 715 bool SandboxedUnpacker::RewriteImageFiles(SkBitmap* install_icon) { |
| 716 DCHECK(!temp_dir_.path().empty()); | 716 DCHECK(!temp_dir_.GetPath().empty()); |
| 717 DecodedImages images; | 717 DecodedImages images; |
| 718 if (!ReadImagesFromFile(temp_dir_.path(), &images)) { | 718 if (!ReadImagesFromFile(temp_dir_.GetPath(), &images)) { |
| 719 // Couldn't read image data from disk. | 719 // Couldn't read image data from disk. |
| 720 ReportFailure(COULD_NOT_READ_IMAGE_DATA_FROM_DISK, | 720 ReportFailure(COULD_NOT_READ_IMAGE_DATA_FROM_DISK, |
| 721 l10n_util::GetStringFUTF16( | 721 l10n_util::GetStringFUTF16( |
| 722 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 722 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 723 ASCIIToUTF16("COULD_NOT_READ_IMAGE_DATA_FROM_DISK"))); | 723 ASCIIToUTF16("COULD_NOT_READ_IMAGE_DATA_FROM_DISK"))); |
| 724 return false; | 724 return false; |
| 725 } | 725 } |
| 726 | 726 |
| 727 // Delete any images that may be used by the browser. We're going to write | 727 // Delete any images that may be used by the browser. We're going to write |
| 728 // out our own versions of the parsed images, and we want to make sure the | 728 // out our own versions of the parsed images, and we want to make sure the |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE"))); | 816 ASCIIToUTF16("ERROR_SAVING_THEME_IMAGE"))); |
| 817 return false; | 817 return false; |
| 818 } | 818 } |
| 819 } | 819 } |
| 820 | 820 |
| 821 return true; | 821 return true; |
| 822 } | 822 } |
| 823 | 823 |
| 824 bool SandboxedUnpacker::RewriteCatalogFiles() { | 824 bool SandboxedUnpacker::RewriteCatalogFiles() { |
| 825 base::DictionaryValue catalogs; | 825 base::DictionaryValue catalogs; |
| 826 if (!ReadMessageCatalogsFromFile(temp_dir_.path(), &catalogs)) { | 826 if (!ReadMessageCatalogsFromFile(temp_dir_.GetPath(), &catalogs)) { |
| 827 // Could not read catalog data from disk. | 827 // Could not read catalog data from disk. |
| 828 ReportFailure(COULD_NOT_READ_CATALOG_DATA_FROM_DISK, | 828 ReportFailure(COULD_NOT_READ_CATALOG_DATA_FROM_DISK, |
| 829 l10n_util::GetStringFUTF16( | 829 l10n_util::GetStringFUTF16( |
| 830 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, | 830 IDS_EXTENSION_PACKAGE_INSTALL_ERROR, |
| 831 ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK"))); | 831 ASCIIToUTF16("COULD_NOT_READ_CATALOG_DATA_FROM_DISK"))); |
| 832 return false; | 832 return false; |
| 833 } | 833 } |
| 834 | 834 |
| 835 // Write our parsed catalogs back to disk. | 835 // Write our parsed catalogs back to disk. |
| 836 for (base::DictionaryValue::Iterator it(catalogs); !it.IsAtEnd(); | 836 for (base::DictionaryValue::Iterator it(catalogs); !it.IsAtEnd(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 } | 882 } |
| 883 } | 883 } |
| 884 | 884 |
| 885 return true; | 885 return true; |
| 886 } | 886 } |
| 887 | 887 |
| 888 void SandboxedUnpacker::Cleanup() { | 888 void SandboxedUnpacker::Cleanup() { |
| 889 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); | 889 DCHECK(unpacker_io_task_runner_->RunsTasksOnCurrentThread()); |
| 890 if (!temp_dir_.Delete()) { | 890 if (!temp_dir_.Delete()) { |
| 891 LOG(WARNING) << "Can not delete temp directory at " | 891 LOG(WARNING) << "Can not delete temp directory at " |
| 892 << temp_dir_.path().value(); | 892 << temp_dir_.GetPath().value(); |
| 893 } | 893 } |
| 894 } | 894 } |
| 895 | 895 |
| 896 SandboxedUnpacker::UtilityHostWrapper::UtilityHostWrapper() {} | 896 SandboxedUnpacker::UtilityHostWrapper::UtilityHostWrapper() {} |
| 897 | 897 |
| 898 bool SandboxedUnpacker::UtilityHostWrapper::StartIfNeeded( | 898 bool SandboxedUnpacker::UtilityHostWrapper::StartIfNeeded( |
| 899 const base::FilePath& exposed_dir, | 899 const base::FilePath& exposed_dir, |
| 900 const scoped_refptr<UtilityProcessHostClient>& client, | 900 const scoped_refptr<UtilityProcessHostClient>& client, |
| 901 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner) { | 901 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner) { |
| 902 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 902 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 925 | 925 |
| 926 SandboxedUnpacker::UtilityHostWrapper::~UtilityHostWrapper() { | 926 SandboxedUnpacker::UtilityHostWrapper::~UtilityHostWrapper() { |
| 927 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 927 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 928 if (utility_host_) { | 928 if (utility_host_) { |
| 929 utility_host_->EndBatchMode(); | 929 utility_host_->EndBatchMode(); |
| 930 utility_host_.reset(); | 930 utility_host_.reset(); |
| 931 } | 931 } |
| 932 } | 932 } |
| 933 | 933 |
| 934 } // namespace extensions | 934 } // namespace extensions |
| OLD | NEW |