summaryrefslogtreecommitdiffstats
path: root/extensions/browser/sandboxed_unpacker.h
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/browser/sandboxed_unpacker.h')
-rw-r--r--extensions/browser/sandboxed_unpacker.h102
1 files changed, 77 insertions, 25 deletions
diff --git a/extensions/browser/sandboxed_unpacker.h b/extensions/browser/sandboxed_unpacker.h
index 17156df..826d939 100644
--- a/extensions/browser/sandboxed_unpacker.h
+++ b/extensions/browser/sandboxed_unpacker.h
@@ -2,14 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_EXTENSIONS_SANDBOXED_UNPACKER_H_
-#define CHROME_BROWSER_EXTENSIONS_SANDBOXED_UNPACKER_H_
+#ifndef EXTENSIONS_BROWSER_SANDBOXED_UNPACKER_H_
+#define EXTENSIONS_BROWSER_SANDBOXED_UNPACKER_H_
#include <string>
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted_delete_on_message_loop.h"
+#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/utility_process_host_client.h"
@@ -24,6 +25,10 @@ class DictionaryValue;
class SequencedTaskRunner;
}
+namespace content {
+class UtilityProcessHost;
+}
+
namespace crypto {
class SecureHash;
}
@@ -64,10 +69,11 @@ class SandboxedUnpackerClient
virtual ~SandboxedUnpackerClient() {}
};
-// SandboxedUnpacker unpacks extensions from the CRX format into a
-// directory. This is done in a sandboxed subprocess to protect the browser
-// process from parsing complex formats like JPEG or JSON from untrusted
-// sources.
+// SandboxedUnpacker does work to optionally unpack and then validate/sanitize
+// an extension, either starting from a crx file or an already unzipped
+// directory (eg from differential update). This is done in a sandboxed
+// subprocess to protect the browser process from parsing complex formats like
+// JPEG or JSON from untrusted sources.
//
// Unpacking an extension using this class makes minor changes to its source,
// such as transcoding all images to PNG, parsing all message catalogs
@@ -87,19 +93,25 @@ class SandboxedUnpackerClient
// NOTE: This class should only be used on the file thread.
class SandboxedUnpacker : public content::UtilityProcessHostClient {
public:
- // Unpacks the extension in |crx_path| into a temporary directory and calls
- // |client| with the result. If |run_out_of_process| is provided, unpacking
- // is done in a sandboxed subprocess. Otherwise, it is done in-process.
+ // Creates a SanboxedUnpacker that will do work to unpack an extension,
+ // passing the |location| and |creation_flags| to Extension::Create. The
+ // |extensions_dir| parameter should specify the directory under which we'll
+ // create a subdirectory to write the unpacked extension contents.
SandboxedUnpacker(
- const CRXFileInfo& file,
Manifest::Location location,
int creation_flags,
const base::FilePath& extensions_dir,
const scoped_refptr<base::SequencedTaskRunner>& unpacker_io_task_runner,
SandboxedUnpackerClient* client);
- // Start unpacking the extension. The client is called with the results.
- void Start();
+ // Start processing the extension, either from a CRX file or already unzipped
+ // in a directory. The client is called with the results. The directory form
+ // requires the id and base64-encoded public key (for insertion into the
+ // 'key' field of the manifest.json file).
+ void StartWithCrx(const CRXFileInfo& crx_info);
+ void StartWithDirectory(const std::string& extension_id,
+ const std::string& public_key_base64,
+ const base::FilePath& directory);
private:
class ProcessHostClient;
@@ -163,6 +175,10 @@ class SandboxedUnpacker : public content::UtilityProcessHostClient {
// SandboxedUnpacker::ValidateSignature()
CRX_HASH_VERIFICATION_FAILED,
+ UNZIP_FAILED,
+ DIRECTORY_MOVE_FAILED,
+ COULD_NOT_START_UTILITY_PROCESS,
+
NUM_FAILURE_REASONS
};
@@ -181,16 +197,19 @@ class SandboxedUnpacker : public content::UtilityProcessHostClient {
// Validates the signature of the extension and extract the key to
// |public_key_|. Returns true if the signature validates, false otherwise.
- bool ValidateSignature();
+ bool ValidateSignature(const base::FilePath& crx_path,
+ const std::string& expected_hash);
- // Starts the utility process that unpacks our extension.
- void StartProcessOnIOThread(const base::FilePath& temp_crx_path);
+ void StartUnzipOnIOThread(const base::FilePath& crx_path);
+ void StartUnpackOnIOThread(const base::FilePath& directory_path);
// UtilityProcessHostClient
bool OnMessageReceived(const IPC::Message& message) override;
void OnProcessCrashed(int exit_code) override;
// IPC message handlers.
+ void OnUnzipToDirSucceeded(const base::FilePath& directory);
+ void OnUnzipToDirFailed(const std::string& error);
void OnUnpackExtensionSucceeded(const base::DictionaryValue& manifest);
void OnUnpackExtensionFailed(const base::string16& error_message);
@@ -211,14 +230,41 @@ class SandboxedUnpacker : public content::UtilityProcessHostClient {
// Cleans up temp directory artifacts.
void Cleanup();
- // The path to the CRX to unpack.
- base::FilePath crx_path_;
-
- // The package SHA256 hash sum that was reported from the Web Store.
- std::string package_hash_;
+ // This is a helper class to make it easier to keep track of the lifecycle of
+ // a UtilityProcessHost, including automatic begin and end of batch mode.
+ class UtilityHostWrapper : public base::RefCountedThreadSafe<
+ UtilityHostWrapper,
+ content::BrowserThread::DeleteOnIOThread> {
+ public:
+ UtilityHostWrapper();
+
+ // Start up the utility process if it is not already started, putting it
+ // into batch mode and giving it access to |exposed_dir|. This should only
+ // be called on the IO thread. Returns false if there was an error starting
+ // the utility process or putting it into batch mode.
+ bool StartIfNeeded(
+ const base::FilePath& exposed_dir,
+ const scoped_refptr<UtilityProcessHostClient>& client,
+ const scoped_refptr<base::SequencedTaskRunner>& client_task_runner);
+
+ // This should only be called on the IO thread.
+ content::UtilityProcessHost* host() const;
+
+ private:
+ friend struct content::BrowserThread::DeleteOnThread<
+ content::BrowserThread::IO>;
+ friend class base::DeleteHelper<UtilityHostWrapper>;
+ ~UtilityHostWrapper();
+
+ // Should only be used on the IO thread.
+ base::WeakPtr<content::UtilityProcessHost> utility_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(UtilityHostWrapper);
+ };
- // Whether we need to check the .crx hash sum.
- bool check_crx_hash_;
+ // If we unpacked a crx file, we hold on to the path for use in various
+ // histograms.
+ base::FilePath crx_path_for_histograms_;
// Our client.
scoped_refptr<SandboxedUnpackerClient> client_;
@@ -245,8 +291,9 @@ class SandboxedUnpacker : public content::UtilityProcessHostClient {
// header.
std::string extension_id_;
- // Time at which unpacking started. Used to compute the time unpacking takes.
- base::TimeTicks unpack_start_time_;
+ // If we unpacked a .crx file, the time at which unpacking started. Used to
+ // compute the time unpacking takes.
+ base::TimeTicks crx_unpack_start_time_;
// Location to use for the unpacked extension.
Manifest::Location location_;
@@ -257,8 +304,13 @@ class SandboxedUnpacker : public content::UtilityProcessHostClient {
// Sequenced task runner where file I/O operations will be performed at.
scoped_refptr<base::SequencedTaskRunner> unpacker_io_task_runner_;
+
+ // Used for sending tasks to the utility process.
+ scoped_refptr<UtilityHostWrapper> utility_wrapper_;
+
+ DISALLOW_COPY_AND_ASSIGN(SandboxedUnpacker);
};
} // namespace extensions
-#endif // CHROME_BROWSER_EXTENSIONS_SANDBOXED_UNPACKER_H_
+#endif // EXTENSIONS_BROWSER_SANDBOXED_UNPACKER_H_