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