tenfourfox/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js
Cameron Kaiser c9b2922b70 hello FPR
2017-04-19 00:56:45 -07:00

266 lines
8.5 KiB
JavaScript

// Enable signature checks for these tests
Services.prefs.setBoolPref(PREF_XPI_SIGNATURES_REQUIRED, true);
// Disable update security
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
const DATA = "data/signing_checks/";
const ADDONS = {
bootstrap: {
unsigned: "unsigned_bootstrap_2.xpi",
badid: "signed_bootstrap_badid_2.xpi",
preliminary: "preliminary_bootstrap_2.xpi",
signed: "signed_bootstrap_2.xpi",
},
};
const WORKING = "signed_bootstrap_1.xpi";
const ID = "test@tests.mozilla.org";
var gServer = createHttpServer(4444);
// Creates an add-on with a broken signature by changing an existing file
function createBrokenAddonModify(file) {
let brokenFile = gTmpD.clone();
brokenFile.append("broken.xpi");
file.copyTo(brokenFile.parent, brokenFile.leafName);
var stream = AM_Cc["@mozilla.org/io/string-input-stream;1"].
createInstance(AM_Ci.nsIStringInputStream);
stream.setData("FOOBAR", -1);
var zipW = AM_Cc["@mozilla.org/zipwriter;1"].
createInstance(AM_Ci.nsIZipWriter);
zipW.open(brokenFile, FileUtils.MODE_RDWR | FileUtils.MODE_APPEND);
zipW.removeEntry("test.txt", false);
zipW.addEntryStream("test.txt", 0, AM_Ci.nsIZipWriter.COMPRESSION_NONE,
stream, false);
zipW.close();
return brokenFile;
}
// Creates an add-on with a broken signature by adding a new file
function createBrokenAddonAdd(file) {
let brokenFile = gTmpD.clone();
brokenFile.append("broken.xpi");
file.copyTo(brokenFile.parent, brokenFile.leafName);
var stream = AM_Cc["@mozilla.org/io/string-input-stream;1"].
createInstance(AM_Ci.nsIStringInputStream);
stream.setData("FOOBAR", -1);
var zipW = AM_Cc["@mozilla.org/zipwriter;1"].
createInstance(AM_Ci.nsIZipWriter);
zipW.open(brokenFile, FileUtils.MODE_RDWR | FileUtils.MODE_APPEND);
zipW.addEntryStream("test2.txt", 0, AM_Ci.nsIZipWriter.COMPRESSION_NONE,
stream, false);
zipW.close();
return brokenFile;
}
// Creates an add-on with a broken signature by removing an existing file
function createBrokenAddonRemove(file) {
let brokenFile = gTmpD.clone();
brokenFile.append("broken.xpi");
file.copyTo(brokenFile.parent, brokenFile.leafName);
var stream = AM_Cc["@mozilla.org/io/string-input-stream;1"].
createInstance(AM_Ci.nsIStringInputStream);
stream.setData("FOOBAR", -1);
var zipW = AM_Cc["@mozilla.org/zipwriter;1"].
createInstance(AM_Ci.nsIZipWriter);
zipW.open(brokenFile, FileUtils.MODE_RDWR | FileUtils.MODE_APPEND);
zipW.removeEntry("test.txt", false);
zipW.close();
return brokenFile;
}
function createInstall(url) {
return new Promise(resolve => {
AddonManager.getInstallForURL(url, resolve, "application/x-xpinstall");
});
}
function serveUpdateRDF(leafName) {
gServer.registerPathHandler("/update.rdf", function(request, response) {
let updateData = {};
updateData[ID] = [{
version: "2.0",
targetApplications: [{
id: "xpcshell@tests.mozilla.org",
minVersion: "4",
maxVersion: "6",
updateLink: "http://localhost:4444/" + leafName
}]
}];
response.setStatusLine(request.httpVersion, 200, "OK");
response.write(createUpdateRDF(updateData));
});
}
function* test_install_broken(file, expectedError) {
gServer.registerFile("/" + file.leafName, file);
let install = yield createInstall("http://localhost:4444/" + file.leafName);
yield promiseCompleteAllInstalls([install]);
do_check_eq(install.state, AddonManager.STATE_DOWNLOAD_FAILED);
do_check_eq(install.error, expectedError);
do_check_eq(install.addon, null);
gServer.registerFile("/" + file.leafName, null);
}
function* test_install_working(file, expectedSignedState) {
gServer.registerFile("/" + file.leafName, file);
let install = yield createInstall("http://localhost:4444/" + file.leafName);
yield promiseCompleteAllInstalls([install]);
do_check_eq(install.state, AddonManager.STATE_INSTALLED);
do_check_neq(install.addon, null);
do_check_eq(install.addon.signedState, expectedSignedState);
gServer.registerFile("/" + file.leafName, null);
install.addon.uninstall();
}
function* test_update_broken(file, expectedError) {
// First install the older version
yield promiseInstallAllFiles([do_get_file(DATA + WORKING)]);
gServer.registerFile("/" + file.leafName, file);
serveUpdateRDF(file.leafName);
let addon = yield promiseAddonByID(ID);
let update = yield promiseFindAddonUpdates(addon);
let install = update.updateAvailable;
yield promiseCompleteAllInstalls([install]);
do_check_eq(install.state, AddonManager.STATE_DOWNLOAD_FAILED);
do_check_eq(install.error, expectedError);
do_check_eq(install.addon, null);
gServer.registerFile("/" + file.leafName, null);
gServer.registerPathHandler("/update.rdf", null);
addon.uninstall();
}
function* test_update_working(file, expectedSignedState) {
// First install the older version
yield promiseInstallAllFiles([do_get_file(DATA + WORKING)]);
gServer.registerFile("/" + file.leafName, file);
serveUpdateRDF(file.leafName);
let addon = yield promiseAddonByID(ID);
let update = yield promiseFindAddonUpdates(addon);
let install = update.updateAvailable;
yield promiseCompleteAllInstalls([install]);
do_check_eq(install.state, AddonManager.STATE_INSTALLED);
do_check_neq(install.addon, null);
do_check_eq(install.addon.signedState, expectedSignedState);
gServer.registerFile("/" + file.leafName, null);
gServer.registerPathHandler("/update.rdf", null);
install.addon.uninstall();
}
function run_test() {
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "4", "4");
startupManager();
run_next_test();
}
// Try to install a broken add-on
add_task(function*() {
let file = createBrokenAddonModify(do_get_file(DATA + ADDONS.bootstrap.signed));
yield test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE);
file.remove(true);
});
add_task(function*() {
let file = createBrokenAddonAdd(do_get_file(DATA + ADDONS.bootstrap.signed));
yield test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE);
file.remove(true);
});
add_task(function*() {
let file = createBrokenAddonRemove(do_get_file(DATA + ADDONS.bootstrap.signed));
yield test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE);
file.remove(true);
});
// Try to install an add-on with an incorrect ID
add_task(function*() {
let file = do_get_file(DATA + ADDONS.bootstrap.badid);
yield test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE);
});
// Try to install an unsigned add-on
add_task(function*() {
let file = do_get_file(DATA + ADDONS.bootstrap.unsigned);
yield test_install_broken(file, AddonManager.ERROR_SIGNEDSTATE_REQUIRED);
});
// Try to install a preliminarily reviewed add-on
add_task(function*() {
let file = do_get_file(DATA + ADDONS.bootstrap.preliminary);
yield test_install_working(file, AddonManager.SIGNEDSTATE_PRELIMINARY);
});
// Try to install a signed add-on
add_task(function*() {
let file = do_get_file(DATA + ADDONS.bootstrap.signed);
yield test_install_working(file, AddonManager.SIGNEDSTATE_SIGNED);
});
// Try to update to a broken add-on
add_task(function*() {
let file = createBrokenAddonModify(do_get_file(DATA + ADDONS.bootstrap.signed));
yield test_update_broken(file, AddonManager.ERROR_CORRUPT_FILE);
file.remove(true);
});
add_task(function*() {
let file = createBrokenAddonAdd(do_get_file(DATA + ADDONS.bootstrap.signed));
yield test_update_broken(file, AddonManager.ERROR_CORRUPT_FILE);
file.remove(true);
});
add_task(function*() {
let file = createBrokenAddonRemove(do_get_file(DATA + ADDONS.bootstrap.signed));
yield test_update_broken(file, AddonManager.ERROR_CORRUPT_FILE);
file.remove(true);
});
// Try to update to an add-on with an incorrect ID
add_task(function*() {
let file = do_get_file(DATA + ADDONS.bootstrap.badid);
yield test_update_broken(file, AddonManager.ERROR_CORRUPT_FILE);
});
// Try to update to an unsigned add-on
add_task(function*() {
let file = do_get_file(DATA + ADDONS.bootstrap.unsigned);
yield test_update_broken(file, AddonManager.ERROR_SIGNEDSTATE_REQUIRED);
});
// Try to update to a preliminarily reviewed add-on
add_task(function*() {
let file = do_get_file(DATA + ADDONS.bootstrap.preliminary);
yield test_update_working(file, AddonManager.SIGNEDSTATE_PRELIMINARY);
});
// Try to update to a signed add-on
add_task(function*() {
let file = do_get_file(DATA + ADDONS.bootstrap.signed);
yield test_update_working(file, AddonManager.SIGNEDSTATE_SIGNED);
});