Commit 1d732139 authored by Jared Wein's avatar Jared Wein
Browse files

Bug 1636729 - Record in telemetry if the user has enabled the AutoAdminLogon feature. r=MattN

parent d9d492ed
Loading
Loading
Loading
Loading
+48 −8
Original line number Diff line number Diff line
@@ -38,11 +38,13 @@ using mozilla::dom::Promise;
#  include <ntsecapi.h>
#  include <wincred.h>
#  include <windows.h>
#  include "nsIWindowsRegKey.h"  // Must be included after <windows.h> for HKEY definition
#  define SECURITY_WIN32
#  include <security.h>
#  include <shlwapi.h>
#  if !defined(__MINGW32__)
#    include <Lm.h>
#    undef ACCESS_READ  // nsWindowsRegKey defines its own ACCESS_READ
#  endif                // !defined(__MINGW32__)
struct HandleCloser {
  typedef HANDLE pointer;
@@ -126,6 +128,34 @@ Maybe<int64_t> GetPasswordLastChanged(const WCHAR* username) {
#  endif
}

bool IsAutoAdminLogonEnabled() {
  // https://support.microsoft.com/en-us/help/324737/how-to-turn-on-automatic-logon-in-windows
  nsresult rv;
  nsCOMPtr<nsIWindowsRegKey> regKey =
      do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
  if (NS_FAILED(rv)) {
    return false;
  }

  rv = regKey->Open(
      nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
      NS_LITERAL_STRING(
          "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"),
      nsIWindowsRegKey::ACCESS_READ);
  if (NS_FAILED(rv)) {
    return false;
  }

  nsAutoString value;
  rv = regKey->ReadStringValue(NS_LITERAL_STRING("AutoAdminLogon"), value);
  if (NS_FAILED(rv)) {
    return false;
  }
  regKey->Close();

  return value.Equals(NS_LITERAL_STRING("1"));
}

// Use the Windows credential prompt to ask the user to authenticate the
// currently used account.
static nsresult ReauthenticateUserWindows(
@@ -133,8 +163,10 @@ static nsresult ReauthenticateUserWindows(
    const WindowsHandle& hwndParent,
    /* out */ bool& reauthenticated,
    /* inout */ bool& isBlankPassword,
    /* inout */ int64_t& prefLastChanged) {
    /* inout */ int64_t& prefLastChanged,
    /* out */ bool& isAutoAdminLogonEnabled) {
  reauthenticated = false;
  isAutoAdminLogonEnabled = false;

  // Check if the user has a blank password before proceeding
  DWORD usernameLength = CREDUI_MAX_USERNAME_LENGTH + 1;
@@ -196,6 +228,8 @@ static nsresult ReauthenticateUserWindows(
    isBlankPassword = false;
  }

  isAutoAdminLogonEnabled = IsAutoAdminLogonEnabled();

  // Is used in next iteration if the previous login failed.
  DWORD err = 0;
  std::unique_ptr<char[]> userTokenInfo = GetUserTokenInfo();
@@ -319,11 +353,13 @@ static nsresult ReauthenticateUser(const nsAString& prompt,
                                   const WindowsHandle& hwndParent,
                                   /* out */ bool& reauthenticated,
                                   /* inout */ bool& isBlankPassword,
                                   /* inout */ int64_t& prefLastChanged) {
                                   /* inout */ int64_t& prefLastChanged,
                                   /* out */ bool& isAutoAdminLogonEnabled) {
  reauthenticated = false;
#if defined(XP_WIN)
  return ReauthenticateUserWindows(prompt, caption, hwndParent, reauthenticated,
                                   isBlankPassword, prefLastChanged);
                                   isBlankPassword, prefLastChanged,
                                   isAutoAdminLogonEnabled);
#elif defined(XP_MACOSX)
  return ReauthenticateUserMacOS(prompt, reauthenticated, isBlankPassword);
#endif  // Reauthentication is not implemented for this platform.
@@ -338,9 +374,10 @@ static void BackgroundReauthenticateUser(RefPtr<Promise>& aPromise,
                                         int64_t prefLastChanged) {
  nsAutoCString recovery;
  bool reauthenticated;
  nsresult rv =
      ReauthenticateUser(aMessageText, aCaptionText, hwndParent,
                         reauthenticated, isBlankPassword, prefLastChanged);
  bool isAutoAdminLogonEnabled;
  nsresult rv = ReauthenticateUser(aMessageText, aCaptionText, hwndParent,
                                   reauthenticated, isBlankPassword,
                                   prefLastChanged, isAutoAdminLogonEnabled);

  nsTArray<int32_t> prefLastChangedUpdates;
#if defined(XP_WIN)
@@ -354,9 +391,12 @@ static void BackgroundReauthenticateUser(RefPtr<Promise>& aPromise,
  prefLastChangedUpdates.AppendElement(prefLastChangedLo);
#endif

  nsTArray<int32_t> results(2);
  nsTArray<int32_t> results;
  results.AppendElement(reauthenticated);
  results.AppendElement(isBlankPassword);
#if defined(XP_WIN)
  results.AppendElement(isAutoAdminLogonEnabled);
#endif
  nsCOMPtr<nsIRunnable> runnable(NS_NewRunnableFunction(
      "BackgroundReauthenticateUserResolve",
      [rv, results = std::move(results),
+2 −0
Original line number Diff line number Diff line
@@ -642,6 +642,7 @@ pwmgr:
        "success_disabled" is used when the feature is disabled.
        "success_unsupported_platform" should be set when the user attempts to authenticate on an unsupported platform.
        "success_no_password" should be used when the user doesn't have an OS password set.
        "success_auto_admin_logon" should be used when the user has enabled the "AutoAdminLogon" registry key
        "fail" should be used when the user cancels the authentication prompt or an unexpected exception is encountered. The user may or may not have provided an incorrect password before cancelling.
    objects: [
      "master_password",
@@ -651,6 +652,7 @@ pwmgr:
    bug_numbers:
      - 1628029
      - 1623745
      - 1636729
    expiry_version: never
    notification_emails: ["loines@mozilla.com", "passwords-dev@mozilla.org", "jaws@mozilla.com"]
    release_channel_collection: opt-out
+6 −1
Original line number Diff line number Diff line
@@ -216,9 +216,14 @@ var OSKeyStore = {
              authenticated: true,
              auth_details: "success",
            };
            if (reauthResult.length == 2 && reauthResult[1]) {
            if (reauthResult.length > 1 && reauthResult[1]) {
              result.auth_details += "_no_password";
            }
            if (reauthResult.length > 3) {
              if (reauthResult[2]) {
                result.auth_details += "_auto_admin_logon";
              }
            }
            return result;
          });
      } else {