1 #import <Foundation/Foundation.h>
2 #import <Foundation/NSXPCConnection_Private.h>
4 #import <xpc/private.h>
7 #import <Security/SecEntitlements.h>
8 #import <utilities/debugging.h>
9 #import <utilities/SecFileLocations.h>
11 #import "KeychainStasher.h"
13 NSString* const KeychainStasherMachServiceName = @"com.apple.security.KeychainStasher";
15 @interface ServiceDelegate : NSObject <NSXPCListenerDelegate>
18 @implementation ServiceDelegate
20 - (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
21 // We should encounter no more than 1 transaction per boot in normal conditions, so get out of everyone's way ASAP
22 xpc_transaction_exit_clean();
24 NSNumber* value = [newConnection valueForEntitlement:kSecEntitlementPrivateStashService];
25 if (value == nil || ![value boolValue]) {
26 secerror("KeychainStasher: client not entitled, rejecting connection");
27 [newConnection invalidate];
31 newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(KeychainStasherProtocol)];
32 newConnection.exportedObject = [KeychainStasher new];
33 [newConnection resume];
39 int main(int argc, const char *argv[])
42 secerror("KeychainStasher invoked as root, do not want.");
45 secnotice("KeychainStasher", "Invoked with uid %d", geteuid());
48 NSString* analyticsdir = [[(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory(nil) URLByAppendingPathComponent:@"Analytics/"] path];
50 const char* sandbox_parameters[] = {"ANALYTICSDIR", analyticsdir.UTF8String, NULL};
51 char* sandbox_error = NULL;
52 if (0 != sandbox_init_with_parameters("com.apple.security.KeychainStasher", SANDBOX_NAMED, sandbox_parameters, &sandbox_error)) {
53 secerror("unable to enter sandbox with parameter: %s", sandbox_error);
54 sandbox_free_error(sandbox_error);
57 } else { // If this fails somehow we will go ahead without analytics
58 char* sandbox_error = NULL;
59 if (0 != sandbox_init("com.apple.security.KeychainStasher", SANDBOX_NAMED, &sandbox_error)) {
60 secerror("unable to enter sandbox: %s", sandbox_error);
61 sandbox_free_error(sandbox_error);
66 ServiceDelegate *delegate = [ServiceDelegate new];
67 NSXPCListener *listener = [[NSXPCListener alloc] initWithMachServiceName:KeychainStasherMachServiceName];
68 listener.delegate = delegate;
70 [[NSRunLoop currentRunLoop] run];