2 * Copyright (c) 2007 Apple Inc. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 Change History (most recent first):
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
22 Revision 1.4 2007/09/04 22:32:58 mcguire
23 <rdar://problem/5453633> BTMM: BTMM overwrites /etc/racoon/remote/anonymous.conf
25 Revision 1.3 2007/08/23 21:44:55 cheshire
26 Made code layout style consistent with existing project style; added $Log header
28 Revision 1.2 2007/08/18 01:02:03 mcguire
29 <rdar://problem/5415593> No Bonjour services are getting registered at boot
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
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"
42 #include "helpermsg.h"
44 #define ERROR(x, y) y,
45 static const char *errorstring
[] =
47 #include "helper-error.h"
53 getHelperPort(int retry
)
55 static mach_port_t port
= MACH_PORT_NULL
;
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__
);
67 mDNSHelperError(int err
)
69 const char *p
= "<unknown error>";
70 if (mDNSHelperErrorBase
< err
&& mDNSHelperErrorEnd
> err
)
71 p
= errorstring
[err
- mDNSHelperErrorBase
- 1];
77 #define MACHRETRYLOOP_BEGIN(kr, retry, err, fin) for (;;) {
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; \
84 (err) = kmDNSHelperCommunicationFailed; \
85 LogMsg("%s: Mach communication failed: %s", __func__, mach_error_string(kr)); \
89 if (0 != (err)) { LogMsg("%s: %s", __func__, mDNSHelperError((err))); goto fin; }
92 mDNSPreferencesSetName(int key
, domainlabel
* old
, domainlabel
* new)
94 kern_return_t kr
= KERN_FAILURE
;
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
);
102 MACHRETRYLOOP_BEGIN(kr
, retry
, err
, fin
);
103 kr
= proxy_mDNSPreferencesSetName(getHelperPort(retry
), key
, oldname
, newname
, &err
);
104 MACHRETRYLOOP_END(kr
, retry
, err
, fin
);
111 mDNSDynamicStoreSetConfig(int key
, CFPropertyListRef value
)
113 CFWriteStreamRef stream
= NULL
;
114 CFDataRef bytes
= NULL
;
115 kern_return_t kr
= KERN_FAILURE
;
119 if (NULL
== (stream
= CFWriteStreamCreateWithAllocatedBuffers(NULL
,
122 err
= kmDNSHelperCreationFailed
;
123 LogMsg("%s: CFWriteStreamCreateWithAllocatedBuffers failed",
127 CFWriteStreamOpen(stream
);
128 if (0 == CFPropertyListWriteToStream(value
, stream
,
129 kCFPropertyListBinaryFormat_v1_0
, NULL
))
131 err
= kmDNSHelperPListWriteFailed
;
132 LogMsg("%s: CFPropertyListWriteToStream failed", __func__
);
135 if (NULL
== (bytes
= CFWriteStreamCopyProperty(stream
,
136 kCFStreamPropertyDataWritten
)))
138 err
= kmDNSHelperCreationFailed
;
139 LogMsg("%s: CFWriteStreamCopyProperty failed", __func__
);
142 CFWriteStreamClose(stream
);
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
);
154 CFWriteStreamClose(stream
);
163 mDNSKeychainGetSecrets(CFArrayRef
*result
)
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;
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
);
181 if (NULL
== (bytes
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
,
182 secrets
, secretsCnt
, kCFAllocatorNull
)))
184 err
= kmDNSHelperCreationFailed
;
185 LogMsg("%s: CFDataCreateWithBytesNoCopy failed", __func__
);
188 if (NULL
== (plist
= CFPropertyListCreateFromXMLData(
189 kCFAllocatorDefault
, bytes
, kCFPropertyListImmutable
, NULL
)))
191 err
= kmDNSHelperInvalidPList
;
192 LogMsg("%s: CFPropertyListCreateFromXMLData failed", __func__
);
195 if (CFArrayGetTypeID() != CFGetTypeID(plist
))
197 err
= kmDNSHelperTypeError
;
198 LogMsg("%s: Unexpected result type", __func__
);
203 *result
= (CFArrayRef
)plist
;
209 vm_deallocate(mach_task_self(), (vm_offset_t
)secrets
,
215 mDNSAutoTunnelInterfaceUpDown(int updown
, v6addr_t address
)
217 kern_return_t kr
= KERN_SUCCESS
;
221 MACHRETRYLOOP_BEGIN(kr
, retry
, err
, fin
);
222 kr
= proxy_mDNSAutoTunnelInterfaceUpDown(getHelperPort(retry
),
223 updown
, address
, &err
);
224 MACHRETRYLOOP_END(kr
, retry
, err
, fin
);
231 mDNSConfigureServer(int updown
, const char *keydata
)
233 kern_return_t kr
= KERN_SUCCESS
;
237 MACHRETRYLOOP_BEGIN(kr
, retry
, err
, fin
);
238 kr
= proxy_mDNSConfigureServer(getHelperPort(retry
), updown
, keydata
, &err
);
239 MACHRETRYLOOP_END(kr
, retry
, err
, fin
);
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
)
250 kern_return_t kr
= KERN_SUCCESS
;
251 const char *p
= NULL
;
255 if (kmDNSAutoTunnelSetKeysReplace
== replacedelete
)
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
);