]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/content_filter.h
e3829bf0223bc09cf1d31246330aa06c36a64408
[apple/xnu.git] / bsd / net / content_filter.h
1 /*
2 * Copyright (c) 2013-2019 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #ifndef __CONTENT_FILTER_H__
25 #define __CONTENT_FILTER_H__
26
27 #include <sys/param.h>
28 #include <sys/types.h>
29 #include <sys/_types/_timeval64.h>
30 #include <sys/socket.h>
31 #include <sys/syslog.h>
32 #include <netinet/in.h>
33 #include <stdint.h>
34 #include <corecrypto/ccsha2.h>
35
36 #ifdef BSD_KERNEL_PRIVATE
37 #include <sys/mbuf.h>
38 #include <sys/socketvar.h>
39 #endif /* BSD_KERNEL_PRIVATE */
40
41 __BEGIN_DECLS
42
43 #ifdef PRIVATE
44
45 /*
46 * Kernel control name for an instance of a Content Filter
47 * Use CTLIOCGINFO to find out the corresponding kernel control id
48 * to be set in the sc_id field of sockaddr_ctl for connect(2)
49 * Note: the sc_unit is ephemeral
50 */
51 #define CONTENT_FILTER_CONTROL_NAME "com.apple.content-filter"
52
53 /*
54 * Opaque socket identifier
55 */
56 typedef uint64_t cfil_sock_id_t;
57
58 #define CFIL_SOCK_ID_NONE UINT64_MAX
59
60
61 /*
62 * CFIL_OPT_NECP_CONTROL_UNIT
63 * To set or get the NECP filter control unit for the kernel control socket
64 * The option level is SYSPROTO_CONTROL
65 */
66 #define CFIL_OPT_NECP_CONTROL_UNIT 1 /* uint32_t */
67
68 /*
69 * CFIL_OPT_GET_SOCKET_INFO
70 * To get information about a given socket that is being filtered.
71 */
72 #define CFIL_OPT_GET_SOCKET_INFO 2 /* uint32_t */
73
74 /*
75 * struct cfil_opt_sock_info
76 *
77 * Contains information about a socket that is being filtered.
78 */
79 struct cfil_opt_sock_info {
80 cfil_sock_id_t cfs_sock_id;
81 int cfs_sock_family; /* e.g. PF_INET */
82 int cfs_sock_type; /* e.g. SOCK_STREAM */
83 int cfs_sock_protocol; /* e.g. IPPROTO_TCP */
84 union sockaddr_in_4_6 cfs_local;
85 union sockaddr_in_4_6 cfs_remote;
86 pid_t cfs_pid;
87 pid_t cfs_e_pid;
88 uuid_t cfs_uuid;
89 uuid_t cfs_e_uuid;
90 };
91
92 /*
93 * How many filter may be active simultaneously
94 */
95 #if !TARGET_OS_OSX && !defined(XNU_TARGET_OS_OSX)
96 #define CFIL_MAX_FILTER_COUNT 2
97 #else
98 #define CFIL_MAX_FILTER_COUNT 8
99 #endif
100
101
102 /*
103 * Crypto Support
104 */
105 #define CFIL_CRYPTO 1
106 #define CFIL_CRYPTO_SIGNATURE_SIZE 32
107 #define CFIL_CRYPTO_DATA_EVENT 1
108
109 typedef uint8_t cfil_crypto_key[CCSHA256_OUTPUT_SIZE];
110 typedef uint8_t cfil_crypto_signature[CFIL_CRYPTO_SIGNATURE_SIZE];
111
112 typedef struct cfil_crypto_state {
113 const struct ccdigest_info *digest_info;
114 cfil_crypto_key key;
115 } *cfil_crypto_state_t;
116
117 typedef struct cfil_crypto_data {
118 uuid_t flow_id;
119 u_int64_t sock_id;
120 u_int32_t direction;
121 union sockaddr_in_4_6 remote;
122 union sockaddr_in_4_6 local;
123 u_int32_t socketProtocol;
124 pid_t pid;
125 pid_t effective_pid;
126 uuid_t uuid;
127 uuid_t effective_uuid;
128 u_int64_t byte_count_in;
129 u_int64_t byte_count_out;
130 } *cfil_crypto_data_t;
131
132 /*
133 * Types of messages
134 *
135 * Event messages flow from kernel to user space while action
136 * messages flow in the reverse direction.
137 * A message in entirely represented by a packet sent or received
138 * on a Content Filter kernel control socket.
139 */
140 #define CFM_TYPE_EVENT 1 /* message from kernel */
141 #define CFM_TYPE_ACTION 2 /* message to kernel */
142
143 /*
144 * Operations associated with events from kernel
145 */
146 #define CFM_OP_SOCKET_ATTACHED 1 /* a socket has been attached */
147 #define CFM_OP_SOCKET_CLOSED 2 /* a socket is being closed */
148 #define CFM_OP_DATA_OUT 3 /* data being sent */
149 #define CFM_OP_DATA_IN 4 /* data being received */
150 #define CFM_OP_DISCONNECT_OUT 5 /* no more outgoing data */
151 #define CFM_OP_DISCONNECT_IN 6 /* no more incoming data */
152 #define CFM_OP_STATS 7 /* periodic stats report(s) */
153
154 /*
155 * Operations associated with action from filter to kernel
156 */
157 #define CFM_OP_DATA_UPDATE 16 /* update pass or peek offsets */
158 #define CFM_OP_DROP 17 /* shutdown socket, no more data */
159 #define CFM_OP_BLESS_CLIENT 18 /* mark a client flow as already filtered, passes a uuid */
160 #define CFM_OP_SET_CRYPTO_KEY 19 /* assign client crypto key for message signing */
161
162 /*
163 * struct cfil_msg_hdr
164 *
165 * Header common to all messages
166 */
167 struct cfil_msg_hdr {
168 uint32_t cfm_len; /* total length */
169 uint32_t cfm_version;
170 uint32_t cfm_type;
171 uint32_t cfm_op;
172 cfil_sock_id_t cfm_sock_id;
173 };
174
175 #define CFM_VERSION_CURRENT 1
176
177 /*
178 * Connection Direction
179 */
180 #define CFS_CONNECTION_DIR_IN 0
181 #define CFS_CONNECTION_DIR_OUT 1
182
183 #define CFS_AUDIT_TOKEN 1
184
185 /*
186 * struct cfil_msg_sock_attached
187 *
188 * Information about a new socket being attached to the content filter
189 *
190 * Action: No reply is expected as this does not block the creation of the
191 * TCP/IP but timely action must be taken to avoid user noticeable delays.
192 *
193 * Valid Types: CFM_TYPE_EVENT
194 *
195 * Valid Op: CFM_OP_SOCKET_ATTACHED
196 */
197 struct cfil_msg_sock_attached {
198 struct cfil_msg_hdr cfs_msghdr;
199 int cfs_sock_family; /* e.g. PF_INET */
200 int cfs_sock_type; /* e.g. SOCK_STREAM */
201 int cfs_sock_protocol; /* e.g. IPPROTO_TCP */
202 int cfs_unused; /* padding */
203 pid_t cfs_pid;
204 pid_t cfs_e_pid;
205 uuid_t cfs_uuid;
206 uuid_t cfs_e_uuid;
207 union sockaddr_in_4_6 cfs_src;
208 union sockaddr_in_4_6 cfs_dst;
209 int cfs_conn_dir;
210 unsigned int cfs_audit_token[8]; /* Must match audit_token_t */
211 cfil_crypto_signature cfs_signature;
212 uint32_t cfs_signature_length;
213 };
214
215 /*
216 * struct cfil_msg_data_event
217 *
218 * Event for the content fiter to act on a span of data
219 * A data span is described by a pair of offsets over the cumulative
220 * number of bytes sent or received on the socket.
221 *
222 * Action: The event must be acted upon but the filter may buffer
223 * data spans until it has enough content to make a decision.
224 * The action must be timely to avoid user noticeable delays.
225 *
226 * Valid Type: CFM_TYPE_EVENT
227 *
228 * Valid Ops: CFM_OP_DATA_OUT, CFM_OP_DATA_IN
229 */
230 struct cfil_msg_data_event {
231 struct cfil_msg_hdr cfd_msghdr;
232 union sockaddr_in_4_6 cfc_src;
233 union sockaddr_in_4_6 cfc_dst;
234 uint64_t cfd_start_offset;
235 uint64_t cfd_end_offset;
236 cfil_crypto_signature cfd_signature;
237 uint32_t cfd_signature_length;
238 /* Actual content data immediatly follows */
239 };
240
241 #define CFI_MAX_TIME_LOG_ENTRY 6
242 /*
243 * struct cfil_msg_sock_closed
244 *
245 * Information about a socket being closed to the content filter
246 *
247 * Action: No reply is expected as this does not block the closing of the
248 * TCP/IP.
249 *
250 * Valid Types: CFM_TYPE_EVENT
251 *
252 * Valid Op: CFM_OP_SOCKET_CLOSED
253 */
254 struct cfil_msg_sock_closed {
255 struct cfil_msg_hdr cfc_msghdr;
256 struct timeval64 cfc_first_event;
257 uint32_t cfc_op_list_ctr;
258 uint32_t cfc_op_time[CFI_MAX_TIME_LOG_ENTRY]; /* time interval in microseconds since first event */
259 unsigned char cfc_op_list[CFI_MAX_TIME_LOG_ENTRY];
260 uint64_t cfc_byte_inbound_count;
261 uint64_t cfc_byte_outbound_count;
262 cfil_crypto_signature cfc_signature;
263 uint32_t cfc_signature_length;
264 } __attribute__((aligned(8)));
265
266 /*
267 * struct cfil_msg_stats_report
268 *
269 * Statistics report for flow(s).
270 *
271 * Action: No reply is expected.
272 *
273 * Valid Types: CFM_TYPE_EVENT
274 *
275 * Valid Op: CFM_OP_STATS
276 */
277 struct cfil_msg_sock_stats {
278 cfil_sock_id_t cfs_sock_id;
279 uint64_t cfs_byte_inbound_count;
280 uint64_t cfs_byte_outbound_count;
281 union sockaddr_in_4_6 cfs_laddr;
282 } __attribute__((aligned(8)));
283
284 struct cfil_msg_stats_report {
285 struct cfil_msg_hdr cfr_msghdr;
286 uint32_t cfr_count;
287 struct cfil_msg_sock_stats cfr_stats[];
288 } __attribute__((aligned(8)));
289
290 /*
291 * struct cfil_msg_action
292 *
293 * Valid Type: CFM_TYPE_ACTION
294 *
295 * Valid Ops: CFM_OP_DATA_UPDATE, CFM_OP_DROP
296 *
297 * For CFM_OP_DATA_UPDATE:
298 *
299 * cfa_in_pass_offset and cfa_out_pass_offset indicates how much data is
300 * allowed to pass. A zero value does not modify the corresponding pass offset.
301 *
302 * cfa_in_peek_offset and cfa_out_peek_offset lets the filter specify how much
303 * data it needs to make a decision: the kernel will deliver data up to that
304 * offset (if less than cfa_pass_offset it is ignored). Use CFM_MAX_OFFSET
305 * if you don't value the corresponding peek offset to be updated.
306 */
307 struct cfil_msg_action {
308 struct cfil_msg_hdr cfa_msghdr;
309 uint64_t cfa_in_pass_offset;
310 uint64_t cfa_in_peek_offset;
311 uint64_t cfa_out_pass_offset;
312 uint64_t cfa_out_peek_offset;
313 uint32_t cfa_stats_frequency; // Statistics frequency in milliseconds
314 };
315
316 /*
317 * struct cfil_msg_bless_client
318 *
319 * Marks a client UUID as already filtered at a higher level.
320 *
321 * Valid Type: CFM_TYPE_ACTION
322 *
323 * Valid Ops: CFM_OP_BLESS_CLIENT
324 */
325 struct cfil_msg_bless_client {
326 struct cfil_msg_hdr cfb_msghdr;
327 uuid_t cfb_client_uuid;
328 };
329
330 /*
331 * struct cfil_msg_set_crypto_key
332 *
333 * Filter assigning client crypto key to CFIL for message signing
334 *
335 * Valid Type: CFM_TYPE_ACTION
336 *
337 * Valid Ops: CFM_OP_SET_CRYPTO_KEY
338 */
339 struct cfil_msg_set_crypto_key {
340 struct cfil_msg_hdr cfb_msghdr;
341 cfil_crypto_key crypto_key;
342 };
343
344 #define CFM_MAX_OFFSET UINT64_MAX
345
346 /*
347 * Statistics retrieved via sysctl(3)
348 */
349 struct cfil_filter_stat {
350 uint32_t cfs_len;
351 uint32_t cfs_filter_id;
352 uint32_t cfs_flags;
353 uint32_t cfs_sock_count;
354 uint32_t cfs_necp_control_unit;
355 };
356
357 struct cfil_entry_stat {
358 uint32_t ces_len;
359 uint32_t ces_filter_id;
360 uint32_t ces_flags;
361 uint32_t ces_necp_control_unit;
362 struct timeval64 ces_last_event;
363 struct timeval64 ces_last_action;
364 struct cfe_buf_stat {
365 uint64_t cbs_pending_first;
366 uint64_t cbs_pending_last;
367 uint64_t cbs_ctl_first;
368 uint64_t cbs_ctl_last;
369 uint64_t cbs_pass_offset;
370 uint64_t cbs_peek_offset;
371 uint64_t cbs_peeked;
372 } ces_snd, ces_rcv;
373 };
374
375 struct cfil_sock_stat {
376 uint32_t cfs_len;
377 int cfs_sock_family;
378 int cfs_sock_type;
379 int cfs_sock_protocol;
380 cfil_sock_id_t cfs_sock_id;
381 uint64_t cfs_flags;
382 pid_t cfs_pid;
383 pid_t cfs_e_pid;
384 uuid_t cfs_uuid;
385 uuid_t cfs_e_uuid;
386 struct cfi_buf_stat {
387 uint64_t cbs_pending_first;
388 uint64_t cbs_pending_last;
389 uint64_t cbs_pass_offset;
390 uint64_t cbs_inject_q_len;
391 } cfs_snd, cfs_rcv;
392 struct cfil_entry_stat ces_entries[CFIL_MAX_FILTER_COUNT];
393 };
394
395 /*
396 * Global statistics
397 */
398 struct cfil_stats {
399 int32_t cfs_ctl_connect_ok;
400 int32_t cfs_ctl_connect_fail;
401 int32_t cfs_ctl_disconnect_ok;
402 int32_t cfs_ctl_disconnect_fail;
403 int32_t cfs_ctl_send_ok;
404 int32_t cfs_ctl_send_bad;
405 int32_t cfs_ctl_rcvd_ok;
406 int32_t cfs_ctl_rcvd_bad;
407 int32_t cfs_ctl_rcvd_flow_lift;
408 int32_t cfs_ctl_action_data_update;
409 int32_t cfs_ctl_action_drop;
410 int32_t cfs_ctl_action_bad_op;
411 int32_t cfs_ctl_action_bad_len;
412
413 int32_t cfs_sock_id_not_found;
414
415 int32_t cfs_cfi_alloc_ok;
416 int32_t cfs_cfi_alloc_fail;
417
418 int32_t cfs_sock_userspace_only;
419 int32_t cfs_sock_attach_in_vain;
420 int32_t cfs_sock_attach_already;
421 int32_t cfs_sock_attach_no_mem;
422 int32_t cfs_sock_attach_failed;
423 int32_t cfs_sock_attached;
424 int32_t cfs_sock_detached;
425
426 int32_t cfs_attach_event_ok;
427 int32_t cfs_attach_event_flow_control;
428 int32_t cfs_attach_event_fail;
429
430 int32_t cfs_closed_event_ok;
431 int32_t cfs_closed_event_flow_control;
432 int32_t cfs_closed_event_fail;
433
434 int32_t cfs_data_event_ok;
435 int32_t cfs_data_event_flow_control;
436 int32_t cfs_data_event_fail;
437
438 int32_t cfs_stats_event_ok;
439 int32_t cfs_stats_event_flow_control;
440 int32_t cfs_stats_event_fail;
441
442 int32_t cfs_disconnect_in_event_ok;
443 int32_t cfs_disconnect_out_event_ok;
444 int32_t cfs_disconnect_event_flow_control;
445 int32_t cfs_disconnect_event_fail;
446
447 int32_t cfs_ctl_q_not_started;
448
449 int32_t cfs_close_wait;
450 int32_t cfs_close_wait_timeout;
451
452 int32_t cfs_flush_in_drop;
453 int32_t cfs_flush_out_drop;
454 int32_t cfs_flush_in_close;
455 int32_t cfs_flush_out_close;
456 int32_t cfs_flush_in_free;
457 int32_t cfs_flush_out_free;
458
459 int32_t cfs_inject_q_nomem;
460 int32_t cfs_inject_q_nobufs;
461 int32_t cfs_inject_q_detached;
462 int32_t cfs_inject_q_in_fail;
463 int32_t cfs_inject_q_out_fail;
464
465 int32_t cfs_inject_q_in_retry;
466 int32_t cfs_inject_q_out_retry;
467
468 int32_t cfs_data_in_control;
469 int32_t cfs_data_in_oob;
470 int32_t cfs_data_out_control;
471 int32_t cfs_data_out_oob;
472
473 int64_t cfs_ctl_q_in_enqueued __attribute__((aligned(8)));
474 int64_t cfs_ctl_q_out_enqueued __attribute__((aligned(8)));
475 int64_t cfs_ctl_q_in_peeked __attribute__((aligned(8)));
476 int64_t cfs_ctl_q_out_peeked __attribute__((aligned(8)));
477
478 int64_t cfs_pending_q_in_enqueued __attribute__((aligned(8)));
479 int64_t cfs_pending_q_out_enqueued __attribute__((aligned(8)));
480
481 int64_t cfs_inject_q_in_enqueued __attribute__((aligned(8)));
482 int64_t cfs_inject_q_out_enqueued __attribute__((aligned(8)));
483 int64_t cfs_inject_q_in_passed __attribute__((aligned(8)));
484 int64_t cfs_inject_q_out_passed __attribute__((aligned(8)));
485 };
486 #endif /* PRIVATE */
487
488 #ifdef BSD_KERNEL_PRIVATE
489
490 #define M_SKIPCFIL M_PROTO5
491
492 extern int cfil_log_level;
493
494 #define CFIL_LOG(level, fmt, ...) \
495 do { \
496 if (cfil_log_level >= level) \
497 printf("%s:%d " fmt "\n",\
498 __FUNCTION__, __LINE__, ##__VA_ARGS__); \
499 } while (0)
500
501
502 extern void cfil_init(void);
503
504 extern boolean_t cfil_filter_present(void);
505 extern boolean_t cfil_sock_connected_pending_verdict(struct socket *so);
506 extern errno_t cfil_sock_attach(struct socket *so,
507 struct sockaddr *local, struct sockaddr *remote, int dir);
508 extern errno_t cfil_sock_detach(struct socket *so);
509
510 extern int cfil_sock_data_out(struct socket *so, struct sockaddr *to,
511 struct mbuf *data, struct mbuf *control,
512 uint32_t flags);
513 extern int cfil_sock_data_in(struct socket *so, struct sockaddr *from,
514 struct mbuf *data, struct mbuf *control,
515 uint32_t flags);
516
517 extern int cfil_sock_shutdown(struct socket *so, int *how);
518 extern void cfil_sock_is_closed(struct socket *so);
519 extern void cfil_sock_notify_shutdown(struct socket *so, int how);
520 extern void cfil_sock_close_wait(struct socket *so);
521
522 extern boolean_t cfil_sock_data_pending(struct sockbuf *sb);
523 extern int cfil_sock_data_space(struct sockbuf *sb);
524 extern void cfil_sock_buf_update(struct sockbuf *sb);
525
526 extern cfil_sock_id_t cfil_sock_id_from_socket(struct socket *so);
527
528 extern struct m_tag *cfil_udp_get_socket_state(struct mbuf *m, uint32_t *state_change_cnt,
529 short *options, struct sockaddr **faddr);
530 #endif /* BSD_KERNEL_PRIVATE */
531
532 __END_DECLS
533
534 #endif /* __CONTENT_FILTER_H__ */