]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SNHelper.c
configd-1061.0.2.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SNHelper.c
1 /*
2 * Copyright (c) 2013-2015 Apple Inc.
3 * All rights reserved.
4 */
5 #include <errno.h>
6 #include <syslog.h>
7 #include <xpc/xpc.h>
8
9 #include "SNHelperPrivate.h"
10
11 static xpc_connection_t
12 create_connection(dispatch_queue_t queue)
13 {
14 xpc_connection_t new_connection;
15
16 new_connection = xpc_connection_create_mach_service(kSNHelperService, queue, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
17 if (isa_xpc_connection(new_connection)) {
18 xpc_connection_set_event_handler(new_connection,
19 ^(xpc_object_t message) {
20 if (isa_xpc_error(message)) {
21 syslog(LOG_INFO, "Got an error on the SNHelper connection");
22 } else if (isa_xpc_dictionary(message)) {
23 syslog(LOG_INFO, "Got an unexpected message on the SNHelper connection");
24 }
25 });
26 xpc_connection_resume(new_connection);
27 }
28
29 return new_connection;
30 }
31
32 static xpc_object_t
33 copy_response(xpc_object_t request)
34 {
35 dispatch_queue_t conn_queue = dispatch_queue_create("snhelper request", NULL);
36 xpc_connection_t connection = create_connection(conn_queue);
37 xpc_object_t response = NULL;
38
39 if (connection) {
40 response = xpc_connection_send_message_with_reply_sync(connection, request);
41 xpc_connection_cancel(connection);
42 xpc_release(connection);
43 }
44
45 dispatch_release(conn_queue);
46
47 return response;
48 }
49
50 static int
51 flow_divert_uuid_policy_operate(const uuid_t uuid, int operation)
52 {
53 int result = 0;
54 xpc_object_t request = xpc_dictionary_create(NULL, NULL, 0);
55 xpc_object_t response;
56
57 xpc_dictionary_set_uint64(request, kSNHelperMessageType, operation);
58 xpc_dictionary_set_uuid(request, kSNHelperMessageUUID, uuid);
59
60 response = copy_response(request);
61
62 if (isa_xpc_dictionary(response)) {
63 result = (int)xpc_dictionary_get_int64(response, kSNHelperMessageResult);
64 } else {
65 result = EINVAL;
66 }
67
68 xpc_release(response);
69 xpc_release(request);
70
71 return result;
72 }
73
74 int
75 snhelper_flow_divert_uuid_policy_add(const uuid_t uuid)
76 {
77 return flow_divert_uuid_policy_operate(uuid, kSNHelperMessageTypeFlowDivertUUIDAdd);
78 }
79
80 int
81 snhelper_flow_divert_uuid_policy_remove(const uuid_t uuid)
82 {
83 return flow_divert_uuid_policy_operate(uuid, kSNHelperMessageTypeFlowDivertUUIDRemove);
84 }
85
86 int
87 snhelper_flow_divert_uuid_policy_clear(void)
88 {
89 int result = 0;
90 xpc_object_t request = xpc_dictionary_create(NULL, NULL, 0);
91 xpc_object_t response;
92
93 xpc_dictionary_set_uint64(request, kSNHelperMessageType, kSNHelperMessageTypeFlowDivertUUIDClear);
94
95 response = copy_response(request);
96
97 if (isa_xpc_dictionary(response)) {
98 result = (int)xpc_dictionary_get_int64(response, kSNHelperMessageResult);
99 } else {
100 result = EINVAL;
101 }
102
103 xpc_release(response);
104 xpc_release(request);
105
106 return result;
107 }
108
109 int
110 snhelper_get_uuid_for_app(const char *appID, uuid_t uuid)
111 {
112 int result;
113 xpc_object_t request = xpc_dictionary_create(NULL, NULL, 0);
114 xpc_object_t response;
115
116 xpc_dictionary_set_uint64(request, kSNHelperMessageType, kSNHelperMessageTypeGetUUIDForApp);
117 xpc_dictionary_set_string(request, kSNHelperMessageAppID, appID);
118
119 response = copy_response(request);
120
121 if (isa_xpc_dictionary(response)) {
122 result = (int)xpc_dictionary_get_int64(response, kSNHelperMessageResult);
123 const uint8_t *uuidBytes = xpc_dictionary_get_uuid(response, kSNHelperMessageResultData);
124 if (result == 0 && uuid != NULL && uuidBytes != NULL) {
125 memcpy(uuid, uuidBytes, sizeof(uuid_t));
126 }
127 } else {
128 result = EINVAL;
129 }
130
131 xpc_release(response);
132 xpc_release(request);
133
134 return result;
135 }
136
137 static bool
138 isa_xpc_object_of_type(xpc_object_t obj, xpc_type_t type)
139 {
140 return (obj != NULL && xpc_get_type(obj) == type);
141 }
142
143 bool
144 isa_xpc_connection(xpc_object_t obj)
145 {
146 return isa_xpc_object_of_type(obj, XPC_TYPE_CONNECTION);
147 }
148
149 bool
150 isa_xpc_bool(xpc_object_t obj)
151 {
152 return isa_xpc_object_of_type(obj, XPC_TYPE_BOOL);
153 }
154
155 bool
156 isa_xpc_dictionary(xpc_object_t obj)
157 {
158 return isa_xpc_object_of_type(obj, XPC_TYPE_DICTIONARY);
159 }
160
161 bool
162 isa_xpc_error(xpc_object_t obj)
163 {
164 return isa_xpc_object_of_type(obj, XPC_TYPE_ERROR);
165 }