1/*-
2 * Copyright (c) 2018 Aniket Pandey
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * SUCH DAMAGE.
24 *
25 * $FreeBSD: stable/11/tests/sys/audit/network.c 339090 2018-10-02 17:27:10Z asomers $
26 */
27
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <sys/un.h>
31
32#include <atf-c.h>
33#include <fcntl.h>
34#include <stdarg.h>
35
36#include "utils.h"
37
38#define MAX_DATA 1024
39#define SERVER_PATH "server"
40
41static int sockfd, sockfd2, connectfd;
42static ssize_t data_bytes;
43static struct pollfd fds[1];
44static struct sockaddr_un server;
45static char extregex[80];
46static char data[MAX_DATA];
47static socklen_t len = sizeof(struct sockaddr_un);
48static char msgbuff[MAX_DATA] = "This message does not exist";
49static const char *auclass = "nt";
50static const char *nosupregex = "return,failure : Address family "
51				"not supported by protocol family";
52static const char *invalregex = "return,failure : Bad file descriptor";
53
54/*
55 * Variadic function to close socket descriptors
56 */
57static void
58close_sockets(int count, ...)
59{
60	int sockd;
61	va_list socklist;
62	va_start(socklist, count);
63	for (sockd = 0; sockd < count; sockd++) {
64		close(va_arg(socklist, int));
65	}
66	va_end(socklist);
67}
68
69/*
70 * Assign local filesystem address to a Unix domain socket
71 */
72static void
73assign_address(struct sockaddr_un *serveraddr)
74{
75	memset(serveraddr, 0, sizeof(*serveraddr));
76	serveraddr->sun_family = AF_UNIX;
77	strcpy(serveraddr->sun_path, SERVER_PATH);
78}
79
80
81ATF_TC_WITH_CLEANUP(socket_success);
82ATF_TC_HEAD(socket_success, tc)
83{
84	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
85					"socket(2) call");
86}
87
88ATF_TC_BODY(socket_success, tc)
89{
90	FILE *pipefd = setup(fds, auclass);
91	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
92	/* Check the presence of sockfd in audit record */
93	snprintf(extregex, sizeof(extregex), "socket.*ret.*success,%d", sockfd);
94	check_audit(fds, extregex, pipefd);
95	close(sockfd);
96}
97
98ATF_TC_CLEANUP(socket_success, tc)
99{
100	cleanup();
101}
102
103
104ATF_TC_WITH_CLEANUP(socket_failure);
105ATF_TC_HEAD(socket_failure, tc)
106{
107	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
108					"socket(2) call");
109}
110
111ATF_TC_BODY(socket_failure, tc)
112{
113	snprintf(extregex, sizeof(extregex), "socket.*%s", nosupregex);
114	FILE *pipefd = setup(fds, auclass);
115	/* Failure reason: Unsupported value of 'domain' argument: 0 */
116	ATF_REQUIRE_EQ(-1, socket(0, SOCK_STREAM, 0));
117	check_audit(fds, extregex, pipefd);
118}
119
120ATF_TC_CLEANUP(socket_failure, tc)
121{
122	cleanup();
123}
124
125
126ATF_TC_WITH_CLEANUP(socketpair_success);
127ATF_TC_HEAD(socketpair_success, tc)
128{
129	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
130					"socketpair(2) call");
131}
132
133ATF_TC_BODY(socketpair_success, tc)
134{
135	int sv[2];
136	FILE *pipefd = setup(fds, auclass);
137	ATF_REQUIRE_EQ(0, socketpair(PF_UNIX, SOCK_STREAM, 0, sv));
138
139	/* Check for 0x0 (argument 3: default protocol) in the audit record */
140	snprintf(extregex, sizeof(extregex), "socketpair.*0x0.*return,success");
141	check_audit(fds, extregex, pipefd);
142	close_sockets(2, sv[0], sv[1]);
143}
144
145ATF_TC_CLEANUP(socketpair_success, tc)
146{
147	cleanup();
148}
149
150
151ATF_TC_WITH_CLEANUP(socketpair_failure);
152ATF_TC_HEAD(socketpair_failure, tc)
153{
154	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
155					"socketpair(2) call");
156}
157
158ATF_TC_BODY(socketpair_failure, tc)
159{
160	snprintf(extregex, sizeof(extregex), "socketpair.*%s", nosupregex);
161	FILE *pipefd = setup(fds, auclass);
162	/* Failure reason: Unsupported value of 'domain' argument: 0 */
163	ATF_REQUIRE_EQ(-1, socketpair(0, SOCK_STREAM, 0, NULL));
164	check_audit(fds, extregex, pipefd);
165}
166
167ATF_TC_CLEANUP(socketpair_failure, tc)
168{
169	cleanup();
170}
171
172
173ATF_TC_WITH_CLEANUP(setsockopt_success);
174ATF_TC_HEAD(setsockopt_success, tc)
175{
176	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
177					"setsockopt(2) call");
178}
179
180ATF_TC_BODY(setsockopt_success, tc)
181{
182	int tr = 1;
183	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
184	/* Check the presence of sockfd in audit record */
185	snprintf(extregex, sizeof(extregex),
186			"setsockopt.*0x%x.*return,success", sockfd);
187
188	FILE *pipefd = setup(fds, auclass);
189	ATF_REQUIRE_EQ(0, setsockopt(sockfd, SOL_SOCKET,
190		SO_REUSEADDR, &tr, sizeof(int)));
191	check_audit(fds, extregex, pipefd);
192	close(sockfd);
193}
194
195ATF_TC_CLEANUP(setsockopt_success, tc)
196{
197	cleanup();
198}
199
200
201ATF_TC_WITH_CLEANUP(setsockopt_failure);
202ATF_TC_HEAD(setsockopt_failure, tc)
203{
204	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
205					"setsockopt(2) call");
206}
207
208ATF_TC_BODY(setsockopt_failure, tc)
209{
210	snprintf(extregex, sizeof(extregex), "setsockopt.*%s", invalregex);
211	FILE *pipefd = setup(fds, auclass);
212	/* Failure reason: Invalid socket descriptor */
213	ATF_REQUIRE_EQ(-1, setsockopt(-1, SOL_SOCKET, 0, NULL, 0));
214	check_audit(fds, extregex, pipefd);
215}
216
217ATF_TC_CLEANUP(setsockopt_failure, tc)
218{
219	cleanup();
220}
221
222
223ATF_TC_WITH_CLEANUP(bind_success);
224ATF_TC_HEAD(bind_success, tc)
225{
226	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
227					"bind(2) call");
228}
229
230ATF_TC_BODY(bind_success, tc)
231{
232	assign_address(&server);
233	/* Preliminary socket setup */
234	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
235	/* Check the presence of AF_UNIX address path in audit record */
236	snprintf(extregex, sizeof(extregex),
237		"bind.*unix.*%s.*return,success", SERVER_PATH);
238
239	FILE *pipefd = setup(fds, auclass);
240	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
241	check_audit(fds, extregex, pipefd);
242	close(sockfd);
243}
244
245ATF_TC_CLEANUP(bind_success, tc)
246{
247	cleanup();
248}
249
250
251ATF_TC_WITH_CLEANUP(bind_failure);
252ATF_TC_HEAD(bind_failure, tc)
253{
254	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
255					"bind(2) call");
256}
257
258ATF_TC_BODY(bind_failure, tc)
259{
260	assign_address(&server);
261	/* Check the presence of AF_UNIX path in audit record */
262	snprintf(extregex, sizeof(extregex),
263			"bind.*%s.*return,failure", SERVER_PATH);
264
265	FILE *pipefd = setup(fds, auclass);
266	/* Failure reason: Invalid socket descriptor */
267	ATF_REQUIRE_EQ(-1, bind(0, (struct sockaddr *)&server, len));
268	check_audit(fds, extregex, pipefd);
269}
270
271ATF_TC_CLEANUP(bind_failure, tc)
272{
273	cleanup();
274}
275
276
277ATF_TC_WITH_CLEANUP(bindat_success);
278ATF_TC_HEAD(bindat_success, tc)
279{
280	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
281					"bindat(2) call");
282}
283
284ATF_TC_BODY(bindat_success, tc)
285{
286	assign_address(&server);
287	/* Preliminary socket setup */
288	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
289	/* Check the presence of socket descriptor in audit record */
290	snprintf(extregex, sizeof(extregex),
291			"bindat.*0x%x.*return,success", sockfd);
292
293	FILE *pipefd = setup(fds, auclass);
294	ATF_REQUIRE_EQ(0, bindat(AT_FDCWD, sockfd,
295			(struct sockaddr *)&server, len));
296	check_audit(fds, extregex, pipefd);
297	close(sockfd);
298}
299
300ATF_TC_CLEANUP(bindat_success, tc)
301{
302	cleanup();
303}
304
305
306ATF_TC_WITH_CLEANUP(bindat_failure);
307ATF_TC_HEAD(bindat_failure, tc)
308{
309	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
310					"bindat(2) call");
311}
312
313ATF_TC_BODY(bindat_failure, tc)
314{
315	assign_address(&server);
316	snprintf(extregex, sizeof(extregex), "bindat.*%s", invalregex);
317
318	FILE *pipefd = setup(fds, auclass);
319	/* Failure reason: Invalid socket descriptor */
320	ATF_REQUIRE_EQ(-1, bindat(AT_FDCWD, -1,
321			(struct sockaddr *)&server, len));
322	check_audit(fds, extregex, pipefd);
323}
324
325ATF_TC_CLEANUP(bindat_failure, tc)
326{
327	cleanup();
328}
329
330
331ATF_TC_WITH_CLEANUP(listen_success);
332ATF_TC_HEAD(listen_success, tc)
333{
334	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
335					"listen(2) call");
336}
337
338ATF_TC_BODY(listen_success, tc)
339{
340	assign_address(&server);
341	/* Preliminary socket setup */
342	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
343	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
344	/* Check the presence of socket descriptor in the audit record */
345	snprintf(extregex, sizeof(extregex),
346			"listen.*0x%x.*return,success", sockfd);
347
348	FILE *pipefd = setup(fds, auclass);
349	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
350	check_audit(fds, extregex, pipefd);
351	close(sockfd);
352}
353
354ATF_TC_CLEANUP(listen_success, tc)
355{
356	cleanup();
357}
358
359
360ATF_TC_WITH_CLEANUP(listen_failure);
361ATF_TC_HEAD(listen_failure, tc)
362{
363	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
364					"listen(2) call");
365}
366
367ATF_TC_BODY(listen_failure, tc)
368{
369	snprintf(extregex, sizeof(extregex), "listen.*%s", invalregex);
370	FILE *pipefd = setup(fds, auclass);
371	/* Failure reason: Invalid socket descriptor */
372	ATF_REQUIRE_EQ(-1, listen(-1, 1));
373	check_audit(fds, extregex, pipefd);
374}
375
376ATF_TC_CLEANUP(listen_failure, tc)
377{
378	cleanup();
379}
380
381
382ATF_TC_WITH_CLEANUP(connect_success);
383ATF_TC_HEAD(connect_success, tc)
384{
385	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
386					"connect(2) call");
387}
388
389ATF_TC_BODY(connect_success, tc)
390{
391	assign_address(&server);
392	/* Setup a server socket and bind to the specified address */
393	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
394	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
395	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
396
397	/* Set up "blocking" client socket */
398	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
399
400	/* Audit record must contain AF_UNIX address path & sockfd2 */
401	snprintf(extregex, sizeof(extregex),
402			"connect.*0x%x.*%s.*success", sockfd2, SERVER_PATH);
403
404	FILE *pipefd = setup(fds, auclass);
405	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
406	check_audit(fds, extregex, pipefd);
407
408	/* Close all socket descriptors */
409	close_sockets(2, sockfd, sockfd2);
410}
411
412ATF_TC_CLEANUP(connect_success, tc)
413{
414	cleanup();
415}
416
417
418ATF_TC_WITH_CLEANUP(connect_failure);
419ATF_TC_HEAD(connect_failure, tc)
420{
421	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
422					"connect(2) call");
423}
424
425ATF_TC_BODY(connect_failure, tc)
426{
427	assign_address(&server);
428	/* Audit record must contain AF_UNIX address path */
429	snprintf(extregex, sizeof(extregex),
430			"connect.*%s.*return,failure", SERVER_PATH);
431
432	FILE *pipefd = setup(fds, auclass);
433	/* Failure reason: Invalid socket descriptor */
434	ATF_REQUIRE_EQ(-1, connect(-1, (struct sockaddr *)&server, len));
435	check_audit(fds, extregex, pipefd);
436}
437
438ATF_TC_CLEANUP(connect_failure, tc)
439{
440	cleanup();
441}
442
443
444ATF_TC_WITH_CLEANUP(connectat_success);
445ATF_TC_HEAD(connectat_success, tc)
446{
447	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
448					"connectat(2) call");
449}
450
451ATF_TC_BODY(connectat_success, tc)
452{
453	assign_address(&server);
454	/* Setup a server socket and bind to the specified address */
455	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
456	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
457	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
458
459	/* Set up "blocking" client socket */
460	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
461
462	/* Audit record must contain sockfd2 */
463	snprintf(extregex, sizeof(extregex),
464			"connectat.*0x%x.*return,success", sockfd2);
465
466	FILE *pipefd = setup(fds, auclass);
467	ATF_REQUIRE_EQ(0, connectat(AT_FDCWD, sockfd2,
468			(struct sockaddr *)&server, len));
469	check_audit(fds, extregex, pipefd);
470
471	/* Close all socket descriptors */
472	close_sockets(2, sockfd, sockfd2);
473}
474
475ATF_TC_CLEANUP(connectat_success, tc)
476{
477	cleanup();
478}
479
480
481ATF_TC_WITH_CLEANUP(connectat_failure);
482ATF_TC_HEAD(connectat_failure, tc)
483{
484	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
485					"connectat(2) call");
486}
487
488ATF_TC_BODY(connectat_failure, tc)
489{
490	assign_address(&server);
491	snprintf(extregex, sizeof(extregex), "connectat.*%s", invalregex);
492
493	FILE *pipefd = setup(fds, auclass);
494	/* Failure reason: Invalid socket descriptor */
495	ATF_REQUIRE_EQ(-1, connectat(AT_FDCWD, -1,
496			(struct sockaddr *)&server, len));
497	check_audit(fds, extregex, pipefd);
498}
499
500ATF_TC_CLEANUP(connectat_failure, tc)
501{
502	cleanup();
503}
504
505
506ATF_TC_WITH_CLEANUP(accept_success);
507ATF_TC_HEAD(accept_success, tc)
508{
509	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
510					"accept(2) call");
511}
512
513ATF_TC_BODY(accept_success, tc)
514{
515	assign_address(&server);
516	/* Setup a server socket and bind to the specified address */
517	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
518	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
519	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
520
521	/* Set up "blocking" client socket */
522	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
523	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
524
525	FILE *pipefd = setup(fds, auclass);
526	ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1);
527
528	/* Audit record must contain connectfd & sockfd */
529	snprintf(extregex, sizeof(extregex),
530			"accept.*0x%x.*return,success,%d", sockfd, connectfd);
531	check_audit(fds, extregex, pipefd);
532
533	/* Close all socket descriptors */
534	close_sockets(3, sockfd, sockfd2, connectfd);
535}
536
537ATF_TC_CLEANUP(accept_success, tc)
538{
539	cleanup();
540}
541
542
543ATF_TC_WITH_CLEANUP(accept_failure);
544ATF_TC_HEAD(accept_failure, tc)
545{
546	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
547					"accept(2) call");
548}
549
550ATF_TC_BODY(accept_failure, tc)
551{
552	snprintf(extregex, sizeof(extregex), "accept.*%s", invalregex);
553	FILE *pipefd = setup(fds, auclass);
554	/* Failure reason: Invalid socket descriptor */
555	ATF_REQUIRE_EQ(-1, accept(-1, NULL, NULL));
556	check_audit(fds, extregex, pipefd);
557}
558
559ATF_TC_CLEANUP(accept_failure, tc)
560{
561	cleanup();
562}
563
564
565ATF_TC_WITH_CLEANUP(send_success);
566ATF_TC_HEAD(send_success, tc)
567{
568	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
569					"send(2) call");
570}
571
572ATF_TC_BODY(send_success, tc)
573{
574	assign_address(&server);
575	/* Setup a server socket and bind to the specified address */
576	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
577	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
578	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
579
580	/* Set up "blocking" client and connect with non-blocking server */
581	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
582	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
583	ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1);
584
585	/* Send a sample message to the connected socket */
586	FILE *pipefd = setup(fds, auclass);
587	ATF_REQUIRE((data_bytes =
588		send(sockfd2, msgbuff, strlen(msgbuff), 0)) != -1);
589
590	/* Audit record must contain sockfd2 and data_bytes */
591	snprintf(extregex, sizeof(extregex),
592		"send.*0x%x.*return,success,%zd", sockfd2, data_bytes);
593	check_audit(fds, extregex, pipefd);
594
595	/* Close all socket descriptors */
596	close_sockets(3, sockfd, sockfd2, connectfd);
597}
598
599ATF_TC_CLEANUP(send_success, tc)
600{
601	cleanup();
602}
603
604
605ATF_TC_WITH_CLEANUP(send_failure);
606ATF_TC_HEAD(send_failure, tc)
607{
608	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
609					"send(2) call");
610}
611
612ATF_TC_BODY(send_failure, tc)
613{
614	snprintf(extregex, sizeof(extregex), "send.*%s", invalregex);
615	FILE *pipefd = setup(fds, auclass);
616	/* Failure reason: Invalid socket descriptor */
617	ATF_REQUIRE_EQ(-1, send(-1, NULL, 0, 0));
618	check_audit(fds, extregex, pipefd);
619}
620
621ATF_TC_CLEANUP(send_failure, tc)
622{
623	cleanup();
624}
625
626
627ATF_TC_WITH_CLEANUP(recv_success);
628ATF_TC_HEAD(recv_success, tc)
629{
630	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
631					"recv(2) call");
632}
633
634ATF_TC_BODY(recv_success, tc)
635{
636	assign_address(&server);
637	/* Setup a server socket and bind to the specified address */
638	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
639	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
640	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
641
642	/* Set up "blocking" client and connect with non-blocking server */
643	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
644	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
645	ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1);
646	/* Send a sample message to the connected socket */
647	ATF_REQUIRE(send(sockfd2, msgbuff, strlen(msgbuff), 0) != -1);
648
649	/* Receive data once connectfd is ready for reading */
650	FILE *pipefd = setup(fds, auclass);
651	//ATF_REQUIRE(check_readfs(connectfd) != 0);
652	ATF_REQUIRE((data_bytes = recv(connectfd, data, MAX_DATA, 0)) != 0);
653
654	/* Audit record must contain connectfd and data_bytes */
655	snprintf(extregex, sizeof(extregex),
656		"recv.*0x%x.*return,success,%zd", connectfd, data_bytes);
657	check_audit(fds, extregex, pipefd);
658
659	/* Close all socket descriptors */
660	close_sockets(3, sockfd, sockfd2, connectfd);
661}
662
663ATF_TC_CLEANUP(recv_success, tc)
664{
665	cleanup();
666}
667
668
669ATF_TC_WITH_CLEANUP(recv_failure);
670ATF_TC_HEAD(recv_failure, tc)
671{
672	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
673					"recv(2) call");
674}
675
676ATF_TC_BODY(recv_failure, tc)
677{
678	snprintf(extregex, sizeof(extregex), "recv.*%s", invalregex);
679	FILE *pipefd = setup(fds, auclass);
680	/* Failure reason: Invalid socket descriptor */
681	ATF_REQUIRE_EQ(-1, recv(-1, NULL, 0, 0));
682	check_audit(fds, extregex, pipefd);
683}
684
685ATF_TC_CLEANUP(recv_failure, tc)
686{
687	cleanup();
688}
689
690
691ATF_TC_WITH_CLEANUP(sendto_success);
692ATF_TC_HEAD(sendto_success, tc)
693{
694	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
695					"sendto(2) call");
696}
697
698ATF_TC_BODY(sendto_success, tc)
699{
700	assign_address(&server);
701	/*  Setup a server socket and bind to the specified address */
702	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
703	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
704
705	/* Set up client socket to be used for sending the data */
706	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
707
708	/* Send a sample message to server's address */
709	FILE *pipefd = setup(fds, auclass);
710	ATF_REQUIRE((data_bytes = sendto(sockfd2, msgbuff,
711		strlen(msgbuff), 0, (struct sockaddr *)&server, len)) != -1);
712
713	/* Audit record must contain sockfd2 and data_bytes */
714	snprintf(extregex, sizeof(extregex),
715		"sendto.*0x%x.*return,success,%zd", sockfd2, data_bytes);
716	check_audit(fds, extregex, pipefd);
717
718	/* Close all socket descriptors */
719	close_sockets(2, sockfd, sockfd2);
720}
721
722ATF_TC_CLEANUP(sendto_success, tc)
723{
724	cleanup();
725}
726
727
728ATF_TC_WITH_CLEANUP(sendto_failure);
729ATF_TC_HEAD(sendto_failure, tc)
730{
731	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
732					"sendto(2) call");
733}
734
735ATF_TC_BODY(sendto_failure, tc)
736{
737	snprintf(extregex, sizeof(extregex), "sendto.*%s", invalregex);
738	FILE *pipefd = setup(fds, auclass);
739	/* Failure reason: Invalid socket descriptor */
740	ATF_REQUIRE_EQ(-1, sendto(-1, NULL, 0, 0, NULL, 0));
741	check_audit(fds, extregex, pipefd);
742}
743
744ATF_TC_CLEANUP(sendto_failure, tc)
745{
746	cleanup();
747}
748
749
750ATF_TC_WITH_CLEANUP(recvfrom_success);
751ATF_TC_HEAD(recvfrom_success, tc)
752{
753	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
754					"recvfrom(2) call");
755}
756
757ATF_TC_BODY(recvfrom_success, tc)
758{
759	assign_address(&server);
760	/*  Setup a server socket and bind to the specified address */
761	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
762	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
763
764	/* Set up client socket to be used for sending the data */
765	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
766	ATF_REQUIRE(sendto(sockfd2, msgbuff, strlen(msgbuff), 0,
767		(struct sockaddr *)&server, len) != -1);
768
769	/* Receive data once sockfd is ready for reading */
770	FILE *pipefd = setup(fds, auclass);
771	ATF_REQUIRE((data_bytes = recvfrom(sockfd, data,
772		MAX_DATA, 0, NULL, &len)) != 0);
773
774	/* Audit record must contain sockfd and data_bytes */
775	snprintf(extregex, sizeof(extregex),
776		"recvfrom.*0x%x.*return,success,%zd", sockfd, data_bytes);
777	check_audit(fds, extregex, pipefd);
778
779	/* Close all socket descriptors */
780	close_sockets(2, sockfd, sockfd2);
781}
782
783ATF_TC_CLEANUP(recvfrom_success, tc)
784{
785	cleanup();
786}
787
788
789ATF_TC_WITH_CLEANUP(recvfrom_failure);
790ATF_TC_HEAD(recvfrom_failure, tc)
791{
792	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
793					"recvfrom(2) call");
794}
795
796ATF_TC_BODY(recvfrom_failure, tc)
797{
798	snprintf(extregex, sizeof(extregex), "recvfrom.*%s", invalregex);
799	FILE *pipefd = setup(fds, auclass);
800	/* Failure reason: Invalid socket descriptor */
801	ATF_REQUIRE_EQ(-1, recvfrom(-1, NULL, 0, 0, NULL, NULL));
802	check_audit(fds, extregex, pipefd);
803}
804
805ATF_TC_CLEANUP(recvfrom_failure, tc)
806{
807	cleanup();
808}
809
810
811ATF_TP_ADD_TCS(tp)
812{
813	ATF_TP_ADD_TC(tp, socket_success);
814	ATF_TP_ADD_TC(tp, socket_failure);
815	ATF_TP_ADD_TC(tp, socketpair_success);
816	ATF_TP_ADD_TC(tp, socketpair_failure);
817	ATF_TP_ADD_TC(tp, setsockopt_success);
818	ATF_TP_ADD_TC(tp, setsockopt_failure);
819
820	ATF_TP_ADD_TC(tp, bind_success);
821	ATF_TP_ADD_TC(tp, bind_failure);
822	ATF_TP_ADD_TC(tp, bindat_success);
823	ATF_TP_ADD_TC(tp, bindat_failure);
824	ATF_TP_ADD_TC(tp, listen_success);
825	ATF_TP_ADD_TC(tp, listen_failure);
826
827	ATF_TP_ADD_TC(tp, connect_success);
828	ATF_TP_ADD_TC(tp, connect_failure);
829	ATF_TP_ADD_TC(tp, connectat_success);
830	ATF_TP_ADD_TC(tp, connectat_failure);
831	ATF_TP_ADD_TC(tp, accept_success);
832	ATF_TP_ADD_TC(tp, accept_failure);
833
834	ATF_TP_ADD_TC(tp, send_success);
835	ATF_TP_ADD_TC(tp, send_failure);
836	ATF_TP_ADD_TC(tp, recv_success);
837	ATF_TP_ADD_TC(tp, recv_failure);
838
839	ATF_TP_ADD_TC(tp, sendto_success);
840	ATF_TP_ADD_TC(tp, sendto_failure);
841	ATF_TP_ADD_TC(tp, recvfrom_success);
842	ATF_TP_ADD_TC(tp, recvfrom_failure);
843
844	return (atf_no_error());
845}
846