Commit a26ce122 authored by Michael Kaply's avatar Michael Kaply
Browse files

Bug 1659719 - Add support for arbitrary preferences in policy. r=Gijs,dveditz a=RyanVM

parent f18b7faf
Loading
Loading
Loading
Loading
+92 −1
Original line number Diff line number Diff line
@@ -1432,8 +1432,99 @@ var Policies = {

  Preferences: {
    onBeforeAddons(manager, param) {
      const allowedPrefixes = [
        "accessibility.",
        "browser.",
        "datareporting.policy.",
        "dom.",
        "extensions.",
        "geo.",
        "intl.",
        "layout.",
        "media.",
        "network.",
        "places.",
        "print.",
        "ui.",
        "widget.",
      ];
      const allowedSecurityPrefs = [
        "security.default_personal_cert",
        "security.insecure_connection_text.enabled",
        "security.insecure_connection_text.pbmode.enabled",
        "security.insecure_field_warning.contextual.enabled",
        "security.mixed_content.block_active_content",
        "security.osclientcerts.autoload",
        "security.ssl.errorReporting.enabled",
        "security.tls.hello_downgrade_check",
        "security.warn_submit_secure_to_insecure",
      ];
      const blockedPrefs = [];

      for (let preference in param) {
        if (blockedPrefs.includes(preference)) {
          log.error(
            `Unable to set preference ${preference}. Preference not allowed for security reasons.`
          );
          continue;
        }
        if (preference.startsWith("security.")) {
          if (!allowedSecurityPrefs.includes(preference)) {
            log.error(
              `Unable to set preference ${preference}. Preference not allowed for security reasons.`
            );
            continue;
          }
        } else if (
          !allowedPrefixes.some(prefix => preference.startsWith(prefix))
        ) {
          log.error(
            `Unable to set preference ${preference}. Preference not allowed for stability reasons.`
          );
          continue;
        }
        if (typeof param[preference] != "object") {
          // Legacy policy preferences
          setAndLockPref(preference, param[preference]);
        } else {
          if (param[preference].Status == "clear") {
            Services.prefs.clearUserPref(preference);
            continue;
          }

          if (param[preference].Status == "user") {
            var prefBranch = Services.prefs;
          } else {
            prefBranch = Services.prefs.getDefaultBranch("");
          }

          try {
            switch (typeof param[preference].Value) {
              case "boolean":
                prefBranch.setBoolPref(preference, param[preference].Value);
                break;

              case "number":
                if (!Number.isInteger(param[preference].Value)) {
                  throw new Error(`Non-integer value for ${preference}`);
                }
                prefBranch.setIntPref(preference, param[preference].Value);
                break;

              case "string":
                prefBranch.setStringPref(preference, param[preference].Value);
                break;
            }
          } catch (e) {
            log.error(
              `Unable to set preference ${preference}. Probable type mismatch.`
            );
          }

          if (param[preference].Status == "locked") {
            Services.prefs.lockPref(preference);
          }
        }
      }
    },
  },
+13 −147
Original line number Diff line number Diff line
@@ -903,153 +903,19 @@
    },

    "Preferences": {
      "type": "object",
      "type": ["JSON", "object"],
      "patternProperties": {
        "^.*$": {
          "type": ["number", "boolean", "string", "object"],
          "properties": {
        "accessibility.force_disabled": {
          "type": "number",
          "enum": [-1, 0, 1]
        },
        "browser.bookmarks.autoExportHTML": {
          "type": "boolean"
        },
        "browser.bookmarks.file": {
          "type": "string"
        },
        "browser.places.importBookmarksHTML": {
          "type": "boolean"
        },
        "browser.bookmarks.restore_default_bookmarks": {
          "type": "boolean"
        },
        "browser.cache.disk.enable": {
          "type": "boolean"
        },
        "browser.fixup.dns_first_for_single_words": {
          "type": "boolean"
        },
        "browser.urlbar.dnsResolveSingleWordsAfterSearch": {
          "type": "number",
          "enum": [0, 1, 2]
        },
        "browser.newtabpage.activity-stream.default.sites": {
          "type": "string"
        },
        "browser.safebrowsing.phishing.enabled": {
          "type": "boolean"
        },
        "browser.safebrowsing.malware.enabled": {
          "type": "boolean"
        },
        "browser.search.update": {
          "type": "boolean"
        },
        "browser.tabs.warnOnClose": {
          "type": "boolean"
        },
        "browser.cache.disk.parent_directory": {
          "type": "string"
        },
        "browser.slowStartup.notificationDisabled": {
          "type": "boolean"
        },
        "browser.taskbar.previews.enable": {
          "type": "boolean"
        },
        "browser.urlbar.suggest.bookmark": {
          "type": "boolean"
        },
        "browser.urlbar.suggest.openpage": {
          "type": "boolean"
        },
        "browser.urlbar.suggest.history": {
          "type": "boolean"
        },
        "datareporting.policy.dataSubmissionPolicyBypassNotification": {
          "type": "boolean"
        },
        "dom.allow_scripts_to_close_windows": {
          "type": "boolean"
        },
        "dom.disable_window_flip": {
          "type": "boolean"
        },
        "dom.disable_window_move_resize": {
          "type": "boolean"
        },
        "dom.event.contextmenu.enabled": {
          "type": "boolean"
        },
        "dom.keyboardevent.keypress.hack.dispatch_non_printable_keys.addl": {
          "type": "string"
        },
        "dom.keyboardevent.keypress.hack.use_legacy_keycode_and_charcode.addl": {
          "type": "string"
        },
        "extensions.blocklist.enabled": {
          "type": "boolean"
        },
        "extensions.getAddons.showPane": {
          "type": "boolean"
        },
        "extensions.htmlaboutaddons.recommendations.enabled": {
          "type": "boolean"
        },
        "geo.enabled": {
          "type": "boolean"
        },
        "intl.accept_languages": {
          "type": "string"
        },
        "media.eme.enabled": {
          "type": "boolean"
        },
        "media.gmp-gmpopenh264.enabled": {
          "type": "boolean"
        },
        "media.gmp-widevinecdm.enabled": {
          "type": "boolean"
        },
        "media.peerconnection.enabled": {
          "type": "boolean"
        },
        "media.peerconnection.ice.obfuscate_host_addresses.blocklist": {
          "type": "string"
        },
        "network.dns.disableIPv6": {
          "type": "boolean"
        },
        "network.IDN_show_punycode": {
          "type": "boolean"
        },
        "places.history.enabled": {
          "type": "boolean"
        },
        "print.save_print_settings": {
          "type": "boolean"
        },
        "privacy.file_unique_origin": {
          "type": "boolean"
        },
        "security.default_personal_cert": {
          "type": "string"
        },
        "security.mixed_content.block_active_content": {
          "type": "boolean"
        },
        "security.osclientcerts.autoload": {
          "type": "boolean"
        },
        "security.ssl.errorReporting.enabled": {
          "type": "boolean"
        },
        "security.tls.hello_downgrade_check": {
          "type": "boolean"
        },
        "ui.key.menuAccessKeyFocuses": {
          "type": "boolean"
            "Value": {
              "type": ["number", "boolean", "string"]
            },
        "widget.content.gtk-theme-override": {
          "type": "string"
            "Status": {
              "type": "string",
              "enum": ["default", "locked", "user", "clear"]
            }
          }
        }
      }
    },
+36 −0
Original line number Diff line number Diff line
@@ -100,3 +100,39 @@ function checkUnlockedPref(prefName, prefValue) {
    `Pref ${prefName} has the correct value`
  );
}

function checkUserPref(prefName, prefValue) {
  equal(
    Preferences.get(prefName),
    prefValue,
    `Pref ${prefName} has the correct value`
  );
}

function checkClearPref(prefName, prefValue) {
  equal(
    Services.prefs.prefHasUserValue(prefName),
    false,
    `Pref ${prefName} has no user value`
  );
}

function checkDefaultPref(prefName, prefValue) {
  let defaultPrefBranch = Services.prefs.getDefaultBranch("");
  let prefType = defaultPrefBranch.getPrefType(prefName);
  notEqual(
    prefType,
    Services.prefs.PREF_INVALID,
    `Pref ${prefName} is set on the default branch`
  );
}

function checkUnsetPref(prefName) {
  let defaultPrefBranch = Services.prefs.getDefaultBranch("");
  let prefType = defaultPrefBranch.getPrefType(prefName);
  equal(
    prefType,
    Services.prefs.PREF_INVALID,
    `Pref ${prefName} is not set on the default branch`
  );
}
+209 −13
Original line number Diff line number Diff line
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

/* This test is not intended to test all preferences that
   can be set with Preferences, just a subset to verify
   the overall functionality */

"use strict";

add_task(async function test_policy_preferences() {
  await setupPolicyEngineWithJson({
const OLD_PREFERENCES_TESTS = [
  {
    policies: {
      Preferences: {
        "network.IDN_show_punycode": true,
        "app.update.log": true,
        "accessibility.force_disabled": 1,
        "security.default_personal_cert": "Select Automatically",
      },
    },
    lockedPrefs: {
      "network.IDN_show_punycode": true,
      "accessibility.force_disabled": 1,
      "security.default_personal_cert": "Select Automatically",
    },
  },
];

const NEW_PREFERENCES_TESTS = [
  {
    policies: {
      Preferences: {
        "browser.policies.test.default.boolean": {
          Value: true,
          Status: "default",
        },
        "browser.policies.test.default.string": {
          Value: "string",
          Status: "default",
        },
        "browser.policies.test.default.number": {
          Value: 11,
          Status: "default",
        },
        "browser.policies.test.locked.boolean": {
          Value: true,
          Status: "locked",
        },
        "browser.policies.test.locked.string": {
          Value: "string",
          Status: "locked",
        },
        "browser.policies.test.locked.number": {
          Value: 11,
          Status: "locked",
        },
        "browser.policies.test.user.boolean": {
          Value: true,
          Status: "user",
        },
        "browser.policies.test.user.string": {
          Value: "string",
          Status: "user",
        },
        "browser.policies.test.user.number": {
          Value: 11,
          Status: "user",
        },
      },
    },
    defaultPrefs: {
      "browser.policies.test.default.boolean": true,
      "browser.policies.test.default.string": "string",
      "browser.policies.test.default.number": 11,
    },
    lockedPrefs: {
      "browser.policies.test.locked.boolean": true,
      "browser.policies.test.locked.string": "string",
      "browser.policies.test.locked.number": 11,
    },
    userPrefs: {
      "browser.policies.test.user.boolean": true,
      "browser.policies.test.user.string": "string",
      "browser.policies.test.user.number": 11,
    },
  },
  {
    policies: {
      Preferences: {
        "browser.policies.test.user.boolean": {
          Status: "clear",
        },
        "browser.policies.test.user.string": {
          Status: "clear",
        },
        "browser.policies.test.user.number": {
          Status: "clear",
        },
      },
    },

    clearPrefs: {
      "browser.policies.test.user.boolean": true,
      "browser.policies.test.user.string": "string",
      "browser.policies.test.user.number": 11,
    },
  },
];

const BAD_PREFERENCES_TESTS = [
  {
    policies: {
      Preferences: {
        "not.a.valid.branch": {
          Value: true,
          Status: "default",
        },
        "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer": {
          Value: true,
          Status: "default",
        },
      },
    },
    defaultPrefs: {
      "not.a.valid.branch": true,
      "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer": true,
    },
  },
];

add_task(async function test_old_preferences() {
  for (let test of OLD_PREFERENCES_TESTS) {
    await setupPolicyEngineWithJson({
      policies: test.policies,
    });

    info("Checking policy: " + Object.keys(test.policies)[0]);

    for (let [prefName, prefValue] of Object.entries(test.lockedPrefs || {})) {
      checkLockedPref(prefName, prefValue);
    }
  }
});

add_task(async function test_new_preferences() {
  for (let test of NEW_PREFERENCES_TESTS) {
    await setupPolicyEngineWithJson({
      policies: test.policies,
    });

    info("Checking policy: " + Object.keys(test.policies)[0]);

    for (let [prefName, prefValue] of Object.entries(test.lockedPrefs || {})) {
      checkLockedPref(prefName, prefValue);
    }

    for (let [prefName, prefValue] of Object.entries(test.defaultPrefs || {})) {
      checkDefaultPref(prefName, prefValue);
    }

    for (let [prefName, prefValue] of Object.entries(test.userPrefs || {})) {
      checkUserPref(prefName, prefValue);
    }

    for (let [prefName, prefValue] of Object.entries(test.clearPrefs || {})) {
      checkClearPref(prefName, prefValue);
    }
  }
});

add_task(async function test_bad_preferences() {
  for (let test of BAD_PREFERENCES_TESTS) {
    await setupPolicyEngineWithJson({
      policies: test.policies,
    });

    info("Checking policy: " + Object.keys(test.policies)[0]);

    for (let prefName of Object.entries(test.defaultPrefs || {})) {
      checkUnsetPref(prefName);
    }
  }
});

add_task(async function test_user_default_preference() {
  Services.prefs
    .getDefaultBranch("")
    .setBoolPref("browser.policies.test.override", true);

  await setupPolicyEngineWithJson({
    policies: {
      Preferences: {
        "browser.policies.test.override": {
          Value: true,
          Status: "user",
        },
      },
    },
  });

  checkUserPref("browser.policies.test.override", true);
});

add_task(async function test_security_preference() {
  await setupPolicyEngineWithJson({
    policies: {
      Preferences: {
        "security.this.should.not.work": {
          Value: true,
          Status: "default",
        },
      },
    },
  });

  checkUnsetPref("security.this.should.not.work");
});

add_task(async function test_JSON_preferences() {
  await setupPolicyEngineWithJson({
    policies: {
      Preferences:
        '"browser.policies.test.default.boolean": {"Value": true,"Status": "default"}}',
    },
  });

  checkLockedPref("network.IDN_show_punycode", true);
  equal(
    Services.prefs.getBoolPref("app.update.log"),
    false,
    "Disallowed pref was not been changed"
  );
  checkDefaultPref("browser.policies.test.default.boolean", true);
});