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