1/*
2 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#include <sys/types.h>
30#include <sys/un.h>
31#include <sys/event.h>
32#include <sys/ucred.h>
33
34#include <sys/ipc.h>
35#include <bsm/audit.h>
36#include <bsm/audit_record.h>
37#include <bsm/audit_klib.h>
38#include <bsm/audit_kernel.h>
39
40#include <kern/clock.h>
41#include <kern/kalloc.h>
42
43#include <string.h>
44
45#define GET_TOKEN_AREA(tok, dptr, length) \
46        do {\
47                tok = (token_t *)kalloc(sizeof(*tok) + length); \
48                if(tok != NULL)\
49                {\
50                        tok->len = length;\
51                        dptr = tok->t_data = (u_char *)&tok[1];\
52                                memset(dptr, 0, length);\
53                        }\
54        }while(0)
55
56
57
58/*
59 * token ID                1 byte
60 * argument #              1 byte
61 * argument value          4 bytes/8 bytes (32-bit/64-bit value)
62 * text length             2 bytes
63 * text                    N bytes + 1 terminating NULL byte
64 */
65token_t *
66au_to_arg32(char n, const char *text, u_int32_t v)
67{
68	token_t *t;
69	u_char *dptr;
70	u_int16_t textlen;
71
72	if(text == NULL) {
73		return NULL;
74	}
75
76	textlen = strlen(text);
77
78	GET_TOKEN_AREA(t, dptr, 9 + textlen);
79	if(t == NULL) {
80		return NULL;
81	}
82
83	textlen += 1;
84
85	ADD_U_CHAR(dptr, AU_ARG32_TOKEN);
86	ADD_U_CHAR(dptr, n);
87	ADD_U_INT32(dptr, v);
88	ADD_U_INT16(dptr, textlen);
89	ADD_STRING(dptr, text, textlen);
90
91	return t;
92
93}
94
95token_t *
96au_to_arg64(char n, const char *text, u_int64_t v)
97{
98	token_t *t;
99	u_char *dptr;
100	u_int16_t textlen;
101
102	if(text == NULL) {
103		return NULL;
104	}
105
106	textlen = strlen(text);
107
108	GET_TOKEN_AREA(t, dptr, 13 + textlen);
109	if(t == NULL) {
110		return NULL;
111	}
112
113	textlen += 1;
114
115	ADD_U_CHAR(dptr, AU_ARG64_TOKEN);
116	ADD_U_CHAR(dptr, n);
117	ADD_U_INT64(dptr, v);
118	ADD_U_INT16(dptr, textlen);
119	ADD_STRING(dptr, text, textlen);
120
121	return t;
122
123}
124
125token_t *
126au_to_arg(char n, char *text, u_int32_t v)
127{
128	return au_to_arg32(n, text, v);
129}
130
131/*
132 * token ID                1 byte
133 * file access mode        4 bytes
134 * owner user ID           4 bytes
135 * owner group ID          4 bytes
136 * file system ID          4 bytes
137 * node ID                 8 bytes
138 * device                  4 bytes/8 bytes (32-bit/64-bit)
139 */
140token_t *au_to_attr32(__unused struct vnode_attr *attr)
141{
142	return NULL;
143}
144
145/* Kernel-specific version of the above function */
146token_t *kau_to_attr32(struct vnode_au_info *vni)
147{
148	token_t *t;
149	u_char *dptr;
150	u_int64_t fileid;
151	u_int16_t pad0_16 = 0;
152	u_int32_t pad0_32 = 0;
153
154	if(vni == NULL) {
155		return NULL;
156	}
157
158	GET_TOKEN_AREA(t, dptr, 29);
159	if(t == NULL) {
160		return NULL;
161	}
162
163	ADD_U_CHAR(dptr, AU_ATTR32_TOKEN);
164
165	/*
166	 * Darwin defines the size for the file mode as 2 bytes;
167	 * BSM defines 4. So we copy in a 0 first.
168	 */
169	ADD_U_INT16(dptr, pad0_16);
170	ADD_U_INT16(dptr, vni->vn_mode);
171
172	ADD_U_INT32(dptr, vni->vn_uid);
173	ADD_U_INT32(dptr, vni->vn_gid);
174	ADD_U_INT32(dptr, vni->vn_fsid);
175
176	/*
177	 * Darwin defines the size for fileid as 4 bytes;
178	 * BSM defines 8. So we copy in a 0 first.
179	 */
180	fileid = vni->vn_fileid;
181	ADD_U_INT32(dptr, pad0_32);
182	ADD_U_INT32(dptr, fileid);
183
184	ADD_U_INT32(dptr, vni->vn_dev);
185
186	return t;
187}
188
189token_t *au_to_attr64(__unused struct vnode_attr *attr)
190{
191	return NULL;
192}
193
194token_t *kau_to_attr64(__unused struct vnode_au_info *vni)
195{
196	return NULL;
197}
198
199token_t *au_to_attr(struct vnode_attr *attr)
200{
201	return au_to_attr32(attr);
202
203}
204
205
206/*
207 * token ID                1 byte
208 * how to print            1 byte
209 * basic unit              1 byte
210 * unit count              1 byte
211 * data items              (depends on basic unit)
212 */
213token_t *au_to_data(char unit_print, char unit_type,
214                    char unit_count, unsigned char *p)
215{
216	token_t *t;
217	u_char *dptr;
218	size_t datasize, totdata;
219
220	if(p == NULL) {
221		return NULL;
222	}
223
224	/* Determine the size of the basic unit */
225	switch(unit_type) {
226		case AUR_BYTE:	datasize = AUR_BYTE_SIZE;
227						break;
228
229		case AUR_SHORT:	datasize = AUR_SHORT_SIZE;
230						break;
231
232		case AUR_LONG:	datasize = AUR_LONG_SIZE;
233						break;
234
235		default: return NULL;
236	}
237
238	totdata = datasize * unit_count;
239
240	GET_TOKEN_AREA(t, dptr, totdata + 4);
241	if(t == NULL) {
242		return NULL;
243	}
244
245	ADD_U_CHAR(dptr, AU_ARB_TOKEN);
246	ADD_U_CHAR(dptr, unit_print);
247	ADD_U_CHAR(dptr, unit_type);
248	ADD_U_CHAR(dptr, unit_count);
249	ADD_MEM(dptr, p, totdata);
250
251	return t;
252}
253
254/*
255 * token ID                1 byte
256 * status		   4 bytes
257 * return value            4 bytes
258 */
259token_t *au_to_exit(int retval, int err)
260{
261	token_t *t;
262	u_char *dptr;
263
264	GET_TOKEN_AREA(t, dptr, 9);
265	if(t == NULL) {
266		return NULL;
267	}
268
269	ADD_U_CHAR(dptr, AU_EXIT_TOKEN);
270	ADD_U_INT32(dptr, err);
271	ADD_U_INT32(dptr, retval);
272
273	return t;
274}
275
276/*
277 */
278token_t *
279au_to_groups(gid_t *groups)
280{
281	return au_to_newgroups(MAX_GROUPS, groups);
282}
283
284/*
285 * token ID                1 byte
286 * number groups           2 bytes
287 * group list              count * 4 bytes
288 */
289token_t *au_to_newgroups(u_int16_t n, gid_t *groups)
290{
291	token_t *t;
292	u_char *dptr;
293	int i;
294
295	if(groups == NULL) {
296		return NULL;
297	}
298
299	GET_TOKEN_AREA(t, dptr, n * 4 + 3);
300	if(t == NULL) {
301		return NULL;
302	}
303
304	ADD_U_CHAR(dptr, AU_NEWGROUPS_TOKEN);
305	ADD_U_INT16(dptr, n);
306	for(i = 0; i < n; i++) {
307	    ADD_U_INT32(dptr, groups[i]);
308	}
309
310	return t;
311}
312
313
314
315
316/*
317 * token ID                1 byte
318 * internet address        4 bytes
319 */
320token_t *au_to_in_addr(struct in_addr *internet_addr)
321{
322	token_t *t;
323	u_char *dptr;
324
325	if(internet_addr == NULL) {
326		return NULL;
327	}
328
329	GET_TOKEN_AREA(t, dptr, 5);
330	if(t == NULL) {
331		return NULL;
332	}
333
334	ADD_U_CHAR(dptr, AU_IN_ADDR_TOKEN);
335	ADD_U_INT32(dptr, internet_addr->s_addr);
336
337	return t;
338}
339
340/*
341 * token ID                1 byte
342 * address type/length     4 bytes
343 * Address                16 bytes
344 */
345token_t *au_to_in_addr_ex(struct in6_addr *internet_addr)
346{
347	token_t *t;
348	u_char *dptr;
349	u_int32_t type = AF_INET6;
350
351	if(internet_addr == NULL) {
352		return NULL;
353	}
354
355	GET_TOKEN_AREA(t, dptr, 21);
356	if(t == NULL) {
357		return NULL;
358	}
359
360	ADD_U_CHAR(dptr, AU_IN_ADDR_EX_TOKEN);
361	ADD_U_INT32(dptr, type);
362	ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[0]);
363	ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[1]);
364	ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[2]);
365	ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[3]);
366
367	return t;
368}
369
370/*
371 * token ID                1 byte
372 * ip header		   20 bytes
373 */
374token_t *au_to_ip(struct ip *ip)
375{
376	token_t *t;
377	u_char *dptr;
378
379	if(ip == NULL) {
380		return NULL;
381	}
382
383	GET_TOKEN_AREA(t, dptr, 21);
384	if(t == NULL) {
385		return NULL;
386	}
387
388	ADD_U_CHAR(dptr, AU_IP_TOKEN);
389	ADD_MEM(dptr, ip, sizeof(struct ip));
390
391	return t;
392}
393
394/*
395 * token ID                1 byte
396 * object ID type          1 byte
397 * object ID               4 bytes
398 */
399token_t *au_to_ipc(char type, int id)
400{
401	token_t *t;
402	u_char *dptr;
403
404
405	GET_TOKEN_AREA(t, dptr, 6);
406	if(t == NULL) {
407		return NULL;
408	}
409
410	ADD_U_CHAR(dptr, AU_IPC_TOKEN);
411	ADD_U_CHAR(dptr, type);
412	ADD_U_INT32(dptr, id);
413
414	return t;
415}
416
417/*
418 * token ID                1 byte
419 * owner user ID           4 bytes
420 * owner group ID          4 bytes
421 * creator user ID         4 bytes
422 * creator group ID        4 bytes
423 * access mode             4 bytes
424 * slot sequence #         4 bytes
425 * key                     4 bytes
426 */
427token_t *au_to_ipc_perm(struct ipc_perm *perm)
428{
429	token_t *t;
430	u_char *dptr;
431	u_int16_t pad0 = 0;
432
433	if(perm == NULL) {
434		return NULL;
435	}
436
437	GET_TOKEN_AREA(t, dptr, 29);
438	if(t == NULL) {
439		return NULL;
440	}
441
442	/*
443	 * Darwin defines the sizes for ipc_perm members
444	 * as 2 bytes; BSM defines 4. So we copy in a 0 first.
445	 */
446	ADD_U_CHAR(dptr, AU_IPCPERM_TOKEN);
447
448	ADD_U_INT32(dptr, perm->uid);
449	ADD_U_INT32(dptr, perm->gid);
450	ADD_U_INT32(dptr, perm->cuid);
451	ADD_U_INT32(dptr, perm->cgid);
452
453	ADD_U_INT16(dptr, pad0);
454	ADD_U_INT16(dptr, perm->mode);
455
456	ADD_U_INT16(dptr, pad0);
457	ADD_U_INT16(dptr, perm->_seq);
458
459	ADD_U_INT16(dptr, pad0);
460	ADD_U_INT16(dptr, perm->_key);
461
462	return t;
463}
464
465
466/*
467 * token ID                1 byte
468 * port IP address         2 bytes
469 */
470token_t *au_to_iport(u_int16_t iport)
471{
472	token_t *t;
473	u_char *dptr;
474
475
476	GET_TOKEN_AREA(t, dptr, 3);
477	if(t == NULL) {
478		return NULL;
479	}
480
481	ADD_U_CHAR(dptr, AU_IPORT_TOKEN);
482	ADD_U_INT16(dptr, iport);
483
484	return t;
485}
486
487
488/*
489 * token ID                1 byte
490 * size 				   2 bytes
491 * data                    size bytes
492 */
493token_t *au_to_opaque(char *data, u_int16_t bytes)
494{
495	token_t *t;
496	u_char *dptr;
497
498	if((data == NULL) || (bytes <= 0)) {
499		return NULL;
500	}
501
502	GET_TOKEN_AREA(t, dptr, bytes + 3);
503	if(t == NULL) {
504		return NULL;
505	}
506
507	ADD_U_CHAR(dptr, AU_OPAQUE_TOKEN);
508	ADD_U_INT16(dptr, bytes);
509	ADD_MEM(dptr, data, bytes);
510
511	return t;
512}
513
514/*
515 * Kernel version of the add file token function, where the time value
516 * is passed in as an additional parameter.
517 * token ID                	1 byte
518 * seconds of time		4 bytes
519 * milliseconds of time		4 bytes
520 * file name len		2 bytes
521 * file pathname		N bytes + 1 terminating NULL byte
522 */
523token_t *kau_to_file(const char *file, const struct timeval *tv)
524{
525	token_t *t;
526	u_char *dptr;
527	u_int16_t filelen;
528	u_int32_t timems = tv->tv_usec/1000; /* We need time in ms */
529
530	if(file == NULL) {
531		return NULL;
532	}
533	filelen = strlen(file);
534
535	GET_TOKEN_AREA(t, dptr, filelen + 12);
536	if(t == NULL) {
537		return NULL;
538	}
539
540	filelen += 1;
541
542	ADD_U_CHAR(dptr, AU_FILE_TOKEN);
543
544	/* Add the timestamp */
545	ADD_U_INT32(dptr, tv->tv_sec);
546	ADD_U_INT32(dptr, timems);
547
548	ADD_U_INT16(dptr, filelen);
549	ADD_STRING(dptr, file, filelen);
550
551	return t;
552
553}
554
555/*
556 * token ID                1 byte
557 * text length             2 bytes
558 * text                    N bytes + 1 terminating NULL byte
559 */
560token_t *au_to_text(const char *text)
561{
562	token_t *t;
563	u_char *dptr;
564	u_int16_t textlen;
565
566	if(text == NULL) {
567		return NULL;
568	}
569	textlen = strlen(text);
570
571	GET_TOKEN_AREA(t, dptr, textlen + 4);
572	if(t == NULL) {
573		return NULL;
574	}
575
576	textlen += 1;
577
578	ADD_U_CHAR(dptr, AU_TEXT_TOKEN);
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 *au_to_path(char *text)
591{
592	token_t *t;
593	u_char *dptr;
594	u_int16_t textlen;
595
596	if(text == NULL) {
597		return NULL;
598	}
599	textlen = strlen(text);
600
601	GET_TOKEN_AREA(t, dptr, textlen + 4);
602	if(t == NULL) {
603		return NULL;
604	}
605
606	textlen += 1;
607
608	ADD_U_CHAR(dptr, AU_PATH_TOKEN);
609	ADD_U_INT16(dptr, textlen);
610	ADD_STRING(dptr, text, textlen);
611
612	return t;
613}
614
615/*
616 * token ID                1 byte
617 * audit ID                4 bytes
618 * effective user ID       4 bytes
619 * effective group ID      4 bytes
620 * real user ID            4 bytes
621 * real group ID           4 bytes
622 * process ID              4 bytes
623 * session ID              4 bytes
624 * terminal ID
625 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
626 *   machine address       4 bytes
627 */
628token_t *au_to_process32(au_id_t auid, uid_t euid, gid_t egid,
629		               uid_t ruid, gid_t rgid, pid_t pid,
630		               au_asid_t sid, au_tid_t *tid)
631{
632	token_t *t;
633	u_char *dptr;
634
635	if(tid == NULL) {
636		return NULL;
637	}
638
639	GET_TOKEN_AREA(t, dptr, 37);
640	if(t == NULL) {
641		return NULL;
642	}
643
644	ADD_U_CHAR(dptr, AU_PROCESS_32_TOKEN);
645	ADD_U_INT32(dptr, auid);
646	ADD_U_INT32(dptr, euid);
647	ADD_U_INT32(dptr, egid);
648	ADD_U_INT32(dptr, ruid);
649	ADD_U_INT32(dptr, rgid);
650	ADD_U_INT32(dptr, pid);
651	ADD_U_INT32(dptr, sid);
652	ADD_U_INT32(dptr, tid->port);
653	ADD_U_INT32(dptr, tid->machine);
654
655	return t;
656}
657
658token_t *au_to_process64(__unused au_id_t auid,
659			 __unused uid_t euid,
660			 __unused gid_t egid,
661			 __unused uid_t ruid,
662			 __unused gid_t rgid,
663			 __unused pid_t pid,
664			 __unused au_asid_t sid,
665			 __unused au_tid_t *tid)
666{
667		return NULL;
668	}
669
670token_t *au_to_process(au_id_t auid, uid_t euid, gid_t egid,
671		               uid_t ruid, gid_t rgid, pid_t pid,
672		               au_asid_t sid, au_tid_t *tid)
673{
674	return au_to_process32(auid, euid, egid, ruid, rgid, pid,
675			sid, tid);
676}
677
678
679/*
680 * token ID                1 byte
681 * audit ID                4 bytes
682 * effective user ID       4 bytes
683 * effective group ID      4 bytes
684 * real user ID            4 bytes
685 * real group ID           4 bytes
686 * process ID              4 bytes
687 * session ID              4 bytes
688 * terminal ID
689 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
690 *   address type-len      4 bytes
691 *   machine address      16 bytes
692 */
693token_t *au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid,
694		               	   uid_t ruid, gid_t rgid, pid_t pid,
695		                   au_asid_t sid, au_tid_addr_t *tid)
696{
697	token_t *t;
698	u_char *dptr;
699
700	if(tid == NULL) {
701		return NULL;
702	}
703
704	GET_TOKEN_AREA(t, dptr, 53);
705	if(t == NULL) {
706		return NULL;
707	}
708
709	ADD_U_CHAR(dptr, AU_PROCESS_32_EX_TOKEN);
710	ADD_U_INT32(dptr, auid);
711	ADD_U_INT32(dptr, euid);
712	ADD_U_INT32(dptr, egid);
713	ADD_U_INT32(dptr, ruid);
714	ADD_U_INT32(dptr, rgid);
715	ADD_U_INT32(dptr, pid);
716	ADD_U_INT32(dptr, sid);
717	ADD_U_INT32(dptr, tid->at_port);
718	ADD_U_INT32(dptr, tid->at_type);
719	ADD_U_INT32(dptr, tid->at_addr[0]);
720	ADD_U_INT32(dptr, tid->at_addr[1]);
721	ADD_U_INT32(dptr, tid->at_addr[2]);
722	ADD_U_INT32(dptr, tid->at_addr[3]);
723
724	return t;
725}
726
727token_t *au_to_process64_ex(
728	__unused au_id_t auid,
729	__unused uid_t euid,
730	__unused gid_t egid,
731	__unused uid_t ruid,
732	__unused gid_t rgid,
733	__unused pid_t pid,
734	__unused au_asid_t sid,
735	__unused au_tid_addr_t *tid)
736{
737	return NULL;
738}
739
740token_t *au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid,
741		               	   uid_t ruid, gid_t rgid, pid_t pid,
742		                   au_asid_t sid, au_tid_addr_t *tid)
743{
744	return au_to_process32_ex(auid, euid, egid, ruid, rgid,
745			pid, sid, tid);
746}
747
748/*
749 * token ID                1 byte
750 * error status            1 byte
751 * return value            4 bytes/8 bytes (32-bit/64-bit value)
752 */
753token_t *au_to_return32(char status, u_int32_t ret)
754{
755	token_t *t;
756	u_char *dptr;
757
758
759	GET_TOKEN_AREA(t, dptr, 6);
760	if(t == NULL) {
761		return NULL;
762	}
763
764	ADD_U_CHAR(dptr, AU_RETURN_32_TOKEN);
765	ADD_U_CHAR(dptr, status);
766	ADD_U_INT32(dptr, ret);
767
768	return t;
769}
770
771token_t *au_to_return64(char status, u_int64_t ret)
772{
773	token_t *t;
774	u_char *dptr;
775
776
777	GET_TOKEN_AREA(t, dptr, 10);
778	if(t == NULL) {
779		return NULL;
780	}
781
782	ADD_U_CHAR(dptr, AU_RETURN_64_TOKEN);
783	ADD_U_CHAR(dptr, status);
784	ADD_U_INT64(dptr, ret);
785
786	return t;
787}
788
789token_t *au_to_return(char status, u_int32_t ret)
790{
791	return au_to_return32(status, ret);
792}
793
794/*
795 * token ID                1 byte
796 * sequence number         4 bytes
797 */
798token_t *au_to_seq(u_int32_t audit_count)
799{
800	token_t *t;
801	u_char *dptr;
802
803
804	GET_TOKEN_AREA(t, dptr, 5);
805	if(t == NULL) {
806		return NULL;
807	}
808
809	ADD_U_CHAR(dptr, AU_SEQ_TOKEN);
810	ADD_U_INT32(dptr, audit_count);
811
812	return t;
813}
814
815/*
816 * token ID                1 byte
817 * socket type             2 bytes
818 * local port              2 bytes
819 * local Internet address  4 bytes
820 * remote port             2 bytes
821 * remote Internet address 4 bytes
822 */
823token_t *au_to_socket(__unused struct socket *so)
824{
825	return NULL;
826}
827
828/*
829 * Kernel-specific version of the above function.
830 */
831token_t *kau_to_socket(struct socket_au_info *soi)
832{
833	token_t *t;
834	u_char *dptr;
835	u_int16_t so_type;
836
837	if(soi == NULL) {
838		return NULL;
839	}
840
841	GET_TOKEN_AREA(t, dptr, 15);
842	if(t == NULL) {
843		return NULL;
844	}
845
846	ADD_U_CHAR(dptr, AU_SOCK_TOKEN);
847	/* Coerce the socket type into a short value */
848	so_type = soi->so_type;
849	ADD_U_INT16(dptr, so_type);
850	ADD_U_INT16(dptr, soi->so_lport);
851	ADD_U_INT32(dptr, soi->so_laddr);
852	ADD_U_INT16(dptr, soi->so_rport);
853	ADD_U_INT32(dptr, soi->so_raddr);
854
855	return t;
856}
857
858/*
859 * token ID                1 byte
860 * socket type             2 bytes
861 * local port              2 bytes
862 * address type/length     4 bytes
863 * local Internet address  4 bytes/16 bytes (IPv4/IPv6 address)
864 * remote port             4 bytes
865 * address type/length     4 bytes
866 * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address)
867 */
868token_t *au_to_socket_ex_32(
869	__unused u_int16_t lp,
870	__unused u_int16_t rp,
871	__unused struct sockaddr *la,
872	__unused struct sockaddr *ra)
873{
874	return NULL;
875}
876
877token_t *au_to_socket_ex_128(
878	__unused u_int16_t lp,
879	__unused u_int16_t rp,
880	__unused struct sockaddr *la,
881	__unused struct sockaddr *ra)
882{
883	return NULL;
884}
885
886/*
887 * token ID                1 byte
888 * socket family           2 bytes
889 * local port              2 bytes
890 * socket address          4 bytes
891 */
892token_t *au_to_sock_inet32(struct sockaddr_in *so)
893{
894	token_t *t;
895	u_char *dptr;
896
897	if(so == NULL) {
898		return NULL;
899	}
900
901	GET_TOKEN_AREA(t, dptr, 9);
902	if(t == NULL) {
903		return NULL;
904	}
905
906	ADD_U_CHAR(dptr, AU_SOCK_INET_32_TOKEN);
907	/* In Darwin, sin_family is one octet, but BSM defines the token
908	 * to store two. So we copy in a 0 first.
909	 */
910	ADD_U_CHAR(dptr, 0);
911	ADD_U_CHAR(dptr, so->sin_family);
912	ADD_U_INT16(dptr, so->sin_port);
913	ADD_U_INT32(dptr, so->sin_addr.s_addr);
914
915	return t;
916
917}
918
919token_t *au_to_sock_inet128(struct sockaddr_in6 *so)
920{
921	token_t *t;
922	u_char *dptr;
923
924	if(so == NULL) {
925		return NULL;
926	}
927
928	GET_TOKEN_AREA(t, dptr, 21);
929	if(t == NULL) {
930		return NULL;
931	}
932
933	ADD_U_CHAR(dptr, AU_SOCK_INET_128_TOKEN);
934	/* In Darwin, sin_family is one octet, but BSM defines the token
935	 * to store two. So we copy in a 0 first.
936	 */
937	ADD_U_CHAR(dptr, 0);
938	ADD_U_CHAR(dptr, so->sin6_family);
939	ADD_U_INT16(dptr, so->sin6_port);
940	ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[0]);
941	ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[1]);
942	ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[2]);
943	ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[3]);
944
945	return t;
946
947
948
949}
950
951/*
952 * token ID                1 byte
953 * socket family           2 bytes
954 * path                    104 bytes
955 */
956token_t *au_to_sock_unix(struct sockaddr_un *so)
957{
958	token_t *t;
959	u_char *dptr;
960
961	if(so == NULL) {
962		return NULL;
963	}
964
965	GET_TOKEN_AREA(t, dptr, 107);
966	if(t == NULL) {
967		return NULL;
968	}
969
970	ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN);
971	/* BSM token has two bytes for family */
972	ADD_U_CHAR(dptr, 0);
973	ADD_U_CHAR(dptr, so->sun_family);
974	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path));
975
976	return t;
977
978}
979
980token_t *au_to_sock_inet(struct sockaddr_in *so)
981{
982	return au_to_sock_inet32(so);
983}
984
985/*
986 * token ID                1 byte
987 * audit ID                4 bytes
988 * effective user ID       4 bytes
989 * effective group ID      4 bytes
990 * real user ID            4 bytes
991 * real group ID           4 bytes
992 * process ID              4 bytes
993 * session ID              4 bytes
994 * terminal ID
995 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
996 *   machine address       4 bytes
997 */
998token_t *au_to_subject32(au_id_t auid, uid_t euid, gid_t egid,
999						uid_t ruid, gid_t rgid, pid_t pid,
1000						au_asid_t sid, au_tid_t *tid)
1001{
1002	token_t *t;
1003	u_char *dptr;
1004
1005	if(tid == NULL) {
1006		return NULL;
1007	}
1008
1009	GET_TOKEN_AREA(t, dptr, 37);
1010	if(t == NULL) {
1011		return NULL;
1012	}
1013
1014	ADD_U_CHAR(dptr, AU_SUBJECT_32_TOKEN);
1015	ADD_U_INT32(dptr, auid);
1016	ADD_U_INT32(dptr, euid);
1017	ADD_U_INT32(dptr, egid);
1018	ADD_U_INT32(dptr, ruid);
1019	ADD_U_INT32(dptr, rgid);
1020	ADD_U_INT32(dptr, pid);
1021	ADD_U_INT32(dptr, sid);
1022	ADD_U_INT32(dptr, tid->port);
1023	ADD_U_INT32(dptr, tid->machine);
1024
1025	return t;
1026}
1027
1028token_t *au_to_subject64(
1029	__unused au_id_t auid,
1030	__unused uid_t euid,
1031	__unused gid_t egid,
1032	__unused uid_t ruid,
1033	__unused gid_t rgid,
1034	__unused pid_t pid,
1035	__unused au_asid_t sid,
1036	__unused au_tid_t *tid)
1037{
1038		return NULL;
1039	}
1040
1041token_t *au_to_subject(au_id_t auid, uid_t euid, gid_t egid,
1042						uid_t ruid, gid_t rgid, pid_t pid,
1043						au_asid_t sid, au_tid_t *tid)
1044{
1045	return au_to_subject32(auid, euid, egid, ruid, rgid,
1046			pid, sid, tid);
1047
1048}
1049
1050/*
1051 * token ID                1 byte
1052 * audit ID                4 bytes
1053 * effective user ID       4 bytes
1054 * effective group ID      4 bytes
1055 * real user ID            4 bytes
1056 * real group ID           4 bytes
1057 * process ID              4 bytes
1058 * session ID              4 bytes
1059 * terminal ID
1060 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1061 *   address type/length   4 bytes
1062 *   machine address      16 bytes
1063 */
1064token_t *au_to_subject32_ex(au_id_t auid, uid_t euid,
1065	                       gid_t egid, uid_t ruid, gid_t rgid, pid_t pid,
1066		                   au_asid_t sid, au_tid_addr_t *tid)
1067{
1068	token_t *t;
1069	u_char *dptr;
1070
1071	if(tid == NULL) {
1072		return NULL;
1073	}
1074
1075	GET_TOKEN_AREA(t, dptr, 53);
1076	if(t == NULL) {
1077		return NULL;
1078	}
1079
1080	ADD_U_CHAR(dptr, AU_SUBJECT_32_EX_TOKEN);
1081	ADD_U_INT32(dptr, auid);
1082	ADD_U_INT32(dptr, euid);
1083	ADD_U_INT32(dptr, egid);
1084	ADD_U_INT32(dptr, ruid);
1085	ADD_U_INT32(dptr, rgid);
1086	ADD_U_INT32(dptr, pid);
1087	ADD_U_INT32(dptr, sid);
1088	ADD_U_INT32(dptr, tid->at_port);
1089	ADD_U_INT32(dptr, tid->at_type);
1090	ADD_U_INT32(dptr, tid->at_addr[0]);
1091	ADD_U_INT32(dptr, tid->at_addr[1]);
1092	ADD_U_INT32(dptr, tid->at_addr[2]);
1093	ADD_U_INT32(dptr, tid->at_addr[3]);
1094
1095	return t;
1096}
1097
1098token_t *au_to_subject64_ex(
1099	__unused au_id_t auid,
1100	__unused uid_t euid,
1101	__unused gid_t egid,
1102	__unused uid_t ruid,
1103	__unused gid_t rgid,
1104	__unused pid_t pid,
1105	__unused au_asid_t sid,
1106	__unused au_tid_addr_t *tid)
1107{
1108	return NULL;
1109}
1110
1111token_t *au_to_subject_ex(au_id_t auid, uid_t euid,
1112	                       gid_t egid, uid_t ruid, gid_t rgid, pid_t pid,
1113		                   au_asid_t sid, au_tid_addr_t *tid)
1114{
1115	return au_to_subject32_ex(auid, euid, egid, ruid, rgid,
1116			pid, sid, tid);
1117
1118}
1119
1120/*
1121 * token ID				1 byte
1122 * count				4 bytes
1123 * text					count null-terminated strings
1124 */
1125token_t *au_to_exec_args(const char **args)
1126{
1127	token_t *t;
1128	u_char *dptr;
1129	const char *nextarg;
1130	int i, count = 0;
1131	size_t totlen = 0;
1132
1133	if(args == NULL) {
1134		return NULL;
1135	}
1136
1137	nextarg = *args;
1138
1139	while(nextarg != NULL) {
1140		int nextlen;
1141
1142		nextlen = strlen(nextarg);
1143		totlen += nextlen + 1;
1144		count++;
1145		nextarg = *(args + count);
1146	}
1147
1148
1149	GET_TOKEN_AREA(t, dptr, 5 + totlen);
1150	if(t == NULL) {
1151		return NULL;
1152	}
1153
1154	ADD_U_CHAR(dptr, AU_EXEC_ARG_TOKEN);
1155	ADD_U_INT32(dptr, count);
1156
1157	for(i =0; i< count; i++) {
1158		nextarg = *(args + i);
1159		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1160	}
1161
1162	return t;
1163}
1164
1165
1166/*
1167 * token ID				1 byte
1168 * count				4 bytes
1169 * text					count null-terminated strings
1170 */
1171token_t *au_to_exec_env(const char **env)
1172{
1173	token_t *t;
1174	u_char *dptr;
1175	int i, count = 0;
1176	size_t totlen = 0;
1177	const char *nextenv;
1178
1179	if(env == NULL) {
1180		return NULL;
1181	}
1182
1183	nextenv = *env;
1184
1185	while(nextenv != NULL) {
1186		int nextlen;
1187
1188		nextlen = strlen(nextenv);
1189		totlen += nextlen + 1;
1190		count++;
1191		nextenv = *(env + count);
1192	}
1193
1194
1195	GET_TOKEN_AREA(t, dptr, 5 + totlen);
1196	if(t == NULL) {
1197		return NULL;
1198	}
1199
1200	ADD_U_CHAR(dptr, AU_EXEC_ENV_TOKEN);
1201	ADD_U_INT32(dptr, count);
1202
1203	for(i =0; i< count; i++) {
1204		nextenv = *(env + i);
1205		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1206	}
1207
1208	return t;
1209}
1210
1211
1212/*
1213 * Kernel version of the BSM header token functions. These versions take
1214 * a timespec struct as an additional parameter in order to obtain the
1215 * create time value for the BSM audit record.
1216 * token ID                1 byte
1217 * record byte count       4 bytes
1218 * version #               1 byte    [2]
1219 * event type              2 bytes
1220 * event modifier          2 bytes
1221 * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1222 * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1223 */
1224token_t *kau_to_header32(const struct timespec *ctime, int rec_size,
1225			  au_event_t e_type, au_emod_t e_mod)
1226{
1227	token_t *t;
1228	u_char *dptr;
1229	u_int32_t timems = ctime->tv_nsec/1000000; /* We need time in ms */
1230
1231	GET_TOKEN_AREA(t, dptr, 18);
1232	if(t == NULL) {
1233		return NULL;
1234	}
1235
1236	ADD_U_CHAR(dptr, AU_HEADER_32_TOKEN);
1237	ADD_U_INT32(dptr, rec_size);
1238	ADD_U_CHAR(dptr, HEADER_VERSION);
1239	ADD_U_INT16(dptr, e_type);
1240	ADD_U_INT16(dptr, e_mod);
1241
1242	/* Add the timestamp */
1243	ADD_U_INT32(dptr, ctime->tv_sec);
1244	ADD_U_INT32(dptr, timems);
1245
1246	return t;
1247}
1248
1249token_t *kau_to_header64(
1250	__unused const struct timespec *ctime,
1251	__unused int rec_size,
1252	__unused au_event_t e_type,
1253	__unused au_emod_t e_mod)
1254{
1255	return NULL;
1256}
1257
1258token_t *kau_to_header(const struct timespec *ctime, int rec_size,
1259			  au_event_t e_type, au_emod_t e_mod)
1260{
1261	return kau_to_header32(ctime, rec_size, e_type, e_mod);
1262}
1263
1264/*
1265 * token ID                1 byte
1266 * trailer magic number    2 bytes
1267 * record byte count       4 bytes
1268 */
1269token_t *au_to_trailer(int rec_size)
1270{
1271	token_t *t;
1272	u_char *dptr;
1273	u_int16_t magic = TRAILER_PAD_MAGIC;
1274
1275
1276	GET_TOKEN_AREA(t, dptr, 7);
1277	if(t == NULL) {
1278		return NULL;
1279	}
1280
1281	ADD_U_CHAR(dptr, AU_TRAILER_TOKEN);
1282	ADD_U_INT16(dptr, magic);
1283	ADD_U_INT32(dptr, rec_size);
1284
1285	return t;
1286
1287}
1288
1289