Bug 378216: Disable insecure extension updates by default. r=robstrong

This commit is contained in:
dtownsend@oxymoronical.com 2007-09-03 14:44:12 -07:00
Родитель c267b8a676
Коммит b919fdb929
26 изменённых файлов: 1149 добавлений и 27 удалений

Просмотреть файл

@ -99,6 +99,7 @@
<!ENTITY includeUpdate.tooltip "Include this Add-on when installing the updates">
<!-- Status Messsages -->
<!ENTITY insecureUpdate.label "Does not provide secure updates.">
<!ENTITY needsDependencies.label "Requires additional items.">
<!ENTITY blocklisted.label "Disabled for your protection.">
<!ENTITY toBeDisabled.label "This add-on will be disabled when &brandShortName; is restarted.">

Просмотреть файл

@ -72,6 +72,7 @@ incompatibleThemeName=this Theme
incompatibleExtension=Disabled - not compatible with %S %S
incompatibleAddonMsg=Not compatible with %S %S
blocklistedDisabled=Disabled for your protection
insecureUpdateMessage="%S" will not be installed because it does not provide secure updates
invalidGUIDMessage="%S" could not be installed because of an error in its Install Manifest ("%S" is not a valid GUID). Please contact the author of this item about the problem.
invalidVersionMessage="%S" could not be installed because of an error in its Install Manifest ("%S" is not a valid Version String). Please contact the author of this item about the problem.
@ -130,6 +131,7 @@ xpinstallDisabledMsgLocked=Software installation has been disabled by your syste
xpinstallDisabledMsg=Software installation is currently disabled. Click Enable and try again.
safeModeMsg=All add-ons have been disabled by safe mode.
disabledCompatMsg=Add-on compatibility checking is disabled. You may have incompatible add-ons.
disabledUpdateSecurityMsg=Add-on update security checking is disabled. You may be compromised by updates.
noUpdatesMsg=No updates were found.
offlineUpdateMsg=%S is currently in offline mode and is unable to update Add-ons. Click Go Online and try again.
offlineInstallMsg=%S is currently in offline mode and is unable to install Add-ons. Click Go Online and try again.

Просмотреть файл

@ -57,6 +57,7 @@ var gDownloadManager = null;
var gObserverIndex = -1;
var gInSafeMode = false;
var gCheckCompat = true;
var gCheckUpdateSecurity = true;
var gUpdatesOnly = false;
var gAppID = "";
var gPref = null;
@ -66,6 +67,7 @@ var gPlugins = null;
var gPluginsDS = null;
const PREF_EM_CHECK_COMPATIBILITY = "extensions.checkCompatibility";
const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
const PREF_EXTENSIONS_GETMORETHEMESURL = "extensions.getMoreThemesURL";
const PREF_EXTENSIONS_GETMOREEXTENSIONSURL = "extensions.getMoreExtensionsURL";
const PREF_EXTENSIONS_DSS_ENABLED = "extensions.dss.enabled";
@ -267,6 +269,7 @@ function showView(aView) {
["plugin", "?plugin"],
["previewImage", "?previewImage"],
["satisfiesDependencies", "?satisfiesDependencies"],
["providesUpdatesSecurely", "?providesUpdatesSecurely"],
["type", "?type"],
["updateable", "?updateable"],
["updateURL", "?updateURL"],
@ -316,6 +319,7 @@ function showView(aView) {
["opType", "?opType"],
["previewImage", "?previewImage"],
["satisfiesDependencies", "?satisfiesDependencies"],
["providesUpdatesSecurely", "?providesUpdatesSecurely"],
["type", "?type"],
["updateURL", "?updateURL"],
["version", "?version"],
@ -654,6 +658,10 @@ function Startup()
gCheckCompat = gPref.getBoolPref(PREF_EM_CHECK_COMPATIBILITY);
} catch(e) { }
try {
gCheckUpdateSecurity = gPref.getBoolPref(PREF_EM_CHECK_UPDATE_SECURITY);
} catch(e) { }
// Sort on startup and anytime an add-on is installed or upgraded.
gExtensionManager.sortTypeByProperty(nsIUpdateItem.TYPE_ADDON, "name", true);
// Extension Command Updating is handled by a command controller.
@ -689,6 +697,23 @@ function Startup()
msgText, buttonLabel, buttonAccesskey,
true, notifyData);
}
if (!gCheckUpdateSecurity) {
var defaultCheckSecurity = true;
try {
defaultCheckSecurity = defaultPref.getBoolPref(PREF_EM_CHECK_UPDATE_SECURITY);
} catch (e) { }
// App has update security checking enabled by default so show warning
if (defaultCheckSecurity) {
var msgText = getExtensionString("disabledUpdateSecurityMsg");
var buttonLabel = getExtensionString("enableButtonLabel");
var buttonAccesskey = getExtensionString("enableButtonAccesskey");
var notifyData = "addons-enable-updatesecurity";
showMessage("chrome://mozapps/skin/extensions/question.png",
msgText, buttonLabel, buttonAccesskey,
true, notifyData);
}
}
if (gInSafeMode) {
showMessage("chrome://mozapps/skin/extensions/question.png",
getExtensionString("safeModeMsg"),
@ -809,7 +834,7 @@ XPInstallDownloadManager.prototype = {
var type = isTheme ? nsIUpdateItem.TYPE_THEME : nsIUpdateItem.TYPE_EXTENSION;
var item = Components.classes["@mozilla.org/updates/item;1"]
.createInstance(Components.interfaces.nsIUpdateItem);
item.init(url, " ", "app-profile", "", "", displayName, url, "", iconURL, "", type, "");
item.init(url, " ", "app-profile", "", "", displayName, url, "", iconURL, "", "", type, "");
items.push(item);
// Advance the enumerator
@ -1368,6 +1393,10 @@ const gAddonsMsgObserver = {
gPref.clearUserPref(PREF_EM_CHECK_COMPATIBILITY);
gCheckCompat = true;
break;
case "addons-enable-updatesecurity":
gPref.clearUserPref(PREF_EM_CHECK_UPDATE_SECURITY);
gCheckUpdateSecurity = true;
break;
case "addons-no-updates":
var children = gExtensionsView.children;
for (var i = 0; i < children.length; ++i) {
@ -1690,6 +1719,7 @@ var gExtensionsViewController = {
(!selectedItem.opType ||
selectedItem.opType == "needs-disable")) &&
!selectedItem.isBlocklisted &&
(!gCheckUpdateSecurity || selectedItem.providesUpdatesSecurely) &&
(!gCheckCompat || selectedItem.isCompatible) &&
selectedItem.satisfiesDependencies &&
!gExtensionsView.hasAttribute("update-operation");

Просмотреть файл

@ -129,6 +129,7 @@
<property name="isCompatible" onget="return this.getAttribute('compatible') == 'true';"/>
<property name="isBlocklisted" onget="return this.getAttribute('blocklisted') == 'true';"/>
<property name="isDisabled" onget="return this.getAttribute('isDisabled') == 'true';"/>
<property name="providesUpdatesSecurely" onget="return this.getAttribute('providesUpdatesSecurely') == 'true';"/>
<property name="satisfiesDependencies" onget="return this.getAttribute('satisfiesDependencies') == 'true';"/>
<property name="opType">
<getter>
@ -239,6 +240,9 @@
<xul:hbox flex="1" class="incompatibleBox attention">
<xul:label anonid="incompatibleLabel" crop="end"/>
</xul:hbox>
<xul:hbox flex="1" class="insecureUpdateBox attention">
<xul:label value="&insecureUpdate.label;" crop="end"/>
</xul:hbox>
<xul:hbox flex="1" class="needsDependenciesBox attention">
<xul:label value="&needsDependencies.label;" crop="end"/>
</xul:hbox>

Просмотреть файл

@ -478,7 +478,7 @@ interface nsIExtensionManager : nsISupports
* XXXben work in progress, the name of this interface will change after the
* update system is complete, probably to nsIAddon
*/
[scriptable, uuid(a15390e0-2ad6-422c-9596-94f95286c16f)]
[scriptable, uuid(f559f340-5160-420f-abc8-19b251708e7e)]
interface nsIUpdateItem : nsISupports
{
/**
@ -535,6 +535,12 @@ interface nsIUpdateItem : nsISupports
*/
readonly attribute AString updateRDF;
/**
* The public key to verify updates for this item. This must be the public
* part of the key that was used to sign update manifests for this add-on.
*/
readonly attribute AString updateKey;
const unsigned long TYPE_APP = 0x01;
const unsigned long TYPE_EXTENSION = 0x02;
const unsigned long TYPE_THEME = 0x04;
@ -564,7 +570,8 @@ interface nsIUpdateItem : nsISupports
in AString installLocationKey, in AString minAppVersion,
in AString maxAppVersion, in AString name,
in AString downloadURL, in AString xpiHash, in AString iconURL,
in AString updateURL, in long type, in AString targetAppID);
in AString updateURL, in AString updateKey, in long type,
in AString targetAppID);
/**
* Returns a JS Object source representing an nsIUpdateItem.

Просмотреть файл

@ -60,6 +60,7 @@ const nsIURL = Components.interfaces.nsIURL
const nsIDirectoryEnumerator = Components.interfaces.nsIDirectoryEnumerator;
const PREF_EM_CHECK_COMPATIBILITY = "extensions.checkCompatibility";
const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
const PREF_EM_LAST_APP_VERSION = "extensions.lastAppVersion";
const PREF_UPDATE_COUNT = "extensions.update.count";
const PREF_UPDATE_DEFAULT_URL = "extensions.update.url";
@ -151,6 +152,7 @@ const INSTALLERROR_INCOMPATIBLE_VERSION = -3;
const INSTALLERROR_PHONED_HOME = -4;
const INSTALLERROR_INCOMPATIBLE_PLATFORM = -5;
const INSTALLERROR_BLOCKLISTED = -6;
const INSTALLERROR_INSECURE_UPDATE = -7;
const MODE_RDONLY = 0x01;
const MODE_WRONLY = 0x02;
@ -173,6 +175,7 @@ var gInstallManifestRoot = null;
var gVersionChecker = null;
var gLoggingEnabled = null;
var gCheckCompatibility = true;
var gCheckUpdateSecurity = true;
var gLocale = "en-US";
/**
@ -315,10 +318,12 @@ function getResourceForID(id) {
* ...
*/
function makeItem(id, version, locationKey, minVersion, maxVersion, name,
updateURL, updateHash, iconURL, updateRDF, type, targetAppID) {
updateURL, updateHash, iconURL, updateRDF, updateKey, type,
targetAppID) {
var item = new UpdateItem();
item.init(id, version, locationKey, minVersion, maxVersion, name,
updateURL, updateHash, iconURL, updateRDF, type, targetAppID);
updateURL, updateHash, iconURL, updateRDF, updateKey, type,
targetAppID);
return item;
}
@ -2431,8 +2436,9 @@ ExtensionManager.prototype = {
case "nsPref:changed":
if (data == PREF_EM_LOGGING_ENABLED)
this._loggingToggled();
else if (data == PREF_EM_CHECK_COMPATIBILITY)
this._checkCompatToggled();
else if (data == PREF_EM_CHECK_COMPATIBILITY ||
data == PREF_EM_CHECK_UPDATE_SECURITY)
this._updateAppDisabledState();
else if ((data == PREF_MATCH_OS_LOCALE) || (data == PREF_SELECTED_LOCALE))
this._updateLocale();
break;
@ -2465,11 +2471,12 @@ ExtensionManager.prototype = {
},
/**
* Enables or disables extensions that are incompatible depending upon the pref
* setting for compatibility checking.
* When a preference is toggled that affects whether an item is usable or not
* we must app-enable or app-disable the item based on the new settings.
*/
_checkCompatToggled: function() {
_updateAppDisabledState: function() {
gCheckCompatibility = getPref("getBoolPref", PREF_EM_CHECK_COMPATIBILITY, true);
gCheckUpdateSecurity = getPref("getBoolPref", PREF_EM_CHECK_UPDATE_SECURITY, true);
var ds = this.datasource;
// Enumerate all items
@ -2506,6 +2513,7 @@ ExtensionManager.prototype = {
}
gLoggingEnabled = getPref("getBoolPref", PREF_EM_LOGGING_ENABLED, false);
gCheckCompatibility = getPref("getBoolPref", PREF_EM_CHECK_COMPATIBILITY, true);
gCheckUpdateSecurity = getPref("getBoolPref", PREF_EM_CHECK_UPDATE_SECURITY, true);
gPref.addObserver("extensions.", this, false);
gPref.addObserver(PREF_MATCH_OS_LOCALE, this, false);
gPref.addObserver(PREF_SELECTED_LOCALE, this, false);
@ -2751,6 +2759,7 @@ ExtensionManager.prototype = {
"", /* XPI Update Hash */
getManifestProperty(installManifest, "iconURL"),
getManifestProperty(installManifest, "updateURL"),
getManifestProperty(installManifest, "updateKey"),
installData.type,
targetAppInfo ? targetAppInfo.appID : gApp.ID);
}
@ -2802,6 +2811,11 @@ ExtensionManager.prototype = {
callback(installManifest, installData.id, location, installData.type);
em._appDisableItem(id);
}
else if (installData.error == INSTALLERROR_INSECURE_UPDATE) {
LOG("... success, item installed but does not provide updates securely");
callback(installManifest, installData.id, location, installData.type);
em._appDisableItem(id);
}
else if (installData.error == INSTALLERROR_BLOCKLISTED) {
LOG("... success, item installed but is blocklisted");
callback(installManifest, installData.id, location, installData.type);
@ -2820,8 +2834,6 @@ ExtensionManager.prototype = {
return "Invalid GUID";
case INSTALLERROR_INVALID_VERSION:
return "Invalid Version";
case INSTALLERROR_INCOMPATIBLE_VERSION:
return "Incompatible Version";
case INSTALLERROR_INCOMPATIBLE_PLATFORM:
return "Incompatible Platform";
}
@ -3475,8 +3487,22 @@ ExtensionManager.prototype = {
}
else if (allAppManaged)
allAppManaged = false;
// appDisabled is determined by an item being compatible,
// satisfying its dependencies, and not being blocklisted
if (ds.getItemProperty(id, "providesUpdatesSecurely") == "false") {
/* It's possible the previous version did not understand updateKeys so
* check if we can import one for this addon from it's manifest. */
var location = this.getInstallLocation(id);
var installRDF = location.getItemFile(id, FILE_INSTALL_MANIFEST);
if (installRDF.exists()) {
var metadataDS = getInstallManifest(installRDF);
var literal = metadataDS.GetTarget(gInstallManifestRoot, EM_R("updateKey"), true);
if (literal && literal instanceof Components.interfaces.nsIRDFLiteral)
ds.setItemProperty(id, EM_R("updateKey"), literal);
}
}
// appDisabled is determined by an item being compatible, using secure
// updates, satisfying its dependencies, and not being blocklisted
if (this._isUsableItem(id)) {
if (ds.getItemProperty(id, "appDisabled"))
ds.setItemProperty(id, EM_R("appDisabled"), null);
@ -3853,6 +3879,8 @@ ExtensionManager.prototype = {
* INSTALLERROR_INCOMPATIBLE_PLATFORM
* error, item is not compatible with the operating
* system or ABI the application was built for.
* INSTALLERROR_INSECURE_UPDATE
* error, item has no secure method of providing updates
* INSTALLERROR_BLOCKLISTED
* error, item is blocklisted
*/
@ -3863,6 +3891,8 @@ ExtensionManager.prototype = {
type : 0,
error : INSTALLERROR_SUCCESS,
targetApps : [],
updateURL : "",
updateKey : "",
currentApp : null };
// Fetch properties from the Install Manifest
@ -3871,6 +3901,7 @@ ExtensionManager.prototype = {
installData.name = getManifestProperty(installManifest, "name");
installData.type = getAddonTypeFromInstallManifest(installManifest);
installData.updateURL= getManifestProperty(installManifest, "updateURL");
installData.updateKey= getManifestProperty(installManifest, "updateKey");
/**
* Reads a property off a Target Application resource
@ -3948,12 +3979,23 @@ ExtensionManager.prototype = {
installData.error = INSTALLERROR_INVALID_GUID;
return installData;
}
// Check the target application range specified by the extension metadata.
// Check that the add-on provides a secure update method.
if (gCheckUpdateSecurity &&
installData.updateURL &&
installData.updateURL.substring(0, 6) != "https:" &&
!installData.updateKey) {
installData.error = INSTALLERROR_INSECURE_UPDATE;
return installData;
}
// Check that the target application range allows compatibility with the app
if (gCheckCompatibility &&
!this.datasource.isCompatible(installManifest, gInstallManifestRoot, undefined))
!this.datasource.isCompatible(installManifest, gInstallManifestRoot, undefined)) {
installData.error = INSTALLERROR_INCOMPATIBLE_VERSION;
return installData;
}
// Check if the item is blocklisted.
if (!gBlocklist)
gBlocklist = Components.classes["@mozilla.org/extensions/blocklist;1"]
@ -4192,6 +4234,7 @@ ExtensionManager.prototype = {
"", /* XPI Update Hash */
"", /* Icon URL */
installData.updateURL || "",
installData.updateKey || "",
installData.type,
installData.currentApp.id);
em.update([item], 1, nsIExtensionManager.UPDATE_CHECK_COMPATIBILITY, this);
@ -4415,6 +4458,14 @@ ExtensionManager.prototype = {
installData.version + " was not installed.");
showBlocklistMessage([installData], true);
break;
case INSTALLERROR_INSECURE_UPDATE:
LOG("No secure updates: Item: \"" + installData.id + "\" version " +
installData.version + " was not installed.");
var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
showMessage("incompatibleTitle",
[bundle.GetStringFromName("type-" + installData.type)],
"insecureUpdateMessage", [installData.name]);
break;
default:
break;
}
@ -5064,9 +5115,23 @@ ExtensionManager.prototype = {
*/
_isUsableItem: function(id) {
var ds = this.datasource;
return ((!gCheckCompatibility || ds.getItemProperty(id, "compatible") == "true") &&
ds.getItemProperty(id, "blocklisted") == "false" &&
ds.getItemProperty(id, "satisfiesDependencies") == "true");
/* If we're not compatibility checking or if the item is compatible
* and if it isn't blocklisted and has all dependencies satisfied then
* proceed to the security check */
if ((!gCheckCompatibility || ds.getItemProperty(id, "compatible") == "true") &&
ds.getItemProperty(id, "blocklisted") == "false" &&
ds.getItemProperty(id, "satisfiesDependencies") == "true") {
// appManaged items aren't updated so no need to check update security.
if (ds.getItemProperty(id, "appManaged") == "true")
return true;
/* If we are not ignoring update security then check that the item has
* a secure update mechanism */
return (!gCheckUpdateSecurity ||
ds.getItemProperty(id, "providesUpdatesSecurely") == "true");
}
return false;
},
/**
@ -6164,11 +6229,54 @@ RDFItemUpdater.prototype = {
"doesn't give up much in the way of information when the load fails.\r\n" +
"\r\nTry checking that: \r\n" +
" 1. Your remote RDF file exists at the location.\r\n" +
" 2. Your RDF file is valid XML (starts with <?xml version=\"1.0?\">\r\n" +
" 2. Your RDF file is valid XML (starts with <?xml version=\"1.0\"?>\r\n" +
" and loads in Firefox displaying pretty printed like other XML documents\r\n" +
" 3. Your server is sending the data in the correct MIME\r\n" +
" type (text/xml)");
}
// If we have an update key then the update manifest must be signed
if (aLocalItem.updateKey) {
var extensionRes = gRDF.GetResource(getItemPrefix(aLocalItem.type) + aLocalItem.id);
LOG(extensionRes.Value);
var signature = this._getPropertyFromResource(aDatasource, extensionRes, "signature", null);
if (signature) {
var serializer = new RDFSerializer();
try {
var updateString = serializer.serializeResource(aDatasource, extensionRes);
var verifier = Components.classes["@mozilla.org/security/datasignatureverifier;1"]
.getService(Components.interfaces.nsIDataSignatureVerifier);
try {
if (!verifier.verifyData(updateString, signature, aLocalItem.updateKey)) {
LOG("RDFItemUpdater:onDatasourceLoaded: Update manifest for " +
aLocalItem.id + " failed signature check.");
this._updater.checkForDone(aLocalItem, nsIAddonUpdateCheckListener.STATUS_FAILURE);
return;
}
}
catch (e) {
LOG("RDFItemUpdater:onDatasourceLoaded: Failed to verify signature for " +
aLocalItem.id + ". This indicates a malformed update key or signature.");
this._updater.checkForDone(aLocalItem, nsIAddonUpdateCheckListener.STATUS_FAILURE);
return;
}
}
catch (e) {
LOG("RDFItemUpdater:onDatasourceLoaded: Failed to generate signature " +
"string for " + aLocalItem.id + ". Serializer threw " + e);
this._updater.checkForDone(aLocalItem, nsIAddonUpdateCheckListener.STATUS_FAILURE);
return;
}
}
else {
LOG("RDFItemUpdater:onDatasourceLoaded: Update manifest for " +
aLocalItem.id + " did not contain a signature.");
this._updater.checkForDone(aLocalItem, nsIAddonUpdateCheckListener.STATUS_FAILURE);
return;
}
}
/* If there is no updateKey either the update was over SSL, or it is an old
* addon that we are allowing a grace update. */
// Parse the response RDF
var newerItem, sameItem;
@ -6344,16 +6452,37 @@ RDFItemUpdater.prototype = {
if (appID != this._updater._appID && appID != TOOLKIT_ID)
continue;
var updateLink = this._getPropertyFromResource(aDataSource, targetApp, "updateLink", aLocalItem);
var updateHash = this._getPropertyFromResource(aDataSource, targetApp, "updateHash", aLocalItem);
if (aUpdateCheckType == nsIExtensionManager.UPDATE_CHECK_NEWVERSION) {
// New version information is useless without a link to get it from
if (!updateLink)
continue;
/* If the update link is non-ssl and we do not have a hash or the hash
* is of an insecure nature then we must ignore this update. Bypass
* this if not checking update security. Currently we only consider
* the sha hashing algorithms as secure. */
if (gCheckUpdateSecurity && updateLink.substring(0, 6) != "https:" &&
(!updateHash || updateHash.substring(0, 3) != "sha")) {
LOG("RDFItemUpdater:_parseV20Update: Update for " + aLocalItem.id +
" at " + updateLink + " ignored because it is insecure. updateLink " +
" must be a https url or an updateHash must be specified.");
continue;
}
}
var updatedItem = makeItem(aLocalItem.id,
version,
aLocalItem.installLocationKey,
this._getPropertyFromResource(aDataSource, targetApp, "minVersion", aLocalItem),
this._getPropertyFromResource(aDataSource, targetApp, "maxVersion", aLocalItem),
aLocalItem.name,
this._getPropertyFromResource(aDataSource, targetApp, "updateLink", aLocalItem),
this._getPropertyFromResource(aDataSource, targetApp, "updateHash", aLocalItem),
updateLink,
updateHash,
"", /* Icon URL */
"", /* RDF Update URL */
"", /* Update Key */
aLocalItem.type,
appID);
@ -6369,6 +6498,158 @@ RDFItemUpdater.prototype = {
}
};
/**
* A serialisation method for RDF data that produces an identical string
* provided that the RDF assertions match.
* The serialisation is not complete, only assertions stemming from a given
* resource are included, multiple references to the same resource are not
* permitted, and the RDF prolog and epilog are not included.
* RDF Blob and Date literals are not supported.
*/
function RDFSerializer()
{
this.cUtils = Components.classes["@mozilla.org/rdf/container-utils;1"]
.getService(Components.interfaces.nsIRDFContainerUtils);
this.resources = [];
}
RDFSerializer.prototype = {
INDENT: " ", // The indent used for pretty-printing
resources: null, // Array of the resources that have been found
/**
* Escapes characters from a string that should not appear in XML.
* @param string The string to be escaped
* @returns a string with all characters invalid in XML character data
* converted to entity references.
*/
escapeEntities: function(string)
{
string = string.replace(/&/g, "&amp;");
string = string.replace(/</g, "&lt;");
string = string.replace(/>/g, "&gt;");
string = string.replace(/"/g, "&quot;");
return string;
},
/**
* Serializes all the elements of an RDF container.
* @param ds The datasource holding the data
* @param container The RDF container to output the child elements of
* @param indent The current level of indent for pretty-printing
* @returns a string containing the serialized elements.
*/
serializeContainerItems: function(ds, container, indent)
{
var result = "";
var items = container.GetElements();
while (items.hasMoreElements()) {
var item = items.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
result += indent + "<RDF:li>\n"
result += this.serializeResource(ds, item, indent + this.INDENT);
result += indent + "</RDF:li>\n"
}
return result;
},
/**
* Serializes all em:* (see EM_NS) properties of an RDF resource except for
* the em:signature property. As this serialization is to be compared against
* the manifest signature it cannot contain the em:signature property itself.
* @param ds The datasource holding the data
* @param resource The RDF resource to output the properties of
* @param indent The current level of indent for pretty-printing
* @returns a string containing the serialized properties.
*/
serializeResourceProperties: function(ds, resource, indent)
{
var result = "";
var items = [];
var arcs = ds.ArcLabelsOut(resource);
while (arcs.hasMoreElements()) {
var arc = arcs.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
if (arc.ValueUTF8.substring(0, PREFIX_NS_EM.length) != PREFIX_NS_EM)
continue;
var prop = arc.ValueUTF8.substring(PREFIX_NS_EM.length);
if (prop == "signature")
continue;
var targets = ds.GetTargets(resource, arc, true);
while (targets.hasMoreElements()) {
var target = targets.getNext();
if (target instanceof Components.interfaces.nsIRDFResource) {
var item = indent + "<em:" + prop + ">\n";
item += this.serializeResource(ds, target, indent + this.INDENT);
item += indent + "</em:" + prop + ">\n";
items.push(item);
}
else if (target instanceof Components.interfaces.nsIRDFLiteral) {
items.push(indent + "<em:" + prop + ">" + this.escapeEntities(target.Value) + "</em:" + prop + ">\n");
}
else if (target instanceof Components.interfaces.nsIRDFInt) {
items.push(indent + "<em:" + prop + " NC:parseType=\"Integer\">" + target.Value + "</em:" + prop + ">\n");
}
else {
throw new Error("Cannot serialize unknown literal type");
}
}
}
items.sort();
result += items.join("");
return result;
},
/**
* Recursively serializes an RDF resource and all resources it links to.
* This will only output EM_NS properties and will ignore any em:signature
* property.
* @param ds The datasource holding the data
* @param resource The RDF resource to serialize
* @param indent The current level of indent for pretty-printing.
* Leave undefined for no indent
* @returns a string containing the serialized resource.
* @throws if the RDF data contains multiple references to the same resource.
*/
serializeResource: function(ds, resource, indent)
{
if (this.resources.indexOf(resource) != -1 ) {
// We cannot output multiple references to the same resource.
throw new Error("Cannot serialize multiple references to "+resource.Value);
}
if (indent === undefined)
indent = "";
this.resources.push(resource);
var container = null;
var type = "Description";
if (this.cUtils.IsSeq(ds, resource)) {
type = "Seq";
container = this.cUtils.MakeSeq(ds, resource);
}
else if (this.cUtils.IsAlt(ds, resource)) {
type = "Alt";
container = this.cUtils.MakeAlt(ds, resource);
}
else if (this.cUtils.IsBag(ds, resource)) {
type = "Bag";
container = this.cUtils.MakeBag(ds, resource);
}
var result = indent + "<RDF:" + type;
if (!gRDF.IsAnonymousResource(resource))
result += " about=\"" + this.escapeEntities(resource.ValueUTF8) + "\"";
result += ">\n";
if (container)
result += this.serializeContainerItems(ds, container, indent + this.INDENT);
result += this.serializeResourceProperties(ds, resource, indent + this.INDENT);
result += indent + "</RDF:" + type + ">\n";
return result;
}
}
/**
* A Datasource that holds Extensions.
* - Implements nsIRDFDataSource to drive UI
@ -6669,6 +6950,7 @@ ExtensionsDataSource.prototype = {
updateHash ? updateHash : "",
this.getItemProperty(id, "iconURL"),
this.getItemProperty(id, "updateURL"),
this.getItemProperty(id, "updateKey"),
this.getItemProperty(id, "type"),
targetAppInfo ? targetAppInfo.appID : gApp.ID);
},
@ -7122,7 +7404,7 @@ ExtensionsDataSource.prototype = {
// Copy the assertions over from the source datasource.
// Assert properties with single values
var singleProps = ["version", "updateURL", "updateService", "optionsURL",
"aboutURL", "iconURL", "internalName"];
"aboutURL", "iconURL", "internalName", "updateKey"];
// Items installed into restricted Install Locations can also be locked
// (can't be removed or disabled), and hidden (not shown in the UI)
@ -7737,6 +8019,19 @@ ExtensionsDataSource.prototype = {
return EM_L("true");
},
/**
* Get the providesUpdatesSecurely property (whether or not this item has a
* secure update mechanism)
*/
_rdfGet_providesUpdatesSecurely: function(item, property) {
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
if (this.getItemProperty(id, "updateKey") ||
!this.getItemProperty(id, "updateURL") ||
this.getItemProperty(id, "updateURL").substring(0, 6) == "https:")
return EM_L("true");
return EM_L("false");
},
/**
* Get the em:blocklisted property (whether or not this item is blocklisted)
*/
@ -8192,7 +8487,7 @@ UpdateItem.prototype = {
* See nsIUpdateService.idl
*/
init: function(id, version, installLocationKey, minAppVersion, maxAppVersion,
name, downloadURL, xpiHash, iconURL, updateURL, type,
name, downloadURL, xpiHash, iconURL, updateURL, updateKey, type,
targetAppID) {
this._id = id;
this._version = version;
@ -8204,6 +8499,7 @@ UpdateItem.prototype = {
this._xpiHash = xpiHash;
this._iconURL = iconURL;
this._updateURL = updateURL;
this._updateKey = updateKey;
this._type = type;
this._targetAppID = targetAppID;
},
@ -8221,6 +8517,7 @@ UpdateItem.prototype = {
get xpiHash() { return this._xpiHash; },
get iconURL() { return this._iconURL },
get updateRDF() { return this._updateURL; },
get updateKey() { return this._updateKey; },
get type() { return this._type; },
get targetAppID() { return this._targetAppID; },
@ -8238,6 +8535,7 @@ UpdateItem.prototype = {
xpiHash : this._xpiHash,
iconURL : this._iconURL,
updateRDF : this._updateURL,
updateKey : this._updateKey,
type : this._type,
targetAppID : this._targetAppID
}.toSource();

Просмотреть файл

@ -0,0 +1,22 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_1@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 1</em:name>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_10@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 10</em:name>
<em:updateURL>http://localhost:4444/test_bug378216.rdf</em:updateURL>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_11@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 11</em:name>
<em:updateURL>http://localhost:4444/test_bug378216.rdf</em:updateURL>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_12@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 12</em:name>
<em:updateURL>http://localhost:4444/test_bug378216.rdf</em:updateURL>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_13@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 13</em:name>
<em:updateURL>http://localhost:4444/test_bug378216.rdf</em:updateURL>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_2@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 2</em:name>
<em:updateURL>http://localhost:4444/test_bug378216.rdf</em:updateURL>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_3@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 3</em:name>
<em:updateURL>https://localhost:4444/test_bug378216_3/update.rdf</em:updateURL>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_4@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 4</em:name>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_5@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 5</em:name>
<em:updateURL>http://localhost:4444/test_bug378216.rdf</em:updateURL>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_6@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 6</em:name>
<em:updateURL>https://localhost:4444/test_bug378216_6/update.rdf</em:updateURL>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_7@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 7</em:name>
<em:updateURL>http://localhost:4444/test_bug378216.rdf</em:updateURL>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_8@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 8</em:name>
<em:updateURL>http://localhost:4444/test_bug378216.rdf</em:updateURL>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,27 @@
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>test_bug378216_9@tests.mozilla.org</em:id>
<em:version>1.0</em:version>
<em:targetApplication>
<Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
</Description>
</em:targetApplication>
<!-- Front End MetaData -->
<em:name>Bug 378216 Test 9</em:name>
<em:updateURL>http://localhost:4444/test_bug378216.rdf</em:updateURL>
<em:updateKey>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK426erD/H3XtsjvaB5+PJqbhj
Zc9EDI5OCJS8R3FIObJ9ZHJK1TXeaE7JWqt9WUmBWTEFvwS+FI9vWu8058N9CHhD
NyeP6i4LuUYjTURnn7Yw/IgzyIJ2oKsYa32RuxAyteqAWqPT/J63wBixIeCxmysf
awB/zH4KaPiY3vnrzQIDAQAB</em:updateKey>
</Description>
</RDF>

Просмотреть файл

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="UTF-8"?>
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<RDF:Description about="urn:mozilla:extension:test_bug378216_5@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>2.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
<em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
</RDF:Description>
<RDF:Description about="urn:mozilla:extension:test_bug378216_7@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>2.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>2</em:maxVersion>
<em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
<em:signature>MIGTMA0GCSqGSIb3DQEBBQUAA4GBAMO1O2gwSCCth1GwYMgscfaNakpN40PJfOWt
ub2HVdg8+OXMciF8d/9eVWm8eH/IxuxyZlmRZTs3O5tv9eWAY5uBCtqDf1WgTsGk
jrgZow1fITkZI7w0//C8eKdMLAtGueGfNs2IlTd5P/0KH/hf1rPc1wUqEqKCd4+L
BcVq13ad</em:signature>
</RDF:Description>
<RDF:Description about="urn:mozilla:extension:test_bug378216_8@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>2.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
<em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
<em:signature>MIGTMA0GCSqGSIb3DQEBBQUAA4GBAMH/33P/bn148mVkAB8i5X8c4LhY52E+MPUT
yKHGpowZnRLgL2O0dfpm+rljOBfKi51322PFrsc6VIFml6x4Lrb5foxSyB0Vs9pb
SEDFWUKquOQvceQ9iEx5Pe0VzrmUZgcQxd8ksSunWL4wJaBZ/evE5amFC6sw3pv/
fjt8p3GN</em:signature>
</RDF:Description>
<RDF:Description about="urn:mozilla:extension:test_bug378216_9@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>2.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
<em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
<em:updateHash>sha1:78fc1d2887eda35b4ad2e3a0b60120ca271ce6e6</em:updateHash>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
<em:signature>MIGTMA0GCSqGSIb3DQEBBQUAA4GBAJ5Dv3Zd7/j5dLchCw9iO/cxPq8oOhOYD2M+
jUKvmHCyTBRIEaJrE4N7yVbRYk++ERIfyVepLivsVi4pBmF7JTdw0NaKUA0LiOoT
mRL8I7s5NPjCiiNcdqbncWyiZwIj1w1nkbWGTlH/gEjRW/LbvT4JAuec8yNFDa4S
X8mOMf7k</em:signature>
</RDF:Description>
<RDF:Description about="urn:mozilla:extension:test_bug378216_10@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>2.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
<em:updateLink>https://localhost:4444/broken.xpi</em:updateLink>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
<em:signature>MIGTMA0GCSqGSIb3DQEBBQUAA4GBAGvf7XqqoTl5WofrNq55E7W+UttOEDXLB3Oi
XDiXe0i6njlozilseaUo1hgfQhhzN9gkyetP5tGBVcLRrVyliKpJmD6ABCVGW1lS
qS+SEw7gDHyHkvwKMyWKedpRGChqLYnnf+Y+CX3MWLZLkwPXMKdTYgN3Rx0lEnJk
37LSEMKE</em:signature>
</RDF:Description>
<RDF:Description about="urn:mozilla:extension:test_bug378216_11@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>2.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
<em:updateLink>https://localhost:4444/broken.xpi</em:updateLink>
<em:updateHash>sha1:78fc1d2887eda35b4ad2e3a0b60120ca271ce6e6</em:updateHash>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
<em:signature>MIGTMA0GCSqGSIb3DQEBBQUAA4GBACMX/KReOGSJ8CMGRroH1v3Gjv/Qs/pqH+Ow
o+hCKWLUKx7hpJgVJkXXdAHW0U88NXlp1S2H0WqA7I/CdmNXJSPzzV/J4z1dZgXh
JbW6mqNb0pj6nIe7g8OLzSxDgBmO4DUP5DAmnmqciJLWQzN7OdbcwrWz6xPN5kZF
A90eF5zy</em:signature>
</RDF:Description>
<RDF:Description about="urn:mozilla:extension:test_bug378216_12@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>2.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
<em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
<em:updateHash>md2:78fc1d2887eda35b4ad2e3a0b60120ca271ce6e6</em:updateHash>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
<em:signature>MIGTMA0GCSqGSIb3DQEBBQUAA4GBAJRfcFvHIWxVyycCw8IjNmEhabc2uqA1zQwp
5oKh3Y23hwIsQ6xy68Wtjte1NEYFRt5fWkbMXj9YQj6LpVbzBKiGATcrq6MycZKK
o5N22cWbrKKRweJezTyN4eLfQg21pG7r8mdfS0bIA28ZVFtQOmORejoUesEouCGy
eKYk9nS2</em:signature>
</RDF:Description>
<RDF:Description about="urn:mozilla:extension:test_bug378216_13@tests.mozilla.org">
<em:updates>
<RDF:Seq>
<RDF:li>
<RDF:Description>
<em:version>2.0</em:version>
<em:targetApplication>
<RDF:Description>
<em:id>xpcshell@tests.mozilla.org</em:id>
<em:minVersion>1</em:minVersion>
<em:maxVersion>1</em:maxVersion>
<em:updateLink>https://localhost:4444/broken.xpi</em:updateLink>
<em:updateHash>md2:78fc1d2887eda35b4ad2e3a0b60120ca271ce6e6</em:updateHash>
</RDF:Description>
</em:targetApplication>
</RDF:Description>
</RDF:li>
</RDF:Seq>
</em:updates>
<em:signature>MIGTMA0GCSqGSIb3DQEBBQUAA4GBALQKwzLFr/VOw3gJvv/LCh3/PWDd9FqmFnX+
hJjBmCaUDtG7CXn1i0h8ed8IeRHpLLT7FCzVwU3bH9BUjdm8wc3ObtlNbd8go01a
CoXz50r3rYPcYz4WS+7/+lvrUqsuWd9Wj+q0NeCPiNaaro6/AolE2Qf5JFRL3lxY
lsKWAnVO</em:signature>
</RDF:Description>
</RDF:RDF>

Просмотреть файл

@ -50,6 +50,9 @@ var env = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
env.set("XPCOM_DEBUG_BREAK", "stack");
// Disables security checking our updates which haven't been signed
gPrefs.setBoolPref("extensions.checkUpdateSecurity", false);
// This allows the EM to attempt to display errors to the user without failing.
var promptService = {
// nsIPromptService
@ -300,6 +303,7 @@ var next_test = function() {};
function do_check_item(aItem, aVersion, aAddonsEntry) {
if (aAddonsEntry.installed) {
do_check_neq(aItem, null);
do_check_eq(aItem.version, aVersion);
} else {
do_check_eq(aItem, null);

Просмотреть файл

@ -36,6 +36,9 @@
* ***** END LICENSE BLOCK *****
*/
// Disables security checking our updates which haven't been signed
gPrefs.setBoolPref("extensions.checkUpdateSecurity", false);
// Update check listener.
const checkListener = {
// nsIAddonUpdateCheckListener

Просмотреть файл

@ -0,0 +1,235 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Dave Townsend <dtownsend@oxymoronical.com>.
*
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK *****
*/
/**
* Tests for update security restrictions.
*
* Install tests:
*
* Test updateKey updateURL expected
*-------------------------------------------
* 1 absent absent success
* 2 absent http failure
* 3 absent https success
* 4 present absent success
* 5 present http success
* 6 present https success
*
* Update tests:
*
* Test signature updateHash updateLink expected
*--------------------------------------------------------
* 5 absent absent http fail
* 7 broken absent http fail
* 8 correct absent http no update
* 9 correct sha1 http update
* 10 corrent absent https update
* 11 corrent sha1 https update
* 12 corrent md2 http no update
* 13 corrent md2 https update
*/
do_import_script("netwerk/test/httpserver/httpd.js");
// This allows the EM to attempt to display errors to the user without failing
var promptService = {
alert: function(aParent, aDialogTitle, aText) {
},
alertCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState) {
},
confirm: function(aParent, aDialogTitle, aText) {
},
confirmCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState) {
},
confirmEx: function(aParent, aDialogTitle, aText, aButtonFlags, aButton0Title, aButton1Title, aButton2Title, aCheckMsg, aCheckState) {
},
prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
},
promptUsernameAndPassword: function(aParent, aDialogTitle, aText, aUsername, aPassword, aCheckMsg, aCheckState) {
},
promptPassword: function(aParent, aDialogTitle, aText, aPassword, aCheckMsg, aCheckState) {
},
select: function(aParent, aDialogTitle, aText, aCount, aSelectList, aOutSelection) {
},
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsIPromptService)
|| iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
}
};
var PromptServiceFactory = {
createInstance: function (outer, iid) {
if (outer != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
return promptService.QueryInterface(iid);
}
};
var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
registrar.registerFactory(Components.ID("{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}"), "PromptService",
"@mozilla.org/embedcomp/prompt-service;1", PromptServiceFactory);
var updateListener = {
onUpdateStarted: function()
{
},
onUpdateEnded: function()
{
do_test_finished();
},
onAddonUpdateStarted: function(addon)
{
},
onAddonUpdateEnded: function(addon, status)
{
var nsIAddonUpdateCheckListener = Components.interfaces.nsIAddonUpdateCheckListener;
switch (addon.id)
{
case "test_bug378216_5@tests.mozilla.org":
// Update has no signature
do_check_eq(status, nsIAddonUpdateCheckListener.STATUS_FAILURE);
break;
case "test_bug378216_7@tests.mozilla.org":
// Update has a signature that does not match
do_check_eq(status, nsIAddonUpdateCheckListener.STATUS_FAILURE);
break;
case "test_bug378216_8@tests.mozilla.org":
// Update has a signature but no secure update
do_check_eq(status, nsIAddonUpdateCheckListener.STATUS_NO_UPDATE);
break;
case "test_bug378216_9@tests.mozilla.org":
// Update has a signature and a hashed update
do_check_eq(status, nsIAddonUpdateCheckListener.STATUS_UPDATE);
do_check_eq(addon.version, "2.0");
break;
case "test_bug378216_10@tests.mozilla.org":
// Update has a signature and a https update
do_check_eq(status, nsIAddonUpdateCheckListener.STATUS_UPDATE);
do_check_eq(addon.version, "2.0");
break;
case "test_bug378216_11@tests.mozilla.org":
// Update has a signature and a hashed https update
do_check_eq(status, nsIAddonUpdateCheckListener.STATUS_UPDATE);
do_check_eq(addon.version, "2.0");
break;
case "test_bug378216_12@tests.mozilla.org":
// Update has a signature and an insecure hash against the update
do_check_eq(status, nsIAddonUpdateCheckListener.STATUS_NO_UPDATE);
break;
case "test_bug378216_13@tests.mozilla.org":
// The insecure hash doesn't matter if we have an https link
do_check_eq(status, nsIAddonUpdateCheckListener.STATUS_UPDATE);
do_check_eq(addon.version, "2.0");
break;
default:
do_throw("Update check for unknown "+addon.id);
}
}
}
function run_test()
{
// Setup for test
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1");
startupEM();
gEM.installItemFromFile(do_get_addon("test_bug378216_1"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_2"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_3"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_4"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_5"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_6"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_7"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_8"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_9"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_10"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_11"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_12"), NS_INSTALL_LOCATION_APPPROFILE);
gEM.installItemFromFile(do_get_addon("test_bug378216_13"), NS_INSTALL_LOCATION_APPPROFILE);
restartEM();
do_check_neq(gEM.getItemForID("test_bug378216_1@tests.mozilla.org"), null);
// Test 2 has an insecure updateURL and no updateKey so should fail to install
do_check_eq(gEM.getItemForID("test_bug378216_2@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_3@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_4@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_5@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_6@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_7@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_8@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_9@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_10@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_11@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_12@tests.mozilla.org"), null);
do_check_neq(gEM.getItemForID("test_bug378216_13@tests.mozilla.org"), null);
server = new nsHttpServer();
server.registerDirectory("/", do_get_file("toolkit/mozapps/extensions/test/unit/data"));
server.start(4444);
var updates = [
gEM.getItemForID("test_bug378216_5@tests.mozilla.org"),
gEM.getItemForID("test_bug378216_7@tests.mozilla.org"),
gEM.getItemForID("test_bug378216_8@tests.mozilla.org"),
gEM.getItemForID("test_bug378216_9@tests.mozilla.org"),
gEM.getItemForID("test_bug378216_10@tests.mozilla.org"),
gEM.getItemForID("test_bug378216_11@tests.mozilla.org"),
gEM.getItemForID("test_bug378216_12@tests.mozilla.org"),
gEM.getItemForID("test_bug378216_13@tests.mozilla.org"),
];
gEM.update(updates, updates.length,
Components.interfaces.nsIExtensionManager.UPDATE_CHECK_NEWVERSION,
updateListener);
do_test_pending();
}

Просмотреть файл

@ -80,7 +80,7 @@ function run_test()
var item = Cc["@mozilla.org/updates/item;1"].createInstance(Ci.nsIUpdateItem);
item.init("test@mozilla.org", "1.0", "app-profile", "0.0", "100.0", "Test extension",
null, null, "", null, item.TYPE_EXTENSION, "xpcshell@tests.mozilla.org");
null, null, "", null, null, item.TYPE_EXTENSION, "xpcshell@tests.mozilla.org");
gExpectedURL = gTestURL.replace(/%ITEM_ID%/, item.id)
.replace(/%CUSTOM1%/, "custom_parameter_1")

Просмотреть файл

@ -136,6 +136,7 @@ richlistitem .notifyBadge {
richlistitem[availableUpdateURL][updateable="true"] .updateBadge,
richlistitem[availableUpdateURL][updateable="true"] .updateAvailableBox,
richlistitem[compatible="false"] .notifyBadge,
richlistitem[providesUpdatesSecurely="false"] .notifyBadge,
richlistitem[blocklisted="true"] .notifyBadge,
richlistitem[satisfiesDependencies="false"] .notifyBadge {
display: -moz-box;
@ -205,6 +206,7 @@ richlistitem[type="4"] .disableHide {
/* Selected Add-on status messages and images */
richlistitem[compatible="true"] .incompatibleBox,
richlistitem[providesUpdatesSecurely="true"] .insecureUpdateBox,
richlistitem[satisfiesDependencies="true"] .needsDependenciesBox,
richlistitem[blocklisted="false"] .blocklistedBox,
richlistitem[opType="needs-uninstall"] .blocklistedBox,

Просмотреть файл

@ -205,6 +205,7 @@ richlistitem .notifyBadge {
richlistitem[availableUpdateURL][updateable="true"] .updateBadge,
richlistitem[availableUpdateURL][updateable="true"] .updateAvailableBox,
richlistitem[compatible="false"] .notifyBadge,
richlistitem[providesUpdatesSecurely="false"] .notifyBadge,
richlistitem[blocklisted="true"] .notifyBadge,
richlistitem[satisfiesDependencies="false"] .notifyBadge {
display: -moz-box;
@ -274,6 +275,7 @@ richlistitem[type="4"] .disableHide {
/* Selected Add-on status messages and images */
richlistitem[compatible="true"] .incompatibleBox,
richlistitem[providesUpdatesSecurely="true"] .insecureUpdateBox,
richlistitem[satisfiesDependencies="true"] .needsDependenciesBox,
richlistitem[blocklisted="false"] .blocklistedBox,
richlistitem[opType="needs-uninstall"] .blocklistedBox,