]> git.saurik.com Git - apple/security.git/blame - SOSCCAuthPlugin/SOSCCAuthPlugin.m
Security-59754.80.3.tar.gz
[apple/security.git] / SOSCCAuthPlugin / SOSCCAuthPlugin.m
CommitLineData
5c19dc3a
A
1//
2// SOSCCAuthPlugin.m
3// Security
4//
5// Created by Christian Schmidt on 7/8/15.
6// Copyright 2015 Apple, Inc. All rights reserved.
7//
8
b54c578e 9#import "SOSCCAuthPlugin.h"
5c19dc3a
A
10#import <Foundation/Foundation.h>
11#import <Accounts/Accounts.h>
12#import <Accounts/Accounts_Private.h>
5c19dc3a
A
13#import <AccountsDaemon/ACDAccountStore.h>
14#import <AppleAccount/ACAccount+AppleAccount.h>
15#import <AppleAccount/ACAccountStore+AppleAccount.h>
ecaf5866
A
16#import <AuthKit/AuthKit.h>
17#import <AuthKit/AuthKit_Private.h>
b54c578e 18#import <SoftLinking/SoftLinking.h>
6b200bc3
A
19#import <Security/SecureObjectSync/SOSCloudCircle.h>
20#import "utilities/SecCFRelease.h"
21#import "utilities/debugging.h"
5c19dc3a
A
22
23
ecaf5866
A
24#if !TARGET_OS_SIMULATOR
25SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit);
79b9da22
A
26
27#pragma clang diagnostic push
28#pragma clang diagnostic ignored "-Wstrict-prototypes"
ecaf5866 29SOFT_LINK_CLASS(AuthKit, AKAccountManager);
79b9da22 30#pragma clang diagnostic pop
ecaf5866
A
31#endif
32
5c19dc3a
A
33@implementation SOSCCAuthPlugin
34
79b9da22
A
35static bool accountIsHSA2(ACAccount *account) {
36 bool hsa2 = false;
37
38#if !TARGET_OS_SIMULATOR
39 AKAccountManager *manager = [getAKAccountManagerClass() sharedInstance];
40 if(manager != nil) {
79b9da22 41 ACAccount *aka = [manager authKitAccountWithAltDSID:account.aa_altDSID];
79b9da22
A
42 if (aka) {
43 AKAppleIDSecurityLevel securityLevel = [manager securityLevelForAccount: aka];
44 if(securityLevel == AKAppleIDSecurityLevelHSA2) {
45 hsa2 = true;
46 }
47 }
48 }
49#endif
50 secnotice("accounts", "Account %s HSA2", (hsa2) ? "is": "isn't" );
51 return hsa2;
52}
53
5c19dc3a
A
54- (void) didReceiveAuthenticationResponseParameters: (NSDictionary *) parameters
55 accountStore: (ACDAccountStore *) store
56 account: (ACAccount *) account
57 completion: (dispatch_block_t) completion
58{
59 BOOL do_auth = NO;
866f8763 60 NSString* accountIdentifier = account.identifier; // strong reference
6b200bc3
A
61 secinfo("accounts", "parameters %@", parameters);
62 secinfo("accounts", "account %@", account);
5c19dc3a
A
63
64 if ([account.accountType.identifier isEqualToString:ACAccountTypeIdentifierIdentityServices]) {
65 ACAccount *icloud = [store aa_primaryAppleAccount];
66 NSString *dsid = [parameters[@"com.apple.private.ids"][@"service-data"][@"profile-id"] substringFromIndex:2]; // remove "D:" prefix
6b200bc3 67 secinfo("accounts", "IDS account: iCloud %@ (personID %@)", icloud, icloud.aa_personID);
5c19dc3a
A
68 do_auth = icloud && icloud.aa_personID && [icloud.aa_personID isEqualToString:dsid];
69 } else if ([account.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) {
b54c578e
A
70 do_auth = [account aa_isAccountClass:AAAccountClassPrimary];
71 secinfo("accounts", "AppleID account: primary %@", @(do_auth));
5c19dc3a
A
72 }
73
79b9da22 74 if(do_auth && !accountIsHSA2(account)) {
5c19dc3a
A
75 NSString *rawPassword = [account _aa_rawPassword];
76
77 if (rawPassword != NULL) {
79b9da22
A
78 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
79 CFErrorRef asyncError = NULL;
80 NSString *dsid = [account aa_personID];
81 const char *password = [rawPassword cStringUsingEncoding:NSUTF8StringEncoding];
82 CFDataRef passwordData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *) password, strlen(password));
5c19dc3a 83
79b9da22
A
84 if (passwordData) {
85 secinfo("accounts", "Performing async SOS circle credential set for account %@: %@", accountIdentifier, account.username);
86
87 if (!SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef) account.username, passwordData, (__bridge CFStringRef) dsid, &asyncError)) {
88 secerror("Unable to set SOS circle credentials for account %@: %@", accountIdentifier, asyncError);
89 secinfo("accounts", "Returning from failed async call to SOSCCSetUserCredentialsAndDSID");
90 CFReleaseNull(asyncError);
91 } else {
92 secinfo("accounts", "Returning from successful async call to SOSCCSetUserCredentialsAndDSID");
93 }
94 CFRelease(passwordData);
95 } else {
96 secinfo("accounts", "Failed to create string for call to SOSCCSetUserCredentialsAndDSID");
97 }
98 });
5c19dc3a 99 } else {
79b9da22 100 CFErrorRef authError = NULL;
5c19dc3a 101 if (!SOSCCCanAuthenticate(&authError)) {
866f8763 102 secerror("Account %@ did not present a password and we could not authenticate the SOS circle: %@", accountIdentifier, authError);
79b9da22 103 CFReleaseNull(authError);
5c19dc3a
A
104 }
105 }
106 } else {
866f8763 107 secinfo("accounts", "NOT performing SOS circle credential set for account %@: %@", accountIdentifier, account.username);
5c19dc3a
A
108 }
109
110 completion();
111}
112
113@end