]> git.saurik.com Git - apple/security.git/blob - KeychainSyncAccountNotification/KeychainSyncAccountNotification.m
09cbfb96c17f398089e64d867b554b286cef6d6c
[apple/security.git] / KeychainSyncAccountNotification / KeychainSyncAccountNotification.m
1 //
2 // KeychainSyncAccountNotification.m
3 // Security
4 //
5
6 #import "KeychainSyncAccountNotification.h"
7 #import <Accounts/Accounts.h>
8 #import <Accounts/Accounts_Private.h>
9 #if TARGET_OS_IPHONE
10 #import <AppleAccount/ACAccount+AppleAccount.h>
11 #else
12 #import <AOSAccounts/ACAccount+iCloudAccount.h>
13 #endif
14 #import <AccountsDaemon/ACDAccountStore.h>
15 #import <Security/SecureObjectSync/SOSCloudCircle.h>
16 #if OCTAGON
17 #import <keychain/ot/OTControl.h>
18 #include <utilities/SecCFRelease.h>
19 #endif
20 #import "utilities/debugging.h"
21
22 #if OCTAGON
23
24 static bool SecOTIsEnabled(void)
25 {
26 bool userDefaultsShouldBottledPeer = true;
27 CFBooleanRef enabled = (CFBooleanRef)CFPreferencesCopyValue(CFSTR("EnableOTRestore"),
28 CFSTR("com.apple.security"),
29 kCFPreferencesAnyUser, kCFPreferencesAnyHost);
30 if(enabled && CFGetTypeID(enabled) == CFBooleanGetTypeID()){
31 if(enabled == kCFBooleanFalse){
32 secnotice("octagon", "Octagon Restore Disabled");
33 userDefaultsShouldBottledPeer = false;
34 }
35 if(enabled == kCFBooleanTrue){
36 secnotice("octagon", "Octagon Restore Enabled");
37 userDefaultsShouldBottledPeer = true;
38 }
39 }
40
41 CFReleaseNull(enabled);
42 return userDefaultsShouldBottledPeer;
43 }
44
45 #endif
46
47 @implementation KeychainSyncAccountNotification
48
49 - (bool)accountIsPrimary:(ACAccount *)account
50 {
51 #if TARGET_OS_IPHONE
52 return [account aa_isPrimaryAccount];
53 #else
54 return [account icaIsPrimaryAccount];
55 #endif
56 }
57
58 - (BOOL)account:(ACAccount *)account willChangeWithType:(ACAccountChangeType)changeType inStore:(ACDAccountStore *)store oldAccount:(ACAccount *)oldAccount {
59 NSString* oldAccountIdentifier = oldAccount.identifier;
60 NSString* accountIdentifier = account.identifier;
61
62 if((changeType == kACAccountChangeTypeAdded) &&
63 [account.accountType.identifier isEqualToString: ACAccountTypeIdentifierAppleAccount] &&
64 [self accountIsPrimary:account]) {
65 #if OCTAGON
66 if(SecOTIsEnabled()){
67 __block NSError* error = nil;
68 NSString *dsid = account.accountProperties[@"personID"];
69 OTControl* otcontrol = [OTControl controlObject:&error];
70
71 if (nil == otcontrol) {
72 secerror("octagon: Failed to get OTControl: %@", error.localizedDescription);
73 } else {
74 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
75
76 [otcontrol signIn:dsid reply:^(BOOL result, NSError * _Nullable signedInError) {
77 if(!result || signedInError){
78 secerror("octagon: error signing in: %s", [[signedInError description] UTF8String]);
79 }
80 else{
81 secnotice("octagon", "signed into octagon trust");
82 }
83 dispatch_semaphore_signal(sema);
84
85 }];
86 if (0 != dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60 * 5))) {
87 secerror("octagon: Timed out signing in");
88 }
89 }
90 }else{
91 secerror("Octagon not enabled!");
92 }
93 #endif
94 }
95 if ((changeType == kACAccountChangeTypeDeleted) && [oldAccount.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) {
96 if(oldAccountIdentifier != NULL && oldAccount.username !=NULL) {
97 if ([self accountIsPrimary:oldAccount]) {
98 CFErrorRef removalError = NULL;
99
100 secinfo("accounts", "Performing SOS circle credential removal for account %@: %@", oldAccountIdentifier, oldAccount.username);
101
102 if (!SOSCCLoggedOutOfAccount(&removalError)) {
103 secerror("Account %@ could not leave the SOS circle: %@", oldAccountIdentifier, removalError);
104 }
105 #if OCTAGON
106 if(SecOTIsEnabled()){
107 __block NSError* error = nil;
108 OTControl* otcontrol = [OTControl controlObject:&error];
109
110 if (nil == otcontrol) {
111 secerror("octagon: Failed to get OTControl: %@", error.localizedDescription);
112 } else {
113 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
114
115 [otcontrol signOut:^(BOOL result, NSError * _Nullable signedOutError) {
116 if(!result || signedOutError){
117 secerror("octagon: error signing out: %s", [[signedOutError description] UTF8String]);
118 }
119 else{
120 secnotice("octagon", "signed out of octagon trust");
121 }
122 dispatch_semaphore_signal(sema);
123 }];
124 if (0 != dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60 * 5))) {
125 secerror("octagon: Timed out signing out");
126 }
127 }
128 }
129 else{
130 secerror("Octagon not enabled!");
131 }
132 #endif
133 } else {
134 secinfo("accounts", "NOT performing SOS circle credential removal for secondary account %@: %@", accountIdentifier, account.username);
135 }
136 } else{
137 secinfo("accounts", "Already logged out of account");
138 }
139 }
140
141 return YES;
142 }
143
144 @end