bool xpcEngineControl(const char *control) { Message msg("control"); xpc_dictionary_set_string(msg, "control", control); msg.send(); return true; }
int main(int argc, char *argv[]) { xpc_connection_t conn; if (argc < 2) { fprintf(stderr, "Usage: %s <mach service name>\n", argv[0]); return (1); } conn = xpc_connection_create_mach_service(argv[1], NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER); xpc_connection_set_event_handler(conn, ^(xpc_object_t peer) { printf("New connection, peer=%p\n", peer); xpc_connection_set_event_handler(peer, ^(xpc_object_t event) { if (event == XPC_ERROR_CONNECTION_INVALID) { printf("Connection closed by remote end\n"); return; } if (xpc_get_type(event) != XPC_TYPE_DICTIONARY) { printf("Received something else than a dictionary!\n"); return; } printf("Message received: %p\n", event); printf("%s\n", xpc_copy_description(event)); xpc_object_t resp = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(resp, "foo", "bar"); xpc_connection_send_message(peer, resp); });
static void xpcEventHandler(xpc_connection_t connection, xpc_object_t event) { syslog(LOG_NOTICE, "received event in helper"); xpc_type_t type = xpc_get_type(event); if (type == XPC_TYPE_ERROR) { if (event == XPC_ERROR_CONNECTION_INVALID) { // the client process on the other end of the connection has either // crashed or cancelled the connection. After receiving this error, // the connection is in an invalid state, and you do not need to // call xpc_connection_cancel(). Just tear down any associated state // here. } else if (event == XPC_ERROR_TERMINATION_IMMINENT) { // handle per-connection termination cleanup. } } else { xpc_connection_t remote = xpc_dictionary_get_remote_connection(event); const char* command = xpc_dictionary_get_string(event, "request"); syslog(LOG_NOTICE, "received command in helper: %s", command); system(command); xpc_object_t reply = xpc_dictionary_create_reply(event); xpc_dictionary_set_string(reply, "reply", "command has been executed"); xpc_connection_send_message(remote, reply); xpc_release(reply); } }
static xpc_object_t auth_item_copy_auth_item_xpc(auth_item_t item) { xpc_object_t xpc_data = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(xpc_data, AUTH_XPC_ITEM_NAME, item->data.name); if (item->data.value) { xpc_dictionary_set_data(xpc_data, AUTH_XPC_ITEM_VALUE, item->data.value, item->data.valueLength); } xpc_dictionary_set_uint64(xpc_data, AUTH_XPC_ITEM_FLAGS, item->data.flags); xpc_dictionary_set_uint64(xpc_data, AUTH_XPC_ITEM_TYPE, item->type); return xpc_data; }
CFDictionaryRef xpcEngineUpdate(CFTypeRef target, uint flags, CFDictionaryRef context) { Message msg("update"); // target can be NULL, a CFURLRef, a SecRequirementRef, or a CFNumberRef if (target) { if (CFGetTypeID(target) == CFNumberGetTypeID()) xpc_dictionary_set_uint64(msg, "rule", cfNumber<int64_t>(CFNumberRef(target))); else if (CFGetTypeID(target) == CFURLGetTypeID()) xpc_dictionary_set_string(msg, "url", cfString(CFURLRef(target)).c_str()); else if (CFGetTypeID(target) == SecRequirementGetTypeID()) { CFRef<CFDataRef> data; MacOSError::check(SecRequirementCopyData(SecRequirementRef(target), kSecCSDefaultFlags, &data.aref())); xpc_dictionary_set_data(msg, "requirement", CFDataGetBytePtr(data), CFDataGetLength(data)); } else MacOSError::throwMe(errSecCSInvalidObjectRef); } xpc_dictionary_set_int64(msg, "flags", flags); CFRef<CFMutableDictionaryRef> ctx = makeCFMutableDictionary(); if (context) CFDictionaryApplyFunction(context, copyCFDictionary, ctx); AuthorizationRef localAuthorization = NULL; if (CFDictionaryGetValue(ctx, kSecAssessmentUpdateKeyAuthorization) == NULL) { // no caller-provided authorization MacOSError::check(AuthorizationCreate(NULL, NULL, kAuthorizationFlagDefaults, &localAuthorization)); AuthorizationExternalForm extForm; MacOSError::check(AuthorizationMakeExternalForm(localAuthorization, &extForm)); CFDictionaryAddValue(ctx, kSecAssessmentUpdateKeyAuthorization, CFTempData(&extForm, sizeof(extForm))); } CFRef<CFDataRef> contextData = makeCFData(CFDictionaryRef(ctx)); xpc_dictionary_set_data(msg, "context", CFDataGetBytePtr(contextData), CFDataGetLength(contextData)); msg.send(); if (localAuthorization) AuthorizationFree(localAuthorization, kAuthorizationFlagDefaults); if (int64_t error = xpc_dictionary_get_int64(msg, "error")) MacOSError::throwMe(error); size_t resultLength; const void *resultData = xpc_dictionary_get_data(msg, "result", &resultLength); return makeCFDictionaryFrom(resultData, resultLength); }
void xpcEngineAssess(CFURLRef path, uint flags, CFDictionaryRef context, CFMutableDictionaryRef result) { Message msg("assess"); xpc_dictionary_set_string(msg, "path", cfString(path).c_str()); xpc_dictionary_set_int64(msg, "flags", flags); CFRef<CFMutableDictionaryRef> ctx = makeCFMutableDictionary(); if (context) CFDictionaryApplyFunction(context, copyCFDictionary, ctx); CFRef<CFDataRef> contextData = makeCFData(CFDictionaryRef(ctx)); xpc_dictionary_set_data(msg, "context", CFDataGetBytePtr(contextData), CFDataGetLength(contextData)); msg.send(); if (int64_t error = xpc_dictionary_get_int64(msg, "error")) MacOSError::throwMe(error); size_t resultLength; const void *resultData = xpc_dictionary_get_data(msg, "result", &resultLength); CFRef<CFDictionaryRef> resultDict = makeCFDictionaryFrom(resultData, resultLength); CFDictionaryApplyFunction(resultDict, copyCFDictionary, result); CFDictionaryAddValue(result, CFSTR("assessment:remote"), kCFBooleanTrue); }
Message(const char *function) { init(); obj = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(obj, "function", function); }