main.c
1 // 2 // main.c 3 // securitydservicectrl 4 // 5 // Created by Wade Benson on 12/2/12. 6 // Copyright (c) 2012 Apple. All rights reserved. 7 // 8 9 #include "securityd_service.h" 10 #include "securityd_service_client.h" 11 12 #include <stdio.h> 13 #include <xpc/xpc.h> 14 #include <dispatch/dispatch.h> 15 #include <AssertMacros.h> 16 #include <CoreFoundation/CoreFoundation.h> 17 #include <Security/SecKeychainPriv.h> 18 19 static inline char * 20 hextostr(const uint8_t *buf, size_t len, char *hexbuf) 21 { 22 char *s = hexbuf; 23 size_t i; 24 static const char hexdigits[] = "0123456789abcdef"; 25 for (i = 0; i < len; i++) { 26 *s++ = hexdigits[buf[i]>>4]; 27 *s++ = hexdigits[buf[i]&0xf]; 28 } 29 *s = '\0'; 30 return hexbuf; 31 } 32 33 int main(int argc, const char * argv[]) 34 { 35 uint64_t action = 0; 36 OSStatus status = noErr; 37 uint8_t testkey[128] = "\xde\xad\xbe\xef\xde\xad\xbe\xef\xde\xad\xbe\xef\xde\xad\xbe\xef"; 38 xpc_connection_t connection = xpc_connection_create_mach_service(SECURITYD_SERVICE_NAME, NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED); 39 xpc_object_t message = NULL, reply = NULL; 40 41 xpc_connection_set_event_handler(connection, ^(xpc_object_t event) { 42 if (xpc_get_type(event) == XPC_TYPE_ERROR) { 43 printf("XPC error\n"); 44 } 45 }); 46 xpc_connection_resume(connection); 47 48 if (argc < 2) { 49 printf("Usage: securityservicectrl < get | set | stash | login | loginstash | unload | load <uid> >\n"); 50 return 1; 51 } 52 53 if (strcmp(argv[1], "get") == 0) { 54 action = SERVICE_STASH_GET_KEY; 55 printf("Get key\n"); 56 57 } else if (strcmp(argv[1], "set") == 0) { 58 action = SERVICE_STASH_SET_KEY; 59 printf("Set key\n"); 60 61 } else if (strcmp(argv[1], "stash") == 0) { 62 action = SERVICE_STASH_BLOB; 63 printf("Stash\n"); 64 65 } else if (strcmp(argv[1], "login") == 0) { 66 printf("SecKeychainLogin() null passwd\n"); 67 status = SecKeychainLogin((uint32) strlen("test"), "test", 0, NULL); 68 printf("Returned: %i\n", status); 69 return status ? 1 : 0; 70 71 } else if (strcmp(argv[1], "loginstash") == 0) { 72 printf("SecKeychainStash()\n"); 73 status = SecKeychainStash(); 74 printf("Returned: %i\n", status); 75 return status ? 1 : 0; 76 77 } else if (strcmp(argv[1], "unload") == 0) { 78 return service_client_kb_unload(NULL); 79 } else if (strcmp(argv[1], "load") == 0) { 80 require_action(argc == 3, done, printf("missing <uid>\n")); 81 uid_t uid = atoi(argv[2]); 82 return service_client_kb_load_uid(uid); 83 } else { 84 printf("%s not known\n", argv[1]); 85 return 1; 86 } 87 88 // Send 89 message = xpc_dictionary_create(NULL, NULL, 0); 90 xpc_dictionary_set_uint64(message, SERVICE_XPC_REQUEST, action); 91 92 if (action == SERVICE_STASH_SET_KEY) 93 xpc_dictionary_set_data(message, SERVICE_XPC_KEY, testkey, 16); 94 95 reply = xpc_connection_send_message_with_reply_sync(connection, message); 96 require_action(reply != NULL, done, status = -1); 97 require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = -1); 98 99 if (action == SERVICE_STASH_GET_KEY) { 100 size_t len = 0; 101 const uint8_t *keydata = xpc_dictionary_get_data(reply, SERVICE_XPC_KEY, &len); 102 if (keydata) { 103 char buf[sizeof(testkey) + 1]; 104 printf("\tkey = %s\n", hextostr(keydata, len > sizeof(testkey) ? sizeof(testkey) : len, buf)); 105 } 106 } 107 108 status = (OSStatus)xpc_dictionary_get_int64(reply, SERVICE_XPC_RC); 109 110 done: 111 if (message) 112 xpc_release(message); 113 if (reply) 114 xpc_release(reply); 115 if (connection) 116 xpc_release(connection); 117 118 printf("Returned: %i\n", status); 119 120 return status ? 1 : 0; 121 } 122