mirror of
https://github.com/darlinghq/darling-libxpc.git
synced 2024-11-23 11:49:42 +00:00
Implement some stubs and store remote credentials for connections
Also uncomment some code for pipes (I had commented it out during testing)
This commit is contained in:
parent
90b934b336
commit
b91537684e
@ -8,6 +8,8 @@
|
|||||||
#include <xpc/launchd.h>
|
#include <xpc/launchd.h>
|
||||||
#include <xpc/private/pipe.h>
|
#include <xpc/private/pipe.h>
|
||||||
#include <xpc/private/endpoint.h>
|
#include <xpc/private/endpoint.h>
|
||||||
|
#include <xpc/private/mach_send.h>
|
||||||
|
#include <xpc/private/mach_recv.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
10
include/xpc/private/mach_recv.h
Normal file
10
include/xpc/private/mach_recv.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _XPC_PRIVATE_MACH_RECV_H_
|
||||||
|
#define _XPC_PRIVATE_MACH_RECV_H_
|
||||||
|
|
||||||
|
#include <xpc/xpc.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
|
||||||
|
xpc_object_t xpc_mach_recv_create(mach_port_t recv);
|
||||||
|
mach_port_t xpc_mach_recv_extract_right(xpc_object_t xrecv);
|
||||||
|
|
||||||
|
#endif // _XPC_PRIVATE_MACH_RECV_H_
|
14
include/xpc/private/mach_send.h
Normal file
14
include/xpc/private/mach_send.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef _XPC_PRIVATE_MACH_SEND_H_
|
||||||
|
#define _XPC_PRIVATE_MACH_SEND_H_
|
||||||
|
|
||||||
|
#include <xpc/xpc.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
|
||||||
|
xpc_object_t xpc_mach_send_create(mach_port_t send);
|
||||||
|
xpc_object_t xpc_mach_send_create_with_disposition(mach_port_t send, unsigned int disposition);
|
||||||
|
mach_port_t xpc_mach_send_copy_right(xpc_object_t xsend);
|
||||||
|
|
||||||
|
mach_port_t xpc_mach_send_get_right(xpc_object_t xsend);
|
||||||
|
mach_port_t xpc_mach_send_extract_right(xpc_object_t xsend);
|
||||||
|
|
||||||
|
#endif // _XPC_PRIVATE_MACH_SEND_H_
|
@ -58,6 +58,9 @@ struct xpc_connection_s {
|
|||||||
bool activated;
|
bool activated;
|
||||||
pthread_rwlock_t server_peers_lock;
|
pthread_rwlock_t server_peers_lock;
|
||||||
xpc_genarr_connection_t server_peers;
|
xpc_genarr_connection_t server_peers;
|
||||||
|
pthread_rwlock_t remote_credentials_lock;
|
||||||
|
|
||||||
|
audit_token_t remote_credentials;
|
||||||
|
|
||||||
//
|
//
|
||||||
// mutable and lock-free
|
// mutable and lock-free
|
||||||
@ -139,6 +142,9 @@ struct xpc_connection_s {
|
|||||||
- (void)sendMessage: (XPC_CLASS(dictionary)*)message queue: (dispatch_queue_t)queue withReply: (xpc_handler_t)handler;
|
- (void)sendMessage: (XPC_CLASS(dictionary)*)message queue: (dispatch_queue_t)queue withReply: (xpc_handler_t)handler;
|
||||||
- (xpc_object_t)sendMessageWithSynchronousReply: (XPC_CLASS(dictionary)*)message;
|
- (xpc_object_t)sendMessageWithSynchronousReply: (XPC_CLASS(dictionary)*)message;
|
||||||
|
|
||||||
|
- (void)setRemoteCredentials: (audit_token_t*)token;
|
||||||
|
- (void)copyRemoteCredentials: (audit_token_t*)outToken;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif // _XPC_OBJECTS_CONNECTION_H_
|
#endif // _XPC_OBJECTS_CONNECTION_H_
|
||||||
|
@ -125,6 +125,15 @@ static bool handle_send_result(dispatch_mach_msg_t message, dispatch_mach_reason
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static audit_token_t* get_audit_token(mach_msg_header_t* header) {
|
||||||
|
audit_token_t* token = NULL;
|
||||||
|
mach_msg_trailer_t* trailer = (mach_msg_trailer_t *)((char*)header + round_msg(header->msgh_size));
|
||||||
|
if (trailer->msgh_trailer_type == MACH_MSG_TRAILER_FORMAT_0 && trailer->msgh_trailer_size >= sizeof(mach_msg_audit_trailer_t)) {
|
||||||
|
token = &((mach_msg_audit_trailer_t*)trailer)->msgh_audit;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
};
|
||||||
|
|
||||||
static void dispatch_mach_handler(void* context, dispatch_mach_reason_t reason, dispatch_mach_msg_t message, mach_error_t error) {
|
static void dispatch_mach_handler(void* context, dispatch_mach_reason_t reason, dispatch_mach_msg_t message, mach_error_t error) {
|
||||||
XPC_CLASS(connection)* self = context;
|
XPC_CLASS(connection)* self = context;
|
||||||
XPC_THIS_DECL(connection);
|
XPC_THIS_DECL(connection);
|
||||||
@ -140,6 +149,7 @@ static void dispatch_mach_handler(void* context, dispatch_mach_reason_t reason,
|
|||||||
mach_port_t sendPort = MACH_PORT_NULL;
|
mach_port_t sendPort = MACH_PORT_NULL;
|
||||||
mach_port_t receivePort = MACH_PORT_NULL;
|
mach_port_t receivePort = MACH_PORT_NULL;
|
||||||
XPC_CLASS(connection)* serverPeer = nil;
|
XPC_CLASS(connection)* serverPeer = nil;
|
||||||
|
audit_token_t* token = NULL;
|
||||||
|
|
||||||
if (header->msgh_id != XPC_MSGH_ID_CHECKIN) {
|
if (header->msgh_id != XPC_MSGH_ID_CHECKIN) {
|
||||||
xpc_log(XPC_LOG_NOTICE, "server connection received non-checkin message");
|
xpc_log(XPC_LOG_NOTICE, "server connection received non-checkin message");
|
||||||
@ -147,6 +157,8 @@ static void dispatch_mach_handler(void* context, dispatch_mach_reason_t reason,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
token = get_audit_token(header);
|
||||||
|
|
||||||
[message retain]; // because the deserializer consumes a reference on the message
|
[message retain]; // because the deserializer consumes a reference on the message
|
||||||
deserializer = [[[XPC_CLASS(deserializer) alloc] initWithoutHeaderWithMessage: message] autorelease];
|
deserializer = [[[XPC_CLASS(deserializer) alloc] initWithoutHeaderWithMessage: message] autorelease];
|
||||||
|
|
||||||
@ -165,11 +177,15 @@ static void dispatch_mach_handler(void* context, dispatch_mach_reason_t reason,
|
|||||||
}
|
}
|
||||||
|
|
||||||
serverPeer = [[XPC_CLASS(connection) alloc] initAsServerPeerForServer: self sendPort: sendPort receivePort: receivePort];
|
serverPeer = [[XPC_CLASS(connection) alloc] initAsServerPeerForServer: self sendPort: sendPort receivePort: receivePort];
|
||||||
|
if (token) {
|
||||||
|
[serverPeer setRemoteCredentials: token];
|
||||||
|
}
|
||||||
[self addServerPeer: serverPeer]; // takes ownership of the server peer connection
|
[self addServerPeer: serverPeer]; // takes ownership of the server peer connection
|
||||||
|
|
||||||
this->event_handler(serverPeer);
|
this->event_handler(serverPeer);
|
||||||
} else {
|
} else {
|
||||||
XPC_CLASS(dictionary)* dict = nil;
|
XPC_CLASS(dictionary)* dict = nil;
|
||||||
|
audit_token_t* token = NULL;
|
||||||
|
|
||||||
if (header->msgh_id != XPC_MSGH_ID_MESSAGE) {
|
if (header->msgh_id != XPC_MSGH_ID_MESSAGE) {
|
||||||
xpc_log(XPC_LOG_NOTICE, "peer connection received non-normal message in normal event handler");
|
xpc_log(XPC_LOG_NOTICE, "peer connection received non-normal message in normal event handler");
|
||||||
@ -177,6 +193,12 @@ static void dispatch_mach_handler(void* context, dispatch_mach_reason_t reason,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
token = get_audit_token(header);
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
[self setRemoteCredentials: token];
|
||||||
|
}
|
||||||
|
|
||||||
[message retain]; // because the deserializer consumes a reference on the message
|
[message retain]; // because the deserializer consumes a reference on the message
|
||||||
dict = [XPC_CLASS(deserializer) process: message];
|
dict = [XPC_CLASS(deserializer) process: message];
|
||||||
dict.associatedConnection = self;
|
dict.associatedConnection = self;
|
||||||
@ -306,11 +328,18 @@ static void dmxh_async_reply_handler(void* self_context, dispatch_mach_reason_t
|
|||||||
xpc_object_t result = NULL;
|
xpc_object_t result = NULL;
|
||||||
mach_msg_header_t* header = dispatch_mach_msg_get_msg(message, NULL);
|
mach_msg_header_t* header = dispatch_mach_msg_get_msg(message, NULL);
|
||||||
mach_port_t localPort = header->msgh_local_port;
|
mach_port_t localPort = header->msgh_local_port;
|
||||||
|
audit_token_t* token = NULL;
|
||||||
|
|
||||||
xpc_log(XPC_LOG_DEBUG, "connection %p: async reply handler got event %lu (%s)\n", self, reason, reason_to_string(reason));
|
xpc_log(XPC_LOG_DEBUG, "connection %p: async reply handler got event %lu (%s)\n", self, reason, reason_to_string(reason));
|
||||||
|
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case DISPATCH_MACH_MESSAGE_RECEIVED: {
|
case DISPATCH_MACH_MESSAGE_RECEIVED: {
|
||||||
|
token = get_audit_token(header);
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
[self setRemoteCredentials: token];
|
||||||
|
}
|
||||||
|
|
||||||
[message retain]; // because the deserializer consumes a reference on the message
|
[message retain]; // because the deserializer consumes a reference on the message
|
||||||
result = [XPC_CLASS(deserializer) process: message];
|
result = [XPC_CLASS(deserializer) process: message];
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@ -480,6 +509,7 @@ OS_OBJECT_USES_XREF_DISPOSE();
|
|||||||
|
|
||||||
pthread_rwlock_destroy(&this->activated_lock);
|
pthread_rwlock_destroy(&this->activated_lock);
|
||||||
pthread_rwlock_destroy(&this->server_peers_lock);
|
pthread_rwlock_destroy(&this->server_peers_lock);
|
||||||
|
pthread_rwlock_destroy(&this->remote_credentials_lock);
|
||||||
|
|
||||||
xpc_mach_port_release_send(this->send_port);
|
xpc_mach_port_release_send(this->send_port);
|
||||||
xpc_mach_port_release_send(this->checkin_port);
|
xpc_mach_port_release_send(this->checkin_port);
|
||||||
@ -511,10 +541,16 @@ OS_OBJECT_USES_XREF_DISPOSE();
|
|||||||
|
|
||||||
pthread_rwlock_init(&this->activated_lock, NULL);
|
pthread_rwlock_init(&this->activated_lock, NULL);
|
||||||
pthread_rwlock_init(&this->server_peers_lock, NULL);
|
pthread_rwlock_init(&this->server_peers_lock, NULL);
|
||||||
|
pthread_rwlock_init(&this->remote_credentials_lock, NULL);
|
||||||
|
|
||||||
this->suspension_count = 1;
|
this->suspension_count = 1;
|
||||||
|
|
||||||
xpc_genarr_connection_init(&this->server_peers, true, server_peer_array_item_dtor);
|
xpc_genarr_connection_init(&this->server_peers, true, server_peer_array_item_dtor);
|
||||||
|
|
||||||
|
// fill it with invalid values
|
||||||
|
// the default value of 0 can lead to false positives of root access
|
||||||
|
// (this doesn't matter so much for Darling, but we'll do it anyways)
|
||||||
|
memset(&this->remote_credentials, 0xff, sizeof(audit_token_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// init helper/common init
|
// init helper/common init
|
||||||
@ -905,6 +941,22 @@ error_out:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setRemoteCredentials: (audit_token_t*)token
|
||||||
|
{
|
||||||
|
XPC_THIS_DECL(connection);
|
||||||
|
pthread_rwlock_wrlock(&this->remote_credentials_lock);
|
||||||
|
memcpy(&this->remote_credentials, token, sizeof(audit_token_t));
|
||||||
|
pthread_rwlock_unlock(&this->remote_credentials_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)copyRemoteCredentials: (audit_token_t*)outToken
|
||||||
|
{
|
||||||
|
XPC_THIS_DECL(connection);
|
||||||
|
pthread_rwlock_rdlock(&this->remote_credentials_lock);
|
||||||
|
memcpy(outToken, &this->remote_credentials, sizeof(audit_token_t));
|
||||||
|
pthread_rwlock_unlock(&this->remote_credentials_lock);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1011,27 +1063,53 @@ const char* xpc_connection_get_name(xpc_connection_t xconn) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void audit_token_to_au32(audit_token_t atoken, uid_t* auidp, uid_t* euidp, gid_t* egidp, uid_t* ruidp, gid_t* rgidp, pid_t* pidp, au_asid_t* asidp, au_tid_t* tidp);
|
||||||
|
|
||||||
XPC_EXPORT
|
XPC_EXPORT
|
||||||
uid_t xpc_connection_get_euid(xpc_connection_t xconn) {
|
uid_t xpc_connection_get_euid(xpc_connection_t xconn) {
|
||||||
xpc_stub();
|
TO_OBJC_CHECKED(connection, xconn, conn) {
|
||||||
|
audit_token_t token;
|
||||||
|
uid_t euid;
|
||||||
|
[conn copyRemoteCredentials: &token];
|
||||||
|
audit_token_to_au32(token, NULL, &euid, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
return euid;
|
||||||
|
}
|
||||||
return UID_MAX;
|
return UID_MAX;
|
||||||
};
|
};
|
||||||
|
|
||||||
XPC_EXPORT
|
XPC_EXPORT
|
||||||
gid_t xpc_connection_get_egid(xpc_connection_t xconn) {
|
gid_t xpc_connection_get_egid(xpc_connection_t xconn) {
|
||||||
xpc_stub();
|
TO_OBJC_CHECKED(connection, xconn, conn) {
|
||||||
|
audit_token_t token;
|
||||||
|
gid_t egid;
|
||||||
|
[conn copyRemoteCredentials: &token];
|
||||||
|
audit_token_to_au32(token, NULL, NULL, &egid, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
return egid;
|
||||||
|
}
|
||||||
return GID_MAX;
|
return GID_MAX;
|
||||||
};
|
};
|
||||||
|
|
||||||
XPC_EXPORT
|
XPC_EXPORT
|
||||||
pid_t xpc_connection_get_pid(xpc_connection_t xconn) {
|
pid_t xpc_connection_get_pid(xpc_connection_t xconn) {
|
||||||
xpc_stub();
|
TO_OBJC_CHECKED(connection, xconn, conn) {
|
||||||
|
audit_token_t token;
|
||||||
|
pid_t pid;
|
||||||
|
[conn copyRemoteCredentials: &token];
|
||||||
|
audit_token_to_au32(token, NULL, NULL, NULL, NULL, NULL, &pid, NULL, NULL);
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
XPC_EXPORT
|
XPC_EXPORT
|
||||||
au_asid_t xpc_connection_get_asid(xpc_connection_t xconn) {
|
au_asid_t xpc_connection_get_asid(xpc_connection_t xconn) {
|
||||||
xpc_stub();
|
TO_OBJC_CHECKED(connection, xconn, conn) {
|
||||||
|
audit_token_t token;
|
||||||
|
au_asid_t asid;
|
||||||
|
[conn copyRemoteCredentials: &token];
|
||||||
|
audit_token_to_au32(token, NULL, NULL, NULL, NULL, NULL, NULL, &asid, NULL);
|
||||||
|
return asid;
|
||||||
|
}
|
||||||
return AU_ASSIGN_ASID;
|
return AU_ASSIGN_ASID;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1127,7 +1205,9 @@ void xpc_connection_enable_termination_imminent_event(xpc_connection_t xconn) {
|
|||||||
|
|
||||||
XPC_EXPORT
|
XPC_EXPORT
|
||||||
void xpc_connection_get_audit_token(xpc_connection_t xconn, audit_token_t* out_token) {
|
void xpc_connection_get_audit_token(xpc_connection_t xconn, audit_token_t* out_token) {
|
||||||
xpc_stub();
|
TO_OBJC_CHECKED(connection, xconn, conn) {
|
||||||
|
[conn copyRemoteCredentials: out_token];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
XPC_EXPORT
|
XPC_EXPORT
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#import <xpc/xpc.h>
|
#import <xpc/xpc.h>
|
||||||
#import <launch.h>
|
#import <launch.h>
|
||||||
#import <xpc/util.h>
|
#import <xpc/util.h>
|
||||||
|
#import <xpc/private.h>
|
||||||
|
|
||||||
//
|
//
|
||||||
// private C API
|
// private C API
|
||||||
@ -186,10 +187,69 @@ char* launch_version_for_user_service_4coresim(const char* name) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
xpc_object_t ld2xpc(launch_data_t data);
|
||||||
|
|
||||||
|
static void launch_data_dict_iterator(launch_data_t value, const char* key, void* context) {
|
||||||
|
xpc_object_t* result = context;
|
||||||
|
xpc_object_t xpc_value = ld2xpc(value);
|
||||||
|
xpc_dictionary_set_value(*result, key, xpc_value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// this function isn't present in the official libxpc,
|
||||||
|
// so i'm guessing that it's actually an inline function
|
||||||
XPC_EXPORT
|
XPC_EXPORT
|
||||||
xpc_object_t ld2xpc(launch_data_t data) {
|
xpc_object_t ld2xpc(launch_data_t data) {
|
||||||
xpc_stub();
|
xpc_object_t result = NULL;
|
||||||
return NULL;
|
|
||||||
|
switch (launch_data_get_type(data)) {
|
||||||
|
case LAUNCH_DATA_DICTIONARY: {
|
||||||
|
result = xpc_dictionary_create(NULL, NULL, 0);
|
||||||
|
launch_data_dict_iterate(data, launch_data_dict_iterator, &result);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case LAUNCH_DATA_ARRAY: {
|
||||||
|
size_t length = launch_data_array_get_count(data);
|
||||||
|
result = xpc_array_create(NULL, 0);
|
||||||
|
for (size_t i = 0; i < length; ++i) {
|
||||||
|
xpc_array_append_value(result, ld2xpc(launch_data_array_get_index(data, i)));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case LAUNCH_DATA_FD: {
|
||||||
|
result = xpc_fd_create(launch_data_get_fd(data));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case LAUNCH_DATA_INTEGER: {
|
||||||
|
result = xpc_int64_create(launch_data_get_integer(data));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case LAUNCH_DATA_REAL: {
|
||||||
|
result = xpc_double_create(launch_data_get_real(data));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case LAUNCH_DATA_BOOL: {
|
||||||
|
result = xpc_bool_create(launch_data_get_bool(data));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case LAUNCH_DATA_STRING: {
|
||||||
|
result = xpc_string_create(launch_data_get_string(data));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case LAUNCH_DATA_OPAQUE: {
|
||||||
|
result = xpc_data_create(launch_data_get_opaque(data), launch_data_get_opaque_size(data));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case LAUNCH_DATA_ERRNO: {
|
||||||
|
result = xpc_int64_create(launch_data_get_errno(data));
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case LAUNCH_DATA_MACHPORT: {
|
||||||
|
// NOTE: i have verified that the contained port does in fact always hold a receive right, so this is the right XPC class to use
|
||||||
|
result = xpc_mach_recv_create(launch_data_get_machport(data));
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
XPC_EXPORT
|
XPC_EXPORT
|
||||||
|
52
src/pipe.m
52
src/pipe.m
@ -99,37 +99,37 @@ XPC_CLASS_HEADER(pipe);
|
|||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case MACH_RCV_INVALID_NAME: /* fallthrough */
|
case MACH_RCV_INVALID_NAME: /* fallthrough */
|
||||||
case MACH_RCV_IN_SET: /* fallthrough */
|
case MACH_RCV_IN_SET: /* fallthrough */
|
||||||
case MACH_RCV_TIMED_OUT: /* fallthrough */
|
case MACH_RCV_TIMED_OUT: /* fallthrough */
|
||||||
case MACH_RCV_INTERRUPTED: /* fallthrough */
|
case MACH_RCV_INTERRUPTED: /* fallthrough */
|
||||||
case MACH_RCV_PORT_DIED: /* fallthrough */
|
case MACH_RCV_PORT_DIED: /* fallthrough */
|
||||||
case MACH_RCV_PORT_CHANGED: {
|
case MACH_RCV_PORT_CHANGED: {
|
||||||
// nothing happened to the message
|
// nothing happened to the message
|
||||||
|
|
||||||
status = EIO;
|
status = EIO;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MACH_RCV_HEADER_ERROR: /* fallthrough */
|
case MACH_RCV_HEADER_ERROR: /* fallthrough */
|
||||||
case MACH_RCV_INVALID_NOTIFY: {
|
case MACH_RCV_INVALID_NOTIFY: {
|
||||||
// message was dequeued and destroyed
|
// message was dequeued and destroyed
|
||||||
|
|
||||||
status = EIO;
|
status = EIO;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MACH_RCV_TOO_LARGE: {
|
case MACH_RCV_TOO_LARGE: {
|
||||||
status = EAGAIN;
|
status = EAGAIN;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MACH_RCV_BODY_ERROR: /* fallthrough */
|
case MACH_RCV_BODY_ERROR: /* fallthrough */
|
||||||
case MACH_RCV_INVALID_DATA: {
|
case MACH_RCV_INVALID_DATA: {
|
||||||
// message was received
|
// message was received
|
||||||
|
|
||||||
status = EIO;
|
status = EIO;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MACH_MSG_SUCCESS: {
|
case MACH_MSG_SUCCESS: {
|
||||||
status = 0;
|
status = 0;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -378,7 +378,7 @@ out:
|
|||||||
|
|
||||||
self = [self initWithPort: servicePort flags: flags];
|
self = [self initWithPort: servicePort flags: flags];
|
||||||
|
|
||||||
//xpc_mach_port_release_send(servicePort);
|
xpc_mach_port_release_send(servicePort);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -390,12 +390,10 @@ out:
|
|||||||
|
|
||||||
pthread_rwlock_init(&this->state_lock, NULL);
|
pthread_rwlock_init(&this->state_lock, NULL);
|
||||||
|
|
||||||
/*
|
|
||||||
if (xpc_mach_port_retain_send(port) != KERN_SUCCESS) {
|
if (xpc_mach_port_retain_send(port) != KERN_SUCCESS) {
|
||||||
[self release];
|
[self release];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
this->checkin_port = port;
|
this->checkin_port = port;
|
||||||
this->send_port = xpc_mach_port_create_send_receive();
|
this->send_port = xpc_mach_port_create_send_receive();
|
||||||
|
@ -34,6 +34,7 @@ static void handle_server_peer_error(xpc_connection_t connection, xpc_object_t e
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void handle_new_connection(xpc_connection_t connection) {
|
static void handle_new_connection(xpc_connection_t connection) {
|
||||||
|
server_peer_log("got new client with pid=%d, euid=%d, and egid=%d", xpc_connection_get_pid(connection), xpc_connection_get_euid(connection), xpc_connection_get_egid(connection));
|
||||||
xpc_connection_set_event_handler(connection, ^(xpc_object_t object) {
|
xpc_connection_set_event_handler(connection, ^(xpc_object_t object) {
|
||||||
xpc_type_t obj_type = xpc_get_type(object);
|
xpc_type_t obj_type = xpc_get_type(object);
|
||||||
if (obj_type == (xpc_type_t)XPC_TYPE_DICTIONARY) {
|
if (obj_type == (xpc_type_t)XPC_TYPE_DICTIONARY) {
|
||||||
|
Loading…
Reference in New Issue
Block a user