2 * Copyright (c) 2019-2020 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 * https://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.
17 #include "mDNSFeatures.h"
19 #if MDNSRESPONDER_SUPPORTS(APPLE, TRUST_ENFORCEMENT)
21 #include "mdns_trust.h"
22 #include "mdns_trust_checks.h"
23 #include "mdns_objects.h"
24 #include "mdns_helpers.h"
27 #include <bsm/libbsm.h>
28 #include <CoreUtils/DebugServices.h>
30 //======================================================================================================================
31 // MARK: - mdns_trust Kind Definition
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.
42 audit_token_t audit_token
;
44 mdns_trust_flags_t flags
;
47 MDNS_OBJECT_SUBKIND_DEFINE(trust
);
49 //======================================================================================================================
50 // MARK: - mdns_trust check Public Functions
55 mdns_trust_checks_init();
59 mdns_trust_check_register_service(audit_token_t audit_token
, const char * _Nullable service
, mdns_trust_flags_t
* _Nullable flags
)
61 return mdns_trust_checks_check(&audit_token
, trust_request_reg_service
, NULL
, service
, 0, false, flags
);
65 mdns_trust_check_bonjour(audit_token_t audit_token
, const char * _Nullable service
, mdns_trust_flags_t
* _Nullable flags
)
67 return mdns_trust_checks_check(&audit_token
, trust_request_bonjour
, NULL
, service
, 0, true, flags
);
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
)
74 return mdns_trust_checks_check(&audit_token
, trust_request_query
, qname
, service
, qtype
, force_multicast
, flags
);
78 mdns_trust_check_getaddrinfo(audit_token_t audit_token
, const char * hostname
, mdns_trust_flags_t
* _Nullable flags
)
80 return mdns_trust_checks_check(&audit_token
, trust_request_query
, hostname
, NULL
, 0, false, flags
);
83 //======================================================================================================================
84 // MARK: - mdns_trust Private Methods
87 _mdns_trust_finalize(mdns_trust_t me
)
89 dispatch_forget(&me
->queue
);
90 dispatch_release_null_safe(me
->user_queue
);
91 ForgetMem(&me
->query
);
92 BlockForget(&me
->handler
);
95 //======================================================================================================================
98 _mdns_trust_copy_description(mdns_trust_t me
, const bool debug
, const bool __unused privacy
)
100 char * description
= NULL
;
103 const char * const lim
= &buffer
[countof(buffer
)];
108 n
= mdns_snprintf_add(&dst
, lim
, "<%s: %p>: ", me
->base
.kind
->name
, me
);
109 require_quiet(n
>= 0, exit
);
111 n
= mdns_snprintf_add(&dst
, lim
, "%s ", me
->base
.kind
->name
);
112 require_quiet(n
>= 0, exit
);
114 n
= mdns_snprintf_add(&dst
, lim
, "for pid %d", audit_token_to_pid(me
->audit_token
));
115 require_quiet(n
>= 0, exit
);
117 description
= strdup(buffer
);
124 _mdns_trust_activate_internal(mdns_trust_t 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;
132 dispatch_async(me
->user_queue
,
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
);
147 _mdns_trust_invalidate_internal(mdns_trust_t me
)
149 require_quiet(!me
->invalidated
, exit
);
150 me
->invalidated
= true;
152 me
->handler(mdns_trust_event_invalidated
, 0);
159 _mdns_trust_activate_if_ready(mdns_trust_t me
)
161 if (me
->user_activated
&& me
->user_queue
&& !me
->activated
) {
163 dispatch_async(me
->queue
,
165 me
->activated
= true;
166 _mdns_trust_activate_internal(me
);
172 //======================================================================================================================
173 // MARK: - mdns_trust Public instance specific
176 mdns_trust_create(audit_token_t audit_token
, const char *_Nullable query
, mdns_trust_flags_t flags
)
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
;
184 obj
->query
= strdup(query
);
191 mdns_trust_set_context(mdns_trust_t me
, void *_Nullable context
)
193 require_quiet(me
, exit
);
194 me
->context
= context
;
200 mdns_trust_get_context(mdns_trust_t me
)
202 require_quiet(me
, exit
);
209 mdns_trust_activate(mdns_trust_t me
)
211 if (!me
->user_activated
) {
212 me
->user_activated
= true;
213 _mdns_trust_activate_if_ready(me
);
218 mdns_trust_invalidate(mdns_trust_t me
)
221 dispatch_async(me
->queue
,
223 _mdns_trust_invalidate_internal(me
);
229 mdns_trust_set_queue(mdns_trust_t me
, dispatch_queue_t queue
)
231 if (!me
->user_activated
|| !me
->user_queue
)
234 dispatch_retain(queue
);
236 dispatch_release_null_safe(me
->user_queue
);
237 me
->user_queue
= queue
;
238 _mdns_trust_activate_if_ready(me
);
243 mdns_trust_set_event_handler(mdns_trust_t me
, mdns_trust_event_handler_t handler
)
245 const mdns_trust_event_handler_t new_handler
= handler
? Block_copy(handler
) : NULL
;
247 Block_release(me
->handler
);
249 me
->handler
= new_handler
;
252 #endif // MDNSRESPONDER_SUPPORTS(APPLE, TRUST_ENFORCEMENT)