2 // KeychainSyncAccountNotification.m
6 #import "KeychainSyncAccountNotification.h"
7 #import <Accounts/Accounts.h>
8 #import <Accounts/Accounts_Private.h>
10 #import <AppleAccount/ACAccount+AppleAccount.h>
12 #import <AOSAccounts/ACAccount+iCloudAccount.h>
14 #import <AccountsDaemon/ACDAccountStore.h>
15 #import <Security/SecureObjectSync/SOSCloudCircle.h>
17 #import <keychain/ot/OTControl.h>
18 #include <utilities/SecCFRelease.h>
20 #import "utilities/debugging.h"
23 @implementation KeychainSyncAccountNotification
25 - (bool)accountIsPrimary:(ACAccount *)account
28 return [account aa_isPrimaryAccount];
30 return [account icaIsPrimaryAccount];
34 // this is where we initialize SOS and OT for account sign-in
35 // the complement to this logic where we turn off SOS and OT is in KeychainDataclassOwner
36 // in the future we may bring this logic over there and delete KeychainSyncAccountNotification, but accounts people say that's a change that today would require coordination across multiple teams
37 // was asked to file this radar for accounts: <rdar://problem/40176124> Invoke DataclassOwner when enabling or signing into an account
38 - (BOOL)account:(ACAccount *)account willChangeWithType:(ACAccountChangeType)changeType inStore:(ACDAccountStore *)store oldAccount:(ACAccount *)oldAccount {
40 if((changeType == kACAccountChangeTypeAdded) &&
41 [account.accountType.identifier isEqualToString: ACAccountTypeIdentifierAppleAccount] &&
42 [self accountIsPrimary:account]) {
45 __block NSError* error = nil;
46 NSString *dsid = account.accountProperties[@"personID"];
47 OTControl* otcontrol = [OTControl controlObject:&error];
49 if (nil == otcontrol) {
50 secerror("octagon: Failed to get OTControl: %@", error.localizedDescription);
52 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
54 [otcontrol signIn:dsid reply:^(BOOL result, NSError * _Nullable signedInError) {
55 if(!result || signedInError){
56 secerror("octagon: error signing in: %s", [[signedInError description] UTF8String]);
59 secnotice("octagon", "signed into octagon trust");
61 dispatch_semaphore_signal(sema);
64 if (0 != dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60 * 5))) {
65 secerror("octagon: Timed out signing in");
69 secerror("Octagon not enabled!");
74 if ((changeType == kACAccountChangeTypeDeleted) && [oldAccount.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) {
76 NSString *accountIdentifier = oldAccount.identifier;
77 NSString *username = oldAccount.username;
79 if(accountIdentifier != NULL && username !=NULL) {
80 if ([self accountIsPrimary:oldAccount]) {
81 CFErrorRef removalError = NULL;
83 secinfo("accounts", "Performing SOS circle credential removal for account %@: %@", accountIdentifier, username);
85 if (!SOSCCLoggedOutOfAccount(&removalError)) {
86 secerror("Account %@ could not leave the SOS circle: %@", accountIdentifier, removalError);