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