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