]> git.saurik.com Git - apple/configd.git/blob - config-agent-info/config_agent_info.c
configd-963.tar.gz
[apple/configd.git] / config-agent-info / config_agent_info.c
1 /*
2 * Copyright (c) 2015-2017 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 && xpc_get_type(value) == XPC_TYPE_DICTIONARY) {
40 agent_uuid = xpc_dictionary_get_value(info,
41 kConfigAgentOutOfBandDataUUID);
42 if (agent_uuid != NULL) {
43 return false;
44 }
45 }
46 return true;
47 });
48 } else if (xpc_get_type(info) == XPC_TYPE_DICTIONARY) {
49 agent_uuid = xpc_dictionary_get_value(info,
50 kConfigAgentOutOfBandDataUUID);
51 }
52
53 if (agent_uuid != NULL) {
54 const void *bytes = xpc_data_get_bytes_ptr(agent_uuid);
55 uuid_copy(uuid, bytes);
56 } else {
57 uuid_clear(uuid);
58 }
59 }
60
61 static boolean_t
62 is_a_config_agent(const struct netagent *agent)
63 {
64 const char *agentDomain;
65
66 if (agent == NULL) {
67 return false;
68 }
69
70 agentDomain = agent->netagent_domain;
71 if (agentDomain == NULL || strcmp(agentDomain, kConfigAgentDomain)) {
72 return false;
73 }
74
75 return true;
76 }
77
78 boolean_t
79 is_config_agent_type_dns(const struct netagent *agent)
80 {
81 if (!is_a_config_agent(agent)) {
82 return false;
83 }
84
85 const char *agentDesc = agent->netagent_type;
86 if (agentDesc == NULL || strcmp(agentDesc, kConfigAgentTypeDNS)) {
87 return false;
88 }
89
90 return true;
91 }
92
93 boolean_t
94 is_config_agent_type_proxy(const struct netagent *agent)
95 {
96 if (!is_a_config_agent(agent)) {
97 return false;
98 }
99
100 const char *agentDesc = agent->netagent_type;
101 if (agentDesc == NULL || strcmp(agentDesc, kConfigAgentTypeProxy)) {
102 return false;
103 }
104
105 return true;
106 }
107
108 static boolean_t
109 is_config_agent_type_dns_multicast(const struct netagent *agent)
110 {
111 if (strncmp(agent->netagent_desc, kConfigAgentTypeDNSMulticast, sizeof(kConfigAgentTypeDNSMulticast)-1) == 0) {
112 return true;
113 }
114
115 return false;
116 }
117
118 static boolean_t
119 is_config_agent_type_dns_private(const struct netagent *agent)
120 {
121 if (strncmp(agent->netagent_desc, kConfigAgentTypeDNSPrivate, sizeof(kConfigAgentTypeDNSPrivate)-1) == 0) {
122 return true;
123 }
124
125 return false;
126 }
127
128 xpc_object_t
129 config_agent_copy_dns_information(const struct netagent *agent)
130 {
131 xpc_object_t resolver = NULL;
132
133 if (!is_config_agent_type_dns(agent)) {
134 goto done;
135 }
136
137 if (agent->netagent_data_size <= 0 ) {
138 if (!is_config_agent_type_dns_private(agent) && !is_config_agent_type_dns_multicast(agent)) {
139 const char *agent_desc = (*(agent->netagent_desc) != '\0') ? agent->netagent_desc : kConfigAgentTypeDNS;
140 syslog(LOG_ERR, "Cannot parse config agent (%s). No data available", agent_desc);
141 }
142
143 goto done;
144 }
145
146 resolver = xpc_create_from_plist(agent->netagent_data, agent->netagent_data_size);
147
148 done:
149 return resolver;
150 }
151
152 xpc_object_t
153 config_agent_get_dns_nameservers(xpc_object_t resolver)
154 {
155 if (resolver == NULL) {
156 return NULL;
157 }
158
159 return xpc_dictionary_get_value(resolver, kConfigAgentDNSNameServers);
160 }
161
162 xpc_object_t
163 config_agent_get_dns_searchdomains(xpc_object_t resolver)
164 {
165 if (resolver == NULL) {
166 return NULL;
167 }
168
169 return xpc_dictionary_get_value(resolver, kConfigAgentDNSSearchDomains);
170 }
171
172 void
173 config_agent_free_dns_information(xpc_object_t resolver)
174 {
175 if (resolver == NULL) {
176 syslog(LOG_ERR, "Attempting to free invalid resolver");
177 return;
178 }
179
180 xpc_release(resolver);
181 }
182
183 xpc_object_t
184 config_agent_copy_proxy_information(const struct netagent *agent)
185 {
186 xpc_object_t info = NULL;
187
188 if (!is_config_agent_type_proxy(agent)) {
189 goto done;
190 }
191
192 if (agent->netagent_data_size <= 0 ) {
193 const char *agent_desc = (*(agent->netagent_desc) != '\0') ? agent->netagent_desc : kConfigAgentTypeProxy;
194 syslog(LOG_ERR, "Cannot parse config agent (%s). No data available", agent_desc);
195 goto done;
196 }
197
198 info = xpc_create_from_plist(agent->netagent_data, agent->netagent_data_size);
199
200 done:
201 return info;
202 }
203
204 xpc_object_t
205 config_agent_update_proxy_information(xpc_object_t proxyConfig)
206 {
207 if (proxyConfig == NULL) {
208 return NULL;
209 }
210
211 xpc_object_t newProxyConfig = NULL;
212 struct netagent agent;
213
214 get_agent_uuid_if_OOB_data_required(proxyConfig, agent.netagent_uuid);
215
216 if (uuid_is_null(agent.netagent_uuid) == 0) {
217 strlcpy(agent.netagent_type, kConfigAgentTypeProxy, sizeof(agent.netagent_type));
218
219 uint64_t length;
220 const void *buffer = _nwi_config_agent_copy_data(&agent, &length);
221 if (buffer != NULL && length > 0) {
222 newProxyConfig = xpc_create_from_plist(buffer, (size_t)length);
223 free((void *)buffer);
224 }
225 }
226
227 return newProxyConfig;
228 }
229
230 void
231 config_agent_free_proxy_information(xpc_object_t proxyConfig)
232 {
233 if (proxyConfig == NULL) {
234 syslog(LOG_ERR, "Attempting to free proxy configuration");
235 return;
236 }
237
238 xpc_release(proxyConfig);
239 }