]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/helper-stubs.c
mDNSResponder-164.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / helper-stubs.c
1 /*
2 * Copyright (c) 2007 Apple Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15
16 Change History (most recent first):
17
18 $Log: helper-stubs.c,v $
19 Revision 1.5 2007/09/07 22:44:03 mcguire
20 <rdar://problem/5448420> Move CFUserNotification code to mDNSResponderHelper
21
22 Revision 1.4 2007/09/04 22:32:58 mcguire
23 <rdar://problem/5453633> BTMM: BTMM overwrites /etc/racoon/remote/anonymous.conf
24
25 Revision 1.3 2007/08/23 21:44:55 cheshire
26 Made code layout style consistent with existing project style; added $Log header
27
28 Revision 1.2 2007/08/18 01:02:03 mcguire
29 <rdar://problem/5415593> No Bonjour services are getting registered at boot
30
31 Revision 1.1 2007/08/08 22:34:58 mcguire
32 <rdar://problem/5197869> Security: Run mDNSResponder as user id mdnsresponder instead of root
33 */
34
35 #include <mach/mach.h>
36 #include <mach/mach_error.h>
37 #include <mach/vm_map.h>
38 #include <servers/bootstrap.h>
39 #include <CoreFoundation/CoreFoundation.h>
40 #include "mDNSDebug.h"
41 #include "helper.h"
42 #include "helpermsg.h"
43
44 #define ERROR(x, y) y,
45 static const char *errorstring[] =
46 {
47 #include "helper-error.h"
48 NULL
49 };
50 #undef ERROR
51
52 static mach_port_t
53 getHelperPort(int retry)
54 {
55 static mach_port_t port = MACH_PORT_NULL;
56
57 if (retry)
58 port = MACH_PORT_NULL;
59 if (port == MACH_PORT_NULL &&
60 BOOTSTRAP_SUCCESS != bootstrap_look_up(bootstrap_port,
61 kmDNSHelperServiceName, &port))
62 LogMsg("%s: cannot contact helper", __func__);
63 return port;
64 }
65
66 const char *
67 mDNSHelperError(int err)
68 {
69 const char *p = "<unknown error>";
70 if (mDNSHelperErrorBase < err && mDNSHelperErrorEnd > err)
71 p = errorstring[err - mDNSHelperErrorBase - 1];
72 return p;
73 }
74
75
76 /* Ugly but handy. */
77 #define MACHRETRYLOOP_BEGIN(kr, retry, err, fin) for (;;) {
78
79 #define MACHRETRYLOOP_END(kr, retry, err, fin) \
80 if (KERN_SUCCESS == (kr)) break; \
81 else if (MACH_SEND_INVALID_DEST == (kr) && 0 == (retry)++) continue; \
82 else \
83 { \
84 (err) = kmDNSHelperCommunicationFailed; \
85 LogMsg("%s: Mach communication failed: %s", __func__, mach_error_string(kr)); \
86 goto fin; \
87 } \
88 } \
89 if (0 != (err)) { LogMsg("%s: %s", __func__, mDNSHelperError((err))); goto fin; }
90
91 int
92 mDNSPreferencesSetName(int key, domainlabel* old, domainlabel* new)
93 {
94 kern_return_t kr = KERN_FAILURE;
95 int retry = 0;
96 int err = 0;
97 char oldname[MAX_DOMAIN_LABEL+1] = {0};
98 char newname[MAX_DOMAIN_LABEL+1] = {0};
99 ConvertDomainLabelToCString_unescaped(old, oldname);
100 if (new) ConvertDomainLabelToCString_unescaped(new, newname);
101
102 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
103 kr = proxy_mDNSPreferencesSetName(getHelperPort(retry), key, oldname, newname, &err);
104 MACHRETRYLOOP_END(kr, retry, err, fin);
105
106 fin:
107 return err;
108 }
109
110 int
111 mDNSDynamicStoreSetConfig(int key, CFPropertyListRef value)
112 {
113 CFWriteStreamRef stream = NULL;
114 CFDataRef bytes = NULL;
115 kern_return_t kr = KERN_FAILURE;
116 int retry = 0;
117 int err = 0;
118
119 if (NULL == (stream = CFWriteStreamCreateWithAllocatedBuffers(NULL,
120 NULL)))
121 {
122 err = kmDNSHelperCreationFailed;
123 LogMsg("%s: CFWriteStreamCreateWithAllocatedBuffers failed",
124 __func__);
125 goto fin;
126 }
127 CFWriteStreamOpen(stream);
128 if (0 == CFPropertyListWriteToStream(value, stream,
129 kCFPropertyListBinaryFormat_v1_0, NULL))
130 {
131 err = kmDNSHelperPListWriteFailed;
132 LogMsg("%s: CFPropertyListWriteToStream failed", __func__);
133 goto fin;
134 }
135 if (NULL == (bytes = CFWriteStreamCopyProperty(stream,
136 kCFStreamPropertyDataWritten)))
137 {
138 err = kmDNSHelperCreationFailed;
139 LogMsg("%s: CFWriteStreamCopyProperty failed", __func__);
140 goto fin;
141 }
142 CFWriteStreamClose(stream);
143 CFRelease(stream);
144 stream = NULL;
145 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
146 kr = proxy_mDNSDynamicStoreSetConfig(getHelperPort(retry), key,
147 (vm_offset_t)CFDataGetBytePtr(bytes),
148 CFDataGetLength(bytes), &err);
149 MACHRETRYLOOP_END(kr, retry, err, fin);
150
151 fin:
152 if (NULL != stream)
153 {
154 CFWriteStreamClose(stream);
155 CFRelease(stream);
156 }
157 if (NULL != bytes)
158 CFRelease(bytes);
159 return err;
160 }
161
162 int
163 mDNSKeychainGetSecrets(CFArrayRef *result)
164 {
165 CFPropertyListRef plist = NULL;
166 CFDataRef bytes = NULL;
167 kern_return_t kr = KERN_FAILURE;
168 unsigned int numsecrets = 0;
169 void *secrets = NULL;
170 mach_msg_type_number_t secretsCnt = 0;
171 int retry = 0;
172 int err = 0;
173
174
175 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
176 kr = proxy_mDNSKeychainGetSecrets(getHelperPort(retry),
177 &numsecrets, (vm_offset_t *)&secrets, &secretsCnt, &err);
178 MACHRETRYLOOP_END(kr, retry, err, fin);
179 if (0 == numsecrets)
180 goto fin;
181 if (NULL == (bytes = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
182 secrets, secretsCnt, kCFAllocatorNull)))
183 {
184 err = kmDNSHelperCreationFailed;
185 LogMsg("%s: CFDataCreateWithBytesNoCopy failed", __func__);
186 goto fin;
187 }
188 if (NULL == (plist = CFPropertyListCreateFromXMLData(
189 kCFAllocatorDefault, bytes, kCFPropertyListImmutable, NULL)))
190 {
191 err = kmDNSHelperInvalidPList;
192 LogMsg("%s: CFPropertyListCreateFromXMLData failed", __func__);
193 goto fin;
194 }
195 if (CFArrayGetTypeID() != CFGetTypeID(plist))
196 {
197 err = kmDNSHelperTypeError;
198 LogMsg("%s: Unexpected result type", __func__);
199 CFRelease(plist);
200 plist = NULL;
201 goto fin;
202 }
203 *result = (CFArrayRef)plist;
204
205 fin:
206 if (NULL != bytes)
207 CFRelease(bytes);
208 if (NULL != secrets)
209 vm_deallocate(mach_task_self(), (vm_offset_t)secrets,
210 secretsCnt);
211 return err;
212 }
213
214 int
215 mDNSAutoTunnelInterfaceUpDown(int updown, v6addr_t address)
216 {
217 kern_return_t kr = KERN_SUCCESS;
218 int retry = 0;
219 int err = 0;
220
221 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
222 kr = proxy_mDNSAutoTunnelInterfaceUpDown(getHelperPort(retry),
223 updown, address, &err);
224 MACHRETRYLOOP_END(kr, retry, err, fin);
225
226 fin:
227 return err;
228 }
229
230 int
231 mDNSConfigureServer(int updown, const char *keydata)
232 {
233 kern_return_t kr = KERN_SUCCESS;
234 int retry = 0;
235 int err = 0;
236
237 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
238 kr = proxy_mDNSConfigureServer(getHelperPort(retry), updown, keydata, &err);
239 MACHRETRYLOOP_END(kr, retry, err, fin);
240
241 fin:
242 return err;
243 }
244
245 int
246 mDNSAutoTunnelSetKeys(int replacedelete, v6addr_t local_inner,
247 v4addr_t local_outer, short local_port, v6addr_t remote_inner,
248 v4addr_t remote_outer, short remote_port, const char *keydata)
249 {
250 kern_return_t kr = KERN_SUCCESS;
251 const char *p = NULL;
252 int retry = 0;
253 int err = 0;
254
255 if (kmDNSAutoTunnelSetKeysReplace == replacedelete)
256 p = keydata;
257 else
258 p = "";
259 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
260 kr = proxy_mDNSAutoTunnelSetKeys(getHelperPort(retry), replacedelete,
261 local_inner, local_outer, local_port, remote_inner, remote_outer,
262 remote_port, keydata, &err);
263 MACHRETRYLOOP_END(kr, retry, err, fin);
264
265 fin:
266 return err;
267 }