1/*-
2 * Copyright (c) 2006-2007 Robert N. M. Watson
3 * Copyright (c) 2008 Apple Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $P4: //depot/projects/trustedbsd/openbsm/test/bsm/generate.c#14 $
28 */
29
30/*
31 * Generate a series of BSM token samples in the requested directory.
32 */
33
34#include <sys/types.h>
35#include <sys/socket.h>
36#include <sys/stat.h>
37
38#include <netinet/in.h>
39#include <netinet/in_systm.h>
40#include <netinet/ip.h>
41
42#include <arpa/inet.h>
43
44#include <bsm/audit_kevents.h>
45#include <bsm/libbsm.h>
46
47#include <err.h>
48#include <errno.h>
49#include <fcntl.h>
50#include <limits.h>
51#include <stdio.h>
52#include <stdlib.h>
53#include <string.h>
54#include <sysexits.h>
55#include <unistd.h>
56
57static int	do_records, do_tokens;
58
59static void
60usage(void)
61{
62
63	fprintf(stderr, "generate [-rt] path\n");
64	exit(EX_USAGE);
65}
66
67static int
68open_file(const char *directory, const char *name)
69{
70	char pathname[PATH_MAX];
71	int fd;
72
73	snprintf(pathname, PATH_MAX, "%s/%s", directory, name);
74	(void)unlink(pathname);
75	fd = open(pathname, O_WRONLY | O_CREAT | O_EXCL, 0600);
76	if (fd < 0)
77		err(EX_CANTCREAT, "open: %s", name);
78	return (fd);
79}
80
81static void
82write_file(int fd, void *buffer, size_t buflen, const char *filename)
83{
84	ssize_t len;
85
86	len = write(fd, buffer, buflen);
87	if (len < 0)
88		err(EX_OSERR, "write_file: %s", filename);
89	if (len < buflen)
90		err(EX_OSERR, "write_file: short write: %s", filename);
91}
92
93/*
94 * Write a single token to a file.
95 */
96static void
97write_token(const char *directory, const char *filename, token_t *tok)
98{
99	u_char buffer[MAX_AUDIT_RECORD_SIZE];
100	size_t buflen;
101	int fd;
102
103	buflen = MAX_AUDIT_RECORD_SIZE;
104	if (au_close_token(tok, buffer, &buflen) < 0)
105		err(EX_UNAVAILABLE, "au_close_token");
106	fd = open_file(directory, filename);
107	write_file(fd, buffer, buflen, filename);
108	close(fd);
109}
110
111/*
112 * Write a token to a file, wrapped in audit record header and trailer.
113 */
114static void
115write_record(const char *directory, const char *filename, token_t *tok,
116    short event)
117{
118	u_char buffer[MAX_AUDIT_RECORD_SIZE];
119	size_t buflen;
120	int au, fd;
121
122	au = au_open();
123	if (au < 0)
124		err(EX_UNAVAILABLE, "au_open");
125	if (au_write(au, tok) < 0)
126		err(EX_UNAVAILABLE, "au_write");
127	buflen = MAX_AUDIT_RECORD_SIZE;
128	if (au_close_buffer(au, event, buffer, &buflen) < 0)
129		err(EX_UNAVAILABLE, "au_close_buffer");
130	fd = open_file(directory, filename);
131	write_file(fd, buffer, buflen, filename);
132	close(fd);
133}
134
135static struct timeval	 file_token_timeval = { 0x12345, 0x67890} ;
136
137static void
138generate_file_token(const char *directory, const char *token_filename)
139{
140	token_t *file_token;
141
142	file_token = au_to_file("test", file_token_timeval);
143	if (file_token == NULL)
144		err(EX_UNAVAILABLE, "au_to_file");
145	write_token(directory, token_filename, file_token);
146}
147
148static void
149generate_file_record(const char *directory, const char *record_filename)
150{
151	token_t *file_token;
152
153	file_token = au_to_file("test", file_token_timeval);
154	if (file_token == NULL)
155		err(EX_UNAVAILABLE, "au_to_file");
156	write_record(directory, record_filename, file_token, AUE_NULL);
157}
158
159/*
160 * AUT_OHEADER
161 */
162
163static int		 trailer_token_len = 0x12345678;
164
165static void
166generate_trailer_token(const char *directory, const char *token_filename)
167{
168	token_t *trailer_token;
169
170	trailer_token = au_to_trailer(trailer_token_len);
171	if (trailer_token == NULL)
172		err(EX_UNAVAILABLE, "au_to_trailer");
173	write_token(directory, token_filename, trailer_token);
174}
175
176static int		 header32_token_len = 0x12345678;
177static au_event_t	 header32_e_type = AUE_OPEN;
178static au_emod_t	 header32_e_mod = 0x4567;
179static struct timeval	 header32_tm = { 0x12345, 0x67890 };
180
181static void
182generate_header32_token(const char *directory, const char *token_filename)
183{
184	token_t *header32_token;
185
186	header32_token = au_to_header32_tm(header32_token_len,
187	    header32_e_type, header32_e_mod, header32_tm);
188	if (header32_token == NULL)
189		err(EX_UNAVAILABLE, "au_to_header32");
190	write_token(directory, token_filename, header32_token);
191}
192
193/*
194 * AUT_HEADER32_EX
195 */
196
197static char		 data_token_unit_print = AUP_STRING;
198static char		 data_token_unit_type = AUR_CHAR;
199static char		*data_token_data = "SomeData";
200static char		 data_token_unit_count = sizeof("SomeData") + 1;
201
202static void
203generate_data_token(const char *directory, const char *token_filename)
204{
205	token_t *data_token;
206
207	data_token = au_to_data(data_token_unit_print, data_token_unit_type,
208	    data_token_unit_count, data_token_data);
209	if (data_token == NULL)
210		err(EX_UNAVAILABLE, "au_to_data");
211	write_token(directory, token_filename, data_token);
212}
213
214static void
215generate_data_record(const char *directory, const char *record_filename)
216{
217	token_t *data_token;
218
219	data_token = au_to_data(data_token_unit_print, data_token_unit_type,
220	    data_token_unit_count, data_token_data);
221	if (data_token == NULL)
222		err(EX_UNAVAILABLE, "au_to_data");
223	write_record(directory, record_filename, data_token, AUE_NULL);
224}
225
226static char		 ipc_type = AT_IPC_MSG;
227static int		 ipc_id = 0x12345678;
228
229static void
230generate_ipc_token(const char *directory, const char *token_filename)
231{
232	token_t *ipc_token;
233
234	ipc_token = au_to_ipc(ipc_type, ipc_id);
235	if (ipc_token == NULL)
236		err(EX_UNAVAILABLE, "au_to_ipc");
237	write_token(directory, token_filename, ipc_token);
238}
239
240static void
241generate_ipc_record(const char *directory, const char *record_filename)
242{
243	token_t *ipc_token;
244
245	ipc_token = au_to_ipc(ipc_type, ipc_id);
246	if (ipc_token == NULL)
247		err(EX_UNAVAILABLE, "au_to_ipc");
248	write_record(directory, record_filename, ipc_token, AUE_NULL);
249}
250
251static char		*path_token_path = "/test/this/is/a/test";
252
253static void
254generate_path_token(const char *directory, const char *token_filename)
255{
256	token_t *path_token;
257
258	path_token = au_to_path(path_token_path);
259	if (path_token == NULL)
260		err(EX_UNAVAILABLE, "au_to_path");
261	write_token(directory, token_filename, path_token);
262}
263
264static void
265generate_path_record(const char *directory, const char *record_filename)
266{
267	token_t *path_token;
268
269	path_token = au_to_path(path_token_path);
270	if (path_token == NULL)
271		err(EX_UNAVAILABLE, "au_to_path");
272	write_record(directory, record_filename, path_token, AUE_NULL);
273}
274
275static au_id_t		 subject32_auid = 0x12345678;
276static uid_t		 subject32_euid = 0x01234567;
277static gid_t		 subject32_egid = 0x23456789;
278static uid_t		 subject32_ruid = 0x98765432;
279static gid_t		 subject32_rgid = 0x09876543;
280static pid_t		 subject32_pid = 0x13243546;
281static au_asid_t	 subject32_sid = 0x97867564;
282static au_tid_t		 subject32_tid = { 0x16593746 };
283static au_tid_addr_t	 subject32_tid_addr = { 0x16593746 };
284
285static void
286generate_subject32_token(const char *directory, const char *token_filename)
287{
288	token_t *subject32_token;
289
290	subject32_tid.machine = inet_addr("127.0.0.1");
291
292	subject32_token = au_to_subject32(subject32_auid, subject32_euid,
293	    subject32_egid, subject32_ruid, subject32_rgid, subject32_pid,
294	    subject32_sid, &subject32_tid);
295	if (subject32_token == NULL)
296		err(EX_UNAVAILABLE, "au_to_subject32");
297	write_token(directory, token_filename, subject32_token);
298}
299
300static void
301generate_subject32_record(const char *directory, const char *record_filename)
302{
303	token_t *subject32_token;
304
305	subject32_tid.machine = inet_addr("127.0.0.1");
306
307	subject32_token = au_to_subject32(subject32_auid, subject32_euid,
308	    subject32_egid, subject32_ruid, subject32_rgid, subject32_pid,
309	    subject32_sid, &subject32_tid);
310	if (subject32_token == NULL)
311		err(EX_UNAVAILABLE, "au_to_subject32");
312	write_record(directory, record_filename, subject32_token, AUE_NULL);
313}
314
315static void
316generate_subject32ex_token(const char *directory, const char *token_filename,
317    u_int32_t type)
318{
319	token_t *subject32ex_token;
320	char *buf;
321
322	buf = (char *)malloc(strlen(token_filename) + 6);
323	if (type == AU_IPv6) {
324		inet_pton(AF_INET6, "fe80::1", subject32_tid_addr.at_addr);
325		subject32_tid_addr.at_type = AU_IPv6;
326		sprintf(buf, "%s%s", token_filename, "-IPv6");
327	} else {
328		subject32_tid_addr.at_addr[0] = inet_addr("127.0.0.1");
329		subject32_tid_addr.at_type = AU_IPv4;
330		sprintf(buf, "%s%s", token_filename, "-IPv4");
331	}
332
333	subject32ex_token = au_to_subject32_ex(subject32_auid, subject32_euid,
334	    subject32_egid, subject32_ruid, subject32_rgid, subject32_pid,
335	    subject32_sid, &subject32_tid_addr);
336	if (subject32ex_token == NULL)
337		err(EX_UNAVAILABLE, "au_to_subject32_ex");
338	write_token(directory, buf, subject32ex_token);
339	free(buf);
340}
341
342static void
343generate_subject32ex_record(const char *directory, const char *record_filename,
344    u_int32_t type)
345{
346	token_t *subject32ex_token;
347	char *buf;
348
349	buf = (char *)malloc(strlen(record_filename) + 6);
350	if (type == AU_IPv6) {
351		inet_pton(AF_INET6, "fe80::1", subject32_tid_addr.at_addr);
352		subject32_tid_addr.at_type = AU_IPv6;
353		sprintf(buf, "%s%s", record_filename, "-IPv6");
354	} else {
355		subject32_tid_addr.at_addr[0] = inet_addr("127.0.0.1");
356		subject32_tid_addr.at_type = AU_IPv4;
357		sprintf(buf, "%s%s", record_filename, "-IPv4");
358	}
359
360	subject32ex_token = au_to_subject32_ex(subject32_auid, subject32_euid,
361	    subject32_egid, subject32_ruid, subject32_rgid, subject32_pid,
362	    subject32_sid, &subject32_tid_addr);
363	if (subject32ex_token == NULL)
364		err(EX_UNAVAILABLE, "au_to_subject32_ex");
365	write_record(directory, record_filename, subject32ex_token, AUE_NULL);
366	free(buf);
367}
368
369static au_id_t		 process32_auid = 0x12345678;
370static uid_t		 process32_euid = 0x01234567;
371static gid_t		 process32_egid = 0x23456789;
372static uid_t		 process32_ruid = 0x98765432;
373static gid_t		 process32_rgid = 0x09876543;
374static pid_t		 process32_pid = 0x13243546;
375static au_asid_t	 process32_sid = 0x97867564;
376static au_tid_t		 process32_tid = { 0x16593746 };
377static au_tid_addr_t	 process32_tid_addr = { 0x16593746 };
378
379static void
380generate_process32_token(const char *directory, const char *token_filename)
381{
382	token_t *process32_token;
383
384	process32_tid.machine = inet_addr("127.0.0.1");
385
386	process32_token = au_to_process32(process32_auid, process32_euid,
387	    process32_egid, process32_ruid, process32_rgid, process32_pid,
388	    process32_sid, &process32_tid);
389	if (process32_token == NULL)
390		err(EX_UNAVAILABLE, "au_to_process32");
391	write_token(directory, token_filename, process32_token);
392}
393
394static void
395generate_process32_record(const char *directory, const char *record_filename)
396{
397	token_t *process32_token;
398
399	process32_tid.machine = inet_addr("127.0.0.1");
400
401	process32_token = au_to_process32(process32_auid, process32_euid,
402	    process32_egid, process32_ruid, process32_rgid, process32_pid,
403	    process32_sid, &process32_tid);
404	if (process32_token == NULL)
405		err(EX_UNAVAILABLE, "au_ti_process32");
406	write_record(directory, record_filename, process32_token, AUE_NULL);
407}
408
409static void
410generate_process32ex_token(const char *directory, const char *token_filename,
411    u_int32_t type)
412{
413	token_t *process32ex_token;
414	char *buf;
415
416	buf = (char *)malloc(strlen(token_filename) + 6);
417	if (type == AU_IPv6) {
418		inet_pton(AF_INET6, "fe80::1", process32_tid_addr.at_addr);
419		process32_tid_addr.at_type = AU_IPv6;
420		sprintf(buf, "%s%s", token_filename, "-IPv6");
421	} else {
422		process32_tid_addr.at_addr[0] = inet_addr("127.0.0.1");
423		process32_tid_addr.at_type = AU_IPv4;
424		sprintf(buf, "%s%s", token_filename, "-IPv4");
425	}
426
427	process32ex_token = au_to_process32_ex(process32_auid, process32_euid,
428	    process32_egid, process32_ruid, process32_rgid, process32_pid,
429	    process32_sid, &process32_tid_addr);
430	if (process32ex_token == NULL)
431		err(EX_UNAVAILABLE, "au_to_process32_ex");
432	write_token(directory, buf, process32ex_token);
433	free(buf);
434}
435
436static void
437generate_process32ex_record(const char *directory, const char *record_filename,
438    u_int32_t type)
439{
440	token_t *process32ex_token;
441	char *buf;
442
443	buf = (char *)malloc(strlen(record_filename) + 6);
444	if (type == AU_IPv6) {
445		inet_pton(AF_INET6, "fe80::1", process32_tid_addr.at_addr);
446		process32_tid_addr.at_type = AU_IPv6;
447		sprintf(buf, "%s%s", record_filename, "-IPv6");
448	} else {
449		process32_tid_addr.at_addr[0] = inet_addr("127.0.0.1");
450		process32_tid_addr.at_type = AU_IPv4;
451		sprintf(buf, "%s%s", record_filename, "-IPv4");
452	}
453
454	process32ex_token = au_to_process32_ex(process32_auid, process32_euid,
455	    process32_egid, process32_ruid, process32_rgid, process32_pid,
456	    process32_sid, &process32_tid_addr);
457	if (process32ex_token == NULL)
458		err(EX_UNAVAILABLE, "au_to_process32_ex");
459	write_record(directory, buf, process32ex_token, AUE_NULL);
460	free(buf);
461}
462
463static au_id_t		 process64_auid = 0x12345678;
464static uid_t		 process64_euid = 0x01234567;
465static gid_t		 process64_egid = 0x23456789;
466static uid_t		 process64_ruid = 0x98765432;
467static gid_t		 process64_rgid = 0x09876543;
468static pid_t		 process64_pid = 0x13243546;
469static au_asid_t	 process64_sid = 0x97867564;
470static au_tid_t		 process64_tid = { 0x16593746 };
471static au_tid_addr_t	 process64_tid_addr = { 0x16593746 };
472
473static void
474generate_process64_token(const char *directory, const char *token_filename)
475{
476	token_t *process64_token;
477
478	process64_tid.machine = inet_addr("127.0.0.1");
479
480	process64_token = au_to_process64(process64_auid, process64_euid,
481	    process64_egid, process64_ruid, process64_rgid, process64_pid,
482	    process64_sid, &process64_tid);
483	if (process64_token == NULL)
484		err(EX_UNAVAILABLE, "au_to_process64");
485	write_token(directory, token_filename, process64_token);
486}
487
488static void
489generate_process64_record(const char *directory, const char *record_filename)
490{
491	token_t *process64_token;
492
493	process64_tid.machine = inet_addr("127.0.0.1");
494
495	process64_token = au_to_process64(process64_auid, process64_euid,
496	    process64_egid, process64_ruid, process64_rgid, process64_pid,
497	    process64_sid, &process64_tid);
498	if (process64_token == NULL)
499		err(EX_UNAVAILABLE, "au_ti_process64");
500	write_record(directory, record_filename, process64_token, AUE_NULL);
501}
502
503static void
504generate_process64ex_token(const char *directory, const char *token_filename,
505    u_int32_t type)
506{
507	token_t *process64ex_token;
508	char *buf;
509
510	buf = (char *)malloc(strlen(token_filename) + 6);
511	if (type == AU_IPv6) {
512		inet_pton(AF_INET6, "fe80::1", process64_tid_addr.at_addr);
513		process64_tid_addr.at_type = AU_IPv6;
514		sprintf(buf, "%s%s", token_filename, "-IPv6");
515	} else {
516		process64_tid_addr.at_addr[0] = inet_addr("127.0.0.1");
517		process64_tid_addr.at_type = AU_IPv4;
518		sprintf(buf, "%s%s", token_filename, "-IPv4");
519	}
520
521	process64ex_token = au_to_process64_ex(process64_auid, process64_euid,
522	    process64_egid, process64_ruid, process64_rgid, process64_pid,
523	    process64_sid, &process64_tid_addr);
524	if (process64ex_token == NULL)
525		err(EX_UNAVAILABLE, "au_to_process64_ex");
526	write_token(directory, buf, process64ex_token);
527	free(buf);
528}
529
530static void
531generate_process64ex_record(const char *directory, const char *record_filename,
532    u_int32_t type)
533{
534	token_t *process64ex_token;
535	char *buf;
536
537	buf = (char *)malloc(strlen(record_filename) + 6);
538	if (type == AU_IPv6) {
539		inet_pton(AF_INET6, "fe80::1", process64_tid_addr.at_addr);
540		process64_tid_addr.at_type = AU_IPv6;
541		sprintf(buf, "%s%s", record_filename, "-IPv6");
542	} else {
543		process64_tid_addr.at_addr[0] = inet_addr("127.0.0.1");
544		process64_tid_addr.at_type = AU_IPv4;
545		sprintf(buf, "%s%s", record_filename, "-IPv4");
546	}
547
548	process64ex_token = au_to_process64_ex(process64_auid, process64_euid,
549	    process64_egid, process64_ruid, process64_rgid, process64_pid,
550	    process64_sid, &process64_tid_addr);
551	if (process64ex_token == NULL)
552		err(EX_UNAVAILABLE, "au_to_process64_ex");
553	write_record(directory, buf, process64ex_token, AUE_NULL);
554	free(buf);
555}
556
557static char		 return32_status = EINVAL;
558static uint32_t		 return32_ret = 0x12345678;
559
560static void
561generate_return32_token(const char *directory, const char *token_filename)
562{
563	token_t *return32_token;
564
565	return32_token = au_to_return32(au_errno_to_bsm(return32_status),
566	    return32_ret);
567	if (return32_token == NULL)
568		err(EX_UNAVAILABLE, "au_to_return32");
569	write_token(directory, token_filename, return32_token);
570}
571
572static void
573generate_return32_record(const char *directory, const char *record_filename)
574{
575	token_t *return32_token;
576
577	return32_token = au_to_return32(au_errno_to_bsm(return32_status),
578	    return32_ret);
579	if (return32_token == NULL)
580		err(EX_UNAVAILABLE, "au_to_return32");
581	write_record(directory, record_filename, return32_token, AUE_NULL);
582}
583
584static char		*text_token_text = "This is a test.";
585
586static void
587generate_text_token(const char *directory, const char *token_filename)
588{
589	token_t *text_token;
590
591	text_token = au_to_text(text_token_text);
592	if (text_token == NULL)
593		err(EX_UNAVAILABLE, "au_to_text");
594	write_token(directory, token_filename, text_token);
595}
596
597static void
598generate_text_record(const char *directory, const char *record_filename)
599{
600	token_t *text_token;
601
602	text_token = au_to_text(text_token_text);
603	if (text_token == NULL)
604		err(EX_UNAVAILABLE, "au_to_text");
605	write_record(directory, record_filename, text_token, AUE_NULL);
606}
607
608static char		 opaque_token_data[] = {0xaa, 0xbb, 0xcc, 0xdd};
609static int		 opaque_token_bytes = sizeof(opaque_token_data);
610
611static void
612generate_opaque_token(const char *directory, const char *token_filename)
613{
614	token_t *opaque_token;
615
616	opaque_token = au_to_opaque(opaque_token_data, opaque_token_bytes);
617	if (opaque_token == NULL)
618		err(EX_UNAVAILABLE, "au_to_opaque");
619	write_token(directory, token_filename, opaque_token);
620}
621
622static void
623generate_opaque_record(const char *directory, const char *record_filename)
624{
625	token_t *opaque_token;
626
627	opaque_token = au_to_opaque(opaque_token_data, opaque_token_bytes);
628	if (opaque_token == NULL)
629		err(EX_UNAVAILABLE, "au_to_opaque");
630	write_record(directory, record_filename, opaque_token, AUE_NULL);
631}
632
633static struct in_addr	 in_addr_token_addr;
634
635static void
636generate_in_addr_token(const char *directory, const char *token_filename)
637{
638	token_t *in_addr_token;
639
640	in_addr_token_addr.s_addr = inet_addr("192.168.100.15");
641
642	in_addr_token = au_to_in_addr(&in_addr_token_addr);
643	if (in_addr_token == NULL)
644		err(EX_UNAVAILABLE, "au_to_in_addr");
645	write_token(directory, token_filename, in_addr_token);
646}
647
648static void
649generate_in_addr_record(const char *directory, const char *record_filename)
650{
651	token_t *in_addr_token;
652
653	in_addr_token_addr.s_addr = inet_addr("192.168.100.15");
654
655	in_addr_token = au_to_in_addr(&in_addr_token_addr);
656	if (in_addr_token == NULL)
657		err(EX_UNAVAILABLE, "au_to_in_addr");
658	write_record(directory, record_filename, in_addr_token, AUE_NULL);
659}
660
661static struct ip	 ip_token_ip;
662static u_char		 ip_token_ip_v = 4;
663static uint16_t		 ip_token_ip_id = 0x5478;
664static u_char		 ip_token_ip_ttl = 64;
665static u_char		 ip_token_ip_p = IPPROTO_ICMP;
666static struct in_addr	 ip_token_ip_src;
667static struct in_addr	 ip_token_ip_dst;
668
669static void
670generate_ip_token(const char *directory, const char *token_filename)
671{
672	token_t *ip_token;
673
674	ip_token_ip_src.s_addr = inet_addr("192.168.100.155");
675	ip_token_ip_dst.s_addr = inet_addr("192.168.110.48");
676
677	memset(&ip_token_ip, 0, sizeof(ip_token_ip));
678	ip_token_ip.ip_v = ip_token_ip_v;
679	ip_token_ip.ip_len = htons(sizeof(ip_token_ip));
680	ip_token_ip.ip_id = htons(ip_token_ip_id);
681	ip_token_ip.ip_ttl = ip_token_ip_ttl;
682	ip_token_ip.ip_p = ip_token_ip_p;
683	ip_token_ip.ip_src = ip_token_ip_src;
684	ip_token_ip.ip_dst = ip_token_ip_dst;
685
686	ip_token = au_to_ip(&ip_token_ip);
687	if (ip_token == NULL)
688		err(EX_UNAVAILABLE, "au_to_ip");
689	write_token(directory, token_filename, ip_token);
690}
691
692static void
693generate_ip_record(const char *directory, const char *record_filename)
694{
695	token_t *ip_token;
696
697	ip_token_ip_src.s_addr = inet_addr("192.168.100.155");
698	ip_token_ip_dst.s_addr = inet_addr("192.168.110.48");
699
700	memset(&ip_token_ip, 0, sizeof(ip_token_ip));
701	ip_token_ip.ip_v = ip_token_ip_v;
702	ip_token_ip.ip_len = htons(sizeof(ip_token_ip));
703	ip_token_ip.ip_id = htons(ip_token_ip_id);
704	ip_token_ip.ip_ttl = ip_token_ip_ttl;
705	ip_token_ip.ip_p = ip_token_ip_p;
706	ip_token_ip.ip_src = ip_token_ip_src;
707	ip_token_ip.ip_dst = ip_token_ip_dst;
708
709	ip_token = au_to_ip(&ip_token_ip);
710	if (ip_token == NULL)
711		err(EX_UNAVAILABLE, "au_to_ip");
712	write_record(directory, record_filename, ip_token, AUE_NULL);
713}
714
715static u_int16_t		 iport_token_iport;
716
717static void
718generate_iport_token(const char *directory, const char *token_filename)
719{
720	token_t *iport_token;
721
722	iport_token_iport = htons(80);
723
724	iport_token = au_to_iport(iport_token_iport);
725	if (iport_token == NULL)
726		err(EX_UNAVAILABLE, "au_to_iport");
727	write_token(directory, token_filename, iport_token);
728}
729
730static void
731generate_iport_record(const char *directory, const char *record_filename)
732{
733	token_t *iport_token;
734
735	iport_token_iport = htons(80);
736
737	iport_token = au_to_iport(iport_token_iport);
738	if (iport_token == NULL)
739		err(EX_UNAVAILABLE, "au_to_iport");
740	write_record(directory, record_filename, iport_token, AUE_NULL);
741}
742
743static char	 arg32_token_n = 3;
744static char	*arg32_token_text = "test_arg32_token";
745static uint32_t	 arg32_token_v = 0xabcdef00;
746
747static void
748generate_arg32_token(const char *directory, const char *token_filename)
749{
750	token_t *arg32_token;
751
752	arg32_token = au_to_arg32(arg32_token_n, arg32_token_text,
753	    arg32_token_v);
754	if (arg32_token == NULL)
755		err(EX_UNAVAILABLE, "au_to_arg32");
756	write_token(directory, token_filename, arg32_token);
757}
758
759static void
760generate_arg32_record(const char *directory, const char *record_filename)
761{
762	token_t *arg32_token;
763
764	arg32_token = au_to_arg32(arg32_token_n, arg32_token_text,
765	    arg32_token_v);
766	if (arg32_token == NULL)
767		err(EX_UNAVAILABLE, "au_to_arg32");
768	write_record(directory, record_filename, arg32_token, AUE_NULL);
769}
770
771static long	 seq_audit_count = 0x12345678;
772
773static void
774generate_seq_token(const char *directory, const char *token_filename)
775{
776	token_t *seq_token;
777
778	seq_token = au_to_seq(seq_audit_count);
779	if (seq_token == NULL)
780		err(EX_UNAVAILABLE, "au_to_seq");
781	write_token(directory, token_filename, seq_token);
782}
783
784static void
785generate_seq_record(const char *directory, const char *record_filename)
786{
787	token_t *seq_token;
788
789	seq_token = au_to_seq(seq_audit_count);
790	if (seq_token == NULL)
791		err(EX_UNAVAILABLE, "au_to_seq");
792	write_record(directory, record_filename, seq_token, AUE_NULL);
793}
794
795#if 0
796/*
797 * AUT_ACL
798 */
799
800static void
801generate_attr_token(const char *directory, const char *token_filename)
802{
803	token_t *attr_token;
804
805}
806
807static void
808generate_attr_record(const char *directory, const char *record_filename)
809{
810	token_t *attr_token;
811
812}
813
814static void
815generate_ipc_perm_token(const char *directory, const char *token_filename)
816{
817	token_t *ipc_perm_token;
818
819}
820
821static void
822generate_ipc_perm_record(const char *directory, const char *record_filename)
823{
824	token_t *ipc_perm_token;
825
826}
827#endif
828
829#if 0
830/*
831 * AUT_LABEL
832 */
833
834static void
835generate_groups_token(const char *directory, const char *token_filename)
836{
837	token_t *groups_token;
838
839}
840
841static void
842generate_groups_record(const char *directory, const char *record_filename)
843{
844	token_t *groups_token;
845
846}
847#endif
848
849/*
850 * AUT_ILABEL
851 */
852
853/*
854 * AUT_SLABEL
855 */
856
857/*
858 * AUT_CLEAR
859 */
860
861/*
862 * AUT_PRIV
863 */
864
865/*
866 * AUT_UPRIV
867 */
868
869/*
870 * AUT_LIAISON
871 */
872
873/*
874 * AUT_NEWGROUPS
875 */
876
877/*
878 * AUT_EXEC_ARGS
879 */
880
881/*
882 * AUT_EXEC_ENV
883 */
884
885#if 0
886static void
887generate_attr32_token(const char *directory, const char *token_filename)
888{
889	token_t *attr32_token;
890
891}
892
893static void
894generate_attr32_record(const char *directory, const char *record_filename)
895{
896	token_t *attr32_token;
897
898}
899#endif
900
901static char	*zonename_sample = "testzone";
902
903static void
904generate_zonename_token(const char *directory, const char *token_filename)
905{
906	token_t *zonename_token;
907
908	zonename_token = au_to_zonename(zonename_sample);
909	if (zonename_token == NULL)
910		err(EX_UNAVAILABLE, "au_to_zonename");
911	write_token(directory, token_filename, zonename_token);
912}
913
914static void
915generate_zonename_record(const char *directory, const char *record_filename)
916{
917	token_t *zonename_token;
918
919	zonename_token = au_to_zonename(zonename_sample);
920	if (zonename_token == NULL)
921		err(EX_UNAVAILABLE, "au_to_zonename");
922	write_record(directory, record_filename, zonename_token, AUE_NULL);
923}
924
925static u_short socketex_domain = PF_INET;
926static u_short socketex_type = SOCK_STREAM;
927static struct sockaddr_in socketex_laddr, socketex_raddr;
928
929static void
930generate_socketex_token(const char *directory, const char *token_filename)
931{
932	token_t *socketex_token;
933
934	bzero(&socketex_laddr, sizeof(socketex_laddr));
935	socketex_laddr.sin_family = AF_INET;
936	socketex_laddr.sin_len = sizeof(socketex_laddr);
937	socketex_laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
938
939	bzero(&socketex_raddr, sizeof(socketex_raddr));
940	socketex_raddr.sin_family = AF_INET;
941	socketex_raddr.sin_len = sizeof(socketex_raddr);
942	socketex_raddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
943
944	socketex_token = au_to_socket_ex(au_domain_to_bsm(socketex_domain),
945	    au_socket_type_to_bsm(socketex_type),
946	    (struct sockaddr *)&socketex_laddr,
947	    (struct sockaddr *)&socketex_raddr);
948	if (socketex_token == NULL)
949		err(EX_UNAVAILABLE, "au_to_socket_ex");
950	write_token(directory, token_filename, socketex_token);
951}
952
953static void
954generate_socketex_record(const char *directory, const char *record_filename)
955{
956	token_t *socketex_token;
957
958	bzero(&socketex_laddr, sizeof(socketex_laddr));
959	socketex_laddr.sin_family = AF_INET;
960	socketex_laddr.sin_len = sizeof(socketex_laddr);
961	socketex_laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
962
963	bzero(&socketex_raddr, sizeof(socketex_raddr));
964	socketex_raddr.sin_family = AF_INET;
965	socketex_raddr.sin_len = sizeof(socketex_raddr);
966	socketex_raddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
967
968	socketex_token = au_to_socket_ex(au_domain_to_bsm(socketex_domain),
969	    au_socket_type_to_bsm(socketex_type),
970	    (struct sockaddr *)&socketex_laddr,
971	    (struct sockaddr *)&socketex_raddr);
972	if (socketex_token == NULL)
973		err(EX_UNAVAILABLE, "au_to_socket_ex");
974	write_record(directory, record_filename, socketex_token, AUE_NULL);
975}
976
977/*
978 * Generate a series of error-number specific return tokens in records.
979 */
980static void
981generate_error_record(const char *directory, const char *filename, int error)
982{
983	char pathname[PATH_MAX];
984	token_t *return32_token;
985
986	return32_token = au_to_return32(au_errno_to_bsm(error), -1);
987	if (return32_token == NULL)
988		err(EX_UNAVAILABLE, "au_to_return32");
989	(void)snprintf(pathname, PATH_MAX, "%s_record", filename);
990	write_record(directory, pathname, return32_token, AUE_NULL);
991}
992
993/*
994 * Not all the error numbers, just a few present on all platforms for now.
995 */
996const struct {
997	int error_number;
998	const char *error_name;
999} error_list[] = {
1000	{ EPERM, "EPERM" },
1001	{ ENOENT, "ENOENT" },
1002	{ ESRCH, "ESRCH" },
1003	{ EINTR, "EINTR" },
1004	{ EIO, "EIO" },
1005	{ ENXIO, "ENXIO" },
1006	{ E2BIG, "E2BIG" },
1007	{ ENOEXEC, "ENOEXEC" },
1008	{ EBADF, "EBADF" },
1009	{ ECHILD, "ECHILD" },
1010	{ EDEADLK, "EDEADLK" },
1011	{ ENOMEM, "ENOMEM" },
1012	{ EACCES, "EACCES" },
1013	{ EFAULT, "EFAULT" },
1014	{ ENOTBLK, "ENOTBLK" },
1015	{ EBUSY, "EBUSY" },
1016	{ EEXIST, "EEXIST" },
1017	{ EXDEV, "EXDEV" },
1018	{ ENODEV, "ENODEV" },
1019	{ ENOTDIR, "ENOTDIR" },
1020	{ EISDIR, "EISDIR" },
1021	{ EINVAL, "EINVAL" },
1022	{ ENFILE, "ENFILE" },
1023	{ EMFILE, "EMFILE" },
1024	{ ENOTTY, "ENOTTY" },
1025	{ ETXTBSY, "ETXTBSY" },
1026	{ EFBIG, "EFBIG" },
1027	{ ENOSPC, "ENOSPC" },
1028	{ ESPIPE, "ESPIPE" },
1029	{ EROFS, "EROFS" },
1030	{ EMLINK, "EMLINK" },
1031	{ EPIPE, "EPIPE" }
1032};
1033const int error_list_count = sizeof(error_list)/sizeof(error_list[0]);
1034
1035static void
1036do_error_records(const char *directory)
1037{
1038	int i;
1039
1040	for (i = 0; i < error_list_count; i++)
1041		generate_error_record(directory, error_list[i].error_name,
1042		    error_list[i].error_number);
1043}
1044
1045int
1046main(int argc, char *argv[])
1047{
1048	const char *directory;
1049	int ch;
1050
1051	while ((ch = getopt(argc, argv, "rt")) != -1) {
1052		switch (ch) {
1053		case 'r':
1054			do_records++;
1055			break;
1056
1057		case 't':
1058			do_tokens++;
1059			break;
1060
1061		default:
1062			usage();
1063		}
1064	}
1065
1066	argc -= optind;
1067	argv += optind;
1068
1069	if (argc != 1)
1070		usage();
1071
1072	directory = argv[0];
1073
1074	if (mkdir(directory, 0755) < 0 && errno != EEXIST)
1075		err(EX_OSERR, "mkdir: %s", directory);
1076
1077	if (do_tokens) {
1078		generate_file_token(directory, "file_token");
1079		generate_trailer_token(directory, "trailer_token");
1080		generate_header32_token(directory, "header32_token");
1081		generate_data_token(directory, "data_token");
1082		generate_ipc_token(directory, "ipc_token");
1083		generate_path_token(directory, "path_token");
1084		generate_subject32_token(directory, "subject32_token");
1085		generate_subject32ex_token(directory, "subject32ex_token",
1086		    AU_IPv4);
1087		generate_subject32ex_token(directory, "subject32ex_token",
1088		    AU_IPv6);
1089		generate_process32_token(directory, "process32_token");
1090		generate_process32ex_token(directory, "process32ex_token",
1091		    AU_IPv4);
1092		generate_process32ex_token(directory, "process32ex_token",
1093		    AU_IPv6);
1094		generate_process64_token(directory, "process64_token");
1095		generate_process64ex_token(directory, "process64ex_token",
1096		    AU_IPv4);
1097		generate_process64ex_token(directory, "process64ex_token",
1098		    AU_IPv6);
1099		generate_return32_token(directory, "return32_token");
1100		generate_text_token(directory, "text_token");
1101		generate_opaque_token(directory, "opaque_token");
1102		generate_in_addr_token(directory, "in_addr_token");
1103		generate_ip_token(directory, "ip_token");
1104		generate_iport_token(directory, "iport_token");
1105		generate_arg32_token(directory, "arg32_token");
1106		generate_seq_token(directory, "seq_token");
1107#if 0
1108		generate_attr_token(directory,  "attr_token");
1109		generate_ipc_perm_token(directory, "ipc_perm_token");
1110		generate_groups_token(directory, "groups_token");
1111		generate_attr32_token(directory, "attr32_token");
1112#endif
1113		generate_zonename_token(directory, "zonename_token");
1114		generate_socketex_token(directory, "socketex_token");
1115	}
1116
1117	if (do_records) {
1118		generate_file_record(directory, "file_record");
1119		generate_data_record(directory, "data_record");
1120		generate_ipc_record(directory, "ipc_record");
1121		generate_path_record(directory, "path_record");
1122		generate_subject32_record(directory, "subject32_record");
1123		generate_subject32ex_record(directory, "subject32ex_record",
1124		    AU_IPv4);
1125		generate_subject32ex_record(directory, "subject32ex_record",
1126		    AU_IPv6);
1127		generate_process32_record(directory, "process32_record");
1128		generate_process32ex_record(directory, "process32ex_record",
1129		    AU_IPv4);
1130		generate_process32ex_record(directory, "process32ex_record",
1131		    AU_IPv6);
1132		generate_process64_record(directory, "process64_record");
1133		generate_process64ex_record(directory, "process64ex_record",
1134		    AU_IPv4);
1135		generate_process64ex_record(directory, "process64ex_record",
1136		    AU_IPv6);
1137		generate_return32_record(directory, "return32_record");
1138		generate_text_record(directory, "text_record");
1139		generate_opaque_record(directory, "opaque_record");
1140		generate_in_addr_record(directory, "in_addr_record");
1141		generate_ip_record(directory, "ip_record");
1142		generate_iport_record(directory, "iport_record");
1143		generate_arg32_record(directory, "arg32_record");
1144		generate_seq_record(directory, "seq_record");
1145#if 0
1146		generate_attr_record(directory,  "attr_record");
1147		generate_ipc_perm_record(directory, "ipc_perm_record");
1148		generate_groups_record(directory, "groups_record");
1149		generate_attr32_record(directory, "attr32_record");
1150#endif
1151		generate_zonename_record(directory, "zonename_record");
1152		generate_socketex_record(directory, "socketex_record");
1153		do_error_records(directory);
1154	}
1155
1156	return (0);
1157}
1158