bsm_token.c revision 155192
1/*
2 * Copyright (c) 2004 Apple Computer, 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 Computer, 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 * $P4: //depot/projects/trustedbsd/audit3/sys/security/audit/audit_bsm_token.c#7 $
34 * $FreeBSD: head/sys/security/audit/audit_bsm_token.c 155192 2006-02-01 20:01:18Z rwatson $
35 */
36
37#include <sys/types.h>
38#ifdef __APPLE__
39#include <compat/endian.h>
40#else /* !__APPLE__ */
41#include <sys/endian.h>
42#endif /* __APPLE__*/
43#include <sys/socket.h>
44#include <sys/time.h>
45
46#include <sys/ipc.h>
47#include <sys/libkern.h>
48#include <sys/malloc.h>
49#include <sys/un.h>
50
51#include <netinet/in.h>
52#include <netinet/in_systm.h>
53#include <netinet/ip.h>
54
55#include <sys/socketvar.h>
56
57#include <bsm/audit.h>
58#include <bsm/audit_internal.h>
59#include <bsm/audit_record.h>
60#include <security/audit/audit.h>
61#include <security/audit/audit_private.h>
62
63#define	GET_TOKEN_AREA(t, dptr, length) do {				\
64	t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK);		\
65	t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO);	\
66	t->len = length;						\
67	dptr = t->t_data;						\
68} while (0)
69
70/*
71 * token ID                1 byte
72 * argument #              1 byte
73 * argument value          4 bytes/8 bytes (32-bit/64-bit value)
74 * text length             2 bytes
75 * text                    N bytes + 1 terminating NULL byte
76 */
77token_t *
78au_to_arg32(char n, char *text, u_int32_t v)
79{
80	token_t *t;
81	u_char *dptr = NULL;
82	u_int16_t textlen;
83
84	textlen = strlen(text);
85	textlen += 1;
86
87	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
88	    sizeof(u_int16_t) + textlen);
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}
99
100token_t *
101au_to_arg64(char n, char *text, u_int64_t v)
102{
103	token_t *t;
104	u_char *dptr = NULL;
105	u_int16_t textlen;
106
107	textlen = strlen(text);
108	textlen += 1;
109
110	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
111	    sizeof(u_int16_t) + textlen);
112
113	ADD_U_CHAR(dptr, AUT_ARG64);
114	ADD_U_CHAR(dptr, n);
115	ADD_U_INT64(dptr, v);
116	ADD_U_INT16(dptr, textlen);
117	ADD_STRING(dptr, text, textlen);
118
119	return (t);
120
121}
122
123token_t *
124au_to_arg(char n, char *text, u_int32_t v)
125{
126
127	return (au_to_arg32(n, text, v));
128}
129
130#if defined(_KERNEL) || defined(KERNEL)
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 *
141au_to_attr32(struct vnode_au_info *vni)
142{
143	token_t *t;
144	u_char *dptr = NULL;
145	u_int16_t pad0_16 = 0;
146	u_int16_t pad0_32 = 0;
147
148	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
149	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
150
151	ADD_U_CHAR(dptr, AUT_ATTR32);
152
153	/*
154	 * Darwin defines the size for the file mode
155	 * as 2 bytes; BSM defines 4 so pad with 0
156	 */
157	ADD_U_INT16(dptr, pad0_16);
158	ADD_U_INT16(dptr, vni->vn_mode);
159
160	ADD_U_INT32(dptr, vni->vn_uid);
161	ADD_U_INT32(dptr, vni->vn_gid);
162	ADD_U_INT32(dptr, vni->vn_fsid);
163
164	/*
165	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
166	 * Attempt to handle both, and let the compiler sort it out.  If we
167	 * could pick this out at compile-time, it would be better, so as to
168	 * avoid the else case below.
169	 */
170	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
171		ADD_U_INT32(dptr, pad0_32);
172		ADD_U_INT32(dptr, vni->vn_fileid);
173	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
174		ADD_U_INT64(dptr, vni->vn_fileid);
175	else
176		ADD_U_INT64(dptr, 0LL);
177
178	ADD_U_INT32(dptr, vni->vn_dev);
179
180	return (t);
181}
182
183token_t *
184au_to_attr64(struct vnode_au_info *vni)
185{
186
187	return (NULL);
188}
189
190token_t *
191au_to_attr(struct vnode_au_info *vni)
192{
193
194	return (au_to_attr32(vni));
195}
196#endif /* !(defined(_KERNEL) || defined(KERNEL) */
197
198/*
199 * token ID                1 byte
200 * how to print            1 byte
201 * basic unit              1 byte
202 * unit count              1 byte
203 * data items              (depends on basic unit)
204 */
205token_t *
206au_to_data(char unit_print, char unit_type, char unit_count, char *p)
207{
208	token_t *t;
209	u_char *dptr = NULL;
210	size_t datasize, totdata;
211
212	/* Determine the size of the basic unit. */
213	switch (unit_type) {
214	case AUR_BYTE:
215		datasize = AUR_BYTE_SIZE;
216		break;
217
218	case AUR_SHORT:
219		datasize = AUR_SHORT_SIZE;
220		break;
221
222	case AUR_LONG:
223		datasize = AUR_LONG_SIZE;
224		break;
225
226	default:
227 		return (NULL);
228	}
229
230	totdata = datasize * unit_count;
231
232	GET_TOKEN_AREA(t, dptr, totdata + 4 * sizeof(u_char));
233
234	ADD_U_CHAR(dptr, AUT_DATA);
235	ADD_U_CHAR(dptr, unit_print);
236	ADD_U_CHAR(dptr, unit_type);
237	ADD_U_CHAR(dptr, unit_count);
238	ADD_MEM(dptr, p, totdata);
239
240	return (t);
241}
242
243
244/*
245 * token ID                1 byte
246 * status		   4 bytes
247 * return value            4 bytes
248 */
249token_t *
250au_to_exit(int retval, int err)
251{
252	token_t *t;
253	u_char *dptr = NULL;
254
255	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
256
257	ADD_U_CHAR(dptr, AUT_EXIT);
258	ADD_U_INT32(dptr, err);
259	ADD_U_INT32(dptr, retval);
260
261	return (t);
262}
263
264/*
265 */
266token_t *
267au_to_groups(int *groups)
268{
269
270	return (au_to_newgroups(BSM_MAX_GROUPS, groups));
271}
272
273/*
274 * token ID                1 byte
275 * number groups           2 bytes
276 * group list              count * 4 bytes
277 */
278token_t *
279au_to_newgroups(u_int16_t n, gid_t *groups)
280{
281	token_t *t;
282	u_char *dptr = NULL;
283	int i;
284
285	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
286	    n * sizeof(u_int32_t));
287
288	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
289	ADD_U_INT16(dptr, n);
290	for (i = 0; i < n; i++)
291		ADD_U_INT32(dptr, groups[i]);
292
293	return (t);
294}
295
296/*
297 * token ID                1 byte
298 * internet address        4 bytes
299 */
300token_t *
301au_to_in_addr(struct in_addr *internet_addr)
302{
303	token_t *t;
304	u_char *dptr = NULL;
305
306	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
307
308	ADD_U_CHAR(dptr, AUT_IN_ADDR);
309	ADD_U_INT32(dptr, internet_addr->s_addr);
310
311	return (t);
312}
313
314/*
315 * token ID                1 byte
316 * address type/length     4 bytes
317 * Address                16 bytes
318 */
319token_t *
320au_to_in_addr_ex(struct in6_addr *internet_addr)
321{
322	token_t *t;
323	u_char *dptr = NULL;
324	u_int32_t type = AF_INET6;
325
326	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(u_int32_t));
327
328	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
329	ADD_U_INT32(dptr, type);
330	ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[0]);
331	ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[1]);
332	ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[2]);
333	ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[3]);
334
335	return (t);
336}
337
338/*
339 * token ID                1 byte
340 * ip header		   20 bytes
341 */
342token_t *
343au_to_ip(struct ip *ip)
344{
345	token_t *t;
346	u_char *dptr = NULL;
347
348	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
349
350	ADD_U_CHAR(dptr, AUT_IP);
351	/*
352	 * XXXRW: Any byte order work needed on the IP header before writing?
353	 */
354	ADD_MEM(dptr, ip, sizeof(struct ip));
355
356	return (t);
357}
358
359/*
360 * token ID                1 byte
361 * object ID type          1 byte
362 * object ID               4 bytes
363 */
364token_t *
365au_to_ipc(char type, int id)
366{
367	token_t *t;
368	u_char *dptr = NULL;
369
370	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
371
372	ADD_U_CHAR(dptr, AUT_IPC);
373	ADD_U_CHAR(dptr, type);
374	ADD_U_INT32(dptr, id);
375
376	return (t);
377}
378
379/*
380 * token ID                1 byte
381 * owner user ID           4 bytes
382 * owner group ID          4 bytes
383 * creator user ID         4 bytes
384 * creator group ID        4 bytes
385 * access mode             4 bytes
386 * slot sequence #         4 bytes
387 * key                     4 bytes
388 */
389token_t *
390au_to_ipc_perm(struct ipc_perm *perm)
391{
392	token_t *t;
393	u_char *dptr = NULL;
394	u_int16_t pad0 = 0;
395
396	GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t));
397
398	ADD_U_CHAR(dptr, AUT_IPC_PERM);
399
400	/*
401	 * Darwin defines the sizes for ipc_perm members
402	 * as 2 bytes; BSM defines 4 so pad with 0
403	 */
404	ADD_U_INT16(dptr, pad0);
405	ADD_U_INT16(dptr, perm->uid);
406
407	ADD_U_INT16(dptr, pad0);
408	ADD_U_INT16(dptr, perm->gid);
409
410	ADD_U_INT16(dptr, pad0);
411	ADD_U_INT16(dptr, perm->cuid);
412
413	ADD_U_INT16(dptr, pad0);
414	ADD_U_INT16(dptr, perm->cgid);
415
416	ADD_U_INT16(dptr, pad0);
417	ADD_U_INT16(dptr, perm->mode);
418
419	ADD_U_INT16(dptr, pad0);
420	ADD_U_INT16(dptr, perm->seq);
421
422	ADD_U_INT32(dptr, perm->key);
423
424	return (t);
425}
426
427/*
428 * token ID                1 byte
429 * port IP address         2 bytes
430 */
431token_t *
432au_to_iport(u_int16_t iport)
433{
434	token_t *t;
435	u_char *dptr = NULL;
436
437	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
438
439	ADD_U_CHAR(dptr, AUT_IPORT);
440	ADD_U_INT16(dptr, iport);
441
442	return (t);
443}
444
445/*
446 * token ID                1 byte
447 * size                    2 bytes
448 * data                    size bytes
449 */
450token_t *
451au_to_opaque(char *data, u_int16_t bytes)
452{
453	token_t *t;
454	u_char *dptr = NULL;
455
456	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
457
458	ADD_U_CHAR(dptr, AUT_OPAQUE);
459	ADD_U_INT16(dptr, bytes);
460	ADD_MEM(dptr, data, bytes);
461
462	return (t);
463}
464
465/*
466 * token ID                1 byte
467 * seconds of time         4 bytes
468 * milliseconds of time    4 bytes
469 * file name len           2 bytes
470 * file pathname           N bytes + 1 terminating NULL byte
471 */
472token_t *
473#if defined(KERNEL) || defined(_KERNEL)
474au_to_file(char *file, struct timeval tm)
475#else
476au_to_file(char *file)
477#endif
478{
479	token_t *t;
480	u_char *dptr = NULL;
481	u_int16_t filelen;
482	u_int32_t timems;
483#if !defined(KERNEL) && !defined(_KERNEL)
484	struct timeval tm;
485	struct timezone tzp;
486
487	if (gettimeofday(&tm, &tzp) == -1)
488		return (NULL);
489#endif
490	/* XXXRW: else ...? */
491
492	filelen = strlen(file);
493	filelen += 1;
494
495	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
496	    sizeof(u_int16_t) + filelen);
497
498	timems = tm.tv_usec/1000;
499
500	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
501	ADD_U_INT32(dptr, tm.tv_sec);
502	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
503	ADD_U_INT16(dptr, filelen);
504	ADD_STRING(dptr, file, filelen);
505
506	return (t);
507}
508
509/*
510 * token ID                1 byte
511 * text length             2 bytes
512 * text                    N bytes + 1 terminating NULL byte
513 */
514token_t *
515au_to_text(char *text)
516{
517	token_t *t;
518	u_char *dptr = NULL;
519	u_int16_t textlen;
520
521	textlen = strlen(text);
522	textlen += 1;
523
524	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
525
526	ADD_U_CHAR(dptr, AUT_TEXT);
527	ADD_U_INT16(dptr, textlen);
528	ADD_STRING(dptr, text, textlen);
529
530	return (t);
531}
532
533/*
534 * token ID                1 byte
535 * path length             2 bytes
536 * path                    N bytes + 1 terminating NULL byte
537 */
538token_t *
539au_to_path(char *text)
540{
541	token_t *t;
542	u_char *dptr = NULL;
543	u_int16_t textlen;
544
545	textlen = strlen(text);
546	textlen += 1;
547
548	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
549
550	ADD_U_CHAR(dptr, AUT_PATH);
551	ADD_U_INT16(dptr, textlen);
552	ADD_STRING(dptr, text, textlen);
553
554	return (t);
555}
556
557/*
558 * token ID                1 byte
559 * audit ID                4 bytes
560 * effective user ID       4 bytes
561 * effective group ID      4 bytes
562 * real user ID            4 bytes
563 * real group ID           4 bytes
564 * process ID              4 bytes
565 * session ID              4 bytes
566 * terminal ID
567 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
568 *   machine address       4 bytes
569 */
570token_t *
571au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
572    pid_t pid, au_asid_t sid, au_tid_t *tid)
573{
574	token_t *t;
575	u_char *dptr = NULL;
576
577	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
578
579	ADD_U_CHAR(dptr, AUT_PROCESS32);
580	ADD_U_INT32(dptr, auid);
581	ADD_U_INT32(dptr, euid);
582	ADD_U_INT32(dptr, egid);
583	ADD_U_INT32(dptr, ruid);
584	ADD_U_INT32(dptr, rgid);
585	ADD_U_INT32(dptr, pid);
586	ADD_U_INT32(dptr, sid);
587	ADD_U_INT32(dptr, tid->port);
588	ADD_U_INT32(dptr, tid->machine);
589
590	return (t);
591}
592
593token_t *
594au_to_process64(__unused au_id_t auid, __unused uid_t euid,
595    __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid,
596    __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid)
597{
598
599	return (NULL);
600}
601
602token_t *
603au_to_process(__unused au_id_t auid, __unused uid_t euid,
604    __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid,
605    __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid)
606{
607
608	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
609	    tid));
610}
611
612/*
613 * token ID                1 byte
614 * audit ID                4 bytes
615 * effective user ID       4 bytes
616 * effective group ID      4 bytes
617 * real user ID            4 bytes
618 * real group ID           4 bytes
619 * process ID              4 bytes
620 * session ID              4 bytes
621 * terminal ID
622 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
623 *   address type-len      4 bytes
624 *   machine address      16 bytes
625 */
626token_t *
627au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
628    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
629{
630	token_t *t;
631	u_char *dptr = NULL;
632
633	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * sizeof(u_int32_t));
634
635	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
636	ADD_U_INT32(dptr, auid);
637	ADD_U_INT32(dptr, euid);
638	ADD_U_INT32(dptr, egid);
639	ADD_U_INT32(dptr, ruid);
640	ADD_U_INT32(dptr, rgid);
641	ADD_U_INT32(dptr, pid);
642	ADD_U_INT32(dptr, sid);
643	ADD_U_INT32(dptr, tid->at_port);
644	ADD_U_INT32(dptr, tid->at_type);
645	ADD_U_INT32(dptr, tid->at_addr[0]);
646	ADD_U_INT32(dptr, tid->at_addr[1]);
647	ADD_U_INT32(dptr, tid->at_addr[2]);
648	ADD_U_INT32(dptr, tid->at_addr[3]);
649
650	return (t);
651}
652
653token_t *
654au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
655    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
656{
657
658	return (NULL);
659}
660
661token_t *
662au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
663    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
664{
665
666	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
667	    tid));
668}
669
670/*
671 * token ID                1 byte
672 * error status            1 byte
673 * return value            4 bytes/8 bytes (32-bit/64-bit value)
674 */
675token_t *
676au_to_return32(char status, u_int32_t ret)
677{
678	token_t *t;
679	u_char *dptr = NULL;
680
681	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
682
683	ADD_U_CHAR(dptr, AUT_RETURN32);
684	ADD_U_CHAR(dptr, status);
685	ADD_U_INT32(dptr, ret);
686
687	return (t);
688}
689
690token_t *
691au_to_return64(char status, u_int64_t ret)
692{
693	token_t *t;
694	u_char *dptr = NULL;
695
696	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
697
698	ADD_U_CHAR(dptr, AUT_RETURN64);
699	ADD_U_CHAR(dptr, status);
700	ADD_U_INT64(dptr, ret);
701
702	return (t);
703}
704
705token_t *
706au_to_return(char status, u_int32_t ret)
707{
708
709	return (au_to_return32(status, ret));
710}
711
712/*
713 * token ID                1 byte
714 * sequence number         4 bytes
715 */
716token_t *
717au_to_seq(long audit_count)
718{
719	token_t *t;
720	u_char *dptr = NULL;
721
722	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
723
724	ADD_U_CHAR(dptr, AUT_SEQ);
725	ADD_U_INT32(dptr, audit_count);
726
727	return (t);
728}
729
730/*
731 * token ID                1 byte
732 * socket type             2 bytes
733 * local port              2 bytes
734 * local Internet address  4 bytes
735 * remote port             2 bytes
736 * remote Internet address 4 bytes
737 */
738token_t *
739au_to_socket(struct socket *so)
740{
741
742	/* XXXRW ... */
743	return (NULL);
744}
745
746/*
747 * Kernel-specific version of the above function.
748 */
749#ifdef _KERNEL
750token_t *
751kau_to_socket(struct socket_au_info *soi)
752{
753	token_t *t;
754	u_char *dptr;
755	u_int16_t so_type;
756
757	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
758	    sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
759
760	ADD_U_CHAR(dptr, AU_SOCK_TOKEN);
761	/* Coerce the socket type into a short value */
762	so_type = soi->so_type;
763	ADD_U_INT16(dptr, so_type);
764	ADD_U_INT16(dptr, soi->so_lport);
765	ADD_U_INT32(dptr, soi->so_laddr);
766	ADD_U_INT16(dptr, soi->so_rport);
767	ADD_U_INT32(dptr, soi->so_raddr);
768
769	return (t);
770}
771#endif
772
773/*
774 * token ID                1 byte
775 * socket type             2 bytes
776 * local port              2 bytes
777 * address type/length     4 bytes
778 * local Internet address  4 bytes/16 bytes (IPv4/IPv6 address)
779 * remote port             4 bytes
780 * address type/length     4 bytes
781 * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address)
782 */
783token_t *
784au_to_socket_ex_32(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
785    struct sockaddr *ra)
786{
787
788	return (NULL);
789}
790
791token_t *
792au_to_socket_ex_128(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
793    struct sockaddr *ra)
794{
795
796	return (NULL);
797}
798
799/*
800 * token ID                1 byte
801 * socket family           2 bytes
802 * path                    104 bytes
803 */
804token_t *
805au_to_sock_unix(struct sockaddr_un *so)
806{
807	token_t *t;
808	u_char *dptr;
809
810	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
811
812	ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN);
813	/* BSM token has two bytes for family */
814	ADD_U_CHAR(dptr, 0);
815	ADD_U_CHAR(dptr, so->sun_family);
816	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
817
818	return (t);
819}
820
821/*
822 * token ID                1 byte
823 * socket family           2 bytes
824 * local port              2 bytes
825 * socket address          4 bytes
826 */
827token_t *
828au_to_sock_inet32(struct sockaddr_in *so)
829{
830	token_t *t;
831	u_char *dptr = NULL;
832
833	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
834	    sizeof(u_int32_t));
835
836	ADD_U_CHAR(dptr, AUT_SOCKINET32);
837	/*
838	 * In Darwin, sin_family is one octet, but BSM defines the token
839 	 * to store two. So we copy in a 0 first.
840 	 */
841	ADD_U_CHAR(dptr, 0);
842	ADD_U_CHAR(dptr, so->sin_family);
843	ADD_U_INT16(dptr, so->sin_port);
844	ADD_U_INT32(dptr, so->sin_addr.s_addr);
845
846	return (t);
847
848}
849
850token_t *
851au_to_sock_inet128(struct sockaddr_in6 *so)
852{
853	token_t *t;
854	u_char *dptr = NULL;
855
856	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
857	    4 * sizeof(u_int32_t));
858
859	ADD_U_CHAR(dptr, AUT_SOCKINET128);
860	/*
861	 * In Darwin, sin6_family is one octet, but BSM defines the token
862 	 * to store two. So we copy in a 0 first.
863 	 */
864	ADD_U_CHAR(dptr, 0);
865	ADD_U_CHAR(dptr, so->sin6_family);
866
867	ADD_U_INT16(dptr, so->sin6_port);
868	ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[0]);
869	ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[1]);
870	ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[2]);
871	ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[3]);
872
873	return (t);
874
875}
876
877token_t *
878au_to_sock_inet(struct sockaddr_in *so)
879{
880
881	return (au_to_sock_inet32(so));
882}
883
884/*
885 * token ID                1 byte
886 * audit ID                4 bytes
887 * effective user ID       4 bytes
888 * effective group ID      4 bytes
889 * real user ID            4 bytes
890 * real group ID           4 bytes
891 * process ID              4 bytes
892 * session ID              4 bytes
893 * terminal ID
894 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
895 *   machine address       4 bytes
896 */
897token_t *
898au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
899    pid_t pid, au_asid_t sid, au_tid_t *tid)
900{
901	token_t *t;
902	u_char *dptr = NULL;
903
904	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
905
906	ADD_U_CHAR(dptr, AUT_SUBJECT32);
907	ADD_U_INT32(dptr, auid);
908	ADD_U_INT32(dptr, euid);
909	ADD_U_INT32(dptr, egid);
910	ADD_U_INT32(dptr, ruid);
911	ADD_U_INT32(dptr, rgid);
912	ADD_U_INT32(dptr, pid);
913	ADD_U_INT32(dptr, sid);
914	ADD_U_INT32(dptr, tid->port);
915	ADD_U_INT32(dptr, tid->machine);
916
917	return (t);
918}
919
920token_t *
921au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
922    pid_t pid, au_asid_t sid, au_tid_t *tid)
923{
924
925	return (NULL);
926}
927
928token_t *
929au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
930    pid_t pid, au_asid_t sid, au_tid_t *tid)
931{
932
933	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
934	    tid));
935}
936
937/*
938 * token ID                1 byte
939 * audit ID                4 bytes
940 * effective user ID       4 bytes
941 * effective group ID      4 bytes
942 * real user ID            4 bytes
943 * real group ID           4 bytes
944 * process ID              4 bytes
945 * session ID              4 bytes
946 * terminal ID
947 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
948 *   address type/length   4 bytes
949 *   machine address      16 bytes
950 */
951token_t *
952au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
953    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
954{
955	token_t *t;
956	u_char *dptr = NULL;
957
958	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * sizeof(u_int32_t));
959
960	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
961	ADD_U_INT32(dptr, auid);
962	ADD_U_INT32(dptr, euid);
963	ADD_U_INT32(dptr, egid);
964	ADD_U_INT32(dptr, ruid);
965	ADD_U_INT32(dptr, rgid);
966	ADD_U_INT32(dptr, pid);
967	ADD_U_INT32(dptr, sid);
968	ADD_U_INT32(dptr, tid->at_port);
969	ADD_U_INT32(dptr, tid->at_type);
970	ADD_U_INT32(dptr, tid->at_addr[0]);
971	ADD_U_INT32(dptr, tid->at_addr[1]);
972	ADD_U_INT32(dptr, tid->at_addr[2]);
973	ADD_U_INT32(dptr, tid->at_addr[3]);
974
975	return (t);
976}
977
978token_t *
979au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
980    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
981{
982
983	return (NULL);
984}
985
986token_t *
987au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
988    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
989{
990
991	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
992	    tid));
993}
994
995#if !defined(_KERNEL) && !defined(KERNEL)
996/*
997 * Collects audit information for the current process
998 * and creates a subject token from it
999 */
1000token_t *
1001au_to_me(void)
1002{
1003	auditinfo_t auinfo;
1004
1005	if (getaudit(&auinfo) != 0)
1006		return (NULL);
1007
1008	return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1009	    getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1010}
1011#endif
1012
1013/*
1014 * token ID				1 byte
1015 * count				4 bytes
1016 * text					count null-terminated strings
1017 */
1018token_t *
1019au_to_exec_args(const char **args)
1020{
1021	token_t *t;
1022	u_char *dptr = NULL;
1023	const char *nextarg;
1024	int i, count = 0;
1025	size_t totlen = 0;
1026
1027	nextarg = *args;
1028
1029	while (nextarg != NULL) {
1030		int nextlen;
1031
1032		nextlen = strlen(nextarg);
1033		totlen += nextlen + 1;
1034		count++;
1035		nextarg = *(args + count);
1036	}
1037
1038	totlen += count * sizeof(char);	/* nul terminations. */
1039	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1040
1041	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1042	ADD_U_INT32(dptr, count);
1043
1044	for (i = 0; i < count; i++) {
1045		nextarg = *(args + i);
1046		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1047	}
1048
1049	return (t);
1050}
1051
1052/*
1053 * token ID				1 byte
1054 * count				4 bytes
1055 * text					count null-terminated strings
1056 */
1057token_t *
1058au_to_exec_env(const char **env)
1059{
1060	token_t *t;
1061	u_char *dptr = NULL;
1062	int i, count = 0;
1063	size_t totlen = 0;
1064	const char *nextenv;
1065
1066	nextenv = *env;
1067
1068	while (nextenv != NULL) {
1069		int nextlen;
1070
1071		nextlen = strlen(nextenv);
1072		totlen += nextlen + 1;
1073		count++;
1074		nextenv = *(env + count);
1075	}
1076
1077	totlen += sizeof(char) * count;
1078	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1079
1080	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1081	ADD_U_INT32(dptr, count);
1082
1083	for (i = 0; i < count; i++) {
1084		nextenv = *(env + i);
1085		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1086	}
1087
1088	return (t);
1089}
1090
1091/*
1092 * token ID                1 byte
1093 * record byte count       4 bytes
1094 * version #               1 byte    [2]
1095 * event type              2 bytes
1096 * event modifier          2 bytes
1097 * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1098 * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1099 */
1100token_t *
1101#if defined(KERNEL) || defined(_KERNEL)
1102au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod,
1103    struct timeval tm)
1104#else
1105au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1106#endif
1107{
1108	token_t *t;
1109	u_char *dptr = NULL;
1110	u_int32_t timems;
1111#if !defined(KERNEL) && !defined(_KERNEL)
1112	struct timeval tm;
1113	struct timezone tzp;
1114
1115	if (gettimeofday(&tm, &tzp) == -1)
1116		return (NULL);
1117#endif
1118	/* XXXRW: else ...? */
1119
1120	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1121	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1122
1123	ADD_U_CHAR(dptr, AUT_HEADER32);
1124	ADD_U_INT32(dptr, rec_size);
1125	ADD_U_CHAR(dptr, HEADER_VERSION);
1126	ADD_U_INT16(dptr, e_type);
1127	ADD_U_INT16(dptr, e_mod);
1128
1129	timems = tm.tv_usec/1000;
1130	/* Add the timestamp */
1131	ADD_U_INT32(dptr, tm.tv_sec);
1132	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1133
1134	return (t);
1135}
1136
1137token_t *
1138au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1139    __unused au_emod_t e_mod)
1140{
1141
1142	return (NULL);
1143}
1144
1145token_t *
1146#if defined(KERNEL) || defined(_KERNEL)
1147au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod,
1148	struct timeval tm)
1149{
1150
1151	return (au_to_header32(rec_size, e_type, e_mod, tm));
1152}
1153#else
1154au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1155{
1156
1157	return (au_to_header32(rec_size, e_type, e_mod));
1158}
1159#endif
1160
1161/*
1162 * token ID                1 byte
1163 * trailer magic number    2 bytes
1164 * record byte count       4 bytes
1165 */
1166token_t *
1167au_to_trailer(int rec_size)
1168{
1169	token_t *t;
1170	u_char *dptr = NULL;
1171	u_int16_t magic = TRAILER_PAD_MAGIC;
1172
1173	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1174	    sizeof(u_int32_t));
1175
1176	ADD_U_CHAR(dptr, AUT_TRAILER);
1177	ADD_U_INT16(dptr, magic);
1178	ADD_U_INT32(dptr, rec_size);
1179
1180	return (t);
1181}
1182