// // Your standard server-side xpc main // int main (int argc, char * const argv[]) { const char *name = serviceName; if (const char *s = getenv("SYSPOLICYNAME")) name = s; // extern char *optarg; extern int optind; int arg; while ((arg = getopt(argc, argv, "v")) != -1) switch (arg) { case 'v': break; case '?': usage(); } if (optind < argc) usage(); dispatch_queue_t queue = dispatch_queue_create("server", 0); xpc_connection_t service = xpc_connection_create_mach_service(name, queue, XPC_CONNECTION_MACH_SERVICE_LISTENER /* | XPC_CONNECTION_MACH_SERVICE_PRIVILEGED */); xpc_connection_set_event_handler(service, ^(xpc_object_t cmsg) { if (xpc_get_type(cmsg) == XPC_TYPE_CONNECTION) { xpc_connection_t connection = xpc_connection_t(cmsg); syslog(LOG_DEBUG, "Connection from pid %d", xpc_connection_get_pid(connection)); xpc_connection_set_event_handler(connection, ^(xpc_object_t msg) { if (xpc_get_type(msg) == XPC_TYPE_DICTIONARY) { const char *function = xpc_dictionary_get_string(msg, "function"); syslog(LOG_DEBUG, "pid %d requested %s", xpc_connection_get_pid(connection), function); xpc_object_t reply = xpc_dictionary_create_reply(msg); try { if (function == NULL) { xpc_dictionary_set_int64(reply, "error", errSecCSInternalError); } else if (!strcmp(function, "assess")) { doAssess(msg, reply); } else if (!strcmp(function, "update")) { doUpdate(msg, reply); } else if (!strcmp(function, "record")) { doRecord(msg, reply, connection); } else { xpc_dictionary_set_int64(reply, "error", errSecCSInternalError); } } catch (...) { xpc_dictionary_set_int64(reply, "error", errSecCSInternalError); } xpc_connection_send_message(connection, reply); xpc_release(reply); } }); xpc_connection_resume(connection); } else {
__private_extern__ libSC_info_client_t * libSC_info_client_create(dispatch_queue_t q, const char *service_name, const char *service_description) { xpc_connection_t c; libSC_info_client_t *client; #if !TARGET_IPHONE_SIMULATOR const uint64_t flags = XPC_CONNECTION_MACH_SERVICE_PRIVILEGED; #else // !TARGET_IPHONE_SIMULATOR const uint64_t flags = 0; #endif // !TARGET_IPHONE_SIMULATOR if (_has_forked) { return NULL; } client = malloc(sizeof(libSC_info_client_t)); client->active = TRUE; client->service_description = strdup(service_description); client->service_name = strdup(service_name); c = xpc_connection_create_mach_service(service_name, q, flags); xpc_connection_set_event_handler(c, ^(xpc_object_t xobj) { xpc_type_t type; type = xpc_get_type(xobj); if (type == XPC_TYPE_DICTIONARY) { asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: unexpected message", client->service_name); log_xpc_object(" dict = ", xobj); } else if (type == XPC_TYPE_ERROR) { if (xobj == XPC_ERROR_CONNECTION_INVALID) { asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: server not available", client->service_name); client->active = FALSE; } else if (xobj == XPC_ERROR_CONNECTION_INTERRUPTED) { asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "%s: server failed", client->service_name); } else { const char *desc; desc = xpc_dictionary_get_string(xobj, XPC_ERROR_KEY_DESCRIPTION); asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "%s: connection error: %d : %s", client->service_name, xpc_connection_get_pid(c), desc); } } else { asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s: unknown event type : %p", client->service_name, type); } });
void WebProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier) { ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier); for (WebPageProxy* page : m_pageMap.values()) { ASSERT(this == &page->process()); page->processDidFinishLaunching(); } m_webConnection = WebConnectionToWebProcess::create(this); m_processPool->processDidFinishLaunching(this); #if PLATFORM(IOS) xpc_connection_t xpcConnection = connection()->xpcConnection(); ASSERT(xpcConnection); m_throttler.didConnectToProcess(xpc_connection_get_pid(xpcConnection)); #endif }
void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier) { ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier); if (IPC::Connection::identifierIsNull(connectionIdentifier)) { // FIXME: Do better cleanup here. return; } for (unsigned i = 0; i < m_numPendingConnectionRequests; ++i) connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(), 0); m_numPendingConnectionRequests = 0; #if PLATFORM(COCOA) if (m_processPool.processSuppressionEnabled()) setProcessSuppressionEnabled(true); #endif #if PLATFORM(IOS) if (xpc_connection_t connection = this->connection()->xpcConnection()) m_throttler.didConnectToProcess(xpc_connection_get_pid(connection)); #endif }
static void security_auth_peer_event_handler(xpc_connection_t connection, xpc_object_t event) { __block OSStatus status = errAuthorizationDenied; connection_t conn = (connection_t)xpc_connection_get_context(connection); require_action(conn != NULL, done, LOGE("xpc[%i]: process context not found", xpc_connection_get_pid(connection))); CFRetainSafe(conn); 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. LOGV("xpc[%i]: client disconnected", xpc_connection_get_pid(connection)); connection_destory_agents(conn); } else if (event == XPC_ERROR_TERMINATION_IMMINENT) { // Handle per-connection termination cleanup. LOGD("xpc[%i]: per-connection termination", xpc_connection_get_pid(connection)); } } else { assert(type == XPC_TYPE_DICTIONARY); xpc_object_t reply = xpc_dictionary_create_reply(event); require(reply != NULL, done); uint64_t auth_type = xpc_dictionary_get_uint64(event, AUTH_XPC_TYPE); LOGV("xpc[%i]: received message type=%llu", connection_get_pid(conn), auth_type); switch (auth_type) { case AUTHORIZATION_CREATE: status = authorization_create(conn,event,reply); break; case AUTHORIZATION_CREATE_WITH_AUDIT_TOKEN: status = authorization_create_with_audit_token(conn,event,reply); break; case AUTHORIZATION_FREE: status = authorization_free(conn,event,reply); break; case AUTHORIZATION_COPY_RIGHTS: status = authorization_copy_rights(conn,event,reply); break; case AUTHORIZATION_COPY_INFO: status = authorization_copy_info(conn,event,reply); break; case AUTHORIZATION_MAKE_EXTERNAL_FORM: status = authorization_make_external_form(conn,event,reply); break; case AUTHORIZATION_CREATE_FROM_EXTERNAL_FORM: status = authorization_create_from_external_form(conn,event,reply); break; case AUTHORIZATION_RIGHT_GET: status = authorization_right_get(conn,event,reply); break; case AUTHORIZATION_RIGHT_SET: status = authorization_right_set(conn,event,reply); break; case AUTHORIZATION_RIGHT_REMOVE: status = authorization_right_remove(conn,event,reply); break; case SESSION_SET_USER_PREFERENCES: status = session_set_user_preferences(conn,event,reply); break; case AUTHORIZATION_DISMISS: connection_destory_agents(conn); status = errAuthorizationSuccess; break; case AUTHORIZATION_ENABLE_SMARTCARD: status = authorization_enable_smartcard(conn,event,reply); break; case AUTHORIZATION_SETUP: { mach_port_t bootstrap = xpc_dictionary_copy_mach_send(event, AUTH_XPC_BOOTSTRAP); if (!process_set_bootstrap(connection_get_process(conn), bootstrap)) { if (bootstrap != MACH_PORT_NULL) { mach_port_deallocate(mach_task_self(), bootstrap); } } } status = errAuthorizationSuccess; break; #if DEBUG case AUTHORIZATION_DEV: server_dev(); break; #endif default: break; } xpc_dictionary_set_int64(reply, AUTH_XPC_STATUS, status); xpc_connection_send_message(connection, reply); xpc_release(reply); } done: CFReleaseSafe(conn); }