X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m diff --git a/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m b/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m new file mode 100644 index 00000000..c00eed74 --- /dev/null +++ b/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m @@ -0,0 +1,80 @@ +// +// KeychainSyncAccountNotification.m +// Security +// +// Created by keith on 5/2/13. +// +// + +#import "KeychainSyncAccountNotification.h" +#import +#import +#import +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnewline-eof" +#import +#pragma clang diagnostic pop +#import +#import +#import +#import + +@implementation KeychainSyncAccountNotification + +- (BOOL)account:(ACAccount *)account willChangeWithType:(ACAccountChangeType)changeType inStore:(ACDAccountStore *)store oldAccount:(ACAccount *)oldAccount { + if ((changeType == kACAccountChangeTypeDeleted) && [oldAccount.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) { + if ([account aa_isPrimaryAccount]) { + + CFErrorRef removalError = NULL; + + ACLogDebug(@"Performing SOS circle credential removal for account %@: %@", oldAccount.identifier, oldAccount.username); + + if (!SOSCCRemoveThisDeviceFromCircle(&removalError)) { + ACLogError(@"Account %@ could not leave the SOS circle: %@", oldAccount.identifier, removalError); + } + } else { + ACLogDebug(@"NOT performing SOS circle credential removal for secondary account %@: %@", account.identifier, account.username); + } + } + + return YES; +} + +- (void)account:(ACAccount *)account didChangeWithType:(ACAccountChangeType)changeType inStore:(ACDAccountStore *)store oldAccount:(ACAccount *)oldAccount { + if ((changeType == kACAccountChangeTypeAdded || changeType == kACAccountChangeTypeModified) && [account.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) { + if ([account aa_isPrimaryAccount]) { + NSError *errObject; + ACAccountCredential *accountCred = [store credentialForAccount:account error:&errObject]; + if (accountCred != NULL) { + CFErrorRef authenticateError = NULL; + if (accountCred.password != NULL) { + const char *accountPassword = [accountCred.password cStringUsingEncoding:NSUTF8StringEncoding]; + CFDataRef passwordData = CFDataCreate(kCFAllocatorDefault, (const uint8_t *)accountPassword, strlen(accountPassword)); + if (NULL != passwordData) { + ACLogDebug(@"Performing SOS circle credential set for account %@: %@", account.identifier, account.username); + if (!SOSCCSetUserCredentials((__bridge CFStringRef)(account.username), passwordData, &authenticateError)) { + ACLogError(@"Unable to set SOS circle credentials for account %@: %@", account.identifier, authenticateError); + if (NULL != authenticateError) { + CFRelease(authenticateError); + } + } + CFRelease(passwordData); + } + } else { + if (!SOSCCCanAuthenticate(&authenticateError)) { + ACLogError(@"Account %@ did not present a password and we could not authenticate the SOS circle: %@", account.identifier, authenticateError); + if (NULL != authenticateError) { + CFRelease(authenticateError); + } + } + } + } else { + ACLogError(@"Account %@ did not present a credential for SOS circle: %@", account.identifier, errObject); + } + } else { + ACLogDebug(@"NOT performing SOS circle credential set for secondary account %@: %@", account.identifier, account.username); + } + } +} + +@end