Bug 1284407 Generate addon id from the path for temporarily loaded xpis r=rhelmer

MozReview-Commit-ID: 4XChacM8xE0

--HG--
extra : rebase_source : 2549fd7bc0597db1e292e772eefd42dd7f6507f4
This commit is contained in:
Andrew Swan 2016-09-12 16:13:42 -07:00
parent 4c8aff6678
commit 897c54369e
2 changed files with 33 additions and 27 deletions

View File

@ -1300,6 +1300,21 @@ function defineSyncGUID(aAddon) {
});
}
// Generate a unique ID based on the path to this temporary add-on location.
function generateTemporaryInstallID(aFile) {
const hasher = Cc["@mozilla.org/security/hash;1"]
.createInstance(Ci.nsICryptoHash);
hasher.init(hasher.SHA1);
const data = new TextEncoder().encode(aFile.path);
// Make it so this ID cannot be guessed.
const sess = TEMP_INSTALL_ID_GEN_SESSION;
hasher.update(sess, sess.length);
hasher.update(data, data.length);
let id = `${getHashStringForCrypto(hasher)}@temporary-addon`;
logger.info(`Generated temp id ${id} (${sess.join("")}) for ${aFile.path}`);
return id;
}
/**
* Loads an AddonInternal object from an add-on extracted in a directory.
*
@ -1375,19 +1390,7 @@ var loadManifestFromDir = Task.async(function*(aDir, aInstallLocation) {
addon = yield loadManifestFromWebManifest(uri);
if (!addon.id) {
if (aInstallLocation == TemporaryInstallLocation) {
// Generate a unique ID based on the directory path of
// this temporary add-on location.
const hasher = Cc["@mozilla.org/security/hash;1"]
.createInstance(Ci.nsICryptoHash);
hasher.init(hasher.SHA1);
const data = new TextEncoder().encode(aDir.path);
// Make it so this ID cannot be guessed.
const sess = TEMP_INSTALL_ID_GEN_SESSION;
hasher.update(sess, sess.length);
hasher.update(data, data.length);
addon.id = `${getHashStringForCrypto(hasher)}@temporary-addon`;
logger.info(
`Generated temp id ${addon.id} (${sess.join("")}) for ${aDir.path}`);
addon.id = generateTemporaryInstallID(aDir);
} else {
addon.id = aDir.leafName;
}
@ -1475,10 +1478,15 @@ var loadManifestFromZipReader = Task.async(function*(aZipReader, aInstallLocatio
let {signedState, cert} = yield verifyZipSignedState(aZipReader.file, addon);
addon.signedState = signedState;
if (isWebExtension && !addon.id && cert) {
addon.id = cert.commonName;
if (!gIDTest.test(addon.id)) {
throw new Error(`Webextension is signed with an invalid id (${addon.id})`);
if (isWebExtension && !addon.id) {
if (cert) {
addon.id = cert.commonName;
if (!gIDTest.test(addon.id)) {
throw new Error(`Webextension is signed with an invalid id (${addon.id})`);
}
}
if (!addon.id && aInstallLocation == TemporaryInstallLocation) {
addon.id = generateTemporaryInstallID(aZipReader.file);
}
}
addon.appDisabled = !isUsableAddon(addon);
@ -4819,8 +4827,7 @@ this.XPIProvider = {
*/
callBootstrapMethod: function(aAddon, aFile, aMethod, aReason, aExtraParams) {
if (!aAddon.id || !aAddon.version || !aAddon.type) {
logger.error(new Error("aAddon must include an id, version, and type"));
return;
throw new Error("aAddon must include an id, version, and type");
}
// Only run in safe mode if allowed to

View File

@ -69,10 +69,7 @@ add_task(function* test_implicit_id_temp() {
// We should be able to temporarily install an unsigned web extension
// that does not have an ID in its manifest.
add_task(function* test_unsigned_no_id_temp_install() {
if (!TEST_UNPACKED) {
do_print("This test does not apply when using packed extensions");
return;
}
AddonTestUtils.useRealCertChecks = true;
const manifest = {
name: "no ID",
description: "extension without an ID",
@ -97,16 +94,15 @@ add_task(function* test_unsigned_no_id_temp_install() {
equal(secondAddon.id, addon.id, "Reinstalled add-on has the expected ID");
secondAddon.uninstall();
Services.obs.notifyObservers(addonDir, "flush-cache-entry", null);
addonDir.remove(true);
AddonTestUtils.useRealCertChecks = false;
});
// We should be able to install two extensions from manifests without IDs
// at different locations and get two unique extensions.
add_task(function* test_multiple_no_id_extensions() {
if (!TEST_UNPACKED) {
do_print("This test does not apply when using packed extensions");
return;
}
AddonTestUtils.useRealCertChecks = true;
const manifest = {
name: "no ID",
description: "extension without an ID",
@ -132,9 +128,12 @@ add_task(function* test_multiple_no_id_extensions() {
equal(filtered.length, 2, "Two add-ons are installed with the same name");
firstAddon.uninstall();
Services.obs.notifyObservers(firstAddonDir, "flush-cache-entry", null);
firstAddonDir.remove(true);
secondAddon.uninstall();
Services.obs.notifyObservers(secondAddonDir, "flush-cache-entry", null);
secondAddonDir.remove(true);
AddonTestUtils.useRealCertChecks = false;
});
// Test that we can get the ID from browser_specific_settings