5 // Created by Christian Schmidt on 7/8/15.
6 // Copyright 2015 Apple, Inc. All rights reserved.
9 #import <SOSCCAuthPlugin.h>
10 #import <Foundation/Foundation.h>
11 #import <Accounts/Accounts.h>
12 #import <Accounts/Accounts_Private.h>
13 #import <AccountsDaemon/ACDAccountStore.h>
14 #import <AppleAccount/ACAccount+AppleAccount.h>
15 #import <AppleAccount/ACAccountStore+AppleAccount.h>
16 #import <AuthKit/AuthKit.h>
17 #import <AuthKit/AuthKit_Private.h>
18 #import <Security/SecureObjectSync/SOSCloudCircle.h>
19 #import "utilities/SecCFRelease.h"
20 #import "utilities/debugging.h"
23 #if !TARGET_OS_SIMULATOR
24 SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit);
25 SOFT_LINK_CLASS(AuthKit, AKAccountManager);
28 @implementation SOSCCAuthPlugin
30 - (void) didReceiveAuthenticationResponseParameters: (NSDictionary *) parameters
31 accountStore: (ACDAccountStore *) store
32 account: (ACAccount *) account
33 completion: (dispatch_block_t) completion
36 NSString* accountIdentifier = account.identifier; // strong reference
37 secinfo("accounts", "parameters %@", parameters);
38 secinfo("accounts", "account %@", account);
40 if ([account.accountType.identifier isEqualToString:ACAccountTypeIdentifierIdentityServices]) {
41 ACAccount *icloud = [store aa_primaryAppleAccount];
42 NSString *dsid = [parameters[@"com.apple.private.ids"][@"service-data"][@"profile-id"] substringFromIndex:2]; // remove "D:" prefix
43 secinfo("accounts", "IDS account: iCloud %@ (personID %@)", icloud, icloud.aa_personID);
44 do_auth = icloud && icloud.aa_personID && [icloud.aa_personID isEqualToString:dsid];
45 } else if ([account.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) {
46 secinfo("accounts", "AppleID account: primary %@", @([account aa_isPrimaryAccount]));
47 do_auth = [account aa_isPrimaryAccount];
50 #if !TARGET_OS_SIMULATOR
51 // If this is an HSA2 account let cdpd SetCreds
52 AKAccountManager *manager = [getAKAccountManagerClass() sharedInstance];
54 AKAppleIDSecurityLevel securityLevel = [manager securityLevelForAccount: account];
55 if(securityLevel == AKAppleIDSecurityLevelHSA2) {
56 secnotice("accounts", "Not performing SOSCCSetUserCredentialsAndDSID in accountsd plugin since we're HSA2" );
60 secnotice("accounts", "Couldn't softlink AKAccountManager - proceeding with do_auth = %@", do_auth ? @"YES" : @"NO");
64 secnotice("accounts", "do_auth %@", do_auth ? @"YES" : @"NO" );
67 CFErrorRef authError = NULL;
68 NSString *rawPassword = [account _aa_rawPassword];
70 if (rawPassword != NULL) {
71 const char *password = [rawPassword cStringUsingEncoding:NSUTF8StringEncoding];
72 CFDataRef passwordData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *) password, strlen(password));
74 secinfo("accounts", "Performing SOS circle credential set for account %@: %@", accountIdentifier, account.username);
75 NSString *dsid = [account aa_personID];
76 if (!SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef) account.username, passwordData, (__bridge CFStringRef) dsid, &authError)) {
77 secerror("Unable to set SOS circle credentials for account %@: %@", accountIdentifier, authError);
78 CFReleaseNull(authError);
81 CFRelease(passwordData);
84 if (!SOSCCCanAuthenticate(&authError)) {
85 secerror("Account %@ did not present a password and we could not authenticate the SOS circle: %@", accountIdentifier, authError);
86 CFReleaseNull(authError); // CFReleaseSafe?
90 secinfo("accounts", "NOT performing SOS circle credential set for account %@: %@", accountIdentifier, account.username);