diff options
Diffstat (limited to 'services/sync/modules/addonutils.js')
-rw-r--r-- | services/sync/modules/addonutils.js | 94 |
1 files changed, 31 insertions, 63 deletions
diff --git a/services/sync/modules/addonutils.js b/services/sync/modules/addonutils.js index 95da6be0a0..54b441b9e5 100644 --- a/services/sync/modules/addonutils.js +++ b/services/sync/modules/addonutils.js @@ -6,7 +6,7 @@ this.EXPORTED_SYMBOLS = ["AddonUtils"]; -var {interfaces: Ci, utils: Cu} = Components; +const {interfaces: Ci, utils: Cu} = Components; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Log.jsm"); @@ -38,10 +38,21 @@ AddonUtilsInternal.prototype = { * Function to be called with result of operation. */ getInstallFromSearchResult: - function getInstallFromSearchResult(addon, cb) { + function getInstallFromSearchResult(addon, cb, requireSecureURI=true) { this._log.debug("Obtaining install for " + addon.id); + // Verify that the source URI uses TLS. We don't allow installs from + // insecure sources for security reasons. The Addon Manager ensures that + // cert validation, etc is performed. + if (requireSecureURI) { + let scheme = addon.sourceURI.scheme; + if (scheme != "https") { + cb(new Error("Insecure source URI scheme: " + scheme), addon.install); + return; + } + } + // We should theoretically be able to obtain (and use) addon.install if // it is available. However, the addon.sourceURI rewriting won't be // reflected in the AddonInstall, so we can't use it. If we ever get rid @@ -69,6 +80,8 @@ AddonUtilsInternal.prototype = { * syncGUID - Sync GUID to use for the new add-on. * enabled - Boolean indicating whether the add-on should be enabled upon * install. + * requireSecureURI - Boolean indicating whether to require a secure + * URI to install from. This defaults to true. * * When complete it calls a callback with 2 arguments, error and result. * @@ -92,6 +105,10 @@ AddonUtilsInternal.prototype = { function installAddonFromSearchResult(addon, options, cb) { this._log.info("Trying to install add-on from search result: " + addon.id); + if (options.requireSecureURI === undefined) { + options.requireSecureURI = true; + } + this.getInstallFromSearchResult(addon, function onResult(error, install) { if (error) { cb(error, null); @@ -147,10 +164,10 @@ AddonUtilsInternal.prototype = { install.install(); } catch (ex) { - this._log.error("Error installing add-on", ex); + this._log.error("Error installing add-on: " + Utils.exceptionstr(ex)); cb(ex, null); } - }.bind(this)); + }.bind(this), options.requireSecureURI); }, /** @@ -231,7 +248,7 @@ AddonUtilsInternal.prototype = { } let ids = []; - for (let addon of installs) { + for each (let addon in installs) { ids.push(addon.id); } @@ -244,7 +261,6 @@ AddonUtilsInternal.prototype = { installedIDs: [], installs: [], addons: [], - skipped: [], errors: [] }; @@ -282,21 +298,15 @@ AddonUtilsInternal.prototype = { // server-side metrics aren't skewed (bug 708134). The server should // ideally send proper URLs, but this solution was deemed too // complicated at the time the functionality was implemented. - for (let addon of addons) { - // Find the specified options for this addon. - let options; - for (let install of installs) { - if (install.id == addon.id) { - options = install; - break; - } - } - if (!this.canInstallAddon(addon, options)) { - ourResult.skipped.push(addon.id); + for each (let addon in addons) { + // sourceURI presence isn't enforced by AddonRepository. So, we skip + // add-ons without a sourceURI. + if (!addon.sourceURI) { + this._log.info("Skipping install of add-on because missing " + + "sourceURI: " + addon.id); continue; } - // We can go ahead and attempt to install it. toInstall.push(addon); // We should always be able to QI the nsIURI to nsIURL. If not, we @@ -332,9 +342,9 @@ AddonUtilsInternal.prototype = { // Start all the installs asynchronously. They will report back to us // as they finish, eventually triggering the global callback. - for (let addon of toInstall) { + for each (let addon in toInstall) { let options = {}; - for (let install of installs) { + for each (let install in installs) { if (install.id == addon.id) { options = install; break; @@ -353,51 +363,9 @@ AddonUtilsInternal.prototype = { }, /** - * Returns true if we are able to install the specified addon, false - * otherwise. It is expected that this will log the reason if it returns - * false. - * - * @param addon - * (Addon) Add-on instance to check. - * @param options - * (object) The options specified for this addon. See installAddons() - * for the valid elements. - */ - canInstallAddon(addon, options) { - // sourceURI presence isn't enforced by AddonRepository. So, we skip - // add-ons without a sourceURI. - if (!addon.sourceURI) { - this._log.info("Skipping install of add-on because missing " + - "sourceURI: " + addon.id); - return false; - } - // Verify that the source URI uses TLS. We don't allow installs from - // insecure sources for security reasons. The Addon Manager ensures - // that cert validation etc is performed. - // (We should also consider just dropping this entirely and calling - // XPIProvider.isInstallAllowed, but that has additional semantics we might - // need to think through...) - let requireSecureURI = true; - if (options && options.requireSecureURI !== undefined) { - requireSecureURI = options.requireSecureURI; - } - - if (requireSecureURI) { - let scheme = addon.sourceURI.scheme; - if (scheme != "https") { - this._log.info(`Skipping install of add-on "${addon.id}" because sourceURI's scheme of "${scheme}" is not trusted`); - return false; - } - } - this._log.info(`Add-on "${addon.id}" is able to be installed`); - return true; - }, - - - /** * Update the user disabled flag for an add-on. * - * The supplied callback will be called when the operation is + * The supplied callback will ba called when the operation is * complete. If the new flag matches the existing or if the add-on * isn't currently active, the function will fire the callback * immediately. Else, the callback is invoked when the AddonManager |