]> git.saurik.com Git - apple/security.git/blob - SecurityTool/sharedTool/KeychainCheck.m
Security-59306.11.20.tar.gz
[apple/security.git] / SecurityTool / sharedTool / KeychainCheck.m
1 /*
2 * Copyright (c) 2017 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 *
23 */
24
25 #import "KeychainCheck.h"
26 #import "SFKeychainControl.h"
27 #import "builtin_commands.h"
28 #import "SOSControlHelper.h"
29 #import "SOSTypes.h"
30 #import "CKKSControlProtocol.h"
31 #import <Security/SecItemPriv.h>
32 #import <Foundation/NSXPCConnection_Private.h>
33
34 @interface KeychainCheck ()
35
36 - (void)checkKeychain;
37 - (void)cleanKeychain;
38
39 @end
40
41 @implementation KeychainCheck {
42 NSXPCConnection* _connection;
43 }
44
45 - (instancetype)initWithEndpoint:(xpc_endpoint_t)endpoint
46 {
47 if (self = [super init]) {
48 NSXPCListenerEndpoint* listenerEndpoint = [[NSXPCListenerEndpoint alloc] init];
49 [listenerEndpoint _setEndpoint:endpoint];
50 _connection = [[NSXPCConnection alloc] initWithListenerEndpoint:listenerEndpoint];
51 if (!_connection) {
52 return nil;
53 }
54
55 NSXPCInterface* interface = [NSXPCInterface interfaceWithProtocol:@protocol(SFKeychainControl)];
56 _connection.remoteObjectInterface = interface;
57 [_connection resume];
58 }
59
60 return self;
61 }
62
63 - (void)checkKeychain
64 {
65 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
66 [[_connection remoteObjectProxyWithErrorHandler:^(NSError* error) {
67 NSLog(@"failed to communicate with server with error: %@", error);
68 dispatch_semaphore_signal(semaphore);
69 }] rpcFindCorruptedItemsWithReply:^(NSArray* corruptedItems, NSError* error) {
70 if (error) {
71 NSLog(@"error searching keychain: %@", error.localizedDescription);
72 }
73
74 if (corruptedItems.count > 0) {
75 NSLog(@"found %d corrupted items", (int)corruptedItems.count);
76 }
77 else {
78 NSLog(@"no corrupted items found");
79 }
80
81 dispatch_semaphore_signal(semaphore);
82 }];
83
84 if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) {
85 NSLog(@"timed out trying to communicate with server");
86 }
87 }
88
89 - (void)cleanKeychain
90 {
91 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
92 [[_connection remoteObjectProxyWithErrorHandler:^(NSError* error) {
93 NSLog(@"failed to communicate with server with error: %@", error);
94 dispatch_semaphore_signal(semaphore);
95 }] rpcDeleteCorruptedItemsWithReply:^(bool success, NSError* error) {
96 if (success) {
97 NSLog(@"successfully cleaned keychain");
98 }
99 else {
100 NSLog(@"error attempting to clean keychain: %@", error);
101 }
102
103 dispatch_semaphore_signal(semaphore);
104 }];
105
106 if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)) {
107 NSLog(@"timed out trying to communicate with server");
108 }
109 }
110
111 @end
112
113 int command_keychain_check(int argc, char* const* argv)
114 {
115 KeychainCheck* keychainCheck = [[KeychainCheck alloc] initWithEndpoint:_SecSecuritydCopyKeychainControlEndpoint(NULL)];
116 [keychainCheck checkKeychain];
117 return 0;
118 }
119
120 int command_keychain_cleanup(int argc, char* const* argv)
121 {
122 KeychainCheck* keychainCheck = [[KeychainCheck alloc] initWithEndpoint:_SecSecuritydCopyKeychainControlEndpoint(NULL)];
123 [keychainCheck cleanKeychain];
124 return 0;
125 }
126
127 int verify_backup_integrity(int argc, char * const *argv) {
128 int arg;
129 BOOL lightweight = NO;
130
131 while ((arg = getopt(argc, argv, "l")) != -1) {
132 switch(arg) {
133 case 'l':
134 lightweight = YES;
135 break;
136 }
137 }
138
139 NSLog(@"Running backup integrity validation in %@ mode", lightweight ? @"lightweight" : @"default");
140 dispatch_semaphore_t sema = dispatch_semaphore_create(0);
141 SecItemVerifyBackupIntegrity(lightweight, ^(NSDictionary* results, NSError *error) {
142 NSLog(@"%@", results);
143 dispatch_semaphore_signal(sema);
144 });
145
146 if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 30))) {
147 NSLog(@"Timed out waiting for backup integrity validation");
148 }
149
150 return 0;
151 }