Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 Jun 2010 02:03:20 GMT
From:      Sergio Ligregni <ligregni@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 179951 for review
Message-ID:  <201006200203.o5K23KEi030032@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@179951?ac=10

Change 179951 by ligregni@ligPhenom on 2010/06/20 02:02:49

	Main daemon logic implemented, pending the network work...

Affected files ...

.. //depot/projects/soc2010/disaudit/ideas.txt#3 edit
.. //depot/projects/soc2010/disaudit/shipd.c#3 edit
.. //depot/projects/soc2010/disaudit/shipd.h#3 edit

Differences ...

==== //depot/projects/soc2010/disaudit/ideas.txt#3 (text+ko) ====

@@ -1,18 +1,18 @@
 /*-
  * Copyright (c) 2010
- *	Sergio Ligregni.  All rights reserved.
+ *	Sergio Ligregni <ligregni@FreeBSD.org>.  All rights reserved.
  */
 
 DisAudit Project
 
 PARAMETERS (the main idea is to get them from /etc/security/audit_control)
 
-disaudit_type:master					# master, slave, obviouslly depending on this to use the following parameters
+disaudit_type:master					# none, master, slave, obviouslly depending on this to use the following parameters
 
 
 /* SLAVE */
 
-disaudit_slave_level:0 					# 0=disabled
+disaudit_slave_level:1 					# 0=disabled
 							# 1=only when a trail closes (audit will call "shipd -l", 
 							# the last closed trail will be delivered without checkings)
 							# 2=the daemon will perform a comparisson in the master system 
@@ -25,6 +25,9 @@
 							# because a newer trail is ok, this options are available 
 							# to let the admin tune the system and choose between performance
 							# or trustiness (maybe the admin only needs the last slave's trail ok)
+disaudit_slave_init_level:3				# same as above, but this time only 2 or 3 allowed, it will do the same
+							# at startup, maybe we can use level 1 but when system starts check for all
+							# like here: 1, 3 (the 2 remember, is to check for the latest ones)
 disaudit_slave_msec:15000				# the frequency wich slave system will be doing the lists comparissons
 							# and syncronizing both directories of trails
 disaudit_slave_mhost:masterHost				# the master host (maybe we will allow IP address here)

==== //depot/projects/soc2010/disaudit/shipd.c#3 (text+ko) ====

@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2010
- *	Sergio Ligregni.  All rights reserved.
+ *	Sergio Ligregni <ligregni@FreeBSD.org>.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,11 +25,17 @@
  *
  */
 
+/*** INCLUDES ***/
+
 #include "shipd.h"
-#include "/usr/include/stdio.h"
-#include "/usr/include/stdlib.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
 #include <syslog.h>
 #include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 /*** DECLARATIONS ***/
 
@@ -37,13 +43,21 @@
 char audit_trails_dir[MAX_DIR_SIZE + 1];
 char master_host[MAX_HOST_SIZE + 1];
 
-/* The level of trust the shipping process will have */
+/* The level of trust the shipping process will have (0 means disabled) */
 int panic_level;
 
+/* The frequency the daemon will be checking the master's trail list */
+int msec_freq;
+
+/* Two main things to be set by this variable, if daemonize or not, and the destination of the messages */
+int debug;
+
 main (int argc, char *argv[])
 {
-	int debug = 0, last = 0;
 	char cl_opt;
+	int last = 0;
+
+	debug = 0;
 
 	while ((cl_opt = getopt(argc, argv, "dl")) != -1)
 		switch (cl_opt)
@@ -79,6 +93,12 @@
 		exit(0);
 	}
 
+	/* This means that the daemon will only search for the last closed trail and send to the master system */
+	if (last == 1)
+		do_last();
+	else /* Otherwise, we will perform a permanent listing checking and sync them */
+		do_daemon();
+
 	return 0;
 }
 
@@ -97,6 +117,7 @@
 	fscanf(fpars, "%s", audit_trails_dir);
 	fscanf(fpars, "%s", master_host);
 	fscanf(fpars, "%d", &panic_level);
+	fscanf(fpars, "%d", &msec_freq);
 
 	return 0;
 }
@@ -104,6 +125,304 @@
 void
 to_log(char *message)
 {
-	syslog(LOG_ERR, "%s", message);
+	if (debug)
+		perror(message);
+	else
+		syslog(LOG_ERR, "%s", message);
+}
+
+void
+do_last()
+{
+	char last_trail[MAX_PATH_SIZE + 1];
+	char message[MAX_PATH_SIZE + 30];
+
+	if (get_last_trail(last_trail) == -1)
+		to_log("Nothing to send!");
+
+	sprintf(message, "Will send \"%s\" to %s", last_trail, master_host);
+
+	to_log(message);
+
+	if (send_trail(last_trail) == -1)
+		to_log("Error sending the last trail");
+	else
+	{
+		sprintf(message, "Successfully sent \"%s\" to %s", last_trail, master_host);
+		to_log(message);
+	}
+}
+
+int
+get_last_trail(char *path)
+{
+	DIR *dp;
+	struct dirent *dirp;
+	struct stat statbuf;
+
+	char fullpath[MAX_PATH_SIZE + 1];
+	char *ptr;
+
+	*path = 0;
+
+	if ( !(dp = opendir(audit_trails_dir)) )
+	{
+		to_log("Can't open directory");
+		return -1;
+	}
+
+	strcpy(fullpath, audit_trails_dir);
+	ptr = fullpath + strlen(fullpath);
+	*ptr = '/';
+	*(++ptr) = 0;
+
+	/* Here we will pass through the entire directory and get the path of the latest closed trail */
+
+	while ( (dirp = readdir(dp)) != NULL )
+		if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) /* We have other than . or .. */
+		{
+			strcpy(ptr, dirp->d_name);
+
+			if ( stat(fullpath, &statbuf) < 0 )
+			{
+				to_log("Stat error!");
+				return -1;
+			}
+
+			if (S_ISDIR(statbuf.st_mode) == 0) /* It's not a directory */
+			{
+				if ( is_audit_trail(dirp->d_name) ) /* It's not other file */
+				{
+					if (*path == 0) /* This is our first trail, so assumme is the last */
+						strcpy(path, fullpath);
+					else if (strcmp (path, fullpath) < 0) /* Fortunately, the older a trail is, the lower lexocographic value it has */
+						strcpy(path, fullpath);
+				}
+			}
+		}
+
+	closedir(dp);
+
+	return 0;
+}
+
+int
+is_audit_trail(char *path)
+{
+	/*
+	 * We have these posibilities, only the first one is allowed
+	 * 20100619223115.20100619223131
+	 * 20100619223131.not_terminated
+	 * current
+	 */
+
+	if (strlen(path) == 29 && path[14] == '.' && isdigit(path[15])) /* To improve this checking later */
+		return 1;
+	return 0;
+}
+
+void
+do_daemon()
+{
+	while (1)
+	{
+		switch (panic_level)
+		{
+			case PANIC_DATE:
+				do_daemon_date();
+				break;
+			case PANIC_ALL:
+				do_daemon_all();
+				break;
+		}
+
+		usleep(msec_freq * 1000); /* Since we have miliseconds and this function receives microseconds */
+	}
+}
+
+int
+send_trail(char *path)
+{
+	return 0;
+}
+
+/*
+ * This function will search in the master system the 
+ * newest correct trail and sync from it to the last
+ * closed trail
+ */
+void do_daemon_date()
+{
+	DIR *dp;
+	struct dirent *dirp;
+	struct stat statbuf;
+
+	char fullpath[MAX_PATH_SIZE + 1];
+	char message[MAX_PATH_SIZE + 30];
+	char *ptr;
+
+	int n_elements = 0, i;
+
+	if ( !(dp = opendir(audit_trails_dir)) )
+	{
+		to_log("Can't open directory");
+		return;
+	}
+
+	/* Fancy way to use the fullpath */
+	strcpy(fullpath, audit_trails_dir);
+	ptr = fullpath + strlen(fullpath);
+	*ptr = '/';
+	*(++ptr) = 0;
+
+	/* We must count the elements (just the valid ones, this is: the trails) of the directory */
+	while ( (dirp = readdir(dp)) != NULL )
+		if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) /* We have other than . or .. */
+		{
+			strcpy(ptr, dirp->d_name);
+
+			if ( stat(fullpath, &statbuf) < 0 )
+			{
+				to_log("Stat error!");
+				return;
+			}
+
+			if (S_ISDIR(statbuf.st_mode) == 0) /* It's not a directory */
+				if ( is_audit_trail(dirp->d_name) ) /* It's not other file */
+					++n_elements;
+		}
+
+	/* Needed to sort the trail names */
+	char **trail_paths = (char **) malloc(sizeof(char *) * n_elements);
+	for (i=0; i<n_elements; ++i)
+		trail_paths[i] = (char *) malloc(sizeof(char) * (MAX_TRAILPATH_SIZE + 1));
+
+	rewinddir(dp);
+
+	n_elements = 0;
+
+	/* Here we will pass through the entire directory and get the names of the trails and then sort them */
+	while ( (dirp = readdir(dp)) != NULL )
+		if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) /* We have other than . or .. */
+		{
+			strcpy(ptr, dirp->d_name);
+
+			if ( stat(fullpath, &statbuf) < 0 )
+			{
+				to_log("Stat error!");
+				return;
+			}
+
+			if (S_ISDIR(statbuf.st_mode) == 0) /* It's not a directory */
+				if ( is_audit_trail(dirp->d_name) ) /* It's not other file */
+					strcpy(trail_paths[n_elements++], dirp->d_name);
+		}
+
+	closedir(dp);
+
+	/* Sort the trails lexicographically (fortunatelly it's the same than sorting per date thanks to the name structure) */
+	qsort(trail_paths, n_elements, sizeof(*trail_paths), cmp_trails);
+
+	for (i=0; i<n_elements; ++i)
+		if (is_in_master(trail_paths[i]))
+			break;
+
+	/*
+	 * At this point, the variable i holds the index of the first ok trail in master system
+	 * and we will go backwards (i-1 ... 0) in the array to sync the newer ones
+	 */
+
+	while (i--)
+	{
+		strcpy(ptr, trail_paths[i]);
+		if (send_trail(fullpath) == -1)
+		{
+			sprintf(message, "ERROR Sending \"%s\" to %s", trail_paths[i], master_host);
+			to_log(message);
+		}
+		else
+		{
+			sprintf(message, "Successfully sent \"%s\" to %s", trail_paths[i], master_host);
+			to_log(message);
+		}
+	}
+
+	/* Free the memory */
+	for (i=n_elements-1; i>0; --i)
+		free(trail_paths[i]);
+	free(trail_paths);
+
+	return;
+}
+
+int cmp_trails (const void *A, const void *B)
+{
+	if (strcmp(*((char **)A), *((char **)B)) < 0)
+		return 1;
+	return -1;
+}
+
+int is_in_master(char *path)
+{
+	return 0;
+}
+
+
+/*
+ * This function will make sure that ALL the trails 
+ * of the slave system are on master system
+ */
+void do_daemon_all()
+{
+	DIR *dp;
+	struct dirent *dirp;
+	struct stat statbuf;
+
+	char fullpath[MAX_PATH_SIZE + 1];
+	char message[MAX_PATH_SIZE + 30];
+	char *ptr;
+
+	if ( !(dp = opendir(audit_trails_dir)) )
+	{
+		to_log("Can't open directory");
+		return;
+	}
+
+	/* Fancy way to use the fullpath */
+	strcpy(fullpath, audit_trails_dir);
+	ptr = fullpath + strlen(fullpath);
+	*ptr = '/';
+	*(++ptr) = 0;
+
+	/* We must count the elements (just the valid ones, this is: the trails) of the directory */
+	while ( (dirp = readdir(dp)) != NULL )
+		if (strcmp(dirp->d_name, ".") && strcmp(dirp->d_name, "..")) /* We have other than . or .. */
+		{
+			strcpy(ptr, dirp->d_name);
+
+			if ( stat(fullpath, &statbuf) < 0 )
+			{
+				to_log("Stat error!");
+				return;
+			}
+
+			if (S_ISDIR(statbuf.st_mode) == 0) /* It's not a directory */
+				if ( is_audit_trail(dirp->d_name) ) /* It's not other file */
+					if ( !is_in_master(dirp->d_name) )
+						if (send_trail(fullpath) == -1)
+						{
+							sprintf(message, "ERROR Sending \"%s\" to %s", fullpath, master_host);
+							to_log(message);
+						}
+						else
+						{
+							sprintf(message, "Successfully sent \"%s\" to %s", fullpath, master_host);
+							to_log(message);
+						}
+		}
+
+	closedir(dp);
+
+	return;
 }
 

==== //depot/projects/soc2010/disaudit/shipd.h#3 (text+ko) ====

@@ -1,6 +1,6 @@
 /*-
  * Copyright (c) 2010
- *	Sergio Ligregni.  All rights reserved.
+ *	Sergio Ligregni <ligregni@FreeBSD.org>.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,9 +29,23 @@
 #define _SHIPD_H_
 
 #define MAX_DIR_SIZE 255
+#define MAX_PATH_SIZE MAX_DIR_SIZE + 50
 #define MAX_HOST_SIZE 255
+#define MAX_TRAILPATH_SIZE 29
+#define PANIC_DATE 2
+#define PANIC_ALL 3
 
 int get_parameters();
-void to_log();
+void to_log(char *);
+void do_last();
+void do_daemon();
+int get_last_trail(char *);
+int is_audit_trail(char *);
+int send_trail(char *);
+void do_daemon_date();
+int cmp_trails(const void *, const void *);
+int is_in_master(char *);
+void do_daemon_all();
+
 
 #endif



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006200203.o5K23KEi030032>