1/*-
2 * Copyright (c) 2004-2009 Apple Inc.
3 * Copyright (c) 2005 SPARTA, Inc.
4 * All rights reserved.
5 *
6 * This code was developed in part by Robert N. M. Watson, Senior Principal
7 * Scientist, SPARTA, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
18 * its contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <sys/types.h>
35#include <sys/un.h>
36#include <sys/event.h>
37#include <sys/ucred.h>
38#include <sys/systm.h>
39
40#include <sys/ipc.h>
41
42#include <netinet/in.h>
43#include <netinet/in_systm.h>
44#include <netinet/ip.h>
45
46#include <bsm/audit.h>
47#include <bsm/audit_internal.h>
48#include <bsm/audit_record.h>
49#include <security/audit/audit.h>
50#include <security/audit/audit_bsd.h>
51#include <security/audit/audit_private.h>
52
53#include <kern/host.h>
54#include <kern/clock.h>
55
56#include <string.h>
57
58#if CONFIG_AUDIT
59#define GET_TOKEN_AREA(t, dptr, length) do { \
60 t = kalloc_type(token_t, Z_WAITOK | Z_NOFAIL); \
61 t->t_data = kalloc_data(length, Z_WAITOK | Z_ZERO | Z_NOFAIL); \
62 t->len = length; \
63 dptr = t->t_data; \
64} while (0)
65
66/*
67 * token ID 1 byte
68 * argument # 1 byte
69 * argument value 4 bytes/8 bytes (32-bit/64-bit value)
70 * text length 2 bytes
71 * text N bytes + 1 terminating NULL byte
72 */
73token_t *
74au_to_arg32(char n, const char *text, u_int32_t v)
75{
76 token_t *t;
77 u_char *dptr = NULL;
78 u_int16_t textlen;
79 size_t tokenlen;
80
81 textlen = strlen(s: text);
82 textlen += 1;
83
84 tokenlen = 2 * sizeof(u_char) + sizeof(u_int32_t) + sizeof(u_int16_t) + textlen;
85 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
86 ("au_to_arg32: token length (%zu) exceeds maximum allowed size", tokenlen));
87
88 GET_TOKEN_AREA(t, dptr, tokenlen);
89
90 ADD_U_CHAR(dptr, AUT_ARG32);
91 ADD_U_CHAR(dptr, n);
92 ADD_U_INT32(dptr, v);
93 ADD_U_INT16(dptr, textlen);
94 ADD_STRING(dptr, text, textlen);
95
96 return t;
97}
98
99token_t *
100au_to_arg64(char n, const char *text, u_int64_t v)
101{
102 token_t *t;
103 u_char *dptr = NULL;
104 u_int16_t textlen;
105 size_t tokenlen;
106
107 textlen = strlen(s: text);
108 textlen += 1;
109
110 tokenlen = 2 * sizeof(u_char) + sizeof(u_int64_t) + sizeof(u_int16_t) + textlen;
111 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
112 ("au_to_arg64: token length (%zu) exceeds maximum allowed size", tokenlen));
113
114 GET_TOKEN_AREA(t, dptr, tokenlen);
115
116 ADD_U_CHAR(dptr, AUT_ARG64);
117 ADD_U_CHAR(dptr, n);
118 ADD_U_INT64(dptr, v);
119 ADD_U_INT16(dptr, textlen);
120 ADD_STRING(dptr, text, textlen);
121
122 return t;
123}
124
125token_t *
126au_to_arg(char n, const char *text, u_int32_t v)
127{
128 return au_to_arg32(n, text, v);
129}
130
131#if defined(_KERNEL) || defined(KERNEL)
132/*
133 * token ID 1 byte
134 * file access mode 4 bytes
135 * owner user ID 4 bytes
136 * owner group ID 4 bytes
137 * file system ID 4 bytes
138 * node ID 8 bytes
139 * device 4 bytes/8 bytes (32-bit/64-bit)
140 */
141token_t *
142au_to_attr32(struct vnode_au_info *vni)
143{
144 token_t *t;
145 u_char *dptr = NULL;
146 u_int16_t pad0_16 = 0;
147 u_int32_t pad0_32 = 0;
148
149 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
150 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
151
152 ADD_U_CHAR(dptr, AUT_ATTR32);
153
154 /*
155 * Darwin defines the size for the file mode
156 * as 2 bytes; BSM defines 4 so pad with 0
157 */
158 ADD_U_INT16(dptr, pad0_16);
159 ADD_U_INT16(dptr, vni->vn_mode);
160
161 ADD_U_INT32(dptr, vni->vn_uid);
162 ADD_U_INT32(dptr, vni->vn_gid);
163 ADD_U_INT32(dptr, vni->vn_fsid);
164
165 /*
166 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
167 * Attempt to handle both, and let the compiler sort it out. If we
168 * could pick this out at compile-time, it would be better, so as to
169 * avoid the else case below.
170 */
171 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
172 ADD_U_INT32(dptr, pad0_32);
173 ADD_U_INT32(dptr, vni->vn_fileid);
174 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) {
175 ADD_U_INT64(dptr, vni->vn_fileid);
176 } else {
177 ADD_U_INT64(dptr, 0LL);
178 }
179
180 ADD_U_INT32(dptr, vni->vn_dev);
181
182 return t;
183}
184
185token_t *
186au_to_attr64(struct vnode_au_info *vni)
187{
188 token_t *t;
189 u_char *dptr = NULL;
190 u_int16_t pad0_16 = 0;
191 u_int16_t pad0_32 = 0;
192
193 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
194 3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
195
196 ADD_U_CHAR(dptr, AUT_ATTR64);
197
198 /*
199 * Darwin defines the size for the file mode
200 * as 2 bytes; BSM defines 4 so pad with 0
201 */
202 ADD_U_INT16(dptr, pad0_16);
203 ADD_U_INT16(dptr, vni->vn_mode);
204
205 ADD_U_INT32(dptr, vni->vn_uid);
206 ADD_U_INT32(dptr, vni->vn_gid);
207 ADD_U_INT32(dptr, vni->vn_fsid);
208
209 /*
210 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
211 * Attempt to handle both, and let the compiler sort it out. If we
212 * could pick this out at compile-time, it would be better, so as to
213 * avoid the else case below.
214 */
215 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
216 ADD_U_INT32(dptr, pad0_32);
217 ADD_U_INT32(dptr, vni->vn_fileid);
218 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) {
219 ADD_U_INT64(dptr, vni->vn_fileid);
220 } else {
221 ADD_U_INT64(dptr, 0LL);
222 }
223
224 ADD_U_INT64(dptr, vni->vn_dev);
225
226 return t;
227}
228
229token_t *
230au_to_attr(struct vnode_au_info *vni)
231{
232 return au_to_attr32(vni);
233}
234#endif /* defined(_KERNEL) || defined(KERNEL) */
235
236/*
237 * token ID 1 byte
238 * how to print 1 byte
239 * basic unit 1 byte
240 * unit count 1 byte
241 * data items (depends on basic unit)
242 */
243token_t *
244au_to_data(char unit_print, char unit_type, char unit_count, const char *p)
245{
246 token_t *t;
247 u_char *dptr = NULL;
248 size_t datasize, totdata, tokenlen;
249
250 /* Determine the size of the basic unit. */
251 switch (unit_type) {
252 case AUR_BYTE:
253 /* case AUR_CHAR: */
254 datasize = AUR_BYTE_SIZE;
255 break;
256
257 case AUR_SHORT:
258 datasize = AUR_SHORT_SIZE;
259 break;
260
261 case AUR_INT32:
262 /* case AUR_INT: */
263 datasize = AUR_INT32_SIZE;
264 break;
265
266 case AUR_INT64:
267 datasize = AUR_INT64_SIZE;
268 break;
269
270 default:
271 /* For unknown assume byte. */
272 datasize = AUR_BYTE_SIZE;
273 break;
274 }
275
276 totdata = datasize * (size_t)unit_count;
277
278 tokenlen = 4 * sizeof(u_char) + totdata;
279 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
280 ("au_to_data: token length (%zu) exceeds maximum allowed size", tokenlen));
281
282 GET_TOKEN_AREA(t, dptr, tokenlen);
283
284 ADD_U_CHAR(dptr, AUT_DATA);
285 ADD_U_CHAR(dptr, unit_print);
286 ADD_U_CHAR(dptr, unit_type);
287 ADD_U_CHAR(dptr, unit_count);
288 ADD_MEM(dptr, p, totdata);
289
290 return t;
291}
292
293/*
294 * token ID 1 byte
295 * status 4 bytes
296 * return value 4 bytes
297 */
298token_t *
299au_to_exit(int retval, int err)
300{
301 token_t *t;
302 u_char *dptr = NULL;
303
304 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
305
306 ADD_U_CHAR(dptr, AUT_EXIT);
307 ADD_U_INT32(dptr, err);
308 ADD_U_INT32(dptr, retval);
309
310 return t;
311}
312
313/*
314 */
315token_t *
316au_to_groups(int *groups)
317{
318 return au_to_newgroups(AUDIT_MAX_GROUPS, groups: (gid_t *)groups);
319}
320
321/*
322 * token ID 1 byte
323 * number groups 2 bytes
324 * group list count * 4 bytes
325 */
326token_t *
327au_to_newgroups(u_int16_t n, gid_t *groups)
328{
329 token_t *t;
330 u_char *dptr = NULL;
331 int i;
332 size_t tokenlen;
333
334 KASSERT(n <= AUDIT_MAX_GROUPS, "au_to_newgroups: groups exceed maximum number of those allowed");
335
336 tokenlen = sizeof(u_char) + sizeof(u_int16_t) + n * sizeof(u_int32_t);
337 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
338 ("au_to_newgroups: token length (%zu) exceeds maximum allowed size", tokenlen));
339
340 GET_TOKEN_AREA(t, dptr, tokenlen);
341
342 ADD_U_CHAR(dptr, AUT_NEWGROUPS);
343 ADD_U_INT16(dptr, n);
344 for (i = 0; i < n; i++) {
345 ADD_U_INT32(dptr, groups[i]);
346 }
347
348 return t;
349}
350
351/*
352 * token ID 1 byte
353 * internet address 4 bytes
354 */
355token_t *
356au_to_in_addr(struct in_addr *internet_addr)
357{
358 token_t *t;
359 u_char *dptr = NULL;
360
361 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
362
363 ADD_U_CHAR(dptr, AUT_IN_ADDR);
364 ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
365
366 return t;
367}
368
369/*
370 * token ID 1 byte
371 * address type/length 4 bytes
372 * address 16 bytes
373 */
374token_t *
375au_to_in_addr_ex(struct in6_addr *internet_addr)
376{
377 token_t *t;
378 u_char *dptr = NULL;
379 u_int32_t type = AU_IPv6;
380
381 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
382
383 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
384 ADD_U_INT32(dptr, type);
385 ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
386
387 return t;
388}
389
390/*
391 * token ID 1 byte
392 * ip header 20 bytes
393 *
394 * The IP header should be submitted in network byte order.
395 */
396token_t *
397au_to_ip(struct ip *ip)
398{
399 token_t *t;
400 u_char *dptr = NULL;
401
402 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
403
404 ADD_U_CHAR(dptr, AUT_IP);
405 ADD_MEM(dptr, ip, sizeof(struct ip));
406
407 return t;
408}
409
410/*
411 * token ID 1 byte
412 * object ID type 1 byte
413 * object ID 4 bytes
414 */
415token_t *
416au_to_ipc(char type, int id)
417{
418 token_t *t;
419 u_char *dptr = NULL;
420
421 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
422
423 ADD_U_CHAR(dptr, AUT_IPC);
424 ADD_U_CHAR(dptr, type);
425 ADD_U_INT32(dptr, id);
426
427 return t;
428}
429
430/*
431 * token ID 1 byte
432 * owner user ID 4 bytes
433 * owner group ID 4 bytes
434 * creator user ID 4 bytes
435 * creator group ID 4 bytes
436 * access mode 4 bytes
437 * slot sequence # 4 bytes
438 * key 4 bytes
439 */
440token_t *
441au_to_ipc_perm(struct ipc_perm *perm)
442{
443 token_t *t;
444 u_char *dptr = NULL;
445 u_int16_t pad0 = 0;
446
447 if (perm == NULL) {
448 return NULL;
449 }
450
451 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
452 sizeof(u_int32_t));
453
454 ADD_U_CHAR(dptr, AUT_IPC_PERM);
455
456 /*
457 * Darwin defines the size for the file mode
458 * as 2 bytes; BSM defines 4 so pad with 0
459 */
460 ADD_U_INT32(dptr, perm->uid);
461 ADD_U_INT32(dptr, perm->gid);
462 ADD_U_INT32(dptr, perm->cuid);
463 ADD_U_INT32(dptr, perm->cgid);
464
465 ADD_U_INT16(dptr, pad0);
466 ADD_U_INT16(dptr, perm->mode);
467
468 ADD_U_INT16(dptr, pad0);
469 ADD_U_INT16(dptr, perm->_seq);
470
471 ADD_U_INT16(dptr, pad0);
472 ADD_U_INT16(dptr, perm->_key);
473
474 return t;
475}
476
477/*
478 * token ID 1 byte
479 * port IP address 2 bytes
480 */
481token_t *
482au_to_iport(u_int16_t iport)
483{
484 token_t *t;
485 u_char *dptr = NULL;
486
487 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
488
489 ADD_U_CHAR(dptr, AUT_IPORT);
490 ADD_U_INT16(dptr, iport);
491
492 return t;
493}
494
495/*
496 * token ID 1 byte
497 * size 2 bytes
498 * data size bytes
499 */
500token_t *
501au_to_opaque(const char *data, uint16_t bytes)
502{
503 token_t *t;
504 u_char *dptr = NULL;
505 size_t tokenlen;
506
507 tokenlen = sizeof(u_char) + sizeof(u_int16_t) + bytes;
508 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
509 ("au_to_opaque: token length (%zu) exceeds maximum allowed size", tokenlen));
510
511 GET_TOKEN_AREA(t, dptr, tokenlen);
512
513 ADD_U_CHAR(dptr, AUT_OPAQUE);
514 ADD_U_INT16(dptr, bytes);
515 ADD_MEM(dptr, data, bytes);
516
517 return t;
518}
519
520/*
521 * token ID 1 byte
522 * seconds of time 4 bytes
523 * milliseconds of time 4 bytes
524 * file name len 2 bytes
525 * file pathname N bytes + 1 terminating NULL byte
526 */
527token_t *
528au_to_file(const char *file, struct timeval tm)
529{
530 token_t *t;
531 u_char *dptr = NULL;
532 u_int16_t filelen;
533 u_int32_t timems;
534 size_t tokenlen;
535
536 filelen = strlen(s: file);
537 filelen += 1;
538
539 tokenlen = sizeof(u_char) + 2 * sizeof(u_int32_t) + sizeof(u_int16_t) + filelen;
540 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
541 ("au_to_file: token length (%zu) exceeds maximum allowed size", tokenlen));
542
543 GET_TOKEN_AREA(t, dptr, tokenlen);
544
545 timems = tm.tv_usec / 1000;
546
547 ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
548 ADD_U_INT32(dptr, tm.tv_sec);
549 ADD_U_INT32(dptr, timems); /* We need time in ms. */
550 ADD_U_INT16(dptr, filelen);
551 ADD_STRING(dptr, file, filelen);
552
553 return t;
554}
555
556/*
557 * token ID 1 byte
558 * text length 2 bytes
559 * text N bytes + 1 terminating NULL byte
560 */
561token_t *
562au_to_text(const char *text)
563{
564 token_t *t;
565 u_char *dptr = NULL;
566 u_int16_t textlen;
567 size_t tokenlen;
568
569 textlen = strlen(s: text);
570 textlen += 1;
571
572 tokenlen = sizeof(u_char) + sizeof(u_int16_t) + textlen;
573 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
574 ("au_to_text: token length (%zu) exceeds maximum allowed size", tokenlen));
575
576 GET_TOKEN_AREA(t, dptr, tokenlen);
577
578 ADD_U_CHAR(dptr, AUT_TEXT);
579 ADD_U_INT16(dptr, textlen);
580 ADD_STRING(dptr, text, textlen);
581
582 return t;
583}
584
585/*
586 * token ID 1 byte
587 * path length 2 bytes
588 * path N bytes + 1 terminating NULL byte
589 */
590token_t *
591au_to_path(const char *text)
592{
593 token_t *t;
594 u_char *dptr = NULL;
595 u_int16_t textlen;
596 size_t tokenlen;
597
598 textlen = strlen(s: text);
599 textlen += 1;
600
601 tokenlen = sizeof(u_char) + sizeof(u_int16_t) + textlen;
602 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
603 ("au_to_path: token length (%zu) exceeds maximum allowed size", tokenlen));
604
605 GET_TOKEN_AREA(t, dptr, tokenlen);
606
607 ADD_U_CHAR(dptr, AUT_PATH);
608 ADD_U_INT16(dptr, textlen);
609 ADD_STRING(dptr, text, textlen);
610
611 return t;
612}
613
614/*
615 * token ID 1 byte
616 * audit ID 4 bytes
617 * effective user ID 4 bytes
618 * effective group ID 4 bytes
619 * real user ID 4 bytes
620 * real group ID 4 bytes
621 * process ID 4 bytes
622 * session ID 4 bytes
623 * terminal ID
624 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
625 * machine address 4 bytes
626 */
627token_t *
628au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
629 pid_t pid, au_asid_t sid, au_tid_t *tid)
630{
631 token_t *t;
632 u_char *dptr = NULL;
633
634 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
635
636 ADD_U_CHAR(dptr, AUT_PROCESS32);
637 ADD_U_INT32(dptr, auid);
638 ADD_U_INT32(dptr, euid);
639 ADD_U_INT32(dptr, egid);
640 ADD_U_INT32(dptr, ruid);
641 ADD_U_INT32(dptr, rgid);
642 ADD_U_INT32(dptr, pid);
643 ADD_U_INT32(dptr, sid);
644 ADD_U_INT32(dptr, tid->port);
645 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
646
647 return t;
648}
649
650token_t *
651au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
652 pid_t pid, au_asid_t sid, au_tid_t *tid)
653{
654 token_t *t;
655 u_char *dptr = NULL;
656
657 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
658 sizeof(u_int64_t));
659
660 ADD_U_CHAR(dptr, AUT_PROCESS64);
661 ADD_U_INT32(dptr, auid);
662 ADD_U_INT32(dptr, euid);
663 ADD_U_INT32(dptr, egid);
664 ADD_U_INT32(dptr, ruid);
665 ADD_U_INT32(dptr, rgid);
666 ADD_U_INT32(dptr, pid);
667 ADD_U_INT32(dptr, sid);
668 ADD_U_INT64(dptr, tid->port);
669 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
670
671 return t;
672}
673
674token_t *
675au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
676 pid_t pid, au_asid_t sid, au_tid_t *tid)
677{
678 return au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
679 tid);
680}
681
682/*
683 * token ID 1 byte
684 * audit ID 4 bytes
685 * effective user ID 4 bytes
686 * effective group ID 4 bytes
687 * real user ID 4 bytes
688 * real group ID 4 bytes
689 * process ID 4 bytes
690 * session ID 4 bytes
691 * terminal ID
692 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
693 * address type-len 4 bytes
694 * machine address 4/16 bytes
695 */
696token_t *
697au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
698 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
699{
700 token_t *t;
701 u_char *dptr = NULL;
702
703 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
704 ("au_to_process32_ex: type %u", (unsigned int)tid->at_type));
705 if (tid->at_type == AU_IPv6) {
706 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
707 sizeof(u_int32_t));
708 } else {
709 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
710 sizeof(u_int32_t));
711 }
712
713 ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
714 ADD_U_INT32(dptr, auid);
715 ADD_U_INT32(dptr, euid);
716 ADD_U_INT32(dptr, egid);
717 ADD_U_INT32(dptr, ruid);
718 ADD_U_INT32(dptr, rgid);
719 ADD_U_INT32(dptr, pid);
720 ADD_U_INT32(dptr, sid);
721 ADD_U_INT32(dptr, tid->at_port);
722 ADD_U_INT32(dptr, tid->at_type);
723 if (tid->at_type == AU_IPv6) {
724 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
725 } else {
726 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
727 }
728
729 return t;
730}
731
732token_t *
733au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
734 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
735{
736 token_t *t = NULL;
737 u_char *dptr = NULL;
738
739 if (tid->at_type == AU_IPv4) {
740 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
741 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
742 2 * sizeof(u_int32_t));
743 } else if (tid->at_type == AU_IPv6) {
744 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
745 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
746 5 * sizeof(u_int32_t));
747 } else {
748 panic("au_to_process64_ex: invalidate at_type (%d)",
749 tid->at_type);
750 }
751
752 ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
753 ADD_U_INT32(dptr, auid);
754 ADD_U_INT32(dptr, euid);
755 ADD_U_INT32(dptr, egid);
756 ADD_U_INT32(dptr, ruid);
757 ADD_U_INT32(dptr, rgid);
758 ADD_U_INT32(dptr, pid);
759 ADD_U_INT32(dptr, sid);
760 ADD_U_INT64(dptr, tid->at_port);
761 ADD_U_INT32(dptr, tid->at_type);
762 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
763 if (tid->at_type == AU_IPv6) {
764 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
765 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
766 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
767 }
768
769 return t;
770}
771
772token_t *
773au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
774 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
775{
776 return au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
777 tid);
778}
779
780/*
781 * token ID 1 byte
782 * error status 1 byte
783 * return value 4 bytes/8 bytes (32-bit/64-bit value)
784 */
785token_t *
786au_to_return32(char status, u_int32_t ret)
787{
788 token_t *t;
789 u_char *dptr = NULL;
790
791 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
792
793 ADD_U_CHAR(dptr, AUT_RETURN32);
794 ADD_U_CHAR(dptr, status);
795 ADD_U_INT32(dptr, ret);
796
797 return t;
798}
799
800token_t *
801au_to_return64(char status, u_int64_t ret)
802{
803 token_t *t;
804 u_char *dptr = NULL;
805
806 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
807
808 ADD_U_CHAR(dptr, AUT_RETURN64);
809 ADD_U_CHAR(dptr, status);
810 ADD_U_INT64(dptr, ret);
811
812 return t;
813}
814
815token_t *
816au_to_return(char status, u_int32_t ret)
817{
818 return au_to_return32(status, ret);
819}
820
821/*
822 * token ID 1 byte
823 * sequence number 4 bytes
824 */
825token_t *
826au_to_seq(long audit_count)
827{
828 token_t *t;
829 u_char *dptr = NULL;
830
831 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
832
833 ADD_U_CHAR(dptr, AUT_SEQ);
834 ADD_U_INT32(dptr, (u_int32_t) audit_count);
835
836 return t;
837}
838
839/*
840 * token ID 1 byte
841 * socket domain 2 bytes
842 * socket type 2 bytes
843 * address type 2 bytes
844 * local port 2 bytes
845 * local address 4 bytes/16 bytes (IPv4/IPv6 address)
846 * remote port 2 bytes
847 * remote address 4 bytes/16 bytes (IPv4/IPv6 address)
848 */
849token_t *
850au_to_socket_ex(u_short so_domain, u_short so_type,
851 struct sockaddr *sa_local, struct sockaddr *sa_remote)
852{
853 token_t *t;
854 u_char *dptr = NULL;
855 struct sockaddr_in *sin;
856 struct sockaddr_in6 *sin6;
857
858 if (so_domain == AF_INET) {
859 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
860 5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
861 } else if (so_domain == AF_INET6) {
862 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
863 5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
864 } else {
865 return NULL;
866 }
867
868 ADD_U_CHAR(dptr, AUT_SOCKET_EX);
869 ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
870 ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
871 if (so_domain == AF_INET) {
872 ADD_U_INT16(dptr, AU_IPv4);
873 sin = (struct sockaddr_in *)sa_local;
874 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
875 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
876 sin = (struct sockaddr_in *)sa_remote;
877 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
878 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
879 } else { /* if (so_domain == AF_INET6) */
880 ADD_U_INT16(dptr, AU_IPv6);
881 sin6 = (struct sockaddr_in6 *)sa_local;
882 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
883 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
884 sin6 = (struct sockaddr_in6 *)sa_remote;
885 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
886 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
887 }
888
889 return t;
890}
891
892/*
893 * token ID 1 byte
894 * socket family 2 bytes
895 * path (up to) 104 bytes + NULL
896 */
897token_t *
898au_to_sock_unix(struct sockaddr_un *so)
899{
900 token_t *t;
901 u_char *dptr;
902 size_t slen;
903
904 static_assert(3 * sizeof(u_char) + sizeof(so->sun_path) + 1 <= KALLOC_SAFE_ALLOC_SIZE);
905
906 /*
907 * Please note that sun_len may not be correctly set and sun_path may
908 * not be NULL terminated.
909 */
910 if (so->sun_len >= offsetof(struct sockaddr_un, sun_path)) {
911 slen = min(a: so->sun_len - offsetof(struct sockaddr_un, sun_path),
912 b: strnlen(s: so->sun_path, n: sizeof(so->sun_path)));
913 } else {
914 slen = strnlen(s: so->sun_path, n: sizeof(so->sun_path));
915 }
916
917 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + slen + 1);
918
919 ADD_U_CHAR(dptr, AUT_SOCKUNIX);
920 /* BSM token has two bytes for family */
921 ADD_U_CHAR(dptr, 0);
922 ADD_U_CHAR(dptr, so->sun_family);
923 if (slen) {
924 ADD_MEM(dptr, so->sun_path, slen);
925 }
926 ADD_U_CHAR(dptr, '\0'); /* make the path a null-terminated string */
927
928 return t;
929}
930
931/*
932 * token ID 1 byte
933 * socket family 2 bytes
934 * local port 2 bytes
935 * socket address 4 bytes
936 */
937token_t *
938au_to_sock_inet32(struct sockaddr_in *so)
939{
940 token_t *t;
941 u_char *dptr = NULL;
942
943 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
944 sizeof(uint32_t));
945
946 ADD_U_CHAR(dptr, AUT_SOCKINET32);
947 /*
948 * Convert sin_family to the BSM value. Assume that both the port and
949 * the address in the sockaddr_in are already in network byte order,
950 * but family is in local byte order.
951 */
952 ADD_U_INT16(dptr, au_domain_to_bsm(so->sin_family));
953 ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
954 ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
955
956 return t;
957}
958
959/*
960 * token ID 1 byte
961 * socket family 2 bytes
962 * local port 2 bytes
963 * socket address 16 bytes
964 */
965token_t *
966au_to_sock_inet128(struct sockaddr_in6 *so)
967{
968 token_t *t;
969 u_char *dptr = NULL;
970
971 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
972 4 * sizeof(u_int32_t));
973
974 ADD_U_CHAR(dptr, AUT_SOCKINET128);
975 ADD_U_INT16(dptr, au_domain_to_bsm(so->sin6_family));
976
977 ADD_U_INT16(dptr, so->sin6_port);
978 ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
979
980 return t;
981}
982
983token_t *
984au_to_sock_inet(struct sockaddr_in *so)
985{
986 return au_to_sock_inet32(so);
987}
988
989/*
990 * token ID 1 byte
991 * audit ID 4 bytes
992 * effective user ID 4 bytes
993 * effective group ID 4 bytes
994 * real user ID 4 bytes
995 * real group ID 4 bytes
996 * process ID 4 bytes
997 * session ID 4 bytes
998 * terminal ID
999 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1000 * machine address 4 bytes
1001 */
1002token_t *
1003au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1004 pid_t pid, au_asid_t sid, au_tid_t *tid)
1005{
1006 token_t *t;
1007 u_char *dptr = NULL;
1008
1009 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1010
1011 ADD_U_CHAR(dptr, AUT_SUBJECT32);
1012 ADD_U_INT32(dptr, auid);
1013 ADD_U_INT32(dptr, euid);
1014 ADD_U_INT32(dptr, egid);
1015 ADD_U_INT32(dptr, ruid);
1016 ADD_U_INT32(dptr, rgid);
1017 ADD_U_INT32(dptr, pid);
1018 ADD_U_INT32(dptr, sid);
1019 ADD_U_INT32(dptr, tid->port);
1020 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1021
1022 return t;
1023}
1024
1025token_t *
1026au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1027 pid_t pid, au_asid_t sid, au_tid_t *tid)
1028{
1029 token_t *t;
1030 u_char *dptr = NULL;
1031
1032 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1033 sizeof(u_int64_t) + sizeof(u_int32_t));
1034
1035 ADD_U_CHAR(dptr, AUT_SUBJECT64);
1036 ADD_U_INT32(dptr, auid);
1037 ADD_U_INT32(dptr, euid);
1038 ADD_U_INT32(dptr, egid);
1039 ADD_U_INT32(dptr, ruid);
1040 ADD_U_INT32(dptr, rgid);
1041 ADD_U_INT32(dptr, pid);
1042 ADD_U_INT32(dptr, sid);
1043 ADD_U_INT64(dptr, tid->port);
1044 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1045
1046 return t;
1047}
1048
1049token_t *
1050au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1051 pid_t pid, au_asid_t sid, au_tid_t *tid)
1052{
1053 return au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1054 tid);
1055}
1056
1057/*
1058 * token ID 1 byte
1059 * audit ID 4 bytes
1060 * effective user ID 4 bytes
1061 * effective group ID 4 bytes
1062 * real user ID 4 bytes
1063 * real group ID 4 bytes
1064 * process ID 4 bytes
1065 * session ID 4 bytes
1066 * terminal ID
1067 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1068 * address type/length 4 bytes
1069 * machine address 4/16 bytes
1070 */
1071token_t *
1072au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1073 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1074{
1075 token_t *t;
1076 u_char *dptr = NULL;
1077
1078 KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1079 ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1080 if (tid->at_type == AU_IPv6) {
1081 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1082 sizeof(u_int32_t));
1083 } else {
1084 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1085 sizeof(u_int32_t));
1086 }
1087
1088 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1089 ADD_U_INT32(dptr, auid);
1090 ADD_U_INT32(dptr, euid);
1091 ADD_U_INT32(dptr, egid);
1092 ADD_U_INT32(dptr, ruid);
1093 ADD_U_INT32(dptr, rgid);
1094 ADD_U_INT32(dptr, pid);
1095 ADD_U_INT32(dptr, sid);
1096 ADD_U_INT32(dptr, tid->at_port);
1097 ADD_U_INT32(dptr, tid->at_type);
1098 if (tid->at_type == AU_IPv6) {
1099 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1100 } else {
1101 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1102 }
1103
1104 return t;
1105}
1106
1107token_t *
1108au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1109 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1110{
1111 token_t *t = NULL;
1112 u_char *dptr = NULL;
1113
1114 if (tid->at_type == AU_IPv4) {
1115 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1116 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1117 2 * sizeof(u_int32_t));
1118 } else if (tid->at_type == AU_IPv6) {
1119 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1120 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1121 5 * sizeof(u_int32_t));
1122 } else {
1123 panic("au_to_subject64_ex: invalid at_type (%d)",
1124 tid->at_type);
1125 }
1126
1127 ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1128 ADD_U_INT32(dptr, auid);
1129 ADD_U_INT32(dptr, euid);
1130 ADD_U_INT32(dptr, egid);
1131 ADD_U_INT32(dptr, ruid);
1132 ADD_U_INT32(dptr, rgid);
1133 ADD_U_INT32(dptr, pid);
1134 ADD_U_INT32(dptr, sid);
1135 ADD_U_INT64(dptr, tid->at_port);
1136 ADD_U_INT32(dptr, tid->at_type);
1137 if (tid->at_type == AU_IPv6) {
1138 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1139 } else {
1140 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1141 }
1142
1143 return t;
1144}
1145
1146token_t *
1147au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1148 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1149{
1150 return au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1151 tid);
1152}
1153
1154#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1155/*
1156 * Collects audit information for the current process
1157 * and creates a subject token from it
1158 */
1159token_t *
1160au_to_me(void)
1161{
1162 auditinfo_t auinfo;
1163
1164 if (getaudit(&auinfo) != 0) {
1165 return NULL;
1166 }
1167
1168 return au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1169 getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid);
1170}
1171#endif
1172
1173#if defined(_KERNEL) || defined(KERNEL)
1174static token_t *
1175au_to_exec_strings(const char *strs, int count, u_char type)
1176{
1177 token_t *t;
1178 u_char *dptr = NULL;
1179 u_int32_t totlen;
1180 int ctr;
1181 const char *p;
1182 size_t nextlen;
1183 size_t tokenlen;
1184 const size_t totlen_max = KALLOC_SAFE_ALLOC_SIZE - sizeof(u_char) - sizeof(u_int32_t);
1185
1186 totlen = 0;
1187 ctr = count;
1188 p = strs;
1189 while (ctr-- > 0) {
1190 nextlen = strlen(s: p);
1191
1192 if (totlen + nextlen + 1 >= totlen_max) {
1193 break;
1194 }
1195
1196 totlen += nextlen + 1;
1197 p = strs + totlen;
1198 }
1199
1200 tokenlen = sizeof(u_char) + sizeof(u_int32_t) + totlen;
1201 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
1202 ("au_to_exec_strings: token length (%zu) exceeds maximum allowed size", tokenlen));
1203
1204 GET_TOKEN_AREA(t, dptr, tokenlen);
1205 ADD_U_CHAR(dptr, type);
1206 ADD_U_INT32(dptr, count);
1207 ADD_STRING(dptr, strs, totlen);
1208
1209 return t;
1210}
1211
1212/*
1213 * token ID 1 byte
1214 * count 4 bytes
1215 * text count null-terminated strings
1216 */
1217token_t *
1218au_to_exec_args(char *args, int argc)
1219{
1220 return au_to_exec_strings(strs: args, count: argc, AUT_EXEC_ARGS);
1221}
1222
1223/*
1224 * token ID 1 byte
1225 * count 4 bytes
1226 * text count null-terminated strings
1227 */
1228token_t *
1229au_to_exec_env(char *envs, int envc)
1230{
1231 return au_to_exec_strings(strs: envs, count: envc, AUT_EXEC_ENV);
1232}
1233
1234/*
1235 * token ID 1 byte
1236 * count 4 bytes
1237 * text count null-terminated strings
1238 */
1239token_t *
1240au_to_certificate_hash(char *hashes, int hashc)
1241{
1242 return au_to_exec_strings(strs: hashes, count: hashc, AUT_CERT_HASH);
1243}
1244
1245/*
1246 * token ID 1 byte
1247 * count 4 bytes
1248 * text count null-terminated strings
1249 */
1250token_t *
1251au_to_krb5_principal(char *principals, int princ)
1252{
1253 return au_to_exec_strings(strs: principals, count: princ, AUT_KRB5_PRINCIPAL);
1254}
1255#else
1256/*
1257 * token ID 1 byte
1258 * count 4 bytes
1259 * text count null-terminated strings
1260 */
1261token_t *
1262au_to_exec_args(char **argv)
1263{
1264 token_t *t;
1265 u_char *dptr = NULL;
1266 const char *nextarg;
1267 size_t nextlen;
1268 int i, count = 0;
1269 size_t totlen = 0;
1270 size_t tokenlen;
1271 const size_t totlen_max = KALLOC_SAFE_ALLOC_SIZE - sizeof(u_char) - sizeof(u_int32_t);
1272
1273 nextarg = *argv;
1274
1275 while (nextarg != NULL) {
1276 nextlen = strlen(nextarg);
1277
1278 if (totlen + nextlen + 1 >= totlen_max) {
1279 break;
1280 }
1281
1282 totlen += nextlen + 1;
1283 count++;
1284 nextarg = *(argv + count);
1285 }
1286
1287 tokenlen = sizeof(u_char) + sizeof(u_int32_t) + totlen;
1288 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
1289 ("au_to_exec_args: token length (%zu) exceeds maximum allowed size", tokenlen));
1290
1291 GET_TOKEN_AREA(t, dptr, tokenlen);
1292
1293 ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1294 ADD_U_INT32(dptr, count);
1295
1296 for (i = 0; i < count; i++) {
1297 nextarg = *(argv + i);
1298 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1299 }
1300
1301 return t;
1302}
1303
1304/*
1305 * token ID 1 byte
1306 * zonename length 2 bytes
1307 * zonename N bytes + 1 terminating NULL byte
1308 */
1309token_t *
1310au_to_zonename(char *zonename)
1311{
1312 u_char *dptr = NULL;
1313 u_int16_t textlen;
1314 size_t tokenlen;
1315 token_t *t;
1316
1317 textlen = strlen(zonename);
1318 textlen += 1;
1319
1320 tokenlen = sizeof(u_char) + sizeof(u_int16_t) + textlen;
1321 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
1322 ("au_to_zonename: token length (%zu) exceeds maximum allowed size", tokenlen));
1323
1324 GET_TOKEN_AREA(t, dptr, tokenlen);
1325 ADD_U_CHAR(dptr, AUT_ZONENAME);
1326 ADD_U_INT16(dptr, textlen);
1327 ADD_STRING(dptr, zonename, textlen);
1328 return t;
1329}
1330
1331/*
1332 * token ID 1 byte
1333 * count 4 bytes
1334 * text count null-terminated strings
1335 */
1336token_t *
1337au_to_exec_env(char **envp)
1338{
1339 token_t *t;
1340 u_char *dptr = NULL;
1341 int i, count = 0;
1342 size_t nextlen;
1343 size_t totlen = 0;
1344 const char *nextenv;
1345 size_t tokenlen;
1346 const size_t totlen_max = KALLOC_SAFE_ALLOC_SIZE - sizeof(u_char) - sizeof(u_int32_t);
1347
1348 nextenv = *envp;
1349
1350 while (nextenv != NULL) {
1351 nextlen = strlen(nextenv);
1352
1353 if (totlen + nextlen + 1 >= totlen_max) {
1354 break;
1355 }
1356
1357 totlen += nextlen + 1;
1358 count++;
1359 nextenv = *(envp + count);
1360 }
1361
1362 tokenlen = sizeof(u_char) + sizeof(u_int32_t) + totlen;
1363 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
1364 ("au_to_exec_env: token length (%zu) exceeds maximum allowed size", tokenlen));
1365
1366 GET_TOKEN_AREA(t, dptr, tokenlen);
1367
1368 ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1369 ADD_U_INT32(dptr, count);
1370
1371 for (i = 0; i < count; i++) {
1372 nextenv = *(envp + i);
1373 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1374 }
1375
1376 return t;
1377}
1378#endif /* !(defined(_KERNEL) || defined(KERNEL)) */
1379
1380/*
1381 * token ID 1 byte
1382 * signer type 4 bytes
1383 * signer id length 2 bytes
1384 * signer id n bytes
1385 * signer id truncated 1 byte
1386 * team id length 2 bytes
1387 * team id n bytes
1388 * team id truncated 1 byte
1389 * cdhash length 2 bytes
1390 * cdhash n bytes
1391 */
1392token_t*
1393au_to_identity(uint32_t signer_type, const char* signing_id,
1394 u_char signing_id_trunc, const char* team_id, u_char team_id_trunc,
1395 uint8_t* cdhash, uint16_t cdhash_len)
1396{
1397 token_t *t = NULL;
1398 u_char *dptr = NULL;
1399 size_t signing_id_len = 0;
1400 size_t team_id_len = 0;
1401 size_t totlen = 0;
1402
1403 if (signing_id) {
1404 signing_id_len = strlen(s: signing_id);
1405 }
1406
1407 if (team_id) {
1408 team_id_len = strlen(s: team_id);
1409 }
1410
1411 totlen =
1412 sizeof(u_char) + // token id
1413 sizeof(uint32_t) + // signer type
1414 sizeof(uint16_t) + // singing id length
1415 signing_id_len + // length of signing id to copy
1416 sizeof(u_char) + // null terminator for signing id
1417 sizeof(u_char) + // if signing id truncated
1418 sizeof(uint16_t) + // team id length
1419 team_id_len + // length of team id to copy
1420 sizeof(u_char) + // null terminator for team id
1421 sizeof(u_char) + // if team id truncated
1422 sizeof(uint16_t) + // cdhash length
1423 cdhash_len; // cdhash buffer
1424
1425 KASSERT(totlen <= KALLOC_SAFE_ALLOC_SIZE,
1426 ("au_to_identity: token length (%zu) exceeds maximum allowed size", tokenlen));
1427 GET_TOKEN_AREA(t, dptr, totlen);
1428
1429 ADD_U_CHAR(dptr, AUT_IDENTITY); // token id
1430 ADD_U_INT32(dptr, signer_type); // signer type
1431 ADD_U_INT16(dptr, signing_id_len + 1); // signing id length+null
1432 ADD_STRING(dptr, signing_id, signing_id_len); // truncated signing id
1433 ADD_U_CHAR(dptr, 0); // null terminator byte
1434 ADD_U_CHAR(dptr, signing_id_trunc); // if signing id is trunc
1435 ADD_U_INT16(dptr, team_id_len + 1); // team id length+null
1436 ADD_STRING(dptr, team_id, team_id_len); // truncated team id
1437 ADD_U_CHAR(dptr, 0); // null terminator byte
1438 ADD_U_CHAR(dptr, team_id_trunc); // if team id is trunc
1439 ADD_U_INT16(dptr, cdhash_len); // cdhash length
1440 ADD_MEM(dptr, cdhash, cdhash_len); // cdhash
1441
1442 return t;
1443}
1444
1445/*
1446 * token ID 1 byte
1447 * record byte count 4 bytes
1448 * version # 1 byte
1449 * event type 2 bytes
1450 * event modifier 2 bytes
1451 * address type/length 4 bytes
1452 * machine address 4 bytes/16 bytes (IPv4/IPv6 address)
1453 * seconds of time 4 bytes/8 bytes (32/64-bits)
1454 * milliseconds of time 4 bytes/8 bytes (32/64-bits)
1455 */
1456token_t *
1457au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1458 struct timeval tm, struct auditinfo_addr *aia)
1459{
1460 token_t *t;
1461 u_char *dptr = NULL;
1462 u_int32_t timems;
1463 struct au_tid_addr *tid;
1464 size_t tokenlen;
1465
1466 tid = &aia->ai_termid;
1467 KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
1468 ("au_to_header32_ex_tm: invalid address family"));
1469
1470 tokenlen = sizeof(u_char) + sizeof(u_int32_t) +
1471 sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 * sizeof(u_int32_t) +
1472 tid->at_type;
1473 KASSERT(tokenlen <= KALLOC_SAFE_ALLOC_SIZE,
1474 ("au_to_header32_ex_tm: token length (%zu) exceeds maximum allowed size", tokenlen));
1475
1476 GET_TOKEN_AREA(t, dptr, tokenlen);
1477
1478 ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1479 ADD_U_INT32(dptr, rec_size);
1480 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1481 ADD_U_INT16(dptr, e_type);
1482 ADD_U_INT16(dptr, e_mod);
1483 ADD_U_INT32(dptr, tid->at_type);
1484 if (tid->at_type == AU_IPv6) {
1485 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1486 } else {
1487 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1488 }
1489 timems = tm.tv_usec / 1000;
1490 /* Add the timestamp */
1491 ADD_U_INT32(dptr, tm.tv_sec);
1492 ADD_U_INT32(dptr, timems); /* We need time in ms. */
1493 return t;
1494}
1495
1496/*
1497 * token ID 1 byte
1498 * record byte count 4 bytes
1499 * version # 1 byte [2]
1500 * event type 2 bytes
1501 * event modifier 2 bytes
1502 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1503 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1504 */
1505token_t *
1506au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1507 struct timeval tm)
1508{
1509 token_t *t;
1510 u_char *dptr = NULL;
1511 u_int32_t timems;
1512
1513 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1514 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1515
1516 ADD_U_CHAR(dptr, AUT_HEADER32);
1517 ADD_U_INT32(dptr, rec_size);
1518 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1519 ADD_U_INT16(dptr, e_type);
1520 ADD_U_INT16(dptr, e_mod);
1521
1522 timems = tm.tv_usec / 1000;
1523 /* Add the timestamp */
1524 ADD_U_INT32(dptr, tm.tv_sec);
1525 ADD_U_INT32(dptr, timems); /* We need time in ms. */
1526
1527 return t;
1528}
1529
1530token_t *
1531au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1532 struct timeval tm)
1533{
1534 token_t *t;
1535 u_char *dptr = NULL;
1536 u_int32_t timems;
1537
1538 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1539 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1540
1541 ADD_U_CHAR(dptr, AUT_HEADER64);
1542 ADD_U_INT32(dptr, rec_size);
1543 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1544 ADD_U_INT16(dptr, e_type);
1545 ADD_U_INT16(dptr, e_mod);
1546
1547 timems = tm.tv_usec / 1000;
1548 /* Add the timestamp */
1549 ADD_U_INT64(dptr, tm.tv_sec);
1550 ADD_U_INT64(dptr, timems); /* We need time in ms. */
1551
1552 return t;
1553}
1554
1555/*
1556 * token ID 1 byte
1557 * trailer magic number 2 bytes
1558 * record byte count 4 bytes
1559 */
1560token_t *
1561au_to_trailer(int rec_size)
1562{
1563 token_t *t;
1564 u_char *dptr = NULL;
1565 u_int16_t magic = AUT_TRAILER_MAGIC;
1566
1567 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1568 sizeof(u_int32_t));
1569
1570 ADD_U_CHAR(dptr, AUT_TRAILER);
1571 ADD_U_INT16(dptr, magic);
1572 ADD_U_INT32(dptr, rec_size);
1573
1574 return t;
1575}
1576#endif /* CONFIG_AUDIT */
1577