]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/helper-stubs.c
mDNSResponder-170.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.6 2007/12/10 23:23:48 cheshire
20 Removed unnecessary log message ("mDNSKeychainGetSecrets failed 0 00000000" because mDNSKeychainGetSecrets was failing to return a valid array)
21
22 Revision 1.5 2007/09/07 22:44:03 mcguire
23 <rdar://problem/5448420> Move CFUserNotification code to mDNSResponderHelper
24
25 Revision 1.4 2007/09/04 22:32:58 mcguire
26 <rdar://problem/5453633> BTMM: BTMM overwrites /etc/racoon/remote/anonymous.conf
27
28 Revision 1.3 2007/08/23 21:44:55 cheshire
29 Made code layout style consistent with existing project style; added $Log header
30
31 Revision 1.2 2007/08/18 01:02:03 mcguire
32 <rdar://problem/5415593> No Bonjour services are getting registered at boot
33
34 Revision 1.1 2007/08/08 22:34:58 mcguire
35 <rdar://problem/5197869> Security: Run mDNSResponder as user id mdnsresponder instead of root
36 */
37
38 #include <mach/mach.h>
39 #include <mach/mach_error.h>
40 #include <mach/vm_map.h>
41 #include <servers/bootstrap.h>
42 #include <CoreFoundation/CoreFoundation.h>
43 #include "mDNSDebug.h"
44 #include "helper.h"
45 #include "helpermsg.h"
46
47 #define ERROR(x, y) y,
48 static const char *errorstring[] =
49 {
50 #include "helper-error.h"
51 NULL
52 };
53 #undef ERROR
54
55 static mach_port_t
56 getHelperPort(int retry)
57 {
58 static mach_port_t port = MACH_PORT_NULL;
59
60 if (retry)
61 port = MACH_PORT_NULL;
62 if (port == MACH_PORT_NULL &&
63 BOOTSTRAP_SUCCESS != bootstrap_look_up(bootstrap_port,
64 kmDNSHelperServiceName, &port))
65 LogMsg("%s: cannot contact helper", __func__);
66 return port;
67 }
68
69 const char *
70 mDNSHelperError(int err)
71 {
72 const char *p = "<unknown error>";
73 if (mDNSHelperErrorBase < err && mDNSHelperErrorEnd > err)
74 p = errorstring[err - mDNSHelperErrorBase - 1];
75 return p;
76 }
77
78 /* Ugly but handy. */
79 #define MACHRETRYLOOP_BEGIN(kr, retry, err, fin) for (;;) {
80
81 #define MACHRETRYLOOP_END(kr, retry, err, fin) \
82 if (KERN_SUCCESS == (kr)) break; \
83 else if (MACH_SEND_INVALID_DEST == (kr) && 0 == (retry)++) continue; \
84 else \
85 { \
86 (err) = kmDNSHelperCommunicationFailed; \
87 LogMsg("%s: Mach communication failed: %s", __func__, mach_error_string(kr)); \
88 goto fin; \
89 } \
90 } \
91 if (0 != (err)) { LogMsg("%s: %s", __func__, mDNSHelperError((err))); goto fin; }
92
93 int
94 mDNSPreferencesSetName(int key, domainlabel* old, domainlabel* new)
95 {
96 kern_return_t kr = KERN_FAILURE;
97 int retry = 0;
98 int err = 0;
99 char oldname[MAX_DOMAIN_LABEL+1] = {0};
100 char newname[MAX_DOMAIN_LABEL+1] = {0};
101 ConvertDomainLabelToCString_unescaped(old, oldname);
102 if (new) ConvertDomainLabelToCString_unescaped(new, newname);
103
104 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
105 kr = proxy_mDNSPreferencesSetName(getHelperPort(retry), key, oldname, newname, &err);
106 MACHRETRYLOOP_END(kr, retry, err, fin);
107
108 fin:
109 return err;
110 }
111
112 int
113 mDNSDynamicStoreSetConfig(int key, CFPropertyListRef value)
114 {
115 CFWriteStreamRef stream = NULL;
116 CFDataRef bytes = NULL;
117 kern_return_t kr = KERN_FAILURE;
118 int retry = 0;
119 int err = 0;
120
121 if (NULL == (stream = CFWriteStreamCreateWithAllocatedBuffers(NULL,
122 NULL)))
123 {
124 err = kmDNSHelperCreationFailed;
125 LogMsg("%s: CFWriteStreamCreateWithAllocatedBuffers failed",
126 __func__);
127 goto fin;
128 }
129 CFWriteStreamOpen(stream);
130 if (0 == CFPropertyListWriteToStream(value, stream,
131 kCFPropertyListBinaryFormat_v1_0, NULL))
132 {
133 err = kmDNSHelperPListWriteFailed;
134 LogMsg("%s: CFPropertyListWriteToStream failed", __func__);
135 goto fin;
136 }
137 if (NULL == (bytes = CFWriteStreamCopyProperty(stream,
138 kCFStreamPropertyDataWritten)))
139 {
140 err = kmDNSHelperCreationFailed;
141 LogMsg("%s: CFWriteStreamCopyProperty failed", __func__);
142 goto fin;
143 }
144 CFWriteStreamClose(stream);
145 CFRelease(stream);
146 stream = NULL;
147 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
148 kr = proxy_mDNSDynamicStoreSetConfig(getHelperPort(retry), key,
149 (vm_offset_t)CFDataGetBytePtr(bytes),
150 CFDataGetLength(bytes), &err);
151 MACHRETRYLOOP_END(kr, retry, err, fin);
152
153 fin:
154 if (NULL != stream)
155 {
156 CFWriteStreamClose(stream);
157 CFRelease(stream);
158 }
159 if (NULL != bytes)
160 CFRelease(bytes);
161 return err;
162 }
163
164 int
165 mDNSKeychainGetSecrets(CFArrayRef *result)
166 {
167 CFPropertyListRef plist = NULL;
168 CFDataRef bytes = NULL;
169 kern_return_t kr = KERN_FAILURE;
170 unsigned int numsecrets = 0;
171 void *secrets = NULL;
172 mach_msg_type_number_t secretsCnt = 0;
173 int retry = 0;
174 int err = 0;
175
176 MACHRETRYLOOP_BEGIN(kr, retry, err, fin);
177 kr = proxy_mDNSKeychainGetSecrets(getHelperPort(retry),
178 &numsecrets, (vm_offset_t *)&secrets, &secretsCnt, &err);
179 MACHRETRYLOOP_END(kr, retry, err, fin);
180
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 }