]> git.saurik.com Git - apple/security.git/blob - keychain/KeychainStasher/main.m
Security-59754.41.1.tar.gz
[apple/security.git] / keychain / KeychainStasher / main.m
1 #import <Foundation/Foundation.h>
2 #import <Foundation/NSXPCConnection_Private.h>
3 #import <unistd.h>
4 #import <xpc/private.h>
5 #import <sandbox.h>
6
7 #import <Security/SecEntitlements.h>
8 #import <utilities/debugging.h>
9 #import <utilities/SecFileLocations.h>
10
11 #import "KeychainStasher.h"
12
13 NSString* const KeychainStasherMachServiceName = @"com.apple.security.KeychainStasher";
14
15 @interface ServiceDelegate : NSObject <NSXPCListenerDelegate>
16 @end
17
18 @implementation ServiceDelegate
19
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();
23
24 NSNumber* value = [newConnection valueForEntitlement:kSecEntitlementPrivateStashService];
25 if (value == nil || ![value boolValue]) {
26 secerror("KeychainStasher: client not entitled, rejecting connection");
27 [newConnection invalidate];
28 return NO;
29 }
30
31 newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(KeychainStasherProtocol)];
32 newConnection.exportedObject = [KeychainStasher new];
33 [newConnection resume];
34 return YES;
35 }
36
37 @end
38
39 int main(int argc, const char *argv[])
40 {
41 if (geteuid() == 0) {
42 secerror("KeychainStasher invoked as root, do not want.");
43 return 1;
44 } else {
45 secnotice("KeychainStasher", "Invoked with uid %d", geteuid());
46 }
47
48 NSString* analyticsdir = [[(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory(nil) URLByAppendingPathComponent:@"Analytics/"] path];
49 if (analyticsdir) {
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);
55 abort();
56 }
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);
62 abort();
63 }
64 }
65
66 ServiceDelegate *delegate = [ServiceDelegate new];
67 NSXPCListener *listener = [[NSXPCListener alloc] initWithMachServiceName:KeychainStasherMachServiceName];
68 listener.delegate = delegate;
69 [listener resume];
70 [[NSRunLoop currentRunLoop] run];
71 return 0;
72 }