]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m
Security-58286.60.28.tar.gz
[apple/security.git] / OSX / sec / SOSCircle / SecureObjectSync / SOSControlServer.m
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
12 @interface SOSClient : NSObject <SOSControlProtocol>
13 @property (weak) NSXPCConnection * connection;
14 @property (strong) SOSAccount * account;
15
16 - (instancetype)initWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account;
17 @end
18
19 @implementation SOSControlServer
20
21 - (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection
22 {
23 NSNumber *num = [newConnection valueForEntitlement:(__bridge NSString *)kSecEntitlementKeychainCloudCircle];
24 if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) {
25 secerror("sos: Client pid: %d doesn't have entitlement: %@",
26 [newConnection processIdentifier], kSecEntitlementKeychainCloudCircle);
27 return NO;
28 }
29
30
31 SOSClient *sosClient = [[SOSClient alloc] initWithConnection:newConnection account:(__bridge SOSAccount *)SOSKeychainAccountGetSharedAccount()];
32
33 newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)];
34 _SOSControlSetupInterface(newConnection.exportedInterface);
35 newConnection.exportedObject = sosClient;
36
37 [newConnection resume];
38
39 return YES;
40 }
41
42 @end
43
44 @implementation SOSClient
45
46 @synthesize account = _account;
47 @synthesize connection = _connection;
48
49 - (instancetype)initWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account
50 {
51 if ((self = [super init])) {
52 _connection = connection;
53 _account = account;
54 }
55 return self;
56 }
57
58 - (bool)checkEntitlement:(NSString *)entitlement
59 {
60 NSXPCConnection *strongConnection = _connection;
61
62 NSNumber *num = [strongConnection valueForEntitlement:entitlement];
63 if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) {
64 secerror("sos: Client pid: %d doesn't have entitlement: %@",
65 [strongConnection processIdentifier], entitlement);
66 return false;
67 }
68 return true;
69 }
70
71 - (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))reply
72 {
73 [self.account userPublicKey:reply];
74 }
75
76 - (void)kvsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))reply
77 {
78 [self.account kvsPerformanceCounters:reply];
79 }
80
81 - (void)idsPerformanceCounters:(void(^)(NSDictionary <NSString *, NSNumber *> *))reply
82 {
83 [self.account idsPerformanceCounters:reply];
84 }
85
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
116 - (void)circleJoiningBlob:(NSData *)applicant complete:(void (^)(NSData *blob, NSError *))complete
117 {
118 [self.account circleJoiningBlob:applicant complete:complete];
119 }
120
121 - (void)joinCircleWithBlob:(NSData *)blob version:(PiggyBackProtocolVersion)version complete:(void (^)(bool success, NSError *))complete
122 {
123 [self.account joinCircleWithBlob:blob version:version complete:complete];
124 }
125
126 - (void)initialSyncCredentials:(uint32_t)flags complete:(void (^)(NSArray *, NSError *))complete
127 {
128 if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) {
129 complete(@[], [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]);
130 return;
131 }
132
133 [self.account initialSyncCredentials:flags complete:complete];
134 }
135
136 - (void)importInitialSyncCredentials:(NSArray *)items complete:(void (^)(bool success, NSError *))complete
137 {
138 if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainInitialSync]) {
139 complete(false, [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]);
140 return;
141 }
142
143 [self.account importInitialSyncCredentials:items complete:complete];
144 }
145
146 - (void)triggerSync:(NSArray <NSString *> *)peers complete:(void(^)(bool success, NSError *))complete
147 {
148 if (![self checkEntitlement:(__bridge NSString *)kSecEntitlementKeychainCloudCircle]) {
149 complete(false, [NSError errorWithDomain:(__bridge NSString *)kSOSErrorDomain code:kSOSEntitlementMissing userInfo:NULL]);
150 return;
151 }
152
153 [self.account triggerSync:peers complete:complete];
154 }
155
156 - (void)getWatchdogParameters:(void (^)(NSDictionary* parameters, NSError* error))complete
157 {
158 [self.account getWatchdogParameters:complete];
159 }
160
161 - (void)setWatchdogParmeters:(NSDictionary*)parameters complete:(void (^)(NSError* error))complete
162 {
163 [self.account setWatchdogParmeters:parameters complete:complete];
164 }
165
166 @end
167
168 void
169 SOSControlServerInitialize(void)
170 {
171 static dispatch_once_t once;
172 static SOSControlServer *server;
173 static NSXPCListener *listener;
174
175 dispatch_once(&once, ^{
176 @autoreleasepool {
177 server = [SOSControlServer new];
178
179 listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSecuritydSOSServiceName)];
180 listener.delegate = server;
181 [listener resume];
182 }
183 });
184 }