summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js')
-rw-r--r--toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js265
1 files changed, 265 insertions, 0 deletions
diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js b/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js
new file mode 100644
index 000000000..19b07ac16
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js
@@ -0,0 +1,265 @@
+// Enable signature checks for these tests
+gUseRealCertChecks = 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);
+});