bsm_token.c revision 161635
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 161635 2006-08-26 08:17:58Z 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 */
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 *
473au_to_file(char *file, struct timeval tm)
474{
475	token_t *t;
476	u_char *dptr = NULL;
477	u_int16_t filelen;
478	u_int32_t timems;
479
480	filelen = strlen(file);
481	filelen += 1;
482
483	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
484	    sizeof(u_int16_t) + filelen);
485
486	timems = tm.tv_usec/1000;
487
488	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
489	ADD_U_INT32(dptr, tm.tv_sec);
490	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
491	ADD_U_INT16(dptr, filelen);
492	ADD_STRING(dptr, file, filelen);
493
494	return (t);
495}
496
497/*
498 * token ID                1 byte
499 * text length             2 bytes
500 * text                    N bytes + 1 terminating NULL byte
501 */
502token_t *
503au_to_text(char *text)
504{
505	token_t *t;
506	u_char *dptr = NULL;
507	u_int16_t textlen;
508
509	textlen = strlen(text);
510	textlen += 1;
511
512	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
513
514	ADD_U_CHAR(dptr, AUT_TEXT);
515	ADD_U_INT16(dptr, textlen);
516	ADD_STRING(dptr, text, textlen);
517
518	return (t);
519}
520
521/*
522 * token ID                1 byte
523 * path length             2 bytes
524 * path                    N bytes + 1 terminating NULL byte
525 */
526token_t *
527au_to_path(char *text)
528{
529	token_t *t;
530	u_char *dptr = NULL;
531	u_int16_t textlen;
532
533	textlen = strlen(text);
534	textlen += 1;
535
536	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
537
538	ADD_U_CHAR(dptr, AUT_PATH);
539	ADD_U_INT16(dptr, textlen);
540	ADD_STRING(dptr, text, textlen);
541
542	return (t);
543}
544
545/*
546 * token ID                1 byte
547 * audit ID                4 bytes
548 * effective user ID       4 bytes
549 * effective group ID      4 bytes
550 * real user ID            4 bytes
551 * real group ID           4 bytes
552 * process ID              4 bytes
553 * session ID              4 bytes
554 * terminal ID
555 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
556 *   machine address       4 bytes
557 */
558token_t *
559au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
560    pid_t pid, au_asid_t sid, au_tid_t *tid)
561{
562	token_t *t;
563	u_char *dptr = NULL;
564
565	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
566
567	ADD_U_CHAR(dptr, AUT_PROCESS32);
568	ADD_U_INT32(dptr, auid);
569	ADD_U_INT32(dptr, euid);
570	ADD_U_INT32(dptr, egid);
571	ADD_U_INT32(dptr, ruid);
572	ADD_U_INT32(dptr, rgid);
573	ADD_U_INT32(dptr, pid);
574	ADD_U_INT32(dptr, sid);
575	ADD_U_INT32(dptr, tid->port);
576	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
577
578	return (t);
579}
580
581token_t *
582au_to_process64(__unused au_id_t auid, __unused uid_t euid,
583    __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid,
584    __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid)
585{
586
587	return (NULL);
588}
589
590token_t *
591au_to_process(__unused au_id_t auid, __unused uid_t euid,
592    __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid,
593    __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid)
594{
595
596	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
597	    tid));
598}
599
600/*
601 * token ID                1 byte
602 * audit ID                4 bytes
603 * effective user ID       4 bytes
604 * effective group ID      4 bytes
605 * real user ID            4 bytes
606 * real group ID           4 bytes
607 * process ID              4 bytes
608 * session ID              4 bytes
609 * terminal ID
610 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
611 *   address type-len      4 bytes
612 *   machine address    4/16 bytes
613 */
614token_t *
615au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
616    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
617{
618	token_t *t;
619	u_char *dptr = NULL;
620
621	if (tid->at_type == AU_IPv6)
622		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
623		    sizeof(u_int32_t));
624	else
625		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
626		    sizeof(u_int32_t));
627
628	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
629	ADD_U_INT32(dptr, auid);
630	ADD_U_INT32(dptr, euid);
631	ADD_U_INT32(dptr, egid);
632	ADD_U_INT32(dptr, ruid);
633	ADD_U_INT32(dptr, rgid);
634	ADD_U_INT32(dptr, pid);
635	ADD_U_INT32(dptr, sid);
636	ADD_U_INT32(dptr, tid->at_port);
637	ADD_U_INT32(dptr, tid->at_type);
638	ADD_U_INT32(dptr, tid->at_addr[0]);
639	if (tid->at_type == AU_IPv6) {
640		ADD_U_INT32(dptr, tid->at_addr[1]);
641		ADD_U_INT32(dptr, tid->at_addr[2]);
642		ADD_U_INT32(dptr, tid->at_addr[3]);
643	}
644	return (t);
645}
646
647token_t *
648au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
649    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
650{
651
652	return (NULL);
653}
654
655token_t *
656au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
657    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
658{
659
660	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
661	    tid));
662}
663
664/*
665 * token ID                1 byte
666 * error status            1 byte
667 * return value            4 bytes/8 bytes (32-bit/64-bit value)
668 */
669token_t *
670au_to_return32(char status, u_int32_t ret)
671{
672	token_t *t;
673	u_char *dptr = NULL;
674
675	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
676
677	ADD_U_CHAR(dptr, AUT_RETURN32);
678	ADD_U_CHAR(dptr, status);
679	ADD_U_INT32(dptr, ret);
680
681	return (t);
682}
683
684token_t *
685au_to_return64(char status, u_int64_t ret)
686{
687	token_t *t;
688	u_char *dptr = NULL;
689
690	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
691
692	ADD_U_CHAR(dptr, AUT_RETURN64);
693	ADD_U_CHAR(dptr, status);
694	ADD_U_INT64(dptr, ret);
695
696	return (t);
697}
698
699token_t *
700au_to_return(char status, u_int32_t ret)
701{
702
703	return (au_to_return32(status, ret));
704}
705
706/*
707 * token ID                1 byte
708 * sequence number         4 bytes
709 */
710token_t *
711au_to_seq(long audit_count)
712{
713	token_t *t;
714	u_char *dptr = NULL;
715
716	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
717
718	ADD_U_CHAR(dptr, AUT_SEQ);
719	ADD_U_INT32(dptr, audit_count);
720
721	return (t);
722}
723
724/*
725 * token ID                1 byte
726 * socket type             2 bytes
727 * local port              2 bytes
728 * local Internet address  4 bytes
729 * remote port             2 bytes
730 * remote Internet address 4 bytes
731 */
732token_t *
733au_to_socket(struct socket *so)
734{
735
736	/* XXXRW ... */
737	return (NULL);
738}
739
740/*
741 * Kernel-specific version of the above function.
742 */
743#ifdef _KERNEL
744token_t *
745kau_to_socket(struct socket_au_info *soi)
746{
747	token_t *t;
748	u_char *dptr;
749	u_int16_t so_type;
750
751	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
752	    sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
753
754	ADD_U_CHAR(dptr, AU_SOCK_TOKEN);
755	/* Coerce the socket type into a short value */
756	so_type = soi->so_type;
757	ADD_U_INT16(dptr, so_type);
758	ADD_U_INT16(dptr, soi->so_lport);
759	ADD_U_INT32(dptr, soi->so_laddr);
760	ADD_U_INT16(dptr, soi->so_rport);
761	ADD_U_INT32(dptr, soi->so_raddr);
762
763	return (t);
764}
765#endif
766
767/*
768 * token ID                1 byte
769 * socket type             2 bytes
770 * local port              2 bytes
771 * address type/length     4 bytes
772 * local Internet address  4 bytes/16 bytes (IPv4/IPv6 address)
773 * remote port             4 bytes
774 * address type/length     4 bytes
775 * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address)
776 */
777token_t *
778au_to_socket_ex_32(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
779    struct sockaddr *ra)
780{
781
782	return (NULL);
783}
784
785token_t *
786au_to_socket_ex_128(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
787    struct sockaddr *ra)
788{
789
790	return (NULL);
791}
792
793/*
794 * token ID                1 byte
795 * socket family           2 bytes
796 * path                    104 bytes
797 */
798token_t *
799au_to_sock_unix(struct sockaddr_un *so)
800{
801	token_t *t;
802	u_char *dptr;
803
804	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
805
806	ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN);
807	/* BSM token has two bytes for family */
808	ADD_U_CHAR(dptr, 0);
809	ADD_U_CHAR(dptr, so->sun_family);
810	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
811
812	return (t);
813}
814
815/*
816 * token ID                1 byte
817 * socket family           2 bytes
818 * local port              2 bytes
819 * socket address          4 bytes
820 */
821token_t *
822au_to_sock_inet32(struct sockaddr_in *so)
823{
824	token_t *t;
825	u_char *dptr = NULL;
826	uint16_t family;
827
828	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
829	    sizeof(uint32_t));
830
831	ADD_U_CHAR(dptr, AUT_SOCKINET32);
832	/*
833	 * BSM defines the family field as 16 bits, but many operating
834	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
835	 * writing into the token.  Assume that both the port and the address
836	 * in the sockaddr_in are already in network byte order, but family
837	 * is in local byte order.
838	 *
839	 * XXXRW: Should a name space conversion be taking place on the value
840	 * of sin_family?
841 	 */
842	family = so->sin_family;
843	ADD_U_INT16(dptr, family);
844	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
845	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
846
847	return (t);
848
849}
850
851token_t *
852au_to_sock_inet128(struct sockaddr_in6 *so)
853{
854	token_t *t;
855	u_char *dptr = NULL;
856
857	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
858	    4 * sizeof(u_int32_t));
859
860	ADD_U_CHAR(dptr, AUT_SOCKINET128);
861	/*
862	 * In Darwin, sin6_family is one octet, but BSM defines the token
863 	 * to store two. So we copy in a 0 first.
864 	 */
865	ADD_U_CHAR(dptr, 0);
866	ADD_U_CHAR(dptr, so->sin6_family);
867
868	ADD_U_INT16(dptr, so->sin6_port);
869	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
870
871	return (t);
872
873}
874
875token_t *
876au_to_sock_inet(struct sockaddr_in *so)
877{
878
879	return (au_to_sock_inet32(so));
880}
881
882/*
883 * token ID                1 byte
884 * audit ID                4 bytes
885 * effective user ID       4 bytes
886 * effective group ID      4 bytes
887 * real user ID            4 bytes
888 * real group ID           4 bytes
889 * process ID              4 bytes
890 * session ID              4 bytes
891 * terminal ID
892 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
893 *   machine address       4 bytes
894 */
895token_t *
896au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
897    pid_t pid, au_asid_t sid, au_tid_t *tid)
898{
899	token_t *t;
900	u_char *dptr = NULL;
901
902	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
903
904	ADD_U_CHAR(dptr, AUT_SUBJECT32);
905	ADD_U_INT32(dptr, auid);
906	ADD_U_INT32(dptr, euid);
907	ADD_U_INT32(dptr, egid);
908	ADD_U_INT32(dptr, ruid);
909	ADD_U_INT32(dptr, rgid);
910	ADD_U_INT32(dptr, pid);
911	ADD_U_INT32(dptr, sid);
912	ADD_U_INT32(dptr, tid->port);
913	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
914
915	return (t);
916}
917
918token_t *
919au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
920    pid_t pid, au_asid_t sid, au_tid_t *tid)
921{
922
923	return (NULL);
924}
925
926token_t *
927au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
928    pid_t pid, au_asid_t sid, au_tid_t *tid)
929{
930
931	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
932	    tid));
933}
934
935/*
936 * token ID                1 byte
937 * audit ID                4 bytes
938 * effective user ID       4 bytes
939 * effective group ID      4 bytes
940 * real user ID            4 bytes
941 * real group ID           4 bytes
942 * process ID              4 bytes
943 * session ID              4 bytes
944 * terminal ID
945 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
946 *   address type/length   4 bytes
947 *   machine address    4/16 bytes
948 */
949token_t *
950au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
951    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
952{
953	token_t *t;
954	u_char *dptr = NULL;
955
956	if (tid->at_type == AU_IPv6)
957		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
958		    sizeof(u_int32_t));
959	else
960		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
961		    sizeof(u_int32_t));
962
963	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
964	ADD_U_INT32(dptr, auid);
965	ADD_U_INT32(dptr, euid);
966	ADD_U_INT32(dptr, egid);
967	ADD_U_INT32(dptr, ruid);
968	ADD_U_INT32(dptr, rgid);
969	ADD_U_INT32(dptr, pid);
970	ADD_U_INT32(dptr, sid);
971	ADD_U_INT32(dptr, tid->at_port);
972	ADD_U_INT32(dptr, tid->at_type);
973	ADD_U_INT32(dptr, tid->at_addr[0]);
974	if (tid->at_type == AU_IPv6) {
975		ADD_U_INT32(dptr, tid->at_addr[1]);
976		ADD_U_INT32(dptr, tid->at_addr[2]);
977		ADD_U_INT32(dptr, tid->at_addr[3]);
978	}
979	return (t);
980}
981
982token_t *
983au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
984    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
985{
986
987	return (NULL);
988}
989
990token_t *
991au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
992    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
993{
994
995	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
996	    tid));
997}
998
999#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1000/*
1001 * Collects audit information for the current process
1002 * and creates a subject token from it
1003 */
1004token_t *
1005au_to_me(void)
1006{
1007	auditinfo_t auinfo;
1008
1009	if (getaudit(&auinfo) != 0)
1010		return (NULL);
1011
1012	return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1013	    getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1014}
1015#endif
1016
1017/*
1018 * token ID				1 byte
1019 * count				4 bytes
1020 * text					count null-terminated strings
1021 */
1022token_t *
1023au_to_exec_args(const char **args)
1024{
1025	token_t *t;
1026	u_char *dptr = NULL;
1027	const char *nextarg;
1028	int i, count = 0;
1029	size_t totlen = 0;
1030
1031	nextarg = *args;
1032
1033	while (nextarg != NULL) {
1034		int nextlen;
1035
1036		nextlen = strlen(nextarg);
1037		totlen += nextlen + 1;
1038		count++;
1039		nextarg = *(args + count);
1040	}
1041
1042	totlen += count * sizeof(char);	/* nul terminations. */
1043	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1044
1045	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1046	ADD_U_INT32(dptr, count);
1047
1048	for (i = 0; i < count; i++) {
1049		nextarg = *(args + i);
1050		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1051	}
1052
1053	return (t);
1054}
1055
1056/*
1057 * token ID				1 byte
1058 * count				4 bytes
1059 * text					count null-terminated strings
1060 */
1061token_t *
1062au_to_exec_env(const char **env)
1063{
1064	token_t *t;
1065	u_char *dptr = NULL;
1066	int i, count = 0;
1067	size_t totlen = 0;
1068	const char *nextenv;
1069
1070	nextenv = *env;
1071
1072	while (nextenv != NULL) {
1073		int nextlen;
1074
1075		nextlen = strlen(nextenv);
1076		totlen += nextlen + 1;
1077		count++;
1078		nextenv = *(env + count);
1079	}
1080
1081	totlen += sizeof(char) * count;
1082	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1083
1084	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1085	ADD_U_INT32(dptr, count);
1086
1087	for (i = 0; i < count; i++) {
1088		nextenv = *(env + i);
1089		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1090	}
1091
1092	return (t);
1093}
1094
1095/*
1096 * token ID                1 byte
1097 * record byte count       4 bytes
1098 * version #               1 byte    [2]
1099 * event type              2 bytes
1100 * event modifier          2 bytes
1101 * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1102 * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1103 */
1104token_t *
1105au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1106    struct timeval tm)
1107{
1108	token_t *t;
1109	u_char *dptr = NULL;
1110	u_int32_t timems;
1111
1112	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1113	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1114
1115	ADD_U_CHAR(dptr, AUT_HEADER32);
1116	ADD_U_INT32(dptr, rec_size);
1117	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1118	ADD_U_INT16(dptr, e_type);
1119	ADD_U_INT16(dptr, e_mod);
1120
1121	timems = tm.tv_usec/1000;
1122	/* Add the timestamp */
1123	ADD_U_INT32(dptr, tm.tv_sec);
1124	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1125
1126	return (t);
1127}
1128
1129/*
1130 * token ID                1 byte
1131 * trailer magic number    2 bytes
1132 * record byte count       4 bytes
1133 */
1134token_t *
1135au_to_trailer(int rec_size)
1136{
1137	token_t *t;
1138	u_char *dptr = NULL;
1139	u_int16_t magic = TRAILER_PAD_MAGIC;
1140
1141	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1142	    sizeof(u_int32_t));
1143
1144	ADD_U_CHAR(dptr, AUT_TRAILER);
1145	ADD_U_INT16(dptr, magic);
1146	ADD_U_INT32(dptr, rec_size);
1147
1148	return (t);
1149}
1150