]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/audit/network.c
THIS BRANCH IS OBSOLETE, PLEASE READ:
[FreeBSD/FreeBSD.git] / tests / sys / audit / network.c
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$
26  */
27
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <sys/stat.h>
31 #include <sys/uio.h>
32 #include <sys/un.h>
33
34 #include <atf-c.h>
35 #include <fcntl.h>
36 #include <stdarg.h>
37 #include <unistd.h>
38
39 #include "utils.h"
40
41 #define MAX_DATA 128
42 #define SERVER_PATH "server"
43
44 static pid_t pid;
45 static mode_t mode = 0777;
46 static int sockfd, sockfd2, connectfd;
47 static ssize_t data_bytes;
48 static socklen_t len = sizeof(struct sockaddr_un);
49 static struct iovec io1, io2;
50 static struct pollfd fds[1];
51 static struct sockaddr_un server;
52 static struct msghdr sendbuf, recvbuf;
53 static char extregex[MAX_DATA];
54 static char data[MAX_DATA];
55 static char msgbuff[MAX_DATA] = "This message does not exist";
56 static const char *auclass = "nt";
57 static const char *path = "fileforaudit";
58 static const char *nosupregex = "return,failure : Address family "
59                                 "not supported by protocol family";
60 static const char *invalregex = "return,failure : Bad file descriptor";
61
62 /*
63  * Initialize iovec structure to be used as a field of struct msghdr
64  */
65 static void
66 init_iov(struct iovec *io, char msgbuf[], int datalen)
67 {
68         io->iov_base = msgbuf;
69         io->iov_len = datalen;
70 }
71
72 /*
73  * Initialize msghdr structure for communication via datagram sockets
74  */
75 static void
76 init_msghdr(struct msghdr *hdrbuf, struct iovec *io, struct sockaddr_un *addr)
77 {
78         socklen_t length;
79
80         bzero(hdrbuf, sizeof(*hdrbuf));
81         length = (socklen_t)sizeof(struct sockaddr_un);
82         hdrbuf->msg_name = addr;
83         hdrbuf->msg_namelen = length;
84         hdrbuf->msg_iov = io;
85         hdrbuf->msg_iovlen = 1;
86 }
87
88 /*
89  * Variadic function to close socket descriptors
90  */
91 static void
92 close_sockets(int count, ...)
93 {
94         int sockd;
95         va_list socklist;
96         va_start(socklist, count);
97         for (sockd = 0; sockd < count; sockd++) {
98                 close(va_arg(socklist, int));
99         }
100         va_end(socklist);
101 }
102
103 /*
104  * Assign local filesystem address to a Unix domain socket
105  */
106 static void
107 assign_address(struct sockaddr_un *serveraddr)
108 {
109         memset(serveraddr, 0, sizeof(*serveraddr));
110         serveraddr->sun_family = AF_UNIX;
111         strcpy(serveraddr->sun_path, SERVER_PATH);
112 }
113
114
115 ATF_TC_WITH_CLEANUP(socket_success);
116 ATF_TC_HEAD(socket_success, tc)
117 {
118         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
119                                         "socket(2) call");
120 }
121
122 ATF_TC_BODY(socket_success, tc)
123 {
124         FILE *pipefd = setup(fds, auclass);
125         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
126         /* Check the presence of sockfd in audit record */
127         snprintf(extregex, sizeof(extregex), "socket.*ret.*success,%d", sockfd);
128         check_audit(fds, extregex, pipefd);
129         close(sockfd);
130 }
131
132 ATF_TC_CLEANUP(socket_success, tc)
133 {
134         cleanup();
135 }
136
137
138 ATF_TC_WITH_CLEANUP(socket_failure);
139 ATF_TC_HEAD(socket_failure, tc)
140 {
141         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
142                                         "socket(2) call");
143 }
144
145 ATF_TC_BODY(socket_failure, tc)
146 {
147         snprintf(extregex, sizeof(extregex), "socket.*%s", nosupregex);
148         FILE *pipefd = setup(fds, auclass);
149         /* Failure reason: Unsupported value of 'domain' argument: 0 */
150         ATF_REQUIRE_EQ(-1, socket(0, SOCK_STREAM, 0));
151         check_audit(fds, extregex, pipefd);
152 }
153
154 ATF_TC_CLEANUP(socket_failure, tc)
155 {
156         cleanup();
157 }
158
159
160 ATF_TC_WITH_CLEANUP(socketpair_success);
161 ATF_TC_HEAD(socketpair_success, tc)
162 {
163         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
164                                         "socketpair(2) call");
165 }
166
167 ATF_TC_BODY(socketpair_success, tc)
168 {
169         int sv[2];
170         FILE *pipefd = setup(fds, auclass);
171         ATF_REQUIRE_EQ(0, socketpair(PF_UNIX, SOCK_STREAM, 0, sv));
172
173         /* Check for 0x0 (argument 3: default protocol) in the audit record */
174         snprintf(extregex, sizeof(extregex), "socketpair.*0x0.*return,success");
175         check_audit(fds, extregex, pipefd);
176         close_sockets(2, sv[0], sv[1]);
177 }
178
179 ATF_TC_CLEANUP(socketpair_success, tc)
180 {
181         cleanup();
182 }
183
184
185 ATF_TC_WITH_CLEANUP(socketpair_failure);
186 ATF_TC_HEAD(socketpair_failure, tc)
187 {
188         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
189                                         "socketpair(2) call");
190 }
191
192 ATF_TC_BODY(socketpair_failure, tc)
193 {
194         snprintf(extregex, sizeof(extregex), "socketpair.*%s", nosupregex);
195         FILE *pipefd = setup(fds, auclass);
196         /* Failure reason: Unsupported value of 'domain' argument: 0 */
197         ATF_REQUIRE_EQ(-1, socketpair(0, SOCK_STREAM, 0, NULL));
198         check_audit(fds, extregex, pipefd);
199 }
200
201 ATF_TC_CLEANUP(socketpair_failure, tc)
202 {
203         cleanup();
204 }
205
206
207 ATF_TC_WITH_CLEANUP(setsockopt_success);
208 ATF_TC_HEAD(setsockopt_success, tc)
209 {
210         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
211                                         "setsockopt(2) call");
212 }
213
214 ATF_TC_BODY(setsockopt_success, tc)
215 {
216         int tr = 1;
217         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
218         /* Check the presence of sockfd in audit record */
219         snprintf(extregex, sizeof(extregex),
220                         "setsockopt.*0x%x.*return,success", sockfd);
221
222         FILE *pipefd = setup(fds, auclass);
223         ATF_REQUIRE_EQ(0, setsockopt(sockfd, SOL_SOCKET,
224                 SO_REUSEADDR, &tr, sizeof(int)));
225         check_audit(fds, extregex, pipefd);
226         close(sockfd);
227 }
228
229 ATF_TC_CLEANUP(setsockopt_success, tc)
230 {
231         cleanup();
232 }
233
234
235 ATF_TC_WITH_CLEANUP(setsockopt_failure);
236 ATF_TC_HEAD(setsockopt_failure, tc)
237 {
238         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
239                                         "setsockopt(2) call");
240 }
241
242 ATF_TC_BODY(setsockopt_failure, tc)
243 {
244         snprintf(extregex, sizeof(extregex), "setsockopt.*%s", invalregex);
245         FILE *pipefd = setup(fds, auclass);
246         /* Failure reason: Invalid socket descriptor */
247         ATF_REQUIRE_EQ(-1, setsockopt(-1, SOL_SOCKET, 0, NULL, 0));
248         check_audit(fds, extregex, pipefd);
249 }
250
251 ATF_TC_CLEANUP(setsockopt_failure, tc)
252 {
253         cleanup();
254 }
255
256
257 ATF_TC_WITH_CLEANUP(bind_success);
258 ATF_TC_HEAD(bind_success, tc)
259 {
260         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
261                                         "bind(2) call");
262 }
263
264 ATF_TC_BODY(bind_success, tc)
265 {
266         assign_address(&server);
267         /* Preliminary socket setup */
268         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
269         /* Check the presence of AF_UNIX address path in audit record */
270         snprintf(extregex, sizeof(extregex),
271                 "bind.*unix.*%s.*return,success", SERVER_PATH);
272
273         FILE *pipefd = setup(fds, auclass);
274         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
275         check_audit(fds, extregex, pipefd);
276         close(sockfd);
277 }
278
279 ATF_TC_CLEANUP(bind_success, tc)
280 {
281         cleanup();
282 }
283
284
285 ATF_TC_WITH_CLEANUP(bind_failure);
286 ATF_TC_HEAD(bind_failure, tc)
287 {
288         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
289                                         "bind(2) call");
290 }
291
292 ATF_TC_BODY(bind_failure, tc)
293 {
294         assign_address(&server);
295         /* Check the presence of AF_UNIX path in audit record */
296         snprintf(extregex, sizeof(extregex),
297                         "bind.*%s.*return,failure", SERVER_PATH);
298
299         FILE *pipefd = setup(fds, auclass);
300         /* Failure reason: Invalid socket descriptor */
301         ATF_REQUIRE_EQ(-1, bind(0, (struct sockaddr *)&server, len));
302         check_audit(fds, extregex, pipefd);
303 }
304
305 ATF_TC_CLEANUP(bind_failure, tc)
306 {
307         cleanup();
308 }
309
310
311 ATF_TC_WITH_CLEANUP(bindat_success);
312 ATF_TC_HEAD(bindat_success, tc)
313 {
314         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
315                                         "bindat(2) call");
316 }
317
318 ATF_TC_BODY(bindat_success, tc)
319 {
320         assign_address(&server);
321         /* Preliminary socket setup */
322         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
323         /* Check the presence of socket descriptor in audit record */
324         snprintf(extregex, sizeof(extregex),
325                         "bindat.*0x%x.*return,success", sockfd);
326
327         FILE *pipefd = setup(fds, auclass);
328         ATF_REQUIRE_EQ(0, bindat(AT_FDCWD, sockfd,
329                         (struct sockaddr *)&server, len));
330         check_audit(fds, extregex, pipefd);
331         close(sockfd);
332 }
333
334 ATF_TC_CLEANUP(bindat_success, tc)
335 {
336         cleanup();
337 }
338
339
340 ATF_TC_WITH_CLEANUP(bindat_failure);
341 ATF_TC_HEAD(bindat_failure, tc)
342 {
343         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
344                                         "bindat(2) call");
345 }
346
347 ATF_TC_BODY(bindat_failure, tc)
348 {
349         assign_address(&server);
350         snprintf(extregex, sizeof(extregex), "bindat.*%s", invalregex);
351
352         FILE *pipefd = setup(fds, auclass);
353         /* Failure reason: Invalid socket descriptor */
354         ATF_REQUIRE_EQ(-1, bindat(AT_FDCWD, -1,
355                         (struct sockaddr *)&server, len));
356         check_audit(fds, extregex, pipefd);
357 }
358
359 ATF_TC_CLEANUP(bindat_failure, tc)
360 {
361         cleanup();
362 }
363
364
365 ATF_TC_WITH_CLEANUP(listen_success);
366 ATF_TC_HEAD(listen_success, tc)
367 {
368         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
369                                         "listen(2) call");
370 }
371
372 ATF_TC_BODY(listen_success, tc)
373 {
374         assign_address(&server);
375         /* Preliminary socket setup */
376         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
377         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
378         /* Check the presence of socket descriptor in the audit record */
379         snprintf(extregex, sizeof(extregex),
380                         "listen.*0x%x.*return,success", sockfd);
381
382         FILE *pipefd = setup(fds, auclass);
383         ATF_REQUIRE_EQ(0, listen(sockfd, 1));
384         check_audit(fds, extregex, pipefd);
385         close(sockfd);
386 }
387
388 ATF_TC_CLEANUP(listen_success, tc)
389 {
390         cleanup();
391 }
392
393
394 ATF_TC_WITH_CLEANUP(listen_failure);
395 ATF_TC_HEAD(listen_failure, tc)
396 {
397         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
398                                         "listen(2) call");
399 }
400
401 ATF_TC_BODY(listen_failure, tc)
402 {
403         snprintf(extregex, sizeof(extregex), "listen.*%s", invalregex);
404         FILE *pipefd = setup(fds, auclass);
405         /* Failure reason: Invalid socket descriptor */
406         ATF_REQUIRE_EQ(-1, listen(-1, 1));
407         check_audit(fds, extregex, pipefd);
408 }
409
410 ATF_TC_CLEANUP(listen_failure, tc)
411 {
412         cleanup();
413 }
414
415
416 ATF_TC_WITH_CLEANUP(connect_success);
417 ATF_TC_HEAD(connect_success, tc)
418 {
419         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
420                                         "connect(2) call");
421 }
422
423 ATF_TC_BODY(connect_success, tc)
424 {
425         assign_address(&server);
426         /* Setup a server socket and bind to the specified address */
427         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
428         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
429         ATF_REQUIRE_EQ(0, listen(sockfd, 1));
430
431         /* Set up "blocking" client socket */
432         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
433
434         /* Audit record must contain AF_UNIX address path & sockfd2 */
435         snprintf(extregex, sizeof(extregex),
436                         "connect.*0x%x.*%s.*success", sockfd2, SERVER_PATH);
437
438         FILE *pipefd = setup(fds, auclass);
439         ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
440         check_audit(fds, extregex, pipefd);
441
442         /* Close all socket descriptors */
443         close_sockets(2, sockfd, sockfd2);
444 }
445
446 ATF_TC_CLEANUP(connect_success, tc)
447 {
448         cleanup();
449 }
450
451
452 ATF_TC_WITH_CLEANUP(connect_failure);
453 ATF_TC_HEAD(connect_failure, tc)
454 {
455         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
456                                         "connect(2) call");
457 }
458
459 ATF_TC_BODY(connect_failure, tc)
460 {
461         assign_address(&server);
462         /* Audit record must contain AF_UNIX address path */
463         snprintf(extregex, sizeof(extregex),
464                         "connect.*%s.*return,failure", SERVER_PATH);
465
466         FILE *pipefd = setup(fds, auclass);
467         /* Failure reason: Invalid socket descriptor */
468         ATF_REQUIRE_EQ(-1, connect(-1, (struct sockaddr *)&server, len));
469         check_audit(fds, extregex, pipefd);
470 }
471
472 ATF_TC_CLEANUP(connect_failure, tc)
473 {
474         cleanup();
475 }
476
477
478 ATF_TC_WITH_CLEANUP(connectat_success);
479 ATF_TC_HEAD(connectat_success, tc)
480 {
481         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
482                                         "connectat(2) call");
483 }
484
485 ATF_TC_BODY(connectat_success, tc)
486 {
487         assign_address(&server);
488         /* Setup a server socket and bind to the specified address */
489         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
490         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
491         ATF_REQUIRE_EQ(0, listen(sockfd, 1));
492
493         /* Set up "blocking" client socket */
494         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
495
496         /* Audit record must contain sockfd2 */
497         snprintf(extregex, sizeof(extregex),
498                         "connectat.*0x%x.*return,success", sockfd2);
499
500         FILE *pipefd = setup(fds, auclass);
501         ATF_REQUIRE_EQ(0, connectat(AT_FDCWD, sockfd2,
502                         (struct sockaddr *)&server, len));
503         check_audit(fds, extregex, pipefd);
504
505         /* Close all socket descriptors */
506         close_sockets(2, sockfd, sockfd2);
507 }
508
509 ATF_TC_CLEANUP(connectat_success, tc)
510 {
511         cleanup();
512 }
513
514
515 ATF_TC_WITH_CLEANUP(connectat_failure);
516 ATF_TC_HEAD(connectat_failure, tc)
517 {
518         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
519                                         "connectat(2) call");
520 }
521
522 ATF_TC_BODY(connectat_failure, tc)
523 {
524         assign_address(&server);
525         snprintf(extregex, sizeof(extregex), "connectat.*%s", invalregex);
526
527         FILE *pipefd = setup(fds, auclass);
528         /* Failure reason: Invalid socket descriptor */
529         ATF_REQUIRE_EQ(-1, connectat(AT_FDCWD, -1,
530                         (struct sockaddr *)&server, len));
531         check_audit(fds, extregex, pipefd);
532 }
533
534 ATF_TC_CLEANUP(connectat_failure, tc)
535 {
536         cleanup();
537 }
538
539
540 ATF_TC_WITH_CLEANUP(accept_success);
541 ATF_TC_HEAD(accept_success, tc)
542 {
543         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
544                                         "accept(2) call");
545 }
546
547 ATF_TC_BODY(accept_success, tc)
548 {
549         assign_address(&server);
550         /* Setup a server socket and bind to the specified address */
551         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
552         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
553         ATF_REQUIRE_EQ(0, listen(sockfd, 1));
554
555         /* Set up "blocking" client socket */
556         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
557         ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
558
559         FILE *pipefd = setup(fds, auclass);
560         ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1);
561
562         /* Audit record must contain connectfd & sockfd */
563         snprintf(extregex, sizeof(extregex),
564                         "accept.*0x%x.*return,success,%d", sockfd, connectfd);
565         check_audit(fds, extregex, pipefd);
566
567         /* Close all socket descriptors */
568         close_sockets(3, sockfd, sockfd2, connectfd);
569 }
570
571 ATF_TC_CLEANUP(accept_success, tc)
572 {
573         cleanup();
574 }
575
576
577 ATF_TC_WITH_CLEANUP(accept_failure);
578 ATF_TC_HEAD(accept_failure, tc)
579 {
580         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
581                                         "accept(2) call");
582 }
583
584 ATF_TC_BODY(accept_failure, tc)
585 {
586         snprintf(extregex, sizeof(extregex), "accept.*%s", invalregex);
587         FILE *pipefd = setup(fds, auclass);
588         /* Failure reason: Invalid socket descriptor */
589         ATF_REQUIRE_EQ(-1, accept(-1, NULL, NULL));
590         check_audit(fds, extregex, pipefd);
591 }
592
593 ATF_TC_CLEANUP(accept_failure, tc)
594 {
595         cleanup();
596 }
597
598
599 ATF_TC_WITH_CLEANUP(send_success);
600 ATF_TC_HEAD(send_success, tc)
601 {
602         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
603                                         "send(2) call");
604 }
605
606 ATF_TC_BODY(send_success, tc)
607 {
608         assign_address(&server);
609         /* Setup a server socket and bind to the specified address */
610         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
611         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
612         ATF_REQUIRE_EQ(0, listen(sockfd, 1));
613
614         /* Set up "blocking" client and connect with non-blocking server */
615         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
616         ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
617         ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1);
618
619         /* Send a sample message to the connected socket */
620         FILE *pipefd = setup(fds, auclass);
621         ATF_REQUIRE((data_bytes =
622                 send(sockfd2, msgbuff, strlen(msgbuff), 0)) != -1);
623
624         /* Audit record must contain sockfd2 and data_bytes */
625         snprintf(extregex, sizeof(extregex),
626                 "send.*0x%x.*return,success,%zd", sockfd2, data_bytes);
627         check_audit(fds, extregex, pipefd);
628
629         /* Close all socket descriptors */
630         close_sockets(3, sockfd, sockfd2, connectfd);
631 }
632
633 ATF_TC_CLEANUP(send_success, tc)
634 {
635         cleanup();
636 }
637
638
639 ATF_TC_WITH_CLEANUP(send_failure);
640 ATF_TC_HEAD(send_failure, tc)
641 {
642         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
643                                         "send(2) call");
644 }
645
646 ATF_TC_BODY(send_failure, tc)
647 {
648         snprintf(extregex, sizeof(extregex), "send.*%s", invalregex);
649         FILE *pipefd = setup(fds, auclass);
650         /* Failure reason: Invalid socket descriptor */
651         ATF_REQUIRE_EQ(-1, send(-1, NULL, 0, 0));
652         check_audit(fds, extregex, pipefd);
653 }
654
655 ATF_TC_CLEANUP(send_failure, tc)
656 {
657         cleanup();
658 }
659
660
661 ATF_TC_WITH_CLEANUP(recv_success);
662 ATF_TC_HEAD(recv_success, tc)
663 {
664         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
665                                         "recv(2) call");
666 }
667
668 ATF_TC_BODY(recv_success, tc)
669 {
670         assign_address(&server);
671         /* Setup a server socket and bind to the specified address */
672         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
673         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
674         ATF_REQUIRE_EQ(0, listen(sockfd, 1));
675
676         /* Set up "blocking" client and connect with non-blocking server */
677         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
678         ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
679         ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1);
680         /* Send a sample message to the connected socket */
681         ATF_REQUIRE(send(sockfd2, msgbuff, strlen(msgbuff), 0) != -1);
682
683         /* Receive data once connectfd is ready for reading */
684         FILE *pipefd = setup(fds, auclass);
685         ATF_REQUIRE((data_bytes = recv(connectfd, data, MAX_DATA, 0)) != 0);
686
687         /* Audit record must contain connectfd and data_bytes */
688         snprintf(extregex, sizeof(extregex),
689                 "recv.*0x%x.*return,success,%zd", connectfd, data_bytes);
690         check_audit(fds, extregex, pipefd);
691
692         /* Close all socket descriptors */
693         close_sockets(3, sockfd, sockfd2, connectfd);
694 }
695
696 ATF_TC_CLEANUP(recv_success, tc)
697 {
698         cleanup();
699 }
700
701
702 ATF_TC_WITH_CLEANUP(recv_failure);
703 ATF_TC_HEAD(recv_failure, tc)
704 {
705         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
706                                         "recv(2) call");
707 }
708
709 ATF_TC_BODY(recv_failure, tc)
710 {
711         snprintf(extregex, sizeof(extregex), "recv.*%s", invalregex);
712         FILE *pipefd = setup(fds, auclass);
713         /* Failure reason: Invalid socket descriptor */
714         ATF_REQUIRE_EQ(-1, recv(-1, NULL, 0, 0));
715         check_audit(fds, extregex, pipefd);
716 }
717
718 ATF_TC_CLEANUP(recv_failure, tc)
719 {
720         cleanup();
721 }
722
723
724 ATF_TC_WITH_CLEANUP(sendto_success);
725 ATF_TC_HEAD(sendto_success, tc)
726 {
727         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
728                                         "sendto(2) call");
729 }
730
731 ATF_TC_BODY(sendto_success, tc)
732 {
733         assign_address(&server);
734         /*  Setup a server socket and bind to the specified address */
735         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
736         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
737
738         /* Set up client socket to be used for sending the data */
739         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
740
741         /* Send a sample message to server's address */
742         FILE *pipefd = setup(fds, auclass);
743         ATF_REQUIRE((data_bytes = sendto(sockfd2, msgbuff,
744                 strlen(msgbuff), 0, (struct sockaddr *)&server, len)) != -1);
745
746         /* Audit record must contain sockfd2 and data_bytes */
747         snprintf(extregex, sizeof(extregex),
748                 "sendto.*0x%x.*return,success,%zd", sockfd2, data_bytes);
749         check_audit(fds, extregex, pipefd);
750
751         /* Close all socket descriptors */
752         close_sockets(2, sockfd, sockfd2);
753 }
754
755 ATF_TC_CLEANUP(sendto_success, tc)
756 {
757         cleanup();
758 }
759
760
761 ATF_TC_WITH_CLEANUP(sendto_failure);
762 ATF_TC_HEAD(sendto_failure, tc)
763 {
764         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
765                                         "sendto(2) call");
766 }
767
768 ATF_TC_BODY(sendto_failure, tc)
769 {
770         snprintf(extregex, sizeof(extregex), "sendto.*%s", invalregex);
771         FILE *pipefd = setup(fds, auclass);
772         /* Failure reason: Invalid socket descriptor */
773         ATF_REQUIRE_EQ(-1, sendto(-1, NULL, 0, 0, NULL, 0));
774         check_audit(fds, extregex, pipefd);
775 }
776
777 ATF_TC_CLEANUP(sendto_failure, tc)
778 {
779         cleanup();
780 }
781
782
783 ATF_TC_WITH_CLEANUP(recvfrom_success);
784 ATF_TC_HEAD(recvfrom_success, tc)
785 {
786         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
787                                         "recvfrom(2) call");
788 }
789
790 ATF_TC_BODY(recvfrom_success, tc)
791 {
792         assign_address(&server);
793         /*  Setup a server socket and bind to the specified address */
794         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
795         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
796
797         /* Set up client socket to be used for sending the data */
798         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
799         ATF_REQUIRE(sendto(sockfd2, msgbuff, strlen(msgbuff), 0,
800                 (struct sockaddr *)&server, len) != -1);
801
802         /* Receive data once sockfd is ready for reading */
803         FILE *pipefd = setup(fds, auclass);
804         ATF_REQUIRE((data_bytes = recvfrom(sockfd, data,
805                 MAX_DATA, 0, NULL, &len)) != 0);
806
807         /* Audit record must contain sockfd and data_bytes */
808         snprintf(extregex, sizeof(extregex),
809                 "recvfrom.*0x%x.*return,success,%zd", sockfd, data_bytes);
810         check_audit(fds, extregex, pipefd);
811
812         /* Close all socket descriptors */
813         close_sockets(2, sockfd, sockfd2);
814 }
815
816 ATF_TC_CLEANUP(recvfrom_success, tc)
817 {
818         cleanup();
819 }
820
821
822 ATF_TC_WITH_CLEANUP(recvfrom_failure);
823 ATF_TC_HEAD(recvfrom_failure, tc)
824 {
825         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
826                                         "recvfrom(2) call");
827 }
828
829 ATF_TC_BODY(recvfrom_failure, tc)
830 {
831         snprintf(extregex, sizeof(extregex), "recvfrom.*%s", invalregex);
832         FILE *pipefd = setup(fds, auclass);
833         /* Failure reason: Invalid socket descriptor */
834         ATF_REQUIRE_EQ(-1, recvfrom(-1, NULL, 0, 0, NULL, NULL));
835         check_audit(fds, extregex, pipefd);
836 }
837
838 ATF_TC_CLEANUP(recvfrom_failure, tc)
839 {
840         cleanup();
841 }
842
843
844 ATF_TC_WITH_CLEANUP(sendmsg_success);
845 ATF_TC_HEAD(sendmsg_success, tc)
846 {
847         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
848                                         "recvmsg(2) call");
849 }
850
851 ATF_TC_BODY(sendmsg_success, tc)
852 {
853         assign_address(&server);
854         /* Create a datagram server socket & bind to UNIX address family */
855         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
856         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
857
858         /* Message buffer to be sent to the server */
859         init_iov(&io1, msgbuff, sizeof(msgbuff));
860         init_msghdr(&sendbuf, &io1, &server);
861
862         /* Set up UDP client to communicate with the server */
863         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
864
865         /* Send a sample message to the specified client address */
866         FILE *pipefd = setup(fds, auclass);
867         ATF_REQUIRE((data_bytes = sendmsg(sockfd2, &sendbuf, 0)) != -1);
868
869         /* Audit record must contain sockfd2 and data_bytes */
870         snprintf(extregex, sizeof(extregex),
871                 "sendmsg.*0x%x.*return,success,%zd", sockfd2, data_bytes);
872         check_audit(fds, extregex, pipefd);
873
874         /* Close all socket descriptors */
875         close_sockets(2, sockfd, sockfd2);
876 }
877
878 ATF_TC_CLEANUP(sendmsg_success, tc)
879 {
880         cleanup();
881 }
882
883
884 ATF_TC_WITH_CLEANUP(sendmsg_failure);
885 ATF_TC_HEAD(sendmsg_failure, tc)
886 {
887         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
888                                         "sendmsg(2) call");
889 }
890
891 ATF_TC_BODY(sendmsg_failure, tc)
892 {
893         snprintf(extregex, sizeof(extregex),
894                 "sendmsg.*return,failure : Bad address");
895         FILE *pipefd = setup(fds, auclass);
896         ATF_REQUIRE_EQ(-1, sendmsg(-1, NULL, 0));
897         check_audit(fds, extregex, pipefd);
898 }
899
900 ATF_TC_CLEANUP(sendmsg_failure, tc)
901 {
902         cleanup();
903 }
904
905
906 ATF_TC_WITH_CLEANUP(recvmsg_success);
907 ATF_TC_HEAD(recvmsg_success, tc)
908 {
909         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
910                                         "recvmsg(2) call");
911 }
912
913 ATF_TC_BODY(recvmsg_success, tc)
914 {
915         assign_address(&server);
916         /* Create a datagram server socket & bind to UNIX address family */
917         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
918         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
919
920         /* Message buffer to be sent to the server */
921         init_iov(&io1, msgbuff, sizeof(msgbuff));
922         init_msghdr(&sendbuf, &io1, &server);
923
924         /* Prepare buffer to store the received data in */
925         init_iov(&io2, data, sizeof(data));
926         init_msghdr(&recvbuf, &io2, NULL);
927
928         /* Set up UDP client to communicate with the server */
929         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
930         /* Send a sample message to the connected socket */
931         ATF_REQUIRE(sendmsg(sockfd2, &sendbuf, 0) != -1);
932
933         /* Receive data once clientfd is ready for reading */
934         FILE *pipefd = setup(fds, auclass);
935         ATF_REQUIRE((data_bytes = recvmsg(sockfd, &recvbuf, 0)) != -1);
936
937         /* Audit record must contain sockfd and data_bytes */
938         snprintf(extregex, sizeof(extregex),
939                 "recvmsg.*%#x.*return,success,%zd", sockfd, data_bytes);
940         check_audit(fds, extregex, pipefd);
941
942         /* Close all socket descriptors */
943         close_sockets(2, sockfd, sockfd2);
944 }
945
946 ATF_TC_CLEANUP(recvmsg_success, tc)
947 {
948         cleanup();
949 }
950
951
952 ATF_TC_WITH_CLEANUP(recvmsg_failure);
953 ATF_TC_HEAD(recvmsg_failure, tc)
954 {
955         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
956                                         "recvmsg(2) call");
957 }
958
959 ATF_TC_BODY(recvmsg_failure, tc)
960 {
961         snprintf(extregex, sizeof(extregex),
962                 "recvmsg.*return,failure : Bad address");
963         FILE *pipefd = setup(fds, auclass);
964         ATF_REQUIRE_EQ(-1, recvmsg(-1, NULL, 0));
965         check_audit(fds, extregex, pipefd);
966 }
967
968 ATF_TC_CLEANUP(recvmsg_failure, tc)
969 {
970         cleanup();
971 }
972
973
974 ATF_TC_WITH_CLEANUP(shutdown_success);
975 ATF_TC_HEAD(shutdown_success, tc)
976 {
977         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
978                                         "shutdown(2) call");
979 }
980
981 ATF_TC_BODY(shutdown_success, tc)
982 {
983         assign_address(&server);
984         /* Setup server socket and bind to the specified address */
985         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
986         ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
987         ATF_REQUIRE_EQ(0, listen(sockfd, 1));
988
989         /* Setup client and connect with the blocking server */
990         ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
991         ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
992         ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1);
993
994         /* Audit record must contain clientfd */
995         snprintf(extregex, sizeof(extregex),
996                 "shutdown.*%#x.*return,success", connectfd);
997
998         FILE *pipefd = setup(fds, auclass);
999         ATF_REQUIRE_EQ(0, shutdown(connectfd, SHUT_RDWR));
1000         check_audit(fds, extregex, pipefd);
1001
1002         /* Close all socket descriptors */
1003         close_sockets(3, sockfd, sockfd2, connectfd);
1004 }
1005
1006 ATF_TC_CLEANUP(shutdown_success, tc)
1007 {
1008         cleanup();
1009 }
1010
1011
1012 ATF_TC_WITH_CLEANUP(shutdown_failure);
1013 ATF_TC_HEAD(shutdown_failure, tc)
1014 {
1015         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1016                                         "shutdown(2) call");
1017 }
1018
1019 ATF_TC_BODY(shutdown_failure, tc)
1020 {
1021         pid = getpid();
1022         snprintf(extregex, sizeof(extregex),
1023                 "shutdown.*%d.*return,failure", pid);
1024
1025         FILE *pipefd = setup(fds, auclass);
1026         /* Failure reason: Invalid socket descriptor */
1027         ATF_REQUIRE_EQ(-1, shutdown(-1, SHUT_RDWR));
1028         check_audit(fds, extregex, pipefd);
1029 }
1030
1031 ATF_TC_CLEANUP(shutdown_failure, tc)
1032 {
1033         cleanup();
1034 }
1035
1036
1037 ATF_TC_WITH_CLEANUP(sendfile_success);
1038 ATF_TC_HEAD(sendfile_success, tc)
1039 {
1040         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1041                                         "sendfile(2) call");
1042 }
1043
1044 ATF_TC_BODY(sendfile_success, tc)
1045 {
1046         int filedesc;
1047         ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDONLY, mode)) != -1);
1048         /* Create a simple UNIX socket to send out random data */
1049         ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
1050         /* Check the presence of sockfd, non-file in the audit record */
1051         snprintf(extregex, sizeof(extregex),
1052                 "sendfile.*%#x,non-file.*return,success", filedesc);
1053
1054         FILE *pipefd = setup(fds, auclass);
1055         ATF_REQUIRE_EQ(0, sendfile(filedesc, sockfd, 0, 0, NULL, NULL, 0));
1056         check_audit(fds, extregex, pipefd);
1057
1058         /* Teardown socket and file descriptors */
1059         close_sockets(2, sockfd, filedesc);
1060 }
1061
1062 ATF_TC_CLEANUP(sendfile_success, tc)
1063 {
1064         cleanup();
1065 }
1066
1067
1068 ATF_TC_WITH_CLEANUP(sendfile_failure);
1069 ATF_TC_HEAD(sendfile_failure, tc)
1070 {
1071         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1072                                         "sendfile(2) call");
1073 }
1074
1075 ATF_TC_BODY(sendfile_failure, tc)
1076 {
1077         pid = getpid();
1078         snprintf(extregex, sizeof(extregex),
1079                 "sendfile.*%d.*return,failure", pid);
1080         FILE *pipefd = setup(fds, auclass);
1081         ATF_REQUIRE_EQ(-1, sendfile(-1, -1, 0, 0, NULL, NULL, 0));
1082         check_audit(fds, extregex, pipefd);
1083 }
1084
1085 ATF_TC_CLEANUP(sendfile_failure, tc)
1086 {
1087         cleanup();
1088 }
1089
1090
1091 ATF_TC_WITH_CLEANUP(setfib_success);
1092 ATF_TC_HEAD(setfib_success, tc)
1093 {
1094         atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
1095                                         "setfib(2) call");
1096 }
1097
1098 ATF_TC_BODY(setfib_success, tc)
1099 {
1100         pid = getpid();
1101         snprintf(extregex, sizeof(extregex), "setfib.*%d.*return,success", pid);
1102
1103         FILE *pipefd = setup(fds, auclass);
1104         ATF_REQUIRE_EQ(0, setfib(0));
1105         check_audit(fds, extregex, pipefd);
1106 }
1107
1108 ATF_TC_CLEANUP(setfib_success, tc)
1109 {
1110         cleanup();
1111 }
1112
1113
1114 ATF_TC_WITH_CLEANUP(setfib_failure);
1115 ATF_TC_HEAD(setfib_failure, tc)
1116 {
1117         atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
1118                                         "setfib(2) call");
1119 }
1120
1121 ATF_TC_BODY(setfib_failure, tc)
1122 {
1123         pid = getpid();
1124         snprintf(extregex, sizeof(extregex), "setfib.*%d.*return,failure", pid);
1125
1126         FILE *pipefd = setup(fds, auclass);
1127         ATF_REQUIRE_EQ(-1, setfib(-1));
1128         check_audit(fds, extregex, pipefd);
1129 }
1130
1131 ATF_TC_CLEANUP(setfib_failure, tc)
1132 {
1133         cleanup();
1134 }
1135
1136
1137 ATF_TP_ADD_TCS(tp)
1138 {
1139         ATF_TP_ADD_TC(tp, socket_success);
1140         ATF_TP_ADD_TC(tp, socket_failure);
1141         ATF_TP_ADD_TC(tp, socketpair_success);
1142         ATF_TP_ADD_TC(tp, socketpair_failure);
1143         ATF_TP_ADD_TC(tp, setsockopt_success);
1144         ATF_TP_ADD_TC(tp, setsockopt_failure);
1145
1146         ATF_TP_ADD_TC(tp, bind_success);
1147         ATF_TP_ADD_TC(tp, bind_failure);
1148         ATF_TP_ADD_TC(tp, bindat_success);
1149         ATF_TP_ADD_TC(tp, bindat_failure);
1150         ATF_TP_ADD_TC(tp, listen_success);
1151         ATF_TP_ADD_TC(tp, listen_failure);
1152
1153         ATF_TP_ADD_TC(tp, connect_success);
1154         ATF_TP_ADD_TC(tp, connect_failure);
1155         ATF_TP_ADD_TC(tp, connectat_success);
1156         ATF_TP_ADD_TC(tp, connectat_failure);
1157         ATF_TP_ADD_TC(tp, accept_success);
1158         ATF_TP_ADD_TC(tp, accept_failure);
1159
1160         ATF_TP_ADD_TC(tp, send_success);
1161         ATF_TP_ADD_TC(tp, send_failure);
1162         ATF_TP_ADD_TC(tp, recv_success);
1163         ATF_TP_ADD_TC(tp, recv_failure);
1164
1165         ATF_TP_ADD_TC(tp, sendto_success);
1166         ATF_TP_ADD_TC(tp, sendto_failure);
1167         ATF_TP_ADD_TC(tp, recvfrom_success);
1168         ATF_TP_ADD_TC(tp, recvfrom_failure);
1169
1170         ATF_TP_ADD_TC(tp, sendmsg_success);
1171         ATF_TP_ADD_TC(tp, sendmsg_failure);
1172         ATF_TP_ADD_TC(tp, recvmsg_success);
1173         ATF_TP_ADD_TC(tp, recvmsg_failure);
1174
1175         ATF_TP_ADD_TC(tp, shutdown_success);
1176         ATF_TP_ADD_TC(tp, shutdown_failure);
1177         ATF_TP_ADD_TC(tp, sendfile_success);
1178         ATF_TP_ADD_TC(tp, sendfile_failure);
1179         ATF_TP_ADD_TC(tp, setfib_success);
1180         ATF_TP_ADD_TC(tp, setfib_failure);
1181
1182         return (atf_no_error());
1183 }