Пример #1
0
STATIC void
__IPMonitorControlDeallocate(CFTypeRef cf)
{
    IPMonitorControlRef control = (IPMonitorControlRef)cf;

    if (control->connection != NULL) {
	xpc_release(control->connection);
    }
    if (control->queue != NULL) {
	xpc_release(control->queue);
    }
    return;
}
Пример #2
0
static void __XPC_Peer_Event_Handler(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_object_t requestMessage = event;
        
        xpc_object_t replyMessage = xpc_dictionary_create_reply(requestMessage);
        
        // Process request and build a reply message.
        __XPC_Fetch_Process_Request(requestMessage, replyMessage);
        
        xpc_connection_send_message(connection, replyMessage);
        xpc_release(replyMessage);
    }
}
Пример #3
0
void Connection::platformInvalidate()
{
    if (!m_isConnected)
        return;

    m_isConnected = false;

    ASSERT(m_sendPort);
    ASSERT(m_receivePort);

    // Unregister our ports.
    m_connectionQueue.unregisterMachPortEventHandler(m_sendPort);
    m_sendPort = MACH_PORT_NULL;

    m_connectionQueue.unregisterMachPortEventHandler(m_receivePort);
    m_receivePort = MACH_PORT_NULL;

    if (m_exceptionPort) {
        m_connectionQueue.unregisterMachPortEventHandler(m_exceptionPort);
        m_exceptionPort = MACH_PORT_NULL;
    }

#if HAVE(XPC)
    if (m_xpcConnection) {
        xpc_release(m_xpcConnection);
        m_xpcConnection = 0;
    }
#endif
}
Пример #4
0
void DNSXRefDeAlloc(DNSXConnRef connRef)
{
    if (connRef == NULL)
    {
        os_log(OS_LOG_DEFAULT, "dns_services: DNSXRefDeAlloc called with NULL DNSXConnRef");
        return;
    }
    
    // Schedule this work on the internal library queue
    dispatch_sync(connRef->lib_q, ^{
        xpc_connection_set_event_handler((connRef)->conn_ref, ^(__unused xpc_object_t event){}); // ignore any more events
        xpc_release(connRef->conn_ref);
        connRef->conn_ref = NULL;
        dispatch_release(connRef->lib_q);
        connRef->lib_q = NULL;
        connRef->AppCallBack = NULL;
        os_log_info(OS_LOG_DEFAULT, "dns_services: DNSXRefDeAlloc successfully DeAllocated conn_ref & lib_q");
        
        dispatch_async((connRef)->client_q, ^{
            dispatch_release(connRef->client_q);
            connRef->client_q = NULL;
            free(connRef);
            os_log_info(OS_LOG_DEFAULT, "dns_services: DNSXRefDeAlloc successfully DeAllocated client_q & freed connRef");
        });
    });
Пример #5
0
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);
	}
}
Пример #6
0
__attribute__((noreturn)) static void
xpc_server_exit(int status)
{
	xpc_connection_cancel(listener);
	xpc_release(listener);
	dispatch_release(serverq);
	exit(status);
}
Пример #7
0
static void
security_auth_event_handler(xpc_connection_t xpc_conn)
{
    connection_t conn = server_register_connection(xpc_conn);
    
    if (conn) {
        xpc_connection_set_context(xpc_conn, conn);
        xpc_connection_set_finalizer_f(xpc_conn, connection_finalizer);
        
        xpc_connection_set_event_handler(xpc_conn, ^(xpc_object_t event) {
            xpc_retain(xpc_conn);
            xpc_retain(event);
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                security_auth_peer_event_handler(xpc_conn, event);
                xpc_release(event);
                xpc_release(xpc_conn);
            });
        });
Пример #8
0
//
// 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 {
Пример #9
0
	void send()
	{
		xpc_object_t reply = xpc_connection_send_message_with_reply_sync(service, obj);
		xpc_release(obj);
		obj = NULL;
		xpc_type_t type = xpc_get_type(reply);
		if (type == XPC_TYPE_DICTIONARY) {
			obj = reply;
			if (int64_t error = xpc_dictionary_get_int64(obj, "error"))
				MacOSError::throwMe(error);
		} else if (type == XPC_TYPE_ERROR) {
			const char *s = xpc_copy_description(reply);
			printf("Error returned: %s\n", s);
			free((char*)s);
			MacOSError::throwMe(errSecCSInternalError);
		} else {
			const char *s = xpc_copy_description(reply);
			printf("Unexpected type of return object: %s\n", s);
			free((char*)s);
		}
	}
Пример #10
0
void ProcessLauncher::didFinishLaunchingProcess(PlatformProcessIdentifier processIdentifier, CoreIPC::Connection::Identifier identifier)
{
    m_processIdentifier = processIdentifier;
    m_isLaunching = false;
    
    if (!m_client) {
        // FIXME: Make Identifier a move-only object and release port rights/connections in the destructor.
#if PLATFORM(MAC)
        if (identifier.port)
            mach_port_mod_refs(mach_task_self(), identifier.port, MACH_PORT_RIGHT_RECEIVE, -1);

#if HAVE(XPC)
        if (identifier.xpcConnection) {
            xpc_release(identifier.xpcConnection);
            identifier.xpcConnection = 0;
        }
#endif
#endif
        return;
    }
    
    m_client->didFinishLaunching(this, identifier);
}
/*****************************************************************************
* HandleTemporaryEventsForService
* -
* This method handles the firing of one shot events. Aka. Events that are
* signaled when a service appears / disappears. They have a temporarly
* signaled state.
*****************************************************************************/
void HandleTemporaryEventsForService(BonjourUserEventsPlugin* plugin, NetBrowserInfo* browser, CFStringRef serviceName, CFMutableDictionaryRef eventsDictionary)
{
    CFArrayRef events = (CFArrayRef)CFDictionaryGetValue(eventsDictionary, browser); // Get events for the browser we passed in.
    CFIndex i;
    CFIndex count;

    if (!events)  // Somehow we have a orphan browser...
        return;

    count = CFArrayGetCount(events);

    // Go thru the events and run filters, notifity if they pass.
    for (i = 0; i < count; ++i)
    {
        CFDictionaryRef eventDict = (CFDictionaryRef)CFArrayGetValueAtIndex(events, i);
        CFStringRef eventServiceName = (CFStringRef)CFDictionaryGetValue(eventDict, sServiceNameKey);
        CFNumberRef token = (CFNumberRef) CFDictionaryGetValue(eventDict, sLaunchdTokenKey);
        CFDictionaryRef dict = (CFDictionaryRef) CFDictionaryGetValue(eventDict, sLaunchdDictKey);

        // Currently we only filter on service name, that makes this as simple as...
        if (!eventServiceName || CFEqual(serviceName, eventServiceName))
        {
            uint64_t tokenUint64;
            // Signal Event: This is edge trigger. When the action has been taken, it will not
            // be remembered anymore.

            asl_log(NULL, NULL, ASL_LEVEL_INFO, "%s:%s HandleTemporaryEventsForService signal\n", sPluginIdentifier, __FUNCTION__);
            CFNumberGetValue(token, kCFNumberLongLongType, &tokenUint64);

            xpc_object_t jobRequest = _CFXPCCreateXPCObjectFromCFObject(dict);

            UserEventAgentFireEvent(plugin->_pluginContext, tokenUint64, jobRequest);
            xpc_release(jobRequest);
        }
    }
}
Пример #12
0
	~Message()
	{
		if (obj)
			xpc_release(obj);
	}
Пример #13
0
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);
}