Bug 1403081 - Optionally protect filling of saved logins with OS authentication (including biometrics). r=sgalich,settings-reviewers,fluent-reviewers,flod
Depends on D207219 Differential Revision: https://phabricator.services.mozilla.com/D201276
This commit is contained in:
@@ -17,7 +17,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
|||||||
LoginExport: "resource://gre/modules/LoginExport.sys.mjs",
|
LoginExport: "resource://gre/modules/LoginExport.sys.mjs",
|
||||||
LoginHelper: "resource://gre/modules/LoginHelper.sys.mjs",
|
LoginHelper: "resource://gre/modules/LoginHelper.sys.mjs",
|
||||||
MigrationUtils: "resource:///modules/MigrationUtils.sys.mjs",
|
MigrationUtils: "resource:///modules/MigrationUtils.sys.mjs",
|
||||||
OSKeyStore: "resource://gre/modules/OSKeyStore.sys.mjs",
|
|
||||||
UIState: "resource://services-sync/UIState.sys.mjs",
|
UIState: "resource://services-sync/UIState.sys.mjs",
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -36,12 +35,6 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||||||
"identity.fxaccounts.enabled",
|
"identity.fxaccounts.enabled",
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
XPCOMUtils.defineLazyPreferenceGetter(
|
|
||||||
lazy,
|
|
||||||
"OS_AUTH_ENABLED",
|
|
||||||
"signon.management.page.os-auth.enabled",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
XPCOMUtils.defineLazyPreferenceGetter(
|
XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
lazy,
|
lazy,
|
||||||
"VULNERABLE_PASSWORDS_ENABLED",
|
"VULNERABLE_PASSWORDS_ENABLED",
|
||||||
@@ -266,11 +259,15 @@ export class AboutLoginsParent extends JSWindowActorParent {
|
|||||||
let messageText = { value: "NOT SUPPORTED" };
|
let messageText = { value: "NOT SUPPORTED" };
|
||||||
let captionText = { value: "" };
|
let captionText = { value: "" };
|
||||||
|
|
||||||
|
const isOSAuthEnabled = lazy.LoginHelper.getOSAuthEnabled(
|
||||||
|
lazy.LoginHelper.OS_AUTH_FOR_PASSWORDS_PREF
|
||||||
|
);
|
||||||
|
|
||||||
// This feature is only supported on Windows and macOS
|
// This feature is only supported on Windows and macOS
|
||||||
// but we still call in to OSKeyStore on Linux to get
|
// but we still call in to OSKeyStore on Linux to get
|
||||||
// the proper auth_details for Telemetry.
|
// the proper auth_details for Telemetry.
|
||||||
// See bug 1614874 for Linux support.
|
// See bug 1614874 for Linux support.
|
||||||
if (lazy.OS_AUTH_ENABLED && lazy.OSKeyStore.canReauth()) {
|
if (isOSAuthEnabled) {
|
||||||
messageId += "-" + AppConstants.platform;
|
messageId += "-" + AppConstants.platform;
|
||||||
[messageText, captionText] = await lazy.AboutLoginsL10n.formatMessages([
|
[messageText, captionText] = await lazy.AboutLoginsL10n.formatMessages([
|
||||||
{
|
{
|
||||||
@@ -284,7 +281,7 @@ export class AboutLoginsParent extends JSWindowActorParent {
|
|||||||
|
|
||||||
let { isAuthorized, telemetryEvent } = await lazy.LoginHelper.requestReauth(
|
let { isAuthorized, telemetryEvent } = await lazy.LoginHelper.requestReauth(
|
||||||
this.browsingContext.embedderElement,
|
this.browsingContext.embedderElement,
|
||||||
lazy.OS_AUTH_ENABLED,
|
isOSAuthEnabled,
|
||||||
AboutLogins._authExpirationTime,
|
AboutLogins._authExpirationTime,
|
||||||
messageText.value,
|
messageText.value,
|
||||||
captionText.value
|
captionText.value
|
||||||
@@ -378,11 +375,15 @@ export class AboutLoginsParent extends JSWindowActorParent {
|
|||||||
let messageText = { value: "NOT SUPPORTED" };
|
let messageText = { value: "NOT SUPPORTED" };
|
||||||
let captionText = { value: "" };
|
let captionText = { value: "" };
|
||||||
|
|
||||||
|
const isOSAuthEnabled = lazy.LoginHelper.getOSAuthEnabled(
|
||||||
|
lazy.LoginHelper.OS_AUTH_FOR_PASSWORDS_PREF
|
||||||
|
);
|
||||||
|
|
||||||
// This feature is only supported on Windows and macOS
|
// This feature is only supported on Windows and macOS
|
||||||
// but we still call in to OSKeyStore on Linux to get
|
// but we still call in to OSKeyStore on Linux to get
|
||||||
// the proper auth_details for Telemetry.
|
// the proper auth_details for Telemetry.
|
||||||
// See bug 1614874 for Linux support.
|
// See bug 1614874 for Linux support.
|
||||||
if (lazy.OSKeyStore.canReauth()) {
|
if (isOSAuthEnabled) {
|
||||||
const messageId =
|
const messageId =
|
||||||
EXPORT_PASSWORD_OS_AUTH_DIALOG_MESSAGE_IDS[AppConstants.platform];
|
EXPORT_PASSWORD_OS_AUTH_DIALOG_MESSAGE_IDS[AppConstants.platform];
|
||||||
if (!messageId) {
|
if (!messageId) {
|
||||||
|
|||||||
@@ -551,6 +551,12 @@
|
|||||||
/>
|
/>
|
||||||
</hbox>
|
</hbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
<vbox>
|
||||||
|
<hbox id="osReauthRow" align="center">
|
||||||
|
<checkbox id="osReauthCheckbox"
|
||||||
|
data-l10n-id="forms-os-reauth"/>
|
||||||
|
</hbox>
|
||||||
|
</vbox>
|
||||||
<vbox>
|
<vbox>
|
||||||
<hbox id="masterPasswordRow" align="center">
|
<hbox id="masterPasswordRow" align="center">
|
||||||
<checkbox id="useMasterPassword"
|
<checkbox id="useMasterPassword"
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ ChromeUtils.defineLazyGetter(this, "AlertsServiceDND", function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ChromeUtils.defineLazyGetter(lazy, "AboutLoginsL10n", () => {
|
||||||
|
return new Localization(["branding/brand.ftl", "browser/aboutLogins.ftl"]);
|
||||||
|
});
|
||||||
|
|
||||||
XPCOMUtils.defineLazyServiceGetter(
|
XPCOMUtils.defineLazyServiceGetter(
|
||||||
lazy,
|
lazy,
|
||||||
"gParentalControlsService",
|
"gParentalControlsService",
|
||||||
@@ -67,13 +71,6 @@ XPCOMUtils.defineLazyServiceGetter(
|
|||||||
"nsIParentalControlsService"
|
"nsIParentalControlsService"
|
||||||
);
|
);
|
||||||
|
|
||||||
XPCOMUtils.defineLazyPreferenceGetter(
|
|
||||||
this,
|
|
||||||
"OS_AUTH_ENABLED",
|
|
||||||
"signon.management.page.os-auth.enabled",
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyPreferenceGetter(
|
XPCOMUtils.defineLazyPreferenceGetter(
|
||||||
this,
|
this,
|
||||||
"gIsFirstPartyIsolated",
|
"gIsFirstPartyIsolated",
|
||||||
@@ -1053,6 +1050,7 @@ var gPrivacyPane = {
|
|||||||
this._initPasswordGenerationUI();
|
this._initPasswordGenerationUI();
|
||||||
this._initRelayIntegrationUI();
|
this._initRelayIntegrationUI();
|
||||||
this._initMasterPasswordUI();
|
this._initMasterPasswordUI();
|
||||||
|
this._initOSAuthentication();
|
||||||
|
|
||||||
this.initListenersForExtensionControllingPasswordManager();
|
this.initListenersForExtensionControllingPasswordManager();
|
||||||
|
|
||||||
@@ -2863,8 +2861,7 @@ var gPrivacyPane = {
|
|||||||
// OS reauthenticate functionality is not available on Linux yet (bug 1527745)
|
// OS reauthenticate functionality is not available on Linux yet (bug 1527745)
|
||||||
if (
|
if (
|
||||||
!LoginHelper.isPrimaryPasswordSet() &&
|
!LoginHelper.isPrimaryPasswordSet() &&
|
||||||
OS_AUTH_ENABLED &&
|
LoginHelper.getOSAuthEnabled(LoginHelper.OS_AUTH_FOR_PASSWORDS_PREF)
|
||||||
OSKeyStore.canReauth()
|
|
||||||
) {
|
) {
|
||||||
// Uses primary-password-os-auth-dialog-message-win and
|
// Uses primary-password-os-auth-dialog-message-win and
|
||||||
// primary-password-os-auth-dialog-message-macosx via concatenation:
|
// primary-password-os-auth-dialog-message-macosx via concatenation:
|
||||||
@@ -2961,6 +2958,54 @@ var gPrivacyPane = {
|
|||||||
this._updateRelayIntegrationUI();
|
this._updateRelayIntegrationUI();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async _toggleOSAuth() {
|
||||||
|
let osReauthCheckbox = document.getElementById("osReauthCheckbox");
|
||||||
|
|
||||||
|
const messageText = await lazy.AboutLoginsL10n.formatValue(
|
||||||
|
"about-logins-os-auth-dialog-message"
|
||||||
|
);
|
||||||
|
const captionText = await lazy.AboutLoginsL10n.formatValue(
|
||||||
|
"about-logins-os-auth-dialog-caption"
|
||||||
|
);
|
||||||
|
let win =
|
||||||
|
osReauthCheckbox.ownerGlobal.docShell.chromeEventHandler.ownerGlobal;
|
||||||
|
|
||||||
|
// Calling OSKeyStore.ensureLoggedIn() instead of LoginHelper.verifyOSAuth()
|
||||||
|
// since we want to authenticate user each time this stting is changed.
|
||||||
|
let isAuthorized = (
|
||||||
|
await OSKeyStore.ensureLoggedIn(messageText, captionText, win, false)
|
||||||
|
).authenticated;
|
||||||
|
if (!isAuthorized) {
|
||||||
|
osReauthCheckbox.checked = !osReauthCheckbox.checked;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If osReauthCheckbox is checked enable osauth.
|
||||||
|
LoginHelper.setOSAuthEnabled(
|
||||||
|
LoginHelper.OS_AUTH_FOR_PASSWORDS_PREF,
|
||||||
|
osReauthCheckbox.checked
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_initOSAuthentication() {
|
||||||
|
let osReauthCheckbox = document.getElementById("osReauthCheckbox");
|
||||||
|
if (!OSKeyStore.canReauth()) {
|
||||||
|
osReauthCheckbox.hidden = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
osReauthCheckbox.setAttribute(
|
||||||
|
"checked",
|
||||||
|
LoginHelper.getOSAuthEnabled(LoginHelper.OS_AUTH_FOR_PASSWORDS_PREF)
|
||||||
|
);
|
||||||
|
|
||||||
|
setEventListener(
|
||||||
|
"osReauthCheckbox",
|
||||||
|
"command",
|
||||||
|
gPrivacyPane._toggleOSAuth.bind(gPrivacyPane)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the sites where the user has saved passwords and the associated login
|
* Shows the sites where the user has saved passwords and the associated login
|
||||||
* information.
|
* information.
|
||||||
|
|||||||
@@ -134,12 +134,20 @@ login-item-timeline-action-used = Used
|
|||||||
|
|
||||||
## OS Authentication dialog
|
## OS Authentication dialog
|
||||||
|
|
||||||
about-logins-os-auth-dialog-caption = { -brand-full-name }
|
|
||||||
|
|
||||||
## The macOS strings are preceded by the operating system with "Firefox is trying to "
|
## The macOS strings are preceded by the operating system with "Firefox is trying to "
|
||||||
## and includes subtitle of "Enter password for the user "xxx" to allow this." These
|
## and includes subtitle of "Enter password for the user "xxx" to allow this." These
|
||||||
## notes are only valid for English. Please test in your respected locale.
|
## notes are only valid for English. Please test in your respected locale.
|
||||||
|
|
||||||
|
# The macOS strings are preceded by the operating system with "Firefox is trying to ".
|
||||||
|
# This message can be seen when attempting to disable osauth in about:preferences.
|
||||||
|
about-logins-os-auth-dialog-message=
|
||||||
|
{ PLATFORM() ->
|
||||||
|
[macos] change the settings for passwords
|
||||||
|
*[other] { -brand-short-name } is trying to change the settings for passwords. Use your device sign in to allow this.
|
||||||
|
}
|
||||||
|
|
||||||
|
about-logins-os-auth-dialog-caption = { -brand-full-name }
|
||||||
|
|
||||||
# This message can be seen when attempting to edit a login in about:logins on Windows.
|
# This message can be seen when attempting to edit a login in about:logins on Windows.
|
||||||
about-logins-edit-login-os-auth-dialog-message2-win = To edit your password, enter your Windows login credentials. This helps protect the security of your accounts.
|
about-logins-edit-login-os-auth-dialog-message2-win = To edit your password, enter your Windows login credentials. This helps protect the security of your accounts.
|
||||||
# This message can be seen when attempting to edit a login in about:logins
|
# This message can be seen when attempting to edit a login in about:logins
|
||||||
|
|||||||
@@ -1036,6 +1036,9 @@ forms-saved-passwords =
|
|||||||
forms-primary-pw-use =
|
forms-primary-pw-use =
|
||||||
.label = Use a Primary Password
|
.label = Use a Primary Password
|
||||||
.accesskey = U
|
.accesskey = U
|
||||||
|
# This operation requires the user to authenticate with the operating system (device sign-in)
|
||||||
|
forms-os-reauth =
|
||||||
|
.label = Require device sign in to fill and manage passwords
|
||||||
forms-primary-pw-learn-more-link = Learn more
|
forms-primary-pw-learn-more-link = Learn more
|
||||||
# This string uses the former name of the Primary Password feature
|
# This string uses the former name of the Primary Password feature
|
||||||
# ("Master Password" in English) so that the preferences can be found
|
# ("Master Password" in English) so that the preferences can be found
|
||||||
|
|||||||
@@ -373,7 +373,7 @@ class ImportRowProcessor {
|
|||||||
return this.summary;
|
return this.summary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const OS_AUTH_FOR_PASSWORDS_PREF = "signon.management.page.os-auth.optout";
|
||||||
/**
|
/**
|
||||||
* Contains functions shared by different Login Manager components.
|
* Contains functions shared by different Login Manager components.
|
||||||
*/
|
*/
|
||||||
@@ -401,6 +401,7 @@ export const LoginHelper = {
|
|||||||
testOnlyUserHasInteractedWithDocument: null,
|
testOnlyUserHasInteractedWithDocument: null,
|
||||||
userInputRequiredToCapture: null,
|
userInputRequiredToCapture: null,
|
||||||
captureInputChanges: null,
|
captureInputChanges: null,
|
||||||
|
OS_AUTH_FOR_PASSWORDS_PREF,
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// Watch for pref changes to update cached pref values.
|
// Watch for pref changes to update cached pref values.
|
||||||
@@ -1728,18 +1729,21 @@ export const LoginHelper = {
|
|||||||
}
|
}
|
||||||
// Use the OS auth dialog if there is no primary password
|
// Use the OS auth dialog if there is no primary password
|
||||||
if (!token.hasPassword && OSReauthEnabled) {
|
if (!token.hasPassword && OSReauthEnabled) {
|
||||||
let result = await lazy.OSKeyStore.ensureLoggedIn(
|
let isAuthorized = await this.verifyUserOSAuth(
|
||||||
|
OS_AUTH_FOR_PASSWORDS_PREF,
|
||||||
messageText,
|
messageText,
|
||||||
captionText,
|
captionText,
|
||||||
browser.ownerGlobal,
|
browser.ownerGlobal,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
isAuthorized = result.authenticated;
|
let value = lazy.OSKeyStore.canReauth()
|
||||||
|
? "success"
|
||||||
|
: "success_unsupported_platform";
|
||||||
|
|
||||||
telemetryEvent = {
|
telemetryEvent = {
|
||||||
object: "os_auth",
|
object: "os_auth",
|
||||||
method: "reauthenticate",
|
method: "reauthenticate",
|
||||||
value: result.auth_details,
|
value: isAuthorized ? value : "fail",
|
||||||
extra: result.auth_details_extra,
|
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
isAuthorized,
|
isAuthorized,
|
||||||
|
|||||||
Reference in New Issue
Block a user