]>
Commit | Line | Data |
---|---|---|
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 |
25 | SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit); | |
79b9da22 A |
26 | |
27 | #pragma clang diagnostic push | |
28 | #pragma clang diagnostic ignored "-Wstrict-prototypes" | |
ecaf5866 | 29 | SOFT_LINK_CLASS(AuthKit, AKAccountManager); |
79b9da22 | 30 | #pragma clang diagnostic pop |
ecaf5866 A |
31 | #endif |
32 | ||
5c19dc3a A |
33 | @implementation SOSCCAuthPlugin |
34 | ||
79b9da22 A |
35 | static 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 |