PERFORCE change 179951 for review
Sergio Ligregni
ligregni at FreeBSD.org
Sun Jun 20 02:03:21 UTC 2010
http://p4web.freebsd.org/@@179951?ac=10
Change 179951 by ligregni at 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 at 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 at 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 at 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
More information about the p4-projects
mailing list