source: rtems-libbsd/mDNSResponder/mDNSMacOSX/Private/xpc_services.c @ f761b29

55-freebsd-126-freebsd-12
Last change on this file since f761b29 was f761b29, checked in by Sebastian Huber <sebastian.huber@…>, on 09/19/18 at 06:52:21

mDNSResponder: Update to v625.41.2

The sources can be obtained via:

https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-625.41.2.tar.gz

Update #3522.

  • Property mode set to 100644
File size: 8.4 KB
Line 
1/* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2012-2015 Apple Inc. All rights reserved.
4 *
5 * xpc_services.c
6 * mDNSResponder
7 *
8 * XPC as an IPC mechanism to communicate with Clients. Open only to Apple OSX/iOS clients
9 */
10
11#include "xpc_services.h"
12#include "dns_xpc.h"
13
14#ifndef UNICAST_DISABLED
15
16#include "dnsproxy.h"        // DNSProxyInit/ProxyUDPCallback/ProxyTCPCallback
17#include "mDNSMacOSX.h"      // KQueueLock/KQueueUnlock
18#include <xpc/xpc.h>
19#include <xpc/private.h>     // xpc_connection_copy_entitlement_value
20
21// ***************************************************************************
22// Globals
23extern mDNS mDNSStorage;
24static int dps_client_pid; // To track current active client using DNS Proxy Service
25static dispatch_queue_t dps_queue = NULL;
26// ***************************************************************************
27
28// prints current XPC Server State
29mDNSexport void xpcserver_info(mDNS *const m)
30{
31
32    LogMsg("----- Active XPC Clients -----");
33    if (dps_client_pid)
34       LogMsg("DNSProxy->Client[%d]: InputIntfs[%d, %d, %d, %d, %d] Output[%d]", dps_client_pid, m->dp_ipintf[0],
35                m->dp_ipintf[1], m->dp_ipintf[2], m->dp_ipintf[3], m->dp_ipintf[4], m->dp_opintf);
36}
37
38
39mDNSlocal void ActivateDNSProxy(mDNSu32 IpIfArr[MaxIp], mDNSu32 OpIf, mDNSBool proxy_off)
40{
41
42    LogInfo("ActivateDNSProxy: InterfaceIndex List by Client: Input[%d, %d, %d, %d, %d] Output[%d] ", IpIfArr[0], IpIfArr[1],
43             IpIfArr[2], IpIfArr[3], IpIfArr[4], OpIf);
44 
45    KQueueLock(&mDNSStorage);
46    DNSProxyInit(&mDNSStorage, IpIfArr, OpIf);
47    if (proxy_off) // Open skts only if proxy was OFF else we may end up opening extra skts
48        mDNSPlatformInitDNSProxySkts(&mDNSStorage, ProxyUDPCallback, ProxyTCPCallback);
49    KQueueUnlock(&mDNSStorage, "DNSProxy Activated");
50}
51
52mDNSlocal void handle_dps_terminate()
53{
54
55    LogInfo("handle_dps_terminate: Client PID[%d] terminated connection or crashed. Proceed to terminate DNSProxy", dps_client_pid);
56    // Clear the Client's PID, so that we can now accept new DPS requests
57    dps_client_pid = 0;
58
59    KQueueLock(&mDNSStorage);
60    mDNSPlatformCloseDNSProxySkts(&mDNSStorage);
61    // TBD: Close TCP Sockets
62    DNSProxyTerminate(&mDNSStorage);
63    KQueueUnlock(&mDNSStorage, "DNSProxy Deactivated");
64}
65
66mDNSlocal void handle_dps_request(xpc_object_t req)
67{
68    int dps_tmp_client;
69    mDNSBool proxy_off = mDNSfalse;
70    xpc_connection_t remote_conn = xpc_dictionary_get_remote_connection(req);
71    dps_tmp_client = (int) xpc_connection_get_pid(remote_conn);
72
73    LogInfo("handle_dps_request: Handler for DNS Proxy Requests");
74
75    if (dps_client_pid <= 0)
76    {
77        LogInfo("handle_dps_request: DNSProxy is not engaged (New Client)");
78        // No Active Client, save new Client's PID (also indicates DNS Proxy was OFF)
79        dps_client_pid = dps_tmp_client;
80        proxy_off = mDNStrue;       
81    }
82    else
83    {
84        // We already have an active DNS Proxy Client and until that client does not terminate the connection
85        // or crashes, a new client cannot change/override the current DNS Proxy settings.
86        if (dps_client_pid != dps_tmp_client)
87        {
88            LogMsg("handle_dps_request: A Client is already using DNS Proxy and your request cannot be handled at this time");
89            // Return Engaged Status to the client
90            xpc_object_t reply = xpc_dictionary_create(NULL, NULL, 0);
91            if (reply)
92            {   
93                xpc_dictionary_set_uint64(reply, kDNSDaemonReply, kDNSMsg_BadArg);
94                xpc_connection_send_message(remote_conn, reply);
95                xpc_release(reply); 
96            }   
97            else
98            {   
99                LogMsg("handle_dps_request: Reply Dictionary could not be created");
100                return;
101            }
102            // We do not really need to terminate the connection with the client
103            // as it may try again later which is fine
104            return;   
105        }
106    }
107 
108 
109    xpc_object_t response = xpc_dictionary_create_reply(req);
110    // Return Success Status to the client
111    if (response)
112    {
113        xpc_dictionary_set_uint64(response, kDNSDaemonReply, kDNSMsg_NoError);
114        xpc_connection_send_message(remote_conn, response);
115        xpc_release(response); 
116    }
117    else
118    {
119        LogMsg("handle_dps_request: Response Dictionary could not be created");
120        return;
121    }
122
123    // Proceed to get DNS Proxy Settings from the Client
124    if (xpc_dictionary_get_uint64(req, kDNSProxyParameters))
125    {
126        mDNSu32 inIf[MaxIp], outIf;
127       
128        inIf[0]   = (mDNSu32)xpc_dictionary_get_uint64(req, kDNSInIfindex0);
129        inIf[1]   = (mDNSu32)xpc_dictionary_get_uint64(req, kDNSInIfindex1);
130        inIf[2]   = (mDNSu32)xpc_dictionary_get_uint64(req, kDNSInIfindex2);
131        inIf[3]   = (mDNSu32)xpc_dictionary_get_uint64(req, kDNSInIfindex3);
132        inIf[4]   = (mDNSu32)xpc_dictionary_get_uint64(req, kDNSInIfindex4);
133        outIf     = (mDNSu32)xpc_dictionary_get_uint64(req, kDNSOutIfindex);
134       
135        ActivateDNSProxy(inIf, outIf, proxy_off);
136    }
137   
138}
139
140// Verify Client's Entitlement
141mDNSlocal mDNSBool IsEntitled(xpc_connection_t conn, const char *password)
142{
143    mDNSBool entitled = mDNSfalse;
144    xpc_object_t ent = xpc_connection_copy_entitlement_value(conn, password);
145
146    if (ent)
147    {
148        if (xpc_get_type(ent) == XPC_TYPE_BOOL && xpc_bool_get_value(ent))
149        {
150            entitled = mDNStrue;
151        }
152        xpc_release(ent);
153    }
154    else
155    {
156        LogMsg("IsEntitled: Client Entitlement is NULL");
157    }
158   
159    if (!entitled)
160        LogMsg("IsEntitled: DNSProxyService Client is missing Entitlement!");
161   
162    return entitled;
163}
164
165mDNSlocal void accept_dps_client(xpc_connection_t conn)
166{
167    uid_t c_euid;
168    int   c_pid;
169    c_euid  = xpc_connection_get_euid(conn);
170    c_pid   = xpc_connection_get_pid(conn);
171
172    if (c_euid != 0 || !IsEntitled(conn, kDNSProxyService))
173    {   
174        LogMsg("accept_dps_client: DNSProxyService Client PID[%d] is missing Entitlement or is not running as root!", c_pid);
175        xpc_connection_cancel(conn);
176        return;
177    }
178   
179    xpc_retain(conn);
180    xpc_connection_set_target_queue(conn, dps_queue);
181    xpc_connection_set_event_handler(conn, ^(xpc_object_t req_msg)
182        {
183            xpc_type_t type = xpc_get_type(req_msg);
184
185            if (type == XPC_TYPE_DICTIONARY)
186            {
187                handle_dps_request(req_msg);
188            }
189            else // We hit this case ONLY if Client Terminated DPS Connection OR Crashed
190            {
191                LogInfo("accept_dps_client: DPS Client %p teared down the connection or Crashed", (void *) conn);
192                // Only the Client that has activated DPS should be able to terminate it
193                if (c_pid == dps_client_pid)
194                    handle_dps_terminate();
195                xpc_release(conn);
196            }
197        });
198   
199    xpc_connection_resume(conn);
200               
201}
202
203mDNSlocal void init_dnsproxy_service(void)
204{
205   
206    xpc_connection_t dps_listener = xpc_connection_create_mach_service(kDNSProxyService, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER);
207    if (!dps_listener || xpc_get_type(dps_listener) != XPC_TYPE_CONNECTION)
208    {
209        LogMsg("init_dnsproxy_service: Error Creating XPC Listener for DNSProxyService !!");
210        return;
211    }
212   
213    dps_queue = dispatch_queue_create("com.apple.mDNSResponder.dnsproxyservice_queue", NULL);
214
215    xpc_connection_set_event_handler(dps_listener, ^(xpc_object_t eventmsg)
216        {
217            xpc_type_t type = xpc_get_type(eventmsg);
218
219            if (type == XPC_TYPE_CONNECTION)
220            {
221                LogInfo("init_dnsproxy_service: New DNSProxyService Client %p", eventmsg);
222                accept_dps_client(eventmsg);
223            }
224            else if (type == XPC_TYPE_ERROR) // Ideally, we would never hit these cases
225            {
226                LogMsg("init_dnsproxy_service: XPCError: %s", xpc_dictionary_get_string(eventmsg, XPC_ERROR_KEY_DESCRIPTION));
227                return;
228            }
229            else
230            {
231                LogMsg("init_dnsproxy_service: Unknown EventMsg type");
232                return;
233            }
234        });
235   
236    xpc_connection_resume(dps_listener);
237
238}
239
240mDNSexport void xpc_server_init()
241{
242    // Add XPC Services here
243    init_dnsproxy_service();
244}
245
246#else // !UNICAST_DISABLED
247
248mDNSexport void xpc_server_init()
249{
250    return;
251}
252
253mDNSexport void xpcserver_info(mDNS *const m)
254{
255    (void) m;
256   
257    return;
258}
259
260#endif // !UNICAST_DISABLED
261
Note: See TracBrowser for help on using the repository browser.