summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/crx_installer.cc28
-rw-r--r--chrome/browser/extensions/crx_installer.h16
-rw-r--r--chrome/browser/extensions/extensions_service.cc14
-rw-r--r--chrome/browser/extensions/extensions_service.h6
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc5
-rw-r--r--chrome/browser/extensions/sandboxed_extension_unpacker.cc26
-rw-r--r--chrome/browser/extensions/sandboxed_extension_unpacker.h15
7 files changed, 75 insertions, 35 deletions
diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc
index 70f8146..3609320 100644
--- a/chrome/browser/extensions/crx_installer.cc
+++ b/chrome/browser/extensions/crx_installer.cc
@@ -43,7 +43,7 @@ CrxInstaller::CrxInstaller(const FilePath& install_directory,
install_source_(Extension::INTERNAL),
delete_source_(false),
allow_privilege_increase_(false),
- limit_web_extent_to_download_host_(false),
+ force_web_origin_to_download_url_(false),
create_app_shortcut_(false),
frontend_(frontend),
client_(client) {
@@ -84,6 +84,10 @@ void CrxInstaller::InstallCrx(const FilePath& source_file) {
g_browser_process->resource_dispatcher_host(),
this));
+ if (force_web_origin_to_download_url_) {
+ unpacker->set_web_origin(original_url_.GetOrigin());
+ }
+
ChromeThread::PostTask(
ChromeThread::FILE, FROM_HERE,
NewRunnableMethod(
@@ -160,22 +164,6 @@ void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir,
return;
}
- // Require that apps are served from the domain they claim in their extent,
- // or some ancestor domain.
- if (extension_->is_app() && limit_web_extent_to_download_host_) {
- URLPattern pattern;
- pattern.set_host(original_url_.host());
- pattern.set_match_subdomains(true);
-
- for (size_t i = 0; i < extension_->web_extent().patterns().size(); ++i) {
- if (!pattern.MatchesHost(extension_->web_extent().patterns()[i].host())) {
- ReportFailureFromFileThread(StringPrintf(
- "Apps must be served from the host that they affect."));
- return;
- }
- }
- }
-
if (client_ || extension_->GetFullLaunchURL().is_valid()) {
Extension::DecodeIcon(extension_.get(), Extension::EXTENSION_ICON_LARGE,
&install_icon_);
@@ -197,11 +185,13 @@ void CrxInstaller::ConfirmInstall() {
GURL overlapping_url;
Extension* overlapping_extension =
- frontend_->GetExtensionByOverlappingWebExtent(extension_->web_extent());
+ frontend_->GetExtensionByOverlappingWebExtent(
+ extension_->web_extent(), &overlapping_url);
if (overlapping_extension) {
ReportFailureFromUIThread(l10n_util::GetStringFUTF8(
IDS_EXTENSION_OVERLAPPING_WEB_EXTENT,
- UTF8ToUTF16(overlapping_extension->name())));
+ UTF8ToUTF16(overlapping_extension->name()),
+ UTF8ToUTF16(overlapping_url.spec())));
return;
}
diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h
index 905a3f2..d64f668 100644
--- a/chrome/browser/extensions/crx_installer.h
+++ b/chrome/browser/extensions/crx_installer.h
@@ -83,11 +83,11 @@ class CrxInstaller
allow_privilege_increase_ = val;
}
- bool limit_web_extent_to_download_host() const {
- return limit_web_extent_to_download_host_;
+ bool force_web_origin_to_download_url() const {
+ return force_web_origin_to_download_url_;
}
- void set_limit_web_extent_to_download_host(bool val) {
- limit_web_extent_to_download_host_ = val;
+ void set_force_web_origin_to_download_url(bool val) {
+ force_web_origin_to_download_url_ = val;
}
private:
@@ -151,9 +151,11 @@ class CrxInstaller
// either. Defaults to false.
bool allow_privilege_increase_;
- // Limits the web extent to the app being installed to the host of the
- // download URL. If the crx being installed is not an app, this is a no-op.
- bool limit_web_extent_to_download_host_;
+ // If true and the installed extension uses web content, the web origin will
+ // be forced to the origin of |original_url_|. Defaults to false. This is used
+ // for non-gallery installs, where we don't trust the origin given in the
+ // manifest.
+ bool force_web_origin_to_download_url_;
// Whether to create an app shortcut after successful installation. This is
// set based on the user's selection in the UI and can only ever be true for
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 108a214..a416f17 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -264,7 +264,7 @@ void ExtensionsService::UpdateExtension(const std::string& id,
client));
installer->set_expected_id(id);
installer->set_delete_source(true);
- installer->set_limit_web_extent_to_download_host(true);
+ installer->set_force_web_origin_to_download_url(true);
installer->set_original_url(download_url);
installer->InstallCrx(extension_path);
}
@@ -984,8 +984,16 @@ Extension* ExtensionsService::GetExtensionByWebExtent(const GURL& url) {
}
Extension* ExtensionsService::GetExtensionByOverlappingWebExtent(
- const ExtensionExtent& extent) {
- // TODO(aa): Make this work for the new extents. http://crbug.com/47445.
+ const ExtensionExtent& extent, GURL* overlapping_url) {
+ for (size_t i = 0; i < extensions_.size(); ++i) {
+ for (size_t j = 0; j < extent.paths().size(); ++j) {
+ GURL url(extent.origin().Resolve(extent.paths()[j]));
+ if (extensions_[i]->web_extent().ContainsURL(url)) {
+ *overlapping_url = url;
+ return extensions_[i];
+ }
+ }
+ }
return NULL;
}
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index a5725ef..f019630 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -269,8 +269,10 @@ class ExtensionsService
Extension* GetExtensionByWebExtent(const GURL& url);
// Returns an extension that contains any URL that overlaps with the given
- // extent, if one exists.
- Extension* GetExtensionByOverlappingWebExtent(const ExtensionExtent& extent);
+ // extent, if one exists. Also fills |overlapping_url| with the first URL that
+ // overlaps.
+ Extension* GetExtensionByOverlappingWebExtent(const ExtensionExtent& extent,
+ GURL* overlapping_url);
// Clear all ExternalExtensionProviders.
void ClearProvidersForTesting();
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index 5618648..cc50bab 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -1034,9 +1034,8 @@ TEST_F(ExtensionsServiceTest, InstallApps) {
ValidatePrefKeyCount(++pref_count);
// A third app whose extent overlaps the first. Should fail.
- // TODO(aa): bring this back when overlap is fixed. http://crbug.com/47445.
- // PackAndInstallExtension(extensions_path.AppendASCII("app3"), false);
- // ValidatePrefKeyCount(pref_count);
+ PackAndInstallExtension(extensions_path.AppendASCII("app3"), false);
+ ValidatePrefKeyCount(pref_count);
}
// Test that when an extension version is reinstalled, nothing happens.
diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.cc b/chrome/browser/extensions/sandboxed_extension_unpacker.cc
index eda5e3f..ab72325 100644
--- a/chrome/browser/extensions/sandboxed_extension_unpacker.cc
+++ b/chrome/browser/extensions/sandboxed_extension_unpacker.cc
@@ -34,7 +34,8 @@ SandboxedExtensionUnpacker::SandboxedExtensionUnpacker(
SandboxedExtensionUnpackerClient* client)
: crx_path_(crx_path), temp_path_(temp_path),
thread_identifier_(ChromeThread::ID_COUNT),
- rdh_(rdh), client_(client), got_response_(false) {
+ rdh_(rdh), client_(client), got_response_(false),
+ force_web_origin_override_(false) {
}
void SandboxedExtensionUnpacker::Start() {
@@ -275,6 +276,29 @@ DictionaryValue* SandboxedExtensionUnpacker::RewriteManifestFile(
static_cast<DictionaryValue*>(manifest.DeepCopy()));
final_manifest->SetString(extension_manifest_keys::kPublicKey, public_key_);
+ if (final_manifest->HasKey(extension_manifest_keys::kApp)) {
+ bool has_web_origin =
+ final_manifest->Get(extension_manifest_keys::kWebOrigin, NULL);
+ if (force_web_origin_override_) {
+ if (has_web_origin) {
+ ReportFailure("Error: untrusted extension should have no web_origin.");
+ return NULL;
+ }
+ if (!web_origin_override_.is_valid() ||
+ web_origin_override_.SchemeIsFile()) {
+ ReportFailure(
+ "Error: untrusted extension has an invalid download origin.");
+ return NULL;
+ }
+
+ final_manifest->SetString(extension_manifest_keys::kWebOrigin,
+ web_origin_override_.spec());
+ } else if (!has_web_origin) {
+ ReportFailure("Error: trusted extension should have a web_origin.");
+ return NULL;
+ }
+ }
+
std::string manifest_json;
JSONStringValueSerializer serializer(&manifest_json);
serializer.set_pretty_print(true);
diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.h b/chrome/browser/extensions/sandboxed_extension_unpacker.h
index 60d02a9..4c89082 100644
--- a/chrome/browser/extensions/sandboxed_extension_unpacker.h
+++ b/chrome/browser/extensions/sandboxed_extension_unpacker.h
@@ -97,6 +97,12 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client {
ResourceDispatcherHost* rdh,
SandboxedExtensionUnpackerClient* cilent);
+ const GURL& web_origin() const { return web_origin_override_; }
+ void set_web_origin(const GURL& val) {
+ web_origin_override_ = val;
+ force_web_origin_override_ = true;
+ }
+
// Start unpacking the extension. The client is called with the results.
void Start();
@@ -167,6 +173,15 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client {
// The public key that was extracted from the CRX header.
std::string public_key_;
+
+ // If the app uses web content, its origin will be set to this value. This is
+ // used when an app is self-hosted. The only valid origin is the origin it is
+ // served from.
+ GURL web_origin_override_;
+
+ // If true, we require the web_origin field to be empty in the manifest.
+ // Instead, we use the one given in web_origin_override_. Defaults to false.
+ bool force_web_origin_override_;
};
#endif // CHROME_BROWSER_EXTENSIONS_SANDBOXED_EXTENSION_UNPACKER_H_