5 // Created by murf on 6/19/18.
8 #import <Foundation/Foundation.h>
9 #import "SOSAuthKitHelpers.h"
10 #import <utilities/debugging.h>
11 #import <Security/SecureObjectSync/SOSAccount.h>
12 #import <Security/SecureObjectSync/SOSAccountPriv.h>
13 #import <Security/SecureObjectSync/SOSFullPeerInfo.h>
14 #import <Security/SecureObjectSync/SOSPeerInfoV2.h>
15 #import <Security/SecureObjectSync/SOSPeerInfoPriv.h>
17 #if !TARGET_OS_BRIDGE && !TARGET_OS_SIMULATOR
18 #import <AppleAccount/AppleAccount_Private.h>
19 #import <AuthKit/AuthKit.h>
20 #import <AuthKit/AuthKit_Private.h>
25 @implementation SOSAuthKitHelpers
29 SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit);
30 SOFT_LINK_FRAMEWORK(Frameworks, Accounts);
32 #pragma clang diagnostic push
33 #pragma clang diagnostic ignored "-Wstrict-prototypes"
34 SOFT_LINK_CLASS(AuthKit, AKAccountManager);
35 SOFT_LINK_CLASS(AuthKit, AKAnisetteProvisioningController);
36 SOFT_LINK_CLASS(AuthKit, AKAppleIDAuthenticationController);
37 SOFT_LINK_CLASS(AuthKit, AKDeviceListRequestContext);
38 SOFT_LINK_CLASS(Accounts, Accounts);
39 SOFT_LINK_CLASS(Accounts, ACAccountStore);
40 SOFT_LINK_CONSTANT(AuthKit, AKServiceNameiCloud, const NSString *);
41 #pragma clang diagnostic pop
45 + (NSString *) machineID {
47 NSString *retval = nil;
48 secnotice("sosauthkit", "Entering machineID");
50 AKAnisetteProvisioningController *anisetteController = [getAKAnisetteProvisioningControllerClass() new];
51 if(anisetteController) {
52 AKAnisetteData *anisetteData = [anisetteController anisetteDataWithError:&error];
54 retval = [anisetteData.machineID copy];
56 secnotice("sosauthkit", "machineID is %@", retval);
58 secnotice("sosauthkit", "Failed to get machineID");
61 secnotice("sosauthkit", "can't get mID: %@", error);
64 secnotice("sosauthkit", "can't get controller");
69 + (bool) peerinfoHasMID: (SOSAccount *) account {
70 SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(account.fullPeerInfo);
72 return SOSPeerInfoV2DictionaryHasString(pi, sMachineIDKey);
75 + (bool) updateMIDInPeerInfo: (SOSAccount *) account {
76 NSString *mid = [SOSAuthKitHelpers machineID];
78 CFErrorRef error = NULL;
79 SOSAccountSetValue(account, sMachineIDKey, (__bridge CFStringRef)mid, &error);
80 bool peerUpdated = SOSAccountUpdatePeerInfoAndPush(account, CFSTR("Add Machine ID"), &error, ^bool(SOSPeerInfoRef pi, CFErrorRef *error) {
81 if(SOSPeerInfoV2DictionaryHasString(pi, sMachineIDKey)) {
84 secnotice("sosauthkit", "Setting PeerInfo MID to %@", mid);
85 SOSPeerInfoV2DictionarySetValue(pi, sMachineIDKey, (__bridge CFStringRef)mid);
89 secnotice("sosauthkit", "Failed to record MID in PeerInfo: %@", error);
95 + (void)activeMIDs:(void(^_Nonnull)(NSSet *activeMIDs, NSError *error))complete {
96 AKDeviceListRequestContext *context;
97 ACAccount *primaryAccount;
99 ACAccountStore *store = [getACAccountStoreClass() new];
101 complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get store"}]);
104 primaryAccount = [store aa_primaryAppleAccount];
105 if(!primaryAccount) {
106 secnotice("sosauthkit", "can't get account");
107 complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"no primary account"}]);
111 context = [getAKDeviceListRequestContextClass() new];
112 if (context == NULL) {
113 complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get AKDeviceListRequestContextClass"}]);
116 context.altDSID = primaryAccount.aa_altDSID;
117 context.services = @[ getAKServiceNameiCloud() ];
119 AKAppleIDAuthenticationController *authController = [getAKAppleIDAuthenticationControllerClass() new];
120 if(!authController) {
121 complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get authController"}]);
125 [authController fetchDeviceListWithContext:context completion:^(NSArray<AKRemoteDevice *> *deviceList, NSError *error) {
126 NSMutableSet *mids = [[NSMutableSet alloc] init];
127 if (deviceList != nil) {
128 for (AKRemoteDevice *device in deviceList) {
129 [mids addObject:device.machineId];
132 secnotice("sosauthkit", "got no mIDs: %@", error);
134 if([mids count] == 0) {
135 secnotice("sosauthkit", "found not devices in account");
139 complete(mids, error);
144 #else /* TARGET_OS_BRIDGE || TARGET_OS_SIMULATOR */
146 + (NSString *) machineID {
150 + (void)activeMIDs:(void(^_Nonnull)(NSSet *activeMIDs, NSError *error))complete {
151 complete(NULL, NULL);
154 + (bool) updateMIDInPeerInfo: (SOSAccount *) account {
158 + (bool) peerinfoHasMID: (SOSAccount *) account {