Bug 1270832 - Activate standard c++ library hardening r=glandium
[gecko.git] / security / manager / ssl / OSReauthenticatorDarwin.mm
blob82f57c285a6a483f92404a93696d418425c1b3fd
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "OSReauthenticator.h"
9 #include "mozilla/MacStringHelpers.h"
11 using namespace mozilla;
13 #include <CoreFoundation/CoreFoundation.h>
14 #include <LocalAuthentication/LocalAuthentication.h>
16 static const int32_t kPasswordNotSetErrorCode = -1000;
18 nsresult ReauthenticateUserMacOS(const nsAString& aPrompt,
19                                  /* out */ bool& aReauthenticated,
20                                  /* out */ bool& aIsBlankPassword) {
21   // The idea here is that we ask to be authorized to unlock the user's session.
22   // This should cause a prompt to come up for the user asking them for their
23   // password. If they correctly enter it, we'll set aReauthenticated to true.
25   LAContext* context = [[LAContext alloc] init];
26   NSString* prompt = mozilla::XPCOMStringToNSString(aPrompt);
28   dispatch_semaphore_t sema = dispatch_semaphore_create(0);
30   __block BOOL biometricSuccess = NO;     // mark variable r/w across the block
31   __block BOOL errorPasswordNotSet = NO;  // mark variable r/w across the block
33   // Note: This is an async callback in an already-async Promise chain.
34   [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication
35           localizedReason:prompt
36                     reply:^(BOOL success, NSError* error) {
37                       dispatch_async(dispatch_get_main_queue(), ^{
38                         // error is not particularly useful in this context, and
39                         // we have no mechanism to really return it. We could
40                         // use it to set the nsresult, but this is a best-effort
41                         // mechanism and there's no particular case for
42                         // propagating up XPCOM. The one exception being a user
43                         // account that has no passcode set, which we handle
44                         // below.
45                         errorPasswordNotSet =
46                             error && [error code] == kPasswordNotSetErrorCode;
47                         biometricSuccess = success || errorPasswordNotSet;
48                         dispatch_semaphore_signal(sema);
49                       });
50                     }];
52   // What we want to do here is convert this into a blocking call, since
53   // our calling methods expect us to block and set aReauthenticated on return.
54   dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
55   dispatch_release(sema);
56   sema = NULL;
58   aReauthenticated = biometricSuccess;
59   aIsBlankPassword = errorPasswordNotSet;
61   [context release];
62   return NS_OK;