3 // securitydservicectrl
5 // Created by Wade Benson on 12/2/12.
6 // Copyright (c) 2012 Apple. All rights reserved.
9 #include "securityd_service.h"
10 #include "securityd_service_client.h"
14 #include <dispatch/dispatch.h>
15 #include <AssertMacros.h>
16 #include <CoreFoundation/CoreFoundation.h>
17 #include <Security/SecKeychainPriv.h>
20 hextostr(const uint8_t *buf
, size_t len
, char *hexbuf
)
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];
33 int main(int argc
, const char * argv
[])
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
;
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");
46 xpc_connection_resume(connection
);
49 printf("Usage: securityservicectrl < get | set | stash | login | loginstash | unload | load <uid> >\n");
53 if (strcmp(argv
[1], "get") == 0) {
54 action
= SERVICE_STASH_GET_KEY
;
57 } else if (strcmp(argv
[1], "set") == 0) {
58 action
= SERVICE_STASH_SET_KEY
;
61 } else if (strcmp(argv
[1], "stash") == 0) {
62 action
= SERVICE_STASH_BLOB
;
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;
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;
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
);
84 printf("%s not known\n", argv
[1]);
89 message
= xpc_dictionary_create(NULL
, NULL
, 0);
90 xpc_dictionary_set_uint64(message
, SERVICE_XPC_REQUEST
, action
);
92 if (action
== SERVICE_STASH_SET_KEY
)
93 xpc_dictionary_set_data(message
, SERVICE_XPC_KEY
, testkey
, 16);
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);
99 if (action
== SERVICE_STASH_GET_KEY
) {
101 const uint8_t *keydata
= xpc_dictionary_get_data(reply
, SERVICE_XPC_KEY
, &len
);
103 char buf
[sizeof(testkey
) + 1];
104 printf("\tkey = %s\n", hextostr(keydata
, len
> sizeof(testkey
) ? sizeof(testkey
) : len
, buf
));
108 status
= (OSStatus
)xpc_dictionary_get_int64(reply
, SERVICE_XPC_RC
);
112 xpc_release(message
);
116 xpc_release(connection
);
118 printf("Returned: %i\n", status
);
120 return status
? 1 : 0;