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

Unified Diff: chrome/browser/component_updater/component_unpacker.cc

Issue 321473003: Elevated install of recovery component (component update part) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/component_updater/component_unpacker.cc
diff --git a/chrome/browser/component_updater/component_unpacker.cc b/chrome/browser/component_updater/component_unpacker.cc
index 74b17853bacf6890421a15b6ae0302ac5ea9d0b0..6ddff606097eb5dcfe1ed01069b7d184fbe015da 100644
--- a/chrome/browser/component_updater/component_unpacker.cc
+++ b/chrome/browser/component_updater/component_unpacker.cc
@@ -31,6 +31,19 @@ namespace component_updater {
namespace {
+namespace serialize {
+
+const char kKeyFingerprint[] = "fingerprint";
+const char kKeyPKHash[] = "public_key_hash";
+const char kKeyInProcess[] = "in_process";
+
+const base::FilePath::CharType kCrxFileName[] =
+ FILE_PATH_LITERAL("saved_installer.crx");
+const base::FilePath::CharType kInstallDataFileName[] =
+ FILE_PATH_LITERAL("metadata.json");
+
+} // namespace serialize
+
// This class makes sure that the CRX digital signature is valid
// and well formed.
class CRXValidator {
@@ -124,8 +137,7 @@ scoped_ptr<base::DictionaryValue> ReadManifest(
if (!base::PathExists(manifest))
return scoped_ptr<base::DictionaryValue>();
JSONFileValueSerializer serializer(manifest);
- std::string error;
- scoped_ptr<base::Value> root(serializer.Deserialize(NULL, &error));
+ scoped_ptr<base::Value> root(serializer.Deserialize(NULL, NULL));
if (!root.get())
return scoped_ptr<base::DictionaryValue>();
if (!root->IsType(base::Value::TYPE_DICTIONARY))
@@ -182,11 +194,19 @@ bool ComponentUnpacker::Verify() {
return true;
}
+bool ComponentUnpacker::CreateUnpackDirectory(base::FilePath* new_dir) {
+ if (unpack_base_dir_.empty()) {
+ return base::CreateNewTempDirectory(base::FilePath::StringType(), new_dir);
+ }
+
+ return base::CreateTemporaryDirInDir(
+ unpack_base_dir_, base::FilePath::StringType(), new_dir);
+}
+
bool ComponentUnpacker::Unzip() {
base::FilePath& destination = is_delta_ ? unpack_diff_path_ : unpack_path_;
VLOG(1) << "Unpacking in: " << destination.value();
- if (!base::CreateNewTempDirectory(base::FilePath::StringType(),
- &destination)) {
+ if (!CreateUnpackDirectory(&destination)) {
VLOG(1) << "Unable to create temporary directory for unpacking.";
error_ = kUnzipPathError;
return false;
@@ -203,8 +223,7 @@ bool ComponentUnpacker::Unzip() {
bool ComponentUnpacker::BeginPatching() {
if (is_delta_) { // Package is a diff package.
// Use a different temp directory for the patch output files.
- if (!base::CreateNewTempDirectory(base::FilePath::StringType(),
- &unpack_path_)) {
+ if (!CreateUnpackDirectory(&unpack_path_)) {
error_ = kUnzipPathError;
return false;
}
@@ -264,6 +283,14 @@ void ComponentUnpacker::Install() {
}
DCHECK(error_ == kNone);
if (!installer_->Install(*manifest, unpack_path_)) {
+ // Saves the installer files and tries to re-install which is not managed
+ // by the component updater service.
+ if (SaveInstallSource(installer_->GetBackupPath())) {
+ installer_->InstallExternally();
+ }
+
+ // But keep current install error code since we cannot get the external
+ // install result.
error_ = kInstallerError;
return;
}
@@ -280,4 +307,92 @@ void ComponentUnpacker::Finish() {
ComponentUnpacker::~ComponentUnpacker() {
}
+bool ComponentUnpacker::SaveInstallSource(
+ const base::FilePath& backup_path) const {
+ if (backup_path.empty()) {
+ return false;
+ }
+
+ if (!base::CreateDirectory(backup_path)) {
+ return false;
+ }
+
+ const base::FilePath crx_path = backup_path.Append(serialize::kCrxFileName);
+ if (!base::CopyFile(path_, crx_path)) {
+ return false;
+ }
+
+ const base::FilePath install_data_file_path =
+ backup_path.Append(serialize::kInstallDataFileName);
+ JSONFileValueSerializer serializer(install_data_file_path);
+
+ scoped_ptr<base::DictionaryValue> root(new base::DictionaryValue);
+ root->SetString(serialize::kKeyFingerprint, fingerprint_);
+ root->SetBoolean(serialize::kKeyInProcess, in_process_);
+ scoped_ptr<base::ListValue> pk_hash_list(new base::ListValue);
+ for (size_t i = 0; i < pk_hash_.size(); ++i) {
+ pk_hash_list->Append(base::Value::CreateIntegerValue(
+ static_cast<int>(pk_hash_[i])));
+ }
+ root->Set(serialize::kKeyPKHash, pk_hash_list.release());
+ if (!serializer.Serialize(*root)) {
+ return false;
+ }
+
+ return true;
+}
+
+void ComponentUnpacker::set_unpack_base_dir(const base::FilePath& path) {
+ unpack_base_dir_ = path;
+}
+
+scoped_refptr<ComponentUnpacker> ComponentUnpacker::CreateFromBackup(
+ const base::FilePath& backup_path,
+ const std::vector<uint8>& pk_hash,
+ ComponentInstaller* installer,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ const base::FilePath crx_path = backup_path.Append(serialize::kCrxFileName);
+ if (!base::PathExists(crx_path) || base::DirectoryExists(crx_path)) {
+ return scoped_refptr<ComponentUnpacker>();
+ }
+
+ std::string fingerprint;
+ bool in_process = false;
+
+ const base::FilePath install_data_file_path =
+ backup_path.Append(serialize::kInstallDataFileName);
+ if (!base::PathExists(install_data_file_path)) {
+ return scoped_refptr<ComponentUnpacker>();
+ }
+
+ JSONFileValueSerializer serialize(install_data_file_path);
+ scoped_ptr<base::Value> root(serialize.Deserialize(NULL, NULL));
+ if (!root.get() || !root->IsType(base::Value::TYPE_DICTIONARY)) {
+ return scoped_refptr<ComponentUnpacker>();
+ }
+
+ scoped_ptr<base::DictionaryValue> metadata(
+ static_cast<base::DictionaryValue*>(root.release()));
+
+ base::ListValue* pk_hash_list = NULL;
+ if (!metadata->GetStringASCII(serialize::kKeyFingerprint, &fingerprint) ||
+ !metadata->GetBoolean(serialize::kKeyInProcess, &in_process) ||
+ !metadata->GetList(serialize::kKeyPKHash, &pk_hash_list) ||
+ pk_hash_list == NULL ||
+ pk_hash_list->GetSize() != pk_hash.size()) {
+ return scoped_refptr<ComponentUnpacker>();
+ }
+
+ for (size_t i = 0; i < pk_hash.size(); ++i) {
+ int value = 0;
+ if (!pk_hash_list->GetInteger(i, &value) ||
+ pk_hash[i] != static_cast<uint8>(value)) {
+ return scoped_refptr<ComponentUnpacker>();
+ }
+ }
+
+ return make_scoped_refptr(new ComponentUnpacker(
+ pk_hash, crx_path, fingerprint, installer, in_process, task_runner));
+}
+
} // namespace component_updater
« no previous file with comments | « chrome/browser/component_updater/component_unpacker.h ('k') | chrome/browser/component_updater/component_updater_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698