PERFORCE change 136124 for review
Aaron Meihm
alm at FreeBSD.org
Sun Feb 24 21:56:34 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=136124
Change 136124 by alm at 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);
More information about the p4-projects
mailing list