mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-10-15 17:24:27 +00:00
383 lines
11 KiB
JavaScript
383 lines
11 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",
|
|
signed: "signed_bootstrap_2.xpi",
|
|
preliminary: "preliminary_bootstrap_2.xpi",
|
|
},
|
|
nonbootstrap: {
|
|
unsigned: "unsigned_nonbootstrap_2.xpi",
|
|
badid: "signed_nonbootstrap_badid_2.xpi",
|
|
signed: "signed_nonbootstrap_2.xpi",
|
|
}
|
|
};
|
|
const ID = "test@tests.mozilla.org";
|
|
|
|
const profileDir = gProfD.clone();
|
|
profileDir.append("extensions");
|
|
|
|
// Deletes a file from the test add-on in the profile
|
|
function breakAddon(file) {
|
|
if (TEST_UNPACKED) {
|
|
file.append("test.txt");
|
|
file.remove(true);
|
|
}
|
|
else {
|
|
var zipW = AM_Cc["@mozilla.org/zipwriter;1"].
|
|
createInstance(AM_Ci.nsIZipWriter);
|
|
zipW.open(file, FileUtils.MODE_RDWR | FileUtils.MODE_APPEND);
|
|
zipW.removeEntry("test.txt", false);
|
|
zipW.close();
|
|
}
|
|
}
|
|
|
|
function resetPrefs() {
|
|
Services.prefs.setIntPref("bootstraptest.active_version", -1);
|
|
Services.prefs.setIntPref("bootstraptest.installed_version", -1);
|
|
Services.prefs.setIntPref("bootstraptest.startup_reason", -1);
|
|
Services.prefs.setIntPref("bootstraptest.shutdown_reason", -1);
|
|
Services.prefs.setIntPref("bootstraptest.install_reason", -1);
|
|
Services.prefs.setIntPref("bootstraptest.uninstall_reason", -1);
|
|
Services.prefs.setIntPref("bootstraptest.startup_oldversion", -1);
|
|
Services.prefs.setIntPref("bootstraptest.shutdown_newversion", -1);
|
|
Services.prefs.setIntPref("bootstraptest.install_oldversion", -1);
|
|
Services.prefs.setIntPref("bootstraptest.uninstall_newversion", -1);
|
|
}
|
|
|
|
function clearCache(file) {
|
|
if (TEST_UNPACKED)
|
|
return;
|
|
|
|
Services.obs.notifyObservers(file, "flush-cache-entry", null);
|
|
}
|
|
|
|
function getActiveVersion() {
|
|
return Services.prefs.getIntPref("bootstraptest.active_version");
|
|
}
|
|
|
|
function run_test() {
|
|
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "4", "4");
|
|
|
|
// Start and stop the manager to initialise everything in the profile before
|
|
// actual testing
|
|
startupManager();
|
|
shutdownManager();
|
|
resetPrefs();
|
|
|
|
run_next_test();
|
|
}
|
|
|
|
// Injecting into profile (bootstrap)
|
|
add_task(function*() {
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.unsigned), profileDir, ID);
|
|
|
|
startupManager();
|
|
|
|
// Currently we leave the sideloaded add-on there but just don't run it
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_true(addon.appDisabled);
|
|
do_check_false(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_MISSING);
|
|
do_check_eq(getActiveVersion(), -1);
|
|
|
|
addon.uninstall();
|
|
yield promiseShutdownManager();
|
|
resetPrefs();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|
|
|
|
add_task(function*() {
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.signed), profileDir, ID);
|
|
breakAddon(file);
|
|
|
|
startupManager();
|
|
|
|
// Currently we leave the sideloaded add-on there but just don't run it
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_true(addon.appDisabled);
|
|
do_check_false(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
|
|
do_check_eq(getActiveVersion(), -1);
|
|
|
|
addon.uninstall();
|
|
yield promiseShutdownManager();
|
|
resetPrefs();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|
|
|
|
add_task(function*() {
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.badid), profileDir, ID);
|
|
|
|
startupManager();
|
|
|
|
// Currently we leave the sideloaded add-on there but just don't run it
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_true(addon.appDisabled);
|
|
do_check_false(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
|
|
do_check_eq(getActiveVersion(), -1);
|
|
|
|
addon.uninstall();
|
|
yield promiseShutdownManager();
|
|
resetPrefs();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|
|
|
|
// Installs a signed add-on then modifies it in place breaking its signing
|
|
add_task(function*() {
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.signed), profileDir, ID);
|
|
|
|
// Make it appear to come from the past so when we modify it later it is
|
|
// detected during startup. Obviously malware can bypass this method of
|
|
// detection but the periodic scan will catch that
|
|
yield promiseSetExtensionModifiedTime(file.path, Date.now() - 600000);
|
|
|
|
startupManager();
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_false(addon.appDisabled);
|
|
do_check_true(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_SIGNED);
|
|
do_check_eq(getActiveVersion(), 2);
|
|
|
|
yield promiseShutdownManager();
|
|
do_check_eq(getActiveVersion(), 0);
|
|
|
|
clearCache(file);
|
|
breakAddon(file);
|
|
resetPrefs();
|
|
|
|
startupManager();
|
|
|
|
addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_true(addon.appDisabled);
|
|
do_check_false(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
|
|
do_check_eq(getActiveVersion(), -1);
|
|
|
|
let ids = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_DISABLED);
|
|
do_check_eq(ids.length, 1);
|
|
do_check_eq(ids[0], ID);
|
|
|
|
addon.uninstall();
|
|
yield promiseShutdownManager();
|
|
resetPrefs();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|
|
|
|
// Injecting into profile (non-bootstrap)
|
|
add_task(function*() {
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.nonbootstrap.unsigned), profileDir, ID);
|
|
|
|
startupManager();
|
|
|
|
// Currently we leave the sideloaded add-on there but just don't run it
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_true(addon.appDisabled);
|
|
do_check_false(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_MISSING);
|
|
do_check_false(isExtensionInAddonsList(profileDir, ID));
|
|
|
|
addon.uninstall();
|
|
yield promiseRestartManager();
|
|
yield promiseShutdownManager();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|
|
|
|
add_task(function*() {
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.nonbootstrap.signed), profileDir, ID);
|
|
breakAddon(file);
|
|
|
|
startupManager();
|
|
|
|
// Currently we leave the sideloaded add-on there but just don't run it
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_true(addon.appDisabled);
|
|
do_check_false(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
|
|
do_check_false(isExtensionInAddonsList(profileDir, ID));
|
|
|
|
addon.uninstall();
|
|
yield promiseRestartManager();
|
|
yield promiseShutdownManager();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|
|
|
|
add_task(function*() {
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.nonbootstrap.badid), profileDir, ID);
|
|
|
|
startupManager();
|
|
|
|
// Currently we leave the sideloaded add-on there but just don't run it
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_true(addon.appDisabled);
|
|
do_check_false(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
|
|
do_check_false(isExtensionInAddonsList(profileDir, ID));
|
|
|
|
addon.uninstall();
|
|
yield promiseRestartManager();
|
|
yield promiseShutdownManager();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|
|
|
|
// Installs a signed add-on then modifies it in place breaking its signing
|
|
add_task(function*() {
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.nonbootstrap.signed), profileDir, ID);
|
|
|
|
// Make it appear to come from the past so when we modify it later it is
|
|
// detected during startup. Obviously malware can bypass this method of
|
|
// detection but the periodic scan will catch that
|
|
yield promiseSetExtensionModifiedTime(file.path, Date.now() - 60000);
|
|
|
|
startupManager();
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_false(addon.appDisabled);
|
|
do_check_true(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_SIGNED);
|
|
do_check_true(isExtensionInAddonsList(profileDir, ID));
|
|
|
|
yield promiseShutdownManager();
|
|
|
|
clearCache(file);
|
|
breakAddon(file);
|
|
|
|
startupManager();
|
|
|
|
addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_true(addon.appDisabled);
|
|
do_check_false(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_BROKEN);
|
|
do_check_false(isExtensionInAddonsList(profileDir, ID));
|
|
|
|
let ids = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_DISABLED);
|
|
do_check_eq(ids.length, 1);
|
|
do_check_eq(ids[0], ID);
|
|
|
|
addon.uninstall();
|
|
yield promiseRestartManager();
|
|
yield promiseShutdownManager();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|
|
|
|
// Stage install then modify before startup (non-bootstrap)
|
|
add_task(function*() {
|
|
startupManager();
|
|
yield promiseInstallAllFiles([do_get_file(DATA + ADDONS.nonbootstrap.signed)]);
|
|
yield promiseShutdownManager();
|
|
|
|
let staged = profileDir.clone();
|
|
staged.append("staged");
|
|
staged.append(do_get_expected_addon_name(ID));
|
|
do_check_true(staged.exists());
|
|
|
|
breakAddon(staged);
|
|
startupManager();
|
|
|
|
// Should have refused to install the broken staged version
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_eq(addon, null);
|
|
|
|
clearCache(staged);
|
|
|
|
yield promiseShutdownManager();
|
|
});
|
|
|
|
// Manufacture staged install (bootstrap)
|
|
add_task(function*() {
|
|
let stage = profileDir.clone();
|
|
stage.append("staged");
|
|
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.signed), stage, ID);
|
|
breakAddon(file);
|
|
|
|
startupManager();
|
|
|
|
// Should have refused to install the broken staged version
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_eq(addon, null);
|
|
do_check_eq(getActiveVersion(), -1);
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
|
|
yield promiseShutdownManager();
|
|
resetPrefs();
|
|
});
|
|
|
|
// Preliminarily-signed sideloaded add-ons should work
|
|
add_task(function*() {
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.preliminary), profileDir, ID);
|
|
|
|
startupManager();
|
|
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_false(addon.appDisabled);
|
|
do_check_true(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_PRELIMINARY);
|
|
do_check_eq(getActiveVersion(), 2);
|
|
|
|
addon.uninstall();
|
|
yield promiseShutdownManager();
|
|
resetPrefs();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|
|
|
|
// Preliminarily-signed sideloaded add-ons should work via staged install
|
|
add_task(function*() {
|
|
let stage = profileDir.clone();
|
|
stage.append("staged");
|
|
|
|
let file = manuallyInstall(do_get_file(DATA + ADDONS.bootstrap.preliminary), stage, ID);
|
|
|
|
startupManager();
|
|
|
|
let addon = yield promiseAddonByID(ID);
|
|
do_check_neq(addon, null);
|
|
do_check_false(addon.appDisabled);
|
|
do_check_true(addon.isActive);
|
|
do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_PRELIMINARY);
|
|
do_check_eq(getActiveVersion(), 2);
|
|
|
|
addon.uninstall();
|
|
yield promiseShutdownManager();
|
|
resetPrefs();
|
|
|
|
do_check_false(file.exists());
|
|
clearCache(file);
|
|
});
|