Date: Sun, 24 Feb 2008 21:56:33 GMT From: Aaron Meihm <alm@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 136124 for review Message-ID: <200802242156.m1OLuX8b089513@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=136124 Change 136124 by alm@alm_praetorian on 2008/02/24 21:56:10 Handle and aggregate audit records coming in on network sockets. Affected files ... .. //depot/projects/trustedbsd/netauditd/component.c#2 edit .. //depot/projects/trustedbsd/netauditd/netauditd.c#9 edit .. //depot/projects/trustedbsd/netauditd/netauditd.h#6 edit Differences ... ==== //depot/projects/trustedbsd/netauditd/component.c#2 (text+ko) ==== @@ -80,6 +80,7 @@ return (NULL); } TAILQ_INIT(&new->ac_oq); + TAILQ_INIT(&new->ac_sbufq); return (new); } ==== //depot/projects/trustedbsd/netauditd/netauditd.c#9 (text+ko) ==== @@ -30,6 +30,7 @@ #include <sys/stat.h> #include <sys/time.h> #include <sys/ioctl.h> +#include <sys/endian.h> #include <bsm/audit.h> #include <bsm/libbsm.h> @@ -94,9 +95,59 @@ } void +netaudit_build_rfds(fd_set *rfds) +{ + struct au_srcbuffer *asb; + struct au_cmpnt *au; + + TAILQ_FOREACH(au, &au_srclist, ac_glue) { + if (au->ac_type == NETAUDIT_SRC_NET) { + TAILQ_FOREACH(asb, &au->ac_sbufq, sb_glue) + FD_SET(asb->sb_fd, rfds); + } + FD_SET(au->ac_fd, rfds); + } +} + +void +netaudit_record_handler(fd_set *rfds) +{ + struct au_srcbuffer *asb, *tmp; + struct au_cmpnt *au; + + TAILQ_FOREACH(au, &au_srclist, ac_glue) { + if (FD_ISSET(au->ac_fd, rfds)) { + switch(au->ac_type) { + case NETAUDIT_SRC_PIPE: + netaudit_pipe_read(au); + break; + case NETAUDIT_SRC_NET: + netaudit_socket_accept(au); + break; + default: + exit(2); + } + } + } + TAILQ_FOREACH(au, &au_srclist, ac_glue) { + if (au->ac_type != NETAUDIT_SRC_NET) + continue; + TAILQ_FOREACH_SAFE(asb, &au->ac_sbufq, sb_glue, tmp) + if (FD_ISSET(asb->sb_fd, rfds)) + if (netaudit_socket_read(asb) == -1) { + close(asb->sb_fd); + TAILQ_REMOVE(&au->ac_sbufq, asb, + sb_glue); + free(asb->sb_sockaddr); + free(asb); + } + } +} + +void netaudit_run() { - fd_set rfds, srfds; + fd_set rfds; struct timeval tv; struct au_cmpnt *au; int ret; @@ -104,7 +155,6 @@ int opt; #endif - FD_ZERO(&srfds); TAILQ_FOREACH(au, &au_srclist, ac_glue) { switch (au->ac_type) { case NETAUDIT_SRC_PIPE: @@ -126,13 +176,13 @@ default: exit(2); } - FD_SET(au->ac_fd, &srfds); } netaudit_establish(); memset(&tv, 0, sizeof(tv)); tv.tv_usec = 100000; for (;;) { - memcpy(&rfds, &srfds, sizeof(rfds)); + FD_ZERO(&rfds); + netaudit_build_rfds(&rfds); ret = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); if (ret == -1) { if (errno != EINTR) @@ -140,21 +190,8 @@ else continue; } - else if (ret != 0) { - TAILQ_FOREACH(au, &au_srclist, ac_glue) { - if (FD_ISSET(au->ac_fd, &rfds)) { - switch(au->ac_type) { - case NETAUDIT_SRC_PIPE: - netaudit_pipe_read(au); - break; - case NETAUDIT_SRC_NET: - break; - default: - exit(2); - } - } - } - } + else if (ret != 0) + netaudit_record_handler(&rfds); netaudit_establish(); netaudit_oq(); } @@ -289,6 +326,26 @@ } void +netaudit_socket_accept(struct au_cmpnt *au) +{ + struct au_srcbuffer *new; + + new = malloc(sizeof(struct au_srcbuffer)); + memset(new, 0, sizeof(struct au_srcbuffer)); + new->sb_socklen = au->ac_ainfo->ai_addrlen; + if ((new->sb_sockaddr = malloc(new->sb_socklen)) == NULL) + exit(2); + new->sb_fd = accept(au->ac_fd, new->sb_sockaddr, &new->sb_socklen); + if (new->sb_fd == -1) { + free(new->sb_sockaddr); + free(new); + return; + } + new->sb_parent = au; + TAILQ_INSERT_TAIL(&au->ac_sbufq, new, sb_glue); +} + +void netaudit_socket_listen(struct au_cmpnt *au) { struct addrinfo *addrptr; @@ -311,8 +368,78 @@ } int -netaudit_socket_read(struct au_cmpnt *au) +netaudit_socket_read(struct au_srcbuffer *asb) { + u_char *bufptr, *recbufptr; + int ret, left; + u_int32_t hdr_remain; + u_int32_t val; + u_int32_t need; + + ret = read(asb->sb_fd, asb->sb_buf, sizeof(asb->sb_buf)); + if (ret == -1) { + if (errno != EINTR) + return (-1); + else + return (0); + } + else if (ret == 0) + return (-1); + left = ret; + bufptr = asb->sb_buf; + while (left > 0) { + if (asb->sb_recbuf == NULL) { + hdr_remain = sizeof(asb->sb_header) - + asb->sb_read; + if (left >= hdr_remain) { + memcpy(asb->sb_header + asb->sb_read, bufptr, + hdr_remain); + asb->sb_read += hdr_remain; + left -= hdr_remain; + bufptr += hdr_remain; + memcpy(&val, asb->sb_header + 1, sizeof(val)); + asb->sb_recbuf = \ + malloc(sizeof(struct au_recbuf)); + if (asb->sb_recbuf == NULL) + exit(2); + asb->sb_recbuf->ar_reclen = be32toh(val); + dprintf("audit header: rec %u bytes\n", + asb->sb_recbuf->ar_reclen); + asb->sb_recbuf->ar_rec = \ + malloc(asb->sb_recbuf->ar_reclen); + if (asb->sb_recbuf->ar_rec == NULL) + exit(2); + memcpy(asb->sb_recbuf->ar_rec, + asb->sb_header, sizeof(asb->sb_header)); + continue; + } + else { + dprintf("PARTIAL HEADER READ\n"); + memcpy(asb->sb_header + asb->sb_read, bufptr, + left); + asb->sb_read += left; + left = 0; + return (0); + } + } + need = asb->sb_recbuf->ar_reclen - asb->sb_read; + recbufptr = asb->sb_recbuf->ar_rec + asb->sb_read; + dprintf("still need %u bytes\n", need); + if (left < need) { + memcpy(recbufptr, bufptr, left); + asb->sb_read += left; + return (0); + } + else { + memcpy(recbufptr, bufptr, need); + left -= need; + bufptr += need; + /* We have a full record at this point */ + netaudit_queue_record(asb->sb_parent, asb->sb_recbuf); + asb->sb_recbuf = NULL; + asb->sb_read = 0; + } + } return (0); } ==== //depot/projects/trustedbsd/netauditd/netauditd.h#6 (text+ko) ==== @@ -48,10 +48,11 @@ struct au_srcbuffer { struct au_cmpnt *sb_parent; + struct sockaddr *sb_sockaddr; + socklen_t sb_socklen; int sb_fd; - u_int32_t sb_reclen; + struct au_recbuf *sb_recbuf; u_int32_t sb_read; - u_char *sb_rec; u_char sb_buf[8192]; u_char sb_header[5]; TAILQ_ENTRY(au_srcbuffer) sb_glue; @@ -97,11 +98,14 @@ void conf_free_args(args_t *); void dprintf(char *, ...); +void netaudit_build_rfds(fd_set *); void netaudit_establish(void); void netaudit_oq(void); void netaudit_queue_record(struct au_cmpnt *, struct au_recbuf *); void netaudit_pipe_read(struct au_cmpnt *); +void netaudit_record_handler(fd_set *); void netaudit_run(void); +void netaudit_socket_accept(struct au_cmpnt *); void netaudit_socket_listen(struct au_cmpnt *); -int netaudit_socket_read(struct au_cmpnt *); +int netaudit_socket_read(struct au_srcbuffer *); void usage(void);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802242156.m1OLuX8b089513>