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>