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 <Security/SecureObjectSync/SOSCloudCircle.h>
17 #import "utilities/SecCFRelease.h"
18 #import "utilities/debugging.h"
21 @implementation SOSCCAuthPlugin
23 - (void) didReceiveAuthenticationResponseParameters: (NSDictionary *) parameters
24 accountStore: (ACDAccountStore *) store
25 account: (ACAccount *) account
26 completion: (dispatch_block_t) completion
29 NSString* accountIdentifier = account.identifier; // strong reference
30 secinfo("accounts", "parameters %@", parameters);
31 secinfo("accounts", "account %@", account);
33 if ([account.accountType.identifier isEqualToString:ACAccountTypeIdentifierIdentityServices]) {
34 ACAccount *icloud = [store aa_primaryAppleAccount];
35 NSString *dsid = [parameters[@"com.apple.private.ids"][@"service-data"][@"profile-id"] substringFromIndex:2]; // remove "D:" prefix
36 secinfo("accounts", "IDS account: iCloud %@ (personID %@)", icloud, icloud.aa_personID);
37 do_auth = icloud && icloud.aa_personID && [icloud.aa_personID isEqualToString:dsid];
38 } else if ([account.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) {
39 secinfo("accounts", "AppleID account: primary %@", @([account aa_isPrimaryAccount]));
40 do_auth = [account aa_isPrimaryAccount];
43 ACLogNotice(@"do_auth %@", do_auth ? @"YES" : @"NO" );
46 CFErrorRef authError = NULL;
47 NSString *rawPassword = [account _aa_rawPassword];
49 if (rawPassword != NULL) {
50 const char *password = [rawPassword cStringUsingEncoding:NSUTF8StringEncoding];
51 CFDataRef passwordData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *) password, strlen(password));
53 secinfo("accounts", "Performing SOS circle credential set for account %@: %@", accountIdentifier, account.username);
54 NSString *dsid = [account aa_personID];
55 if (!SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef) account.username, passwordData, (__bridge CFStringRef) dsid, &authError)) {
56 secerror("Unable to set SOS circle credentials for account %@: %@", accountIdentifier, authError);
57 CFReleaseNull(authError);
60 CFRelease(passwordData);
63 if (!SOSCCCanAuthenticate(&authError)) {
64 secerror("Account %@ did not present a password and we could not authenticate the SOS circle: %@", accountIdentifier, authError);
65 CFReleaseNull(authError); // CFReleaseSafe?
69 secinfo("accounts", "NOT performing SOS circle credential set for account %@: %@", accountIdentifier, account.username);