Commit 6f6e95b2 authored by Yuki Hiroshi's avatar Yuki Hiroshi
Browse files

Bug 1440573 - Policy: Disable safe mode. r=jimm,felipe

This policy disables the safe-mode UI entry points. In addition, only on Windows when using GPO, it also disables entering Safe Mode by holding down the Shift Key
parent ed15f7d5
......@@ -832,6 +832,9 @@ function buildHelpMenu() {
document.getElementById("feedbackPage")
.disabled = !Services.policies.isAllowed("feedbackCommands");
document.getElementById("helpSafeMode")
.disabled = !Services.policies.isAllowed("safeMode");
// Enable/disable the "Report Web Forgery" menu item.
if (typeof gSafeBrowsing != "undefined") {
gSafeBrowsing.setReportPhishingMenu();
......
......@@ -215,6 +215,14 @@ var Policies = {
}
},
"DisableSafeMode": {
onBeforeUIStartup(manager, param) {
if (param) {
manager.disallowFeature("safeMode");
}
}
},
"DisableSysAddonUpdate": {
onBeforeAddons(manager, param) {
if (param) {
......
......@@ -170,6 +170,13 @@
"type": "boolean"
},
"DisableSafeMode": {
"description": "Prevents ability to restart in safe mode.",
"first_available": "60.0",
"type": "boolean"
},
"DisableSysAddonUpdate": {
"description": "Prevent the browser from installing and updating system addons.",
"first_available": "60.0",
......
......@@ -32,6 +32,7 @@ support-files =
[browser_policy_disable_pdfjs.js]
[browser_policy_disable_pocket.js]
[browser_policy_disable_privatebrowsing.js]
[browser_policy_disable_safemode.js]
[browser_policy_disable_shield.js]
[browser_policy_display_bookmarks.js]
[browser_policy_display_menu.js]
......
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
add_task(async function setup() {
await setupPolicyEngineWithJson({
"policies": {
"DisableSafeMode": true
}
});
});
add_task(async function test_help_menu() {
buildHelpMenu();
let safeModeMenu = document.getElementById("helpSafeMode");
is(safeModeMenu.getAttribute("disabled"), "true",
"The `Restart with Add-ons Disabled...` item should be disabled");
});
add_task(async function test_safemode_from_about_support() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:support");
await ContentTask.spawn(tab.linkedBrowser, null, async function() {
let button = content.document.getElementById("restart-in-safe-mode-button");
is(button.getAttribute("disabled"), "true",
"The `Restart with Add-ons Disabled...` button should be disabled");
});
await BrowserTestUtils.removeTab(tab);
});
add_task(async function test_safemode_from_about_profiles() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:profiles");
await ContentTask.spawn(tab.linkedBrowser, null, async function() {
let button = content.document.getElementById("restart-in-safe-mode-button");
is(button.getAttribute("disabled"), "true",
"The `Restart with Add-ons Disabled...` button should be disabled");
});
await BrowserTestUtils.removeTab(tab);
});
......@@ -5,6 +5,14 @@
from __future__ import absolute_import
import copy
import platform
try:
import winreg
except ImportError:
try:
import _winreg as winreg
except ImportError:
pass
from marionette_harness import MarionetteTestCase
......@@ -34,9 +42,36 @@ class TestCommandLineArguments(MarionetteTestCase):
return Services.appinfo.inSafeMode;
""")
self.assertTrue(safe_mode, "Safe Mode has not been enabled")
def test_safe_mode_blocked_by_policy(self):
if platform.system() != 'Windows':
return
reg_policies = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, "SOFTWARE\\Policies", 0, winreg.KEY_WRITE)
reg_mozilla = winreg.CreateKeyEx(reg_policies, "Mozilla", 0, winreg.KEY_WRITE)
reg_firefox = winreg.CreateKeyEx(reg_mozilla, "Firefox", 0, winreg.KEY_WRITE)
winreg.SetValueEx(reg_firefox, "DisableSafeMode", 0, winreg.REG_DWORD, 1)
self.marionette.instance.app_args.append("-safe-mode")
self.marionette.quit()
self.marionette.start_session()
with self.marionette.using_context("chrome"):
safe_mode = self.marionette.execute_script("""
Cu.import("resource://gre/modules/Services.jsm");
return Services.appinfo.inSafeMode;
""")
self.assertFalse(safe_mode, "Safe Mode has been enabled")
winreg.CloseKey(reg_firefox)
winreg.DeleteKey(reg_mozilla, "Firefox")
winreg.CloseKey(reg_mozilla)
winreg.DeleteKey(reg_policies, "Mozilla")
winreg.CloseKey(reg_policies)
def test_startup_timeout(self):
startup_timeout = self.marionette.startup_timeout
......
......@@ -85,7 +85,11 @@ function refreshUI() {
createButton.onclick = createProfileWizard;
let restartSafeModeButton = document.getElementById("restart-in-safe-mode-button");
restartSafeModeButton.onclick = function() { restart(true); };
if (!Services.policies || Services.policies.isAllowed("safeMode")) {
restartSafeModeButton.onclick = function() { restart(true); };
} else {
restartSafeModeButton.setAttribute("disabled", "true");
}
let restartNormalModeButton = document.getElementById("restart-button");
restartNormalModeButton.onclick = function() { restart(false); };
......
......@@ -1206,6 +1206,10 @@ function populateActionBox() {
if (!Services.appinfo.inSafeMode && AppConstants.platform !== "android") {
$("safe-mode-box").style.display = "block";
$("action-box").style.display = "block";
if (Services.policies && !Services.policies.isAllowed("safeMode")) {
$("restart-in-safe-mode-button").setAttribute("disabled", "true");
}
}
}
......
......@@ -3154,6 +3154,40 @@ public:
#endif
};
#ifdef XP_WIN
namespace {
bool PolicyHasRegValue(HKEY aKey, LPCTSTR aName, DWORD* aValue)
{
HKEY hkey = NULL;
LONG ret = RegOpenKeyExW(aKey,
L"SOFTWARE\\Policies\\Mozilla\\Firefox", 0, KEY_READ, &hkey);
if (ret != ERROR_SUCCESS) {
return false;
}
nsAutoRegKey key(hkey);
DWORD len = sizeof(aValue);
ret = RegQueryValueExW(hkey, aName, 0, NULL, (LPBYTE)aValue, &len);
RegCloseKey(key);
return ret == ERROR_SUCCESS;
}
bool SafeModeBlockedByPolicy()
{
LPCTSTR policyName = L"DisableSafeMode";
DWORD value;
if (PolicyHasRegValue(HKEY_LOCAL_MACHINE, policyName, &value)) {
return value == 1;
}
if (PolicyHasRegValue(HKEY_CURRENT_USER, policyName, &value)) {
return value == 1;
}
return false;
}
} // anonymous namespace
#endif // XP_WIN
/*
* XRE_mainInit - Initial setup and command line parameter processing.
* Main() will exit early if either return value != 0 or if aExitFlag is
......@@ -3490,12 +3524,6 @@ XREMain::XRE_mainInit(bool* aExitFlag)
gRestartArgv[gRestartArgc] = nullptr;
if (EnvHasValue("MOZ_SAFE_MODE_RESTART")) {
gSafeMode = true;
// unset the env variable
SaveToEnv("MOZ_SAFE_MODE_RESTART=");
}
ar = CheckArg("safe-mode", true);
if (ar == ARG_BAD) {
PR_fprintf(PR_STDERR, "Error: argument --safe-mode is invalid when argument --osint is specified\n");
......@@ -3525,6 +3553,20 @@ XREMain::XRE_mainInit(bool* aExitFlag)
gSafeMode = true;
#endif
#ifdef XP_WIN
if (gSafeMode && SafeModeBlockedByPolicy()) {
gSafeMode = false;
}
#endif
// The Safe Mode Policy should not be enforced for the env var case
// (used by updater and crash-recovery).
if (EnvHasValue("MOZ_SAFE_MODE_RESTART")) {
gSafeMode = true;
// unset the env variable
SaveToEnv("MOZ_SAFE_MODE_RESTART=");
}
#ifdef XP_WIN
{
// Add CPU microcode version to the crash report as "CPUMicrocodeVersion".
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment