]>
Commit | Line | Data |
---|---|---|
ecaf5866 A |
1 | #import <Foundation/Foundation.h> |
2 | #import <Foundation/NSXPCConnection_Private.h> | |
3 | #import <Security/SecEntitlements.h> | |
4 | #import <ipc/securityd_client.h> | |
5 | #import "SOSAccount.h" | |
6 | #import "SOSControlHelper.h" | |
7 | #import "SOSControlServer.h" | |
8 | ||
9 | @interface SOSControlServer : NSObject <NSXPCListenerDelegate> | |
10 | @end | |
11 | ||
b54c578e | 12 | @interface SOSClient () |
ecaf5866 | 13 | @property (strong) SOSAccount * account; |
b54c578e A |
14 | - (instancetype)initSOSClientWithAccount:(SOSAccount *)account; |
15 | - (bool)checkEntitlement:(NSString *)entitlement; | |
16 | @end | |
ecaf5866 | 17 | |
b54c578e A |
18 | @interface SOSClientRemote : SOSClient |
19 | @property (weak) NSXPCConnection * connection; | |
20 | - (instancetype)initSOSConnectionWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account; | |
ecaf5866 A |
21 | @end |
22 | ||
23 | @implementation SOSControlServer | |
24 | ||
25 | - (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection | |
26 | { | |
27 | NSNumber *num = [newConnection valueForEntitlement:(__bridge NSString *)kSecEntitlementKeychainCloudCircle]; | |
28 | if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { | |
29 | secerror("sos: Client pid: %d doesn't have entitlement: %@", | |
30 | [newConnection processIdentifier], kSecEntitlementKeychainCloudCircle); | |
31 | return NO; | |
32 | } | |
33 | ||
805875f8 A |
34 | SOSAccount *account = (__bridge SOSAccount *)SOSKeychainAccountGetSharedAccount(); |
35 | if (account == nil) { | |
36 | secerror("sos: SOS have not launched yet, come later, pid: %d", | |
37 | [newConnection processIdentifier]); | |
38 | return NO; | |
39 | } | |
40 | ||
41 | SOSClientRemote *sosClient = [[SOSClientRemote alloc] initSOSConnectionWithConnection:newConnection account:account]; | |
ecaf5866 A |
42 | |
43 | newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)]; | |
44 | _SOSControlSetupInterface(newConnection.exportedInterface); | |
45 | newConnection.exportedObject = sosClient; | |
46 | ||
47 | [newConnection resume]; | |
48 | ||
49 | return YES; | |
50 | } | |
51 | ||
b54c578e A |
52 | - (SOSClient *)internalSOSClient |
53 | { | |
54 | return [[SOSClient alloc] initSOSClientWithAccount:(__bridge SOSAccount *)SOSKeychainAccountGetSharedAccount()]; | |
55 | } | |
56 | ||
ecaf5866 A |
57 | @end |
58 | ||
59 | @implementation SOSClient | |
60 | ||
61 | @synthesize account = _account; | |
ecaf5866 | 62 | |
b54c578e | 63 | - (instancetype)initSOSClientWithAccount:(SOSAccount *)account |
ecaf5866 A |
64 | { |
65 | if ((self = [super init])) { | |
ecaf5866 A |
66 | _account = account; |
67 | } | |
68 | return self; | |
69 | } | |
70 | ||
71 | - (bool)checkEntitlement:(NSString *)entitlement | |
72 | { | |
ecaf5866 A |
73 | return true; |
74 | } | |
75 | ||
76 | - (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))reply | |
77 | { | |
78 | [self.account userPublicKey:reply]; | |
79 | } | |
80 | ||
81 | - (void)kvsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))reply | |
82 | { | |
83 | [self.account kvsPerformanceCounters:reply]; | |
84 | } | |
85 | ||
ecaf5866 A |
86 | - (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary <NSString *, NSString *> *))reply |
87 | { | |
88 | [self.account rateLimitingPerformanceCounters:reply]; | |
89 | } | |
90 | ||
91 | - (void)stashedCredentialPublicKey:(void(^)(NSData *, NSError *error))reply | |
92 | { | |
93 | [self.account stashedCredentialPublicKey:reply]; | |
94 | } | |
95 | ||
96 | - (void)assertStashedAccountCredential:(void(^)(BOOL result, NSError *error))reply | |
97 | { | |
98 | [self.account assertStashedAccountCredential:reply]; | |
99 | } | |
100 | ||
101 | - (void)validatedStashedAccountCredential:(void(^)(NSData *credential, NSError *error))complete | |
102 | { | |
103 | [self.account validatedStashedAccountCredential:complete]; | |
104 | } | |
105 | ||
106 | - (void)stashAccountCredential:(NSData *)credential complete:(void(^)(bool success, NSError *error))complete | |
107 | { | |
108 | [self.account stashAccountCredential:credential complete:complete]; | |
109 | } | |
110 | ||
111 | - (void)myPeerInfo:(void (^)(NSData *, NSError *))complete | |
112 | { | |
113 | [self.account myPeerInfo:complete]; | |
114 | } | |
115 | ||
b54c578e A |
116 | - (void)circleHash:(void (^)(NSString *, NSError *))complete |
117 | { | |
118 | [self.account circleHash:complete]; | |
119 | } | |
120 | ||
121 | ||
ecaf5866 A |
122 | - (void)circleJoiningBlob:(NSData *)applicant complete:(void (^)(NSData *blob, NSError *))complete |
123 | { | |
124 | [self.account circleJoiningBlob:applicant complete:complete]; | |
125 | } | |
126 | ||
127 | - (void)joinCircleWithBlob:(NSData *)blob version:(PiggyBackProtocolVersion)version complete:(void (^)(bool success, NSError *))complete | |
128 | { | |
129 | [self.account joinCircleWithBlob:blob version:version complete:complete]; | |
130 | } | |
131 | ||
132 | - (void)initialSyncCredentials:(uint32_t)flags complete:(void (^)(NSArray *, NSError *))complete | |
133 | { | |
134 | if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) { | |
135 | complete(@[], [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]); | |
136 | return; | |
137 | } | |
138 | ||
139 | [self.account initialSyncCredentials:flags complete:complete]; | |
140 | } | |
141 | ||
142 | - (void)importInitialSyncCredentials:(NSArray *)items complete:(void (^)(bool success, NSError *))complete | |
143 | { | |
144 | if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) { | |
145 | complete(false, [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]); | |
146 | return; | |
147 | } | |
148 | ||
149 | [self.account importInitialSyncCredentials:items complete:complete]; | |
150 | } | |
151 | ||
d64be36e | 152 | - (void)rpcTriggerSync:(NSArray <NSString *> *)peers complete:(void(^)(bool success, NSError *))complete |
ecaf5866 | 153 | { |
d64be36e | 154 | [self.account rpcTriggerSync:peers complete:complete]; |
ecaf5866 A |
155 | } |
156 | ||
157 | - (void)getWatchdogParameters:(void (^)(NSDictionary* parameters, NSError* error))complete | |
158 | { | |
159 | [self.account getWatchdogParameters:complete]; | |
160 | } | |
161 | ||
162 | - (void)setWatchdogParmeters:(NSDictionary*)parameters complete:(void (^)(NSError* error))complete | |
163 | { | |
164 | [self.account setWatchdogParmeters:parameters complete:complete]; | |
165 | } | |
166 | ||
b54c578e A |
167 | - (void) ghostBust:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete { |
168 | [self.account ghostBust:options complete:complete]; | |
169 | } | |
170 | ||
171 | - (void)ghostBustTriggerTimed:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete { | |
172 | [self.account ghostBustTriggerTimed:options complete:complete]; | |
173 | } | |
174 | ||
175 | - (void) ghostBustPeriodic:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete { | |
176 | [self.account ghostBustPeriodic:options complete:complete]; | |
177 | } | |
178 | ||
179 | - (void) ghostBustInfo: (void(^)(NSData *json, NSError *error))complete { | |
180 | [self.account ghostBustInfo:complete]; | |
181 | } | |
182 | ||
d64be36e A |
183 | - (void)iCloudIdentityStatus: (void (^)(NSData *json, NSError *error))complete { |
184 | [self.account iCloudIdentityStatus: complete]; | |
185 | } | |
186 | ||
187 | - (void)rpcTriggerBackup:(NSArray<NSString *>* _Nullable)backupPeers complete:(void (^)(NSError *error))complete | |
805875f8 | 188 | { |
d64be36e A |
189 | [self.account rpcTriggerBackup:backupPeers complete:complete]; |
190 | } | |
191 | ||
192 | - (void)rpcTriggerRingUpdate:(void (^)(NSError *))complete { | |
193 | [self.account rpcTriggerRingUpdate:complete]; | |
194 | } | |
195 | ||
196 | - (void)iCloudIdentityStatus_internal:(void (^)(NSDictionary *, NSError *))complete { | |
197 | [self.account iCloudIdentityStatus_internal:complete]; | |
805875f8 A |
198 | } |
199 | ||
805875f8 | 200 | |
b54c578e A |
201 | @end |
202 | ||
203 | @implementation SOSClientRemote | |
204 | ||
205 | - (instancetype)initSOSConnectionWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account | |
206 | { | |
d64be36e | 207 | if ((self = [super initSOSClientWithAccount:account])) { |
b54c578e A |
208 | self.connection = connection; |
209 | } | |
210 | return self; | |
211 | } | |
212 | ||
213 | - (bool)checkEntitlement:(NSString *)entitlement | |
214 | { | |
215 | NSXPCConnection *strongConnection = _connection; | |
216 | ||
217 | NSNumber *num = [strongConnection valueForEntitlement:entitlement]; | |
218 | if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { | |
219 | secerror("sos: Client pid: %d doesn't have entitlement: %@", | |
220 | [strongConnection processIdentifier], entitlement); | |
221 | return false; | |
222 | } | |
223 | return true; | |
224 | } | |
ecaf5866 A |
225 | @end |
226 | ||
b54c578e A |
227 | static SOSControlServer *sosServer; |
228 | ||
ecaf5866 A |
229 | void |
230 | SOSControlServerInitialize(void) | |
231 | { | |
232 | static dispatch_once_t once; | |
ecaf5866 A |
233 | static NSXPCListener *listener; |
234 | ||
235 | dispatch_once(&once, ^{ | |
236 | @autoreleasepool { | |
b54c578e | 237 | sosServer = [SOSControlServer new]; |
ecaf5866 A |
238 | |
239 | listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSecuritydSOSServiceName)]; | |
b54c578e | 240 | listener.delegate = sosServer; |
ecaf5866 A |
241 | [listener resume]; |
242 | } | |
243 | }); | |
244 | } | |
b54c578e A |
245 | |
246 | SOSClient * | |
247 | SOSControlServerInternalClient(void) | |
248 | { | |
249 | SOSControlServerInitialize(); | |
250 | return [sosServer internalSOSClient]; | |
251 | } |