Post

Replies

Boosts

Views

Activity

Testing XPC Code With an Anonymous Listener using Low Level C APIs
I have implemented a XPC server using C APIs. I want to write unit tests for it. I came across the following links that use Swift APIs- Testing and Debugging XPC Code With an Anonymous Listener TN3113 I have tried to write anonymous listener code and the client code in the same file, using C APIs- #include <unistd.h> #include <syslog.h> #include <pthread.h> #include <stdio.h> #include <xpc/xpc.h> #include <xpc/connection.h> #include <CoreFoundation/CoreFoundation.h> static void Anon_Client_Connection_Handler(xpc_connection_t connection, xpc_object_t clientMessage) { const char *description = xpc_copy_description(clientMessage); printf("Event received - %s\n", description); free((void *)description); xpc_type_t type = xpc_get_type(clientMessage); if (type == XPC_TYPE_ERROR) { if (clientMessage == XPC_ERROR_CONNECTION_INVALID) printf("Client_Connection_Handler received invalid connection n"); else if (clientMessage == XPC_ERROR_TERMINATION_IMMINENT) printf("Client_Connection_Handler received termination notice n"); } else { const char *clientMsg = xpc_dictionary_get_string(clientMessage, "message"); printf("Received from client: %s ", clientMsg); } } static void Anon_Listener_Connection_Handler(xpc_connection_t connection) { printf("Anon_Listener_Connection_Handler called, setting up event handler \n"); xpc_connection_set_event_handler(connection, ^(xpc_object_t clientMessage) { printf("Processing the connection! \n"); Anon_Client_Connection_Handler(connection, clientMessage); }); xpc_connection_resume(connection); } int main(int argc, const char *argv[]) { xpc_connection_t anon_listener = xpc_connection_create(NULL, NULL); xpc_connection_set_event_handler(anon_listener, ^(xpc_object_t clientConnection) { printf("Client tried to connect \n"); Anon_Listener_Connection_Handler(clientConnection); }); xpc_connection_resume(anon_listener); printf("\nINFO Anonymous connection resumed"); xpc_object_t anon_endpoint = xpc_endpoint_create(anon_listener); xpc_connection_t clientConnection = xpc_connection_create_from_endpoint(anon_endpoint); xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(message, "message", "client's message"); xpc_connection_send_message_with_reply(clientConnection, message, dispatch_get_main_queue(), ^(xpc_object_t event) { printf("\nINFO inside reply"); const char *description = xpc_copy_description(event); printf("\nINFO %s",description); free((void *)description); }); xpc_release(message); xpc_release(anon_listener); printf("\nINFO Releasing listener"); xpc_release(anon_endpoint); printf("\nINFO Releasing endpoint"); // dispatch_main(); return 0; } and this is the output I get INFO Anonymous connection resumed INFO Releasing listener INFO Releasing endpoint I am not able to connect to the client and exchange messages. Where am I going wrong?
1
1
137
1d
Do i need to free memory for C strings obtained from xpc_dictionary_get_string?
I am using C APIs for XPC communication. When my XPC server gets a xpc_dictionary as a message, I use xpc_dictionary_get_string to get the string which is of type const char*. Afterwards, when I try to free up the memory for the string, I get an error. I could not find any details on why this happens. Does XPC handle the lifecycle of these C strings ? I did some tests to see the behaviour. The following code snippet prints a string temp before and after releasing the dictionary memory. char* string = "dummy-string"; xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(dict, "str", string); const char* temp = xpc_dictionary_get_string(reply, "str"); printf("temp before release: %s\n", temp); xpc_release(reply); printf("temp after release: %s\n", temp); output: # temp before release: dummy-string # temp after release: I tried to free the variable temp before and after releasing dict . char* string = "dummy-string"; xpc_object_t dict = xpc_dictionary_create(NULL, NULL, 0); xpc_dictionary_set_string(dict, "str", string); const char* temp = xpc_dictionary_get_string(dict, "str"); printf("temp before release: %s\n", temp); free((void *)temp); // case 1 xpc_release(dict); // free((void *)temp); // case 2 printf("temp after release: %s\n", temp); in both the cases i got the output: # temp before release: dummy-string # app(18502,0x1f02fc840) malloc: Double free of object 0x145004a20 # app(18502,0x1f02fc840) malloc: *** set a breakpoint in malloc_error_break to debug # SIGABRT: abort # PC=0x186953720 m=0 sigcode=0 # signal arrived during cgo execution # ... # ...
2
0
247
1w
Performance Implications of XPC polling
On my MAC, I have a XPC server running as a daemon. It also checks the clients for codesigning requirements. I have multiple clients(2 or more). Each of these clients periodically(say 5 seconds) poll the XPC server to ask for a particular data. I want to understand how the performance of my MAC will be affected when multiple XPC clients keep polling a XPC server.
4
0
289
4w
How does xpc_connection_set_peer_code_signing_requirement work?
I have created a XPC server and client using C APIs. I want to ensure that I trust the client, so I want to have a codesigning requirement on the server side, something like - xpc_connection_set_peer_code_signing_requirement(listener, "anchor apple generic and certificate leaf[subject.OU] = \"1234567\"") This checks if the client code was signed by a code-signing-identity issued by Apple and that the teamID in the leaf certificate is 1234567. My questions are- Is using teamID as a signing requirement enough? What else can I add to this requirement to make it more secure? How does xpc_connection_set_peer_code_signing_requirement work internally? Does it do any cryptographic operations to verify the clients signature or does it simply do string matching on the teamID? Is there a way actually verify the clients signature(cryptographically) before establishing a connection with the server? (so we know the client is who he claims to be)
2
0
406
Jan ’25
Using protocols with XPC C API instead of dictionaries for sending and receiving messages
I have followed this post for creating a Launch Agent that provides an XPC service on macOS using Swift- post link - https://rderik.com/blog/creating-a-launch-agent-that-provides-an-xpc-service-on-macos/ In the swift code the interface of the XPC service is defined by protocols which makes the code nice and neat. I want to implement the XPC service using C APIs for XPC, and C APIs send and receive messages using dictionaries, which need manual handling with conditional statements. I want to know if its possible to go with the protocol based approach with C APIs.
2
0
299
Jan ’25