bug 1499846 - implement user reauthentication on MacOS r=franziskus,spohl
authorDavid Keeler <dkeeler@mozilla.com>
Thu, 25 Oct 2018 00:24:04 +0000
changeset 491239 ccfeb561645b499025c28c26287ee0b8d96cc7ad
parent 491238 74050b668ada1a9f3ddabfed1a98cc2b969f067f
child 491240 63d0906068ff45e427a5b09ebfc5d0c2f3b07ebe
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersfranziskus, spohl
bugs1499846
milestone65.0a1
bug 1499846 - implement user reauthentication on MacOS r=franziskus,spohl Differential Revision: https://phabricator.services.mozilla.com/D9025
security/manager/ssl/OSReauthenticator.cpp
security/manager/ssl/tests/unit/xpcshell.ini
--- a/security/manager/ssl/OSReauthenticator.cpp
+++ b/security/manager/ssl/OSReauthenticator.cpp
@@ -199,24 +199,77 @@ ReauthenticateUserWindows(const nsACStri
               ("Login successfully (correct user)."));
       reauthenticated = true;
       return NS_OK;
   }
   MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug,
           ("Login failed (wrong user)."));
   return NS_ERROR_FAILURE;
 }
-#endif
+#endif // XP_WIN
+
+#ifdef XP_MACOSX
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+
+static nsresult
+ReauthenticateUserMacOS(const nsACString& aPrompt,
+              /* out */ bool& aReauthenticated)
+{
+  // The idea here is that we ask to be authorized to unlock the user's session.
+  // This should cause a prompt to come up for the user asking them for their
+  // password. If they correctly enter it, we'll return a successful result. If
+  // they cancel the prompt or otherwise fail to provide their password, we
+  // return a failing result.
+  AuthorizationItem authorizationItems[] = {
+    { "system.login.screensaver", 0, NULL, 0 },
+  };
+  AuthorizationRights authorizationRights = {
+    ArrayLength(authorizationItems),
+    authorizationItems,
+  };
+  const nsCString& promptFlat = PromiseFlatCString(aPrompt);
+  // All "kAuthorization..." constants come from the MacOS SDK.
+  AuthorizationItem environmentItems[] =  {
+    { kAuthorizationEnvironmentPrompt,
+      promptFlat.Length(),
+      (void*)promptFlat.get(),
+      0
+    },
+  };
+  AuthorizationEnvironment environment = {
+    ArrayLength(environmentItems),
+    environmentItems,
+  };
+  AuthorizationFlags flags = kAuthorizationFlagDefaults |
+                             kAuthorizationFlagInteractionAllowed |
+                             kAuthorizationFlagExtendRights |
+                             kAuthorizationFlagPreAuthorize |
+                             kAuthorizationFlagDestroyRights;
+  AuthorizationRef authorizationRef = nullptr;
+  OSStatus result = AuthorizationCreate(&authorizationRights,
+                                        &environment,
+                                        flags,
+                                        &authorizationRef);
+  aReauthenticated = result == errAuthorizationSuccess;
+  if (authorizationRef) {
+    AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
+  }
+  return NS_OK;
+}
+#endif // XP_MACOSX
 
 static nsresult
 ReauthenticateUser(const nsACString& prompt, /* out */ bool& reauthenticated)
 {
   reauthenticated = false;
 #if defined(XP_WIN)
   return ReauthenticateUserWindows(prompt, reauthenticated);
+#elif defined(XP_MACOSX)
+  return ReauthenticateUserMacOS(prompt, reauthenticated);
 #endif // Reauthentication is not implemented for this platform.
   return NS_OK;
 }
 
 static void
 BackgroundReauthenticateUser(RefPtr<Promise>& aPromise,
                              const nsACString& aPrompt)
 {
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -137,19 +137,20 @@ run-sequentially = hardcoded ports
 [test_ocsp_stapling_with_intermediate.js]
 run-sequentially = hardcoded ports
 [test_ocsp_timeout.js]
 run-sequentially = hardcoded ports
 [test_ocsp_url.js]
 run-sequentially = hardcoded ports
 [test_oskeystore.js]
 [test_osreauthenticator.js]
-# Reauthentication has been implemented on Windows, so running this test results in
-# the OS popping up a dialog, which means we can't run it in automation.
-skip-if = os == 'win'
+# Reauthentication has been implemented on Windows and MacOS, so running this
+# test results in the OS popping up a dialog, which means we can't run it in
+# automation.
+skip-if = os == 'win' || os == 'mac'
 [test_password_prompt.js]
 [test_pinning.js]
 run-sequentially = hardcoded ports
 # This test can take longer than 300 seconds on B2G emulator debug builds, so
 # give it enough time to finish. See bug 1081128.
 requesttimeoutfactor = 2
 [test_pinning_dynamic.js]
 [test_pinning_header_parsing.js]