]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/mdns_objects/mdns_trust.c
mDNSResponder-1310.40.42.tar.gz
[apple/mdnsresponder.git] / mDNSMacOSX / mdns_objects / mdns_trust.c
1 /*
2 * Copyright (c) 2019-2020 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 * https://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
17 #include "mDNSFeatures.h"
18
19 #if MDNSRESPONDER_SUPPORTS(APPLE, TRUST_ENFORCEMENT)
20
21 #include "mdns_trust.h"
22 #include "mdns_trust_checks.h"
23 #include "mdns_objects.h"
24 #include "mdns_helpers.h"
25 #include "dns_sd.h"
26
27 #include <bsm/libbsm.h>
28 #include <CoreUtils/DebugServices.h>
29
30 //======================================================================================================================
31 // MARK: - mdns_trust Kind Definition
32
33 struct mdns_trust_s {
34 struct mdns_object_s base; // Object base.
35 bool activated; // True if the trust has been activated.
36 bool invalidated; // True if the trust has bee invalidated.
37 bool user_activated; // True if user called activate method.
38 dispatch_queue_t queue; // Internal serial queue.
39 dispatch_queue_t user_queue; // Users serial queue.
40 mdns_trust_event_handler_t handler; // User's event handler.
41 void * context;
42 audit_token_t audit_token;
43 char * query;
44 mdns_trust_flags_t flags;
45 };
46
47 MDNS_OBJECT_SUBKIND_DEFINE(trust);
48
49 //======================================================================================================================
50 // MARK: - mdns_trust check Public Functions
51
52 void
53 mdns_trust_init(void)
54 {
55 mdns_trust_checks_init();
56 }
57
58 mdns_trust_status_t
59 mdns_trust_check_register_service(audit_token_t audit_token, const char * _Nullable service, mdns_trust_flags_t * _Nullable flags)
60 {
61 return mdns_trust_checks_check(&audit_token, trust_request_reg_service, NULL, service, 0, false, flags);
62 }
63
64 mdns_trust_status_t
65 mdns_trust_check_bonjour(audit_token_t audit_token, const char * _Nullable service, mdns_trust_flags_t * _Nullable flags)
66 {
67 return mdns_trust_checks_check(&audit_token, trust_request_bonjour, NULL, service, 0, true, flags);
68 }
69
70 mdns_trust_status_t
71 mdns_trust_check_query(audit_token_t audit_token, const char * qname, const char * _Nullable service, uint16_t qtype,
72 bool force_multicast, mdns_trust_flags_t * _Nullable flags)
73 {
74 return mdns_trust_checks_check(&audit_token, trust_request_query, qname, service, qtype, force_multicast, flags);
75 }
76
77 mdns_trust_status_t
78 mdns_trust_check_getaddrinfo(audit_token_t audit_token, const char * hostname, mdns_trust_flags_t * _Nullable flags)
79 {
80 return mdns_trust_checks_check(&audit_token, trust_request_query, hostname, NULL, 0, false, flags);
81 }
82
83 //======================================================================================================================
84 // MARK: - mdns_trust Private Methods
85
86 static void
87 _mdns_trust_finalize(mdns_trust_t me)
88 {
89 dispatch_forget(&me->queue);
90 dispatch_release_null_safe(me->user_queue);
91 ForgetMem(&me->query);
92 BlockForget(&me->handler);
93 }
94
95 //======================================================================================================================
96
97 static char *
98 _mdns_trust_copy_description(mdns_trust_t me, const bool debug, const bool __unused privacy)
99 {
100 char * description = NULL;
101 char buffer[256];
102 char * dst = buffer;
103 const char * const lim = &buffer[countof(buffer)];
104 int n;
105
106 *dst = '\0';
107 if (debug) {
108 n = mdns_snprintf_add(&dst, lim, "<%s: %p>: ", me->base.kind->name, me);
109 require_quiet(n >= 0, exit);
110 }
111 n = mdns_snprintf_add(&dst, lim, "%s ", me->base.kind->name);
112 require_quiet(n >= 0, exit);
113
114 n = mdns_snprintf_add(&dst, lim, "for pid %d", audit_token_to_pid(me->audit_token));
115 require_quiet(n >= 0, exit);
116
117 description = strdup(buffer);
118
119 exit:
120 return description;
121 }
122
123 static void
124 _mdns_trust_activate_internal(mdns_trust_t me)
125 {
126 mdns_retain(me);
127 mdns_trust_checks_local_network_access_policy_update(&me->audit_token, me->queue, me->query, me->flags,
128 ^(trust_policy_state_t state) {
129 if (!me->invalidated) {
130 me->invalidated = true;
131 mdns_retain(me);
132 dispatch_async(me->user_queue,
133 ^{
134 if (me->handler) {
135 mdns_trust_status_t status = (state != trust_policy_state_granted) ?
136 mdns_trust_status_denied : mdns_trust_status_granted;
137 me->handler(mdns_trust_event_result, status);
138 }
139 mdns_release(me);
140 });
141 }
142 mdns_release(me);
143 });
144 }
145
146 static void
147 _mdns_trust_invalidate_internal(mdns_trust_t me)
148 {
149 require_quiet(!me->invalidated, exit);
150 me->invalidated = true;
151 if (me->handler) {
152 me->handler(mdns_trust_event_invalidated, 0);
153 }
154 exit:
155 return;
156 }
157
158 static void
159 _mdns_trust_activate_if_ready(mdns_trust_t me)
160 {
161 if (me->user_activated && me->user_queue && !me->activated) {
162 mdns_retain(me);
163 dispatch_async(me->queue,
164 ^{
165 me->activated = true;
166 _mdns_trust_activate_internal(me);
167 mdns_release(me);
168 });
169 }
170 }
171
172 //======================================================================================================================
173 // MARK: - mdns_trust Public instance specific
174
175 mdns_trust_t
176 mdns_trust_create(audit_token_t audit_token, const char *_Nullable query, mdns_trust_flags_t flags)
177 {
178 mdns_trust_t op = NULL;
179 mdns_trust_t obj = _mdns_trust_alloc();
180 obj->queue = dispatch_queue_create("trust-internal", DISPATCH_QUEUE_SERIAL);
181 obj->audit_token = audit_token;
182 obj->flags = flags;
183 if (query != NULL) {
184 obj->query = strdup(query);
185 }
186 op = obj;
187 return op;
188 }
189
190 void
191 mdns_trust_set_context(mdns_trust_t me, void *_Nullable context)
192 {
193 require_quiet(me, exit);
194 me->context = context;
195 exit:
196 ;
197 }
198
199 void *_Nullable
200 mdns_trust_get_context(mdns_trust_t me)
201 {
202 require_quiet(me, exit);
203 return me->context;
204 exit:
205 return NULL;
206 }
207
208 void
209 mdns_trust_activate(mdns_trust_t me)
210 {
211 if (!me->user_activated) {
212 me->user_activated = true;
213 _mdns_trust_activate_if_ready(me);
214 }
215 }
216
217 void
218 mdns_trust_invalidate(mdns_trust_t me)
219 {
220 mdns_retain(me);
221 dispatch_async(me->queue,
222 ^{
223 _mdns_trust_invalidate_internal(me);
224 mdns_release(me);
225 });
226 }
227
228 void
229 mdns_trust_set_queue(mdns_trust_t me, dispatch_queue_t queue)
230 {
231 if (!me->user_activated || !me->user_queue)
232 {
233 if (queue) {
234 dispatch_retain(queue);
235 }
236 dispatch_release_null_safe(me->user_queue);
237 me->user_queue = queue;
238 _mdns_trust_activate_if_ready(me);
239 }
240 }
241
242 void
243 mdns_trust_set_event_handler(mdns_trust_t me, mdns_trust_event_handler_t handler)
244 {
245 const mdns_trust_event_handler_t new_handler = handler ? Block_copy(handler) : NULL;
246 if (me->handler) {
247 Block_release(me->handler);
248 }
249 me->handler = new_handler;
250 }
251
252 #endif // MDNSRESPONDER_SUPPORTS(APPLE, TRUST_ENFORCEMENT)