]> git.saurik.com Git - apple/configd.git/blob - config-agent-info/config_agent_info.c
configd-1061.40.2.tar.gz
[apple/configd.git] / config-agent-info / config_agent_info.c
1 /*
2 * Copyright (c) 2015-2017, 2019 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #include "config_agent_info.h"
26 #include "configAgentDefines.h"
27 #include "network_config_agent_info_priv.h"
28
29 #include <syslog.h>
30
31 static void
32 get_agent_uuid_if_OOB_data_required(xpc_object_t info, uuid_t uuid)
33 {
34 __block xpc_object_t agent_uuid = NULL;
35
36 if (xpc_get_type(info) == XPC_TYPE_ARRAY) {
37 xpc_array_apply(info, ^bool(size_t index, xpc_object_t value) {
38 #pragma unused(index)
39 if ((value != NULL) &&
40 (xpc_get_type(value) == XPC_TYPE_DICTIONARY)) {
41 agent_uuid = xpc_dictionary_get_value(value,
42 kConfigAgentOutOfBandDataUUID);
43 if (agent_uuid != NULL) {
44 return false;
45 }
46 }
47 return true;
48 });
49 } else if (xpc_get_type(info) == XPC_TYPE_DICTIONARY) {
50 agent_uuid = xpc_dictionary_get_value(info,
51 kConfigAgentOutOfBandDataUUID);
52 }
53
54 if ((agent_uuid != NULL) &&
55 (xpc_get_type(agent_uuid) == XPC_TYPE_DATA) &&
56 (xpc_data_get_length(agent_uuid) >= sizeof(uuid_t))) {
57 const void *bytes = xpc_data_get_bytes_ptr(agent_uuid);
58 uuid_copy(uuid, bytes);
59 } else {
60 uuid_clear(uuid);
61 }
62 }
63
64 static boolean_t
65 is_a_config_agent(const struct netagent *agent)
66 {
67 const char *agentDomain;
68
69 if (agent == NULL) {
70 return false;
71 }
72
73 agentDomain = agent->netagent_domain;
74 if (agentDomain == NULL || strcmp(agentDomain, kConfigAgentDomain)) {
75 return false;
76 }
77
78 return true;
79 }
80
81 boolean_t
82 is_config_agent_type_dns(const struct netagent *agent)
83 {
84 if (!is_a_config_agent(agent)) {
85 return false;
86 }
87
88 const char *agentDesc = agent->netagent_type;
89 if (agentDesc == NULL || strcmp(agentDesc, kConfigAgentTypeDNS)) {
90 return false;
91 }
92
93 return true;
94 }
95
96 boolean_t
97 is_config_agent_type_proxy(const struct netagent *agent)
98 {
99 if (!is_a_config_agent(agent)) {
100 return false;
101 }
102
103 const char *agentDesc = agent->netagent_type;
104 if (agentDesc == NULL || strcmp(agentDesc, kConfigAgentTypeProxy)) {
105 return false;
106 }
107
108 return true;
109 }
110
111 static boolean_t
112 is_config_agent_type_dns_multicast(const struct netagent *agent)
113 {
114 if (strncmp(agent->netagent_desc, kConfigAgentTypeDNSMulticast, sizeof(kConfigAgentTypeDNSMulticast)-1) == 0) {
115 return true;
116 }
117
118 return false;
119 }
120
121 static boolean_t
122 is_config_agent_type_dns_private(const struct netagent *agent)
123 {
124 if (strncmp(agent->netagent_desc, kConfigAgentTypeDNSPrivate, sizeof(kConfigAgentTypeDNSPrivate)-1) == 0) {
125 return true;
126 }
127
128 return false;
129 }
130
131 xpc_object_t
132 config_agent_copy_dns_information(const struct netagent *agent)
133 {
134 xpc_object_t resolver = NULL;
135
136 if (!is_config_agent_type_dns(agent)) {
137 goto done;
138 }
139
140 if (agent->netagent_data_size <= 0 ) {
141 if (!is_config_agent_type_dns_private(agent) && !is_config_agent_type_dns_multicast(agent)) {
142 const char *agent_desc = (*(agent->netagent_desc) != '\0') ? agent->netagent_desc : kConfigAgentTypeDNS;
143 syslog(LOG_ERR, "Cannot parse config agent (%s). No data available", agent_desc);
144 }
145
146 goto done;
147 }
148
149 resolver = xpc_create_from_plist(agent->netagent_data, agent->netagent_data_size);
150
151 done:
152 return resolver;
153 }
154
155 xpc_object_t
156 config_agent_get_dns_nameservers(xpc_object_t resolver)
157 {
158 if ((resolver == NULL) ||
159 (xpc_get_type(resolver) != XPC_TYPE_DICTIONARY)) {
160 return NULL;
161 }
162
163 return xpc_dictionary_get_value(resolver, kConfigAgentDNSNameServers);
164 }
165
166 xpc_object_t
167 config_agent_get_dns_searchdomains(xpc_object_t resolver)
168 {
169 if ((resolver == NULL) ||
170 (xpc_get_type(resolver) != XPC_TYPE_DICTIONARY)) {
171 return NULL;
172 }
173
174 return xpc_dictionary_get_value(resolver, kConfigAgentDNSSearchDomains);
175 }
176
177 void
178 config_agent_free_dns_information(xpc_object_t resolver)
179 {
180 if (resolver == NULL) {
181 syslog(LOG_ERR, "Attempting to free invalid resolver");
182 return;
183 }
184
185 xpc_release(resolver);
186 }
187
188 xpc_object_t
189 config_agent_copy_proxy_information(const struct netagent *agent)
190 {
191 xpc_object_t info = NULL;
192
193 if (!is_config_agent_type_proxy(agent)) {
194 goto done;
195 }
196
197 if (agent->netagent_data_size <= 0 ) {
198 const char *agent_desc = (*(agent->netagent_desc) != '\0') ? agent->netagent_desc : kConfigAgentTypeProxy;
199 syslog(LOG_ERR, "Cannot parse config agent (%s). No data available", agent_desc);
200 goto done;
201 }
202
203 info = xpc_create_from_plist(agent->netagent_data, agent->netagent_data_size);
204
205 done:
206 return info;
207 }
208
209 xpc_object_t
210 config_agent_update_proxy_information(xpc_object_t proxyConfig)
211 {
212 if (proxyConfig == NULL) {
213 return NULL;
214 }
215
216 xpc_object_t newProxyConfig = NULL;
217 struct netagent agent;
218
219 get_agent_uuid_if_OOB_data_required(proxyConfig, agent.netagent_uuid);
220
221 if (uuid_is_null(agent.netagent_uuid) == 0) {
222 strlcpy(agent.netagent_type, kConfigAgentTypeProxy, sizeof(agent.netagent_type));
223
224 uint64_t length;
225 const void *buffer = _nwi_config_agent_copy_data(&agent, &length);
226 if (buffer != NULL && length > 0) {
227 newProxyConfig = xpc_create_from_plist(buffer, (size_t)length);
228 free((void *)buffer);
229 }
230 }
231
232 return newProxyConfig;
233 }
234
235 void
236 config_agent_free_proxy_information(xpc_object_t proxyConfig)
237 {
238 if (proxyConfig == NULL) {
239 syslog(LOG_ERR, "Attempting to free proxy configuration");
240 return;
241 }
242
243 xpc_release(proxyConfig);
244 }