]> git.saurik.com Git - apple/mdnsresponder.git/blame - mDNSMacOSX/helper-stubs.c
mDNSResponder-214.3.2.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / helper-stubs.c
CommitLineData
67c8f8a1
A
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 $
32bb7e43
A
19Revision 1.19 2009/04/20 20:40:14 cheshire
20<rdar://problem/6786150> uDNS: Running location cycling caused configd and mDNSResponder to deadlock
21Changed mDNSPreferencesSetName (and similar) routines from MIG "routine" to MIG "simpleroutine"
22so we don't deadlock waiting for a result that we're just going to ignore anyway
23
24Revision 1.18 2009/03/20 22:12:27 mcguire
25<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
26Make the call to the helper a simpleroutine: don't wait for an unused return value
27
28Revision 1.17 2009/03/20 20:52:22 cheshire
29<rdar://problem/6703952> Support CFUserNotificationDisplayNotice in mDNSResponderHelper
30
31Revision 1.16 2009/03/14 01:42:56 mcguire
32<rdar://problem/5457116> BTMM: Fix issues with multiple .Mac accounts on the same machine
33
34Revision 1.15 2009/01/22 02:14:27 cheshire
35<rdar://problem/6515626> Sleep Proxy: Set correct target MAC address, instead of all zeroes
36
37Revision 1.14 2009/01/14 01:38:42 mcguire
38<rdar://problem/6492710> Write out DynamicStore per-interface SleepProxyServer info
39
40Revision 1.13 2009/01/14 01:28:17 mcguire
41removed unused variable
42
43Revision 1.12 2008/11/11 00:46:37 cheshire
44Don't just show "<unknown error>"; show the actual numeric error code too, so we can see what the unknown error was
45
46Revision 1.11 2008/11/04 23:54:09 cheshire
47Added routine mDNSSetARP(), used to replace an SPS client's entry in our ARP cache with
48a dummy one, so that IP traffic to the SPS client initiated by the SPS machine can be
49captured by our BPF filters, and used as a trigger to wake the sleeping machine.
50
51Revision 1.10 2008/10/29 21:25:35 cheshire
52Don't report kIOReturnNotReady errors
53
54Revision 1.9 2008/10/24 01:42:36 cheshire
55Added mDNSPowerRequest helper routine to request a scheduled wakeup some time in the future
56
57Revision 1.8 2008/10/20 22:01:28 cheshire
58Made new Mach simpleroutine "mDNSRequestBPF"
59
60Revision 1.7 2008/09/27 00:58:32 cheshire
61Added mDNSRequestBPF definition
62
030b743d
A
63Revision 1.6 2007/12/10 23:23:48 cheshire
64Removed unnecessary log message ("mDNSKeychainGetSecrets failed 0 00000000" because mDNSKeychainGetSecrets was failing to return a valid array)
65
67c8f8a1
A
66Revision 1.5 2007/09/07 22:44:03 mcguire
67<rdar://problem/5448420> Move CFUserNotification code to mDNSResponderHelper
68
69Revision 1.4 2007/09/04 22:32:58 mcguire
70<rdar://problem/5453633> BTMM: BTMM overwrites /etc/racoon/remote/anonymous.conf
71
72Revision 1.3 2007/08/23 21:44:55 cheshire
73Made code layout style consistent with existing project style; added $Log header
74
75Revision 1.2 2007/08/18 01:02:03 mcguire
76<rdar://problem/5415593> No Bonjour services are getting registered at boot
77
78Revision 1.1 2007/08/08 22:34:58 mcguire
79<rdar://problem/5197869> Security: Run mDNSResponder as user id mdnsresponder instead of root
80 */
81
82#include <mach/mach.h>
83#include <mach/mach_error.h>
84#include <mach/vm_map.h>
85#include <servers/bootstrap.h>
32bb7e43 86#include <IOKit/IOReturn.h>
67c8f8a1
A
87#include <CoreFoundation/CoreFoundation.h>
88#include "mDNSDebug.h"
89#include "helper.h"
90#include "helpermsg.h"
91
92#define ERROR(x, y) y,
93static const char *errorstring[] =
94 {
95 #include "helper-error.h"
96 NULL
97 };
98#undef ERROR
99
32bb7e43 100static mach_port_t getHelperPort(int retry)
67c8f8a1
A
101 {
102 static mach_port_t port = MACH_PORT_NULL;
32bb7e43
A
103 if (retry) port = MACH_PORT_NULL;
104 if (port == MACH_PORT_NULL && BOOTSTRAP_SUCCESS != bootstrap_look_up(bootstrap_port, kmDNSHelperServiceName, &port))
67c8f8a1
A
105 LogMsg("%s: cannot contact helper", __func__);
106 return port;
107 }
108
32bb7e43 109const char *mDNSHelperError(int err)
67c8f8a1 110 {
32bb7e43 111 static const char *p = "<unknown error>";
67c8f8a1
A
112 if (mDNSHelperErrorBase < err && mDNSHelperErrorEnd > err)
113 p = errorstring[err - mDNSHelperErrorBase - 1];
114 return p;
115 }
116
67c8f8a1 117/* Ugly but handy. */
32bb7e43
A
118// We don't bother reporting kIOReturnNotReady because that error code occurs in "normal" operation
119// and doesn't indicate anything unexpected that needs to be investigated
120
121#define MACHRETRYLOOP_BEGIN(kr, retry, err, fin) \
122 for (;;) \
123 {
124#define MACHRETRYLOOP_END(kr, retry, err, fin) \
125 if (KERN_SUCCESS == (kr)) break; \
126 else if (MACH_SEND_INVALID_DEST == (kr) && 0 == (retry)++) continue; \
127 else \
128 { \
129 (err) = kmDNSHelperCommunicationFailed; \
130 LogMsg("%s: Mach communication failed: %s", __func__, mach_error_string(kr)); \
131 goto fin; \
132 } \
133 } \
134 if (0 != (err) && kIOReturnNotReady != (err)) \
135 { LogMsg("%s: %d 0x%X (%s)", __func__, (err), (err), mDNSHelperError(err)); goto fin; }
136
137void mDNSPreferencesSetName(int key, domainlabel *old, domainlabel *new)
67c8f8a1
A
138 {
139 kern_return_t kr = KERN_FAILURE;
140 int retry = 0;
141 int err = 0;
142 char oldname[MAX_DOMAIN_LABEL+1] = {0};
143 char newname[MAX_DOMAIN_LABEL+1] = {0};
144 ConvertDomainLabelToCString_unescaped(old, oldname);
145 if (new) ConvertDomainLabelToCString_unescaped(new, newname);
146
147 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
32bb7e43 148 kr = proxy_mDNSPreferencesSetName(getHelperPort(retry), key, oldname, newname);
67c8f8a1
A
149 MACHRETRYLOOP_END(kr, retry, err, fin);
150
151fin:
32bb7e43 152 (void)err;
67c8f8a1
A
153 }
154
32bb7e43 155void mDNSDynamicStoreSetConfig(int key, const char *subkey, CFPropertyListRef value)
67c8f8a1
A
156 {
157 CFWriteStreamRef stream = NULL;
158 CFDataRef bytes = NULL;
159 kern_return_t kr = KERN_FAILURE;
160 int retry = 0;
161 int err = 0;
162
32bb7e43 163 if (NULL == (stream = CFWriteStreamCreateWithAllocatedBuffers(NULL, NULL)))
67c8f8a1
A
164 {
165 err = kmDNSHelperCreationFailed;
32bb7e43 166 LogMsg("%s: CFWriteStreamCreateWithAllocatedBuffers failed", __func__);
67c8f8a1
A
167 goto fin;
168 }
169 CFWriteStreamOpen(stream);
32bb7e43 170 if (0 == CFPropertyListWriteToStream(value, stream, kCFPropertyListBinaryFormat_v1_0, NULL))
67c8f8a1
A
171 {
172 err = kmDNSHelperPListWriteFailed;
173 LogMsg("%s: CFPropertyListWriteToStream failed", __func__);
174 goto fin;
175 }
32bb7e43 176 if (NULL == (bytes = CFWriteStreamCopyProperty(stream, kCFStreamPropertyDataWritten)))
67c8f8a1
A
177 {
178 err = kmDNSHelperCreationFailed;
179 LogMsg("%s: CFWriteStreamCopyProperty failed", __func__);
180 goto fin;
181 }
182 CFWriteStreamClose(stream);
183 CFRelease(stream);
184 stream = NULL;
185 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
32bb7e43 186 kr = proxy_mDNSDynamicStoreSetConfig(getHelperPort(retry), key, subkey ? subkey : "", (vm_offset_t)CFDataGetBytePtr(bytes), CFDataGetLength(bytes));
67c8f8a1
A
187 MACHRETRYLOOP_END(kr, retry, err, fin);
188
189fin:
32bb7e43
A
190 if (NULL != stream) { CFWriteStreamClose(stream); CFRelease(stream); }
191 if (NULL != bytes) CFRelease(bytes);
192 (void)err;
193 }
194
195void mDNSRequestBPF(void)
196 {
197 kern_return_t kr = KERN_FAILURE;
198 int retry = 0, err = 0;
199 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
200 kr = proxy_mDNSRequestBPF(getHelperPort(retry));
201 MACHRETRYLOOP_END(kr, retry, err, fin);
202fin:
203 (void)err;
204 }
205
206int mDNSPowerRequest(int key, int interval)
207 {
208 kern_return_t kr = KERN_FAILURE;
209 int retry = 0, err = 0;
210 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
211 kr = proxy_mDNSPowerRequest(getHelperPort(retry), key, interval, &err);
212 MACHRETRYLOOP_END(kr, retry, err, fin);
213fin:
214 return err;
215 }
216
217int mDNSSetARP(int ifindex, const v4addr_t ip, const ethaddr_t eth)
218 {
219 kern_return_t kr = KERN_FAILURE;
220 int retry = 0, err = 0;
221 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
222 kr = proxy_mDNSSetARP(getHelperPort(retry), ifindex, (uint8_t*)ip, (uint8_t*)eth, &err);
223 MACHRETRYLOOP_END(kr, retry, err, fin);
224fin:
67c8f8a1
A
225 return err;
226 }
227
32bb7e43
A
228void mDNSNotify(const char *title, const char *msg) // Both strings are UTF-8 text
229 {
230 kern_return_t kr = KERN_FAILURE;
231 int retry = 0, err = 0;
232 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
233 kr = proxy_mDNSNotify(getHelperPort(retry), title, msg);
234 MACHRETRYLOOP_END(kr, retry, err, fin);
235fin:
236 (void)err;
237 }
238
239int mDNSKeychainGetSecrets(CFArrayRef *result)
67c8f8a1
A
240 {
241 CFPropertyListRef plist = NULL;
242 CFDataRef bytes = NULL;
243 kern_return_t kr = KERN_FAILURE;
244 unsigned int numsecrets = 0;
245 void *secrets = NULL;
246 mach_msg_type_number_t secretsCnt = 0;
32bb7e43 247 int retry = 0, err = 0;
67c8f8a1 248
67c8f8a1 249 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
32bb7e43 250 kr = proxy_mDNSKeychainGetSecrets(getHelperPort(retry), &numsecrets, (vm_offset_t *)&secrets, &secretsCnt, &err);
67c8f8a1 251 MACHRETRYLOOP_END(kr, retry, err, fin);
030b743d 252
32bb7e43 253 if (NULL == (bytes = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, secrets, secretsCnt, kCFAllocatorNull)))
67c8f8a1
A
254 {
255 err = kmDNSHelperCreationFailed;
256 LogMsg("%s: CFDataCreateWithBytesNoCopy failed", __func__);
257 goto fin;
258 }
32bb7e43 259 if (NULL == (plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, bytes, kCFPropertyListImmutable, NULL)))
67c8f8a1
A
260 {
261 err = kmDNSHelperInvalidPList;
262 LogMsg("%s: CFPropertyListCreateFromXMLData failed", __func__);
263 goto fin;
264 }
265 if (CFArrayGetTypeID() != CFGetTypeID(plist))
266 {
267 err = kmDNSHelperTypeError;
268 LogMsg("%s: Unexpected result type", __func__);
269 CFRelease(plist);
270 plist = NULL;
271 goto fin;
272 }
273 *result = (CFArrayRef)plist;
274
275fin:
32bb7e43
A
276 if (NULL != bytes) CFRelease(bytes);
277 if (NULL != secrets) vm_deallocate(mach_task_self(), (vm_offset_t)secrets, secretsCnt);
67c8f8a1
A
278 return err;
279 }
280
32bb7e43 281void mDNSAutoTunnelInterfaceUpDown(int updown, v6addr_t address)
67c8f8a1
A
282 {
283 kern_return_t kr = KERN_SUCCESS;
32bb7e43 284 int retry = 0, err = 0;
67c8f8a1 285 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
32bb7e43 286 kr = proxy_mDNSAutoTunnelInterfaceUpDown(getHelperPort(retry), updown, address);
67c8f8a1 287 MACHRETRYLOOP_END(kr, retry, err, fin);
67c8f8a1 288fin:
32bb7e43 289 (void)err;
67c8f8a1
A
290 }
291
32bb7e43 292void mDNSConfigureServer(int updown, const domainname *const fqdn)
67c8f8a1
A
293 {
294 kern_return_t kr = KERN_SUCCESS;
32bb7e43
A
295 int retry = 0, err = 0;
296 char fqdnStr[MAX_ESCAPED_DOMAIN_NAME] = { 0 };
297 if (fqdn && ConvertDomainNameToCString(fqdn, fqdnStr))
298 {
299 // remove the trailing dot, as that is not used in the keychain entry racoon will lookup
300 mDNSu32 fqdnEnd = mDNSPlatformStrLen(fqdnStr);
301 if (fqdnEnd) fqdnStr[fqdnEnd - 1] = 0;
302 }
67c8f8a1 303 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
32bb7e43 304 kr = proxy_mDNSConfigureServer(getHelperPort(retry), updown, fqdnStr);
67c8f8a1 305 MACHRETRYLOOP_END(kr, retry, err, fin);
67c8f8a1 306fin:
32bb7e43 307 (void)err;
67c8f8a1
A
308 }
309
32bb7e43 310int mDNSAutoTunnelSetKeys(int replacedelete, v6addr_t local_inner,
67c8f8a1 311 v4addr_t local_outer, short local_port, v6addr_t remote_inner,
32bb7e43 312 v4addr_t remote_outer, short remote_port, const domainname *const fqdn)
67c8f8a1
A
313 {
314 kern_return_t kr = KERN_SUCCESS;
32bb7e43
A
315 int retry = 0, err = 0;
316 char fqdnStr[MAX_ESCAPED_DOMAIN_NAME] = { 0 };
317 if (fqdn && ConvertDomainNameToCString(fqdn, fqdnStr))
318 {
319 // remove the trailing dot, as that is not used in the keychain entry racoon will lookup
320 mDNSu32 fqdnEnd = mDNSPlatformStrLen(fqdnStr);
321 if (fqdnEnd) fqdnStr[fqdnEnd - 1] = 0;
322 }
67c8f8a1 323 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
32bb7e43 324 kr = proxy_mDNSAutoTunnelSetKeys(getHelperPort(retry), replacedelete, local_inner, local_outer, local_port, remote_inner, remote_outer, remote_port, fqdnStr, &err);
67c8f8a1 325 MACHRETRYLOOP_END(kr, retry, err, fin);
67c8f8a1
A
326fin:
327 return err;
328 }