Alert serialization for db too, configuration fixed

This commit is contained in:
BlackLight 2010-09-21 21:47:48 +02:00
parent 4792e5bf4e
commit 0ac6af9921
11 changed files with 100 additions and 102 deletions

View file

@ -73,12 +73,11 @@ AI_alerts_hash_free ( AI_alert_event **events )
/** /**
* \brief Deserialize a alerts' hash table from the binary history file * \brief Deserialize a alerts' hash table from the binary history file
* \param conf Configuration of the module
* \return A void* pointer (to be casted to AI_alert_event*) to the stored hash table * \return A void* pointer (to be casted to AI_alert_event*) to the stored hash table
*/ */
void* void*
AI_deserialize_alerts ( AI_config *conf ) AI_deserialize_alerts ()
{ {
FILE *fp = NULL; FILE *fp = NULL;
struct stat st; struct stat st;
@ -90,19 +89,19 @@ AI_deserialize_alerts ( AI_config *conf )
*event_list = NULL; *event_list = NULL;
AI_alert_event_key key; AI_alert_event_key key;
if ( stat ( conf->alert_history_file, &st ) < 0 ) if ( stat ( config->alert_history_file, &st ) < 0 )
return NULL; return NULL;
if ( ! S_ISREG ( st.st_mode )) if ( ! S_ISREG ( st.st_mode ))
_dpd.fatalMsg ( "AIPreproc: '%s' is not a regular file\n", conf->alert_history_file ); _dpd.fatalMsg ( "AIPreproc: '%s' is not a regular file\n", config->alert_history_file );
if ( !( fp = fopen ( conf->alert_history_file, "r" ))) if ( !( fp = fopen ( config->alert_history_file, "r" )))
_dpd.fatalMsg ( "AIPreproc: Unable to read from the file '%s'\n", conf->alert_history_file ); _dpd.fatalMsg ( "AIPreproc: Unable to read from the file '%s'\n", config->alert_history_file );
AI_alerts_hash_free ( &alerts_hash ); AI_alerts_hash_free ( &alerts_hash );
if ( fread ( &lists_count, sizeof ( unsigned int ), 1, fp ) <= 0 ) if ( fread ( &lists_count, sizeof ( unsigned int ), 1, fp ) <= 0 )
_dpd.fatalMsg ( "AIPreproc: Malformed history file '%s'\n", conf->alert_history_file ); _dpd.fatalMsg ( "AIPreproc: Malformed history file '%s'\n", config->alert_history_file );
/* Fill the hash table reading from the file */ /* Fill the hash table reading from the file */
for ( i=0; i < lists_count; i++ ) for ( i=0; i < lists_count; i++ )
@ -111,7 +110,7 @@ AI_deserialize_alerts ( AI_config *conf )
event_prev = NULL; event_prev = NULL;
if ( fread ( &items_count, sizeof ( unsigned int ), 1, fp ) <= 0 ) if ( fread ( &items_count, sizeof ( unsigned int ), 1, fp ) <= 0 )
_dpd.fatalMsg ( "AIPreproc: Malformed history file '%s'\n", conf->alert_history_file ); _dpd.fatalMsg ( "AIPreproc: Malformed history file '%s'\n", config->alert_history_file );
for ( j=0; j < items_count; j++ ) for ( j=0; j < items_count; j++ )
{ {
@ -131,10 +130,10 @@ AI_deserialize_alerts ( AI_config *conf )
event_iterator->count = items_count; event_iterator->count = items_count;
if ( fread ( &( event_iterator->key ), sizeof ( event_iterator->key ), 1, fp ) <= 0 ) if ( fread ( &( event_iterator->key ), sizeof ( event_iterator->key ), 1, fp ) <= 0 )
_dpd.fatalMsg ( "AIPreproc: Malformed history file '%s'\n", conf->alert_history_file ); _dpd.fatalMsg ( "AIPreproc: Malformed history file '%s'\n", config->alert_history_file );
if ( fread ( &( event_iterator->timestamp ), sizeof ( event_iterator->timestamp ), 1, fp ) <= 0 ) if ( fread ( &( event_iterator->timestamp ), sizeof ( event_iterator->timestamp ), 1, fp ) <= 0 )
_dpd.fatalMsg ( "AIPreproc: Malformed history file '%s'\n", conf->alert_history_file ); _dpd.fatalMsg ( "AIPreproc: Malformed history file '%s'\n", config->alert_history_file );
if ( event_prev ) if ( event_prev )
{ {
@ -157,11 +156,10 @@ AI_deserialize_alerts ( AI_config *conf )
* \brief Serialize a buffer of alerts to the binary history file * \brief Serialize a buffer of alerts to the binary history file
* \param alerts_pool Buffer of alerts to be serialized * \param alerts_pool Buffer of alerts to be serialized
* \param alerts_pool_count Number of alerts in the buffer * \param alerts_pool_count Number of alerts in the buffer
* \param conf Configuration of the module
*/ */
void void
AI_serialize_alerts ( AI_snort_alert **alerts_pool, unsigned int alerts_pool_count, AI_config *conf ) AI_serialize_alerts ( AI_snort_alert **alerts_pool, unsigned int alerts_pool_count )
{ {
unsigned int i, unsigned int i,
hash_count = 0, hash_count = 0,
@ -175,7 +173,7 @@ AI_serialize_alerts ( AI_snort_alert **alerts_pool, unsigned int alerts_pool_cou
if ( !alerts_hash ) if ( !alerts_hash )
{ {
AI_deserialize_alerts ( conf ); AI_deserialize_alerts();
} }
for ( i=0; i < alerts_pool_count; i++ ) for ( i=0; i < alerts_pool_count; i++ )
@ -220,8 +218,8 @@ AI_serialize_alerts ( AI_snort_alert **alerts_pool, unsigned int alerts_pool_cou
hash_count = HASH_COUNT ( alerts_hash ); hash_count = HASH_COUNT ( alerts_hash );
if ( !( fp = fopen ( conf->alert_history_file, "w" ))) if ( !( fp = fopen ( config->alert_history_file, "w" )))
_dpd.fatalMsg ( "AIPreproc: Unable to write on '%s'\n", conf->alert_history_file ); _dpd.fatalMsg ( "AIPreproc: Unable to write on '%s'\n", config->alert_history_file );
fwrite ( &hash_count, sizeof ( hash_count ), 1, fp ); fwrite ( &hash_count, sizeof ( hash_count ), 1, fp );
for ( event = alerts_hash; event; event = ( AI_alert_event* ) event->hh.next ) for ( event = alerts_hash; event; event = ( AI_alert_event* ) event->hh.next )

View file

@ -22,21 +22,23 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#ifndef MACOS
#ifdef LINUX
#include <sys/inotify.h> #include <sys/inotify.h>
#endif #endif
#include <sys/stat.h> #include <sys/stat.h>
#include <pthread.h> #include <pthread.h>
PRIVATE AI_snort_alert *alerts = NULL; PRIVATE AI_snort_alert *alerts = NULL;
PRIVATE AI_snort_alert **alerts_pool = NULL;
PRIVATE AI_config *conf = NULL;
PRIVATE FILE *alert_fp = NULL; PRIVATE FILE *alert_fp = NULL;
PRIVATE unsigned int alerts_pool_count = 0;
PRIVATE pthread_mutex_t alert_mutex; PRIVATE pthread_mutex_t alert_mutex;
PRIVATE pthread_mutex_t alerts_pool_mutex; PRIVATE pthread_mutex_t alerts_pool_mutex;
AI_snort_alert **alerts_pool = NULL;
unsigned int alerts_pool_count = 0;
/** \defgroup alert_parser Parse the alert log into binary structures /** \defgroup alert_parser Parse the alert log into binary structures
* @{ */ * @{ */
@ -47,8 +49,8 @@ PRIVATE pthread_mutex_t alerts_pool_mutex;
* \param arg void* pointer to the alert to be added to the pool, if any * \param arg void* pointer to the alert to be added to the pool, if any
*/ */
PRIVATE void* void*
_AI_serializer_thread ( void *arg ) AI_serializer_thread ( void *arg )
{ {
unsigned int i = 0; unsigned int i = 0;
AI_snort_alert *alert = NULL; AI_snort_alert *alert = NULL;
@ -62,10 +64,10 @@ _AI_serializer_thread ( void *arg )
pthread_mutex_unlock ( &alerts_pool_mutex ); pthread_mutex_unlock ( &alerts_pool_mutex );
} }
if ( !arg || ( arg && alerts_pool_count >= conf->alert_bufsize )) if ( !arg || ( arg && alerts_pool_count >= config->alert_bufsize ))
{ {
pthread_mutex_lock ( &alerts_pool_mutex ); pthread_mutex_lock ( &alerts_pool_mutex );
AI_serialize_alerts ( alerts_pool, alerts_pool_count, conf ); AI_serialize_alerts ( alerts_pool, alerts_pool_count );
for ( i=0; i < alerts_pool_count; i++ ) for ( i=0; i < alerts_pool_count; i++ )
{ {
@ -78,43 +80,36 @@ _AI_serializer_thread ( void *arg )
pthread_exit ((void*) 0); pthread_exit ((void*) 0);
return (void*) 0; return (void*) 0;
} /* ----- end of function _AI_serializer_thread ----- */ } /* ----- end of function AI_serializer_thread ----- */
/** /**
* \brief Thread for managing the buffer of alerts and serialize them at constant intervals * \brief Thread for managing the buffer of alerts and serialize them at constant intervals
*/ */
PRIVATE void* void*
_AI_alerts_pool_thread ( void *arg ) AI_alerts_pool_thread ( void *arg )
{ {
pthread_t serializer_thread; pthread_t serializer_thread;
while ( 1 ) while ( 1 )
{ {
if ( !conf ) sleep ( config->alertSerializationInterval );
{
pthread_exit ((void*) 0);
return (void*) 0;
}
sleep ( conf->alertSerializationInterval );
if ( !alerts_pool || alerts_pool_count == 0 ) if ( !alerts_pool || alerts_pool_count == 0 )
continue; continue;
if ( pthread_create ( &serializer_thread, NULL, _AI_serializer_thread, NULL ) != 0 ) if ( pthread_create ( &serializer_thread, NULL, AI_serializer_thread, NULL ) != 0 )
_dpd.fatalMsg ( "Failed to create the alerts' serializer thread\n" ); _dpd.fatalMsg ( "Failed to create the alerts' serializer thread\n" );
} }
pthread_exit ((void*) 0); pthread_exit ((void*) 0);
return (void*) 0; return (void*) 0;
} /* ----- end of function _AI_alerts_pool_thread ----- */ } /* ----- end of function AI_alerts_pool_thread ----- */
/** /**
* \brief Thread for parsing Snort's alert file * \brief Thread for parsing Snort's alert file
* \param arg void* pointer to module's configuration
*/ */
void* void*
@ -155,8 +150,6 @@ AI_file_alertparser_thread ( void* arg )
pthread_t alerts_pool_thread; pthread_t alerts_pool_thread;
pthread_t serializer_thread; pthread_t serializer_thread;
conf = ( AI_config* ) arg;
/* Initialize the mutex lock, so nobody can read the alerts while we write there */ /* Initialize the mutex lock, so nobody can read the alerts while we write there */
pthread_mutex_init ( &alert_mutex, NULL ); pthread_mutex_init ( &alert_mutex, NULL );
@ -164,14 +157,14 @@ AI_file_alertparser_thread ( void* arg )
pthread_mutex_init ( &alerts_pool_mutex, NULL ); pthread_mutex_init ( &alerts_pool_mutex, NULL );
/* Initialize the pool of alerts to be passed to the serialization thread */ /* Initialize the pool of alerts to be passed to the serialization thread */
if ( !( alerts_pool = ( AI_snort_alert** ) malloc ( conf->alert_bufsize * sizeof ( AI_snort_alert* )))) if ( !( alerts_pool = ( AI_snort_alert** ) malloc ( config->alert_bufsize * sizeof ( AI_snort_alert* ))))
_dpd.fatalMsg ( "Dynamic memory allocation error at %s:%d\n", __FILE__, __LINE__ ); _dpd.fatalMsg ( "Dynamic memory allocation error at %s:%d\n", __FILE__, __LINE__ );
for ( i=0; i < conf->alert_bufsize; i++ ) for ( i=0; i < config->alert_bufsize; i++ )
alerts_pool[i] = NULL; alerts_pool[i] = NULL;
/* Initialize the thread for managing the serialization of alerts' pool */ /* Initialize the thread for managing the serialization of alerts' pool */
if ( pthread_create ( &alerts_pool_thread, NULL, _AI_alerts_pool_thread, NULL ) != 0 ) if ( pthread_create ( &alerts_pool_thread, NULL, AI_alerts_pool_thread, NULL ) != 0 )
_dpd.fatalMsg ( "Failed to create the alerts' pool management thread\n" ); _dpd.fatalMsg ( "Failed to create the alerts' pool management thread\n" );
while ( 1 ) while ( 1 )
@ -182,9 +175,9 @@ AI_file_alertparser_thread ( void* arg )
_dpd.fatalMsg ( "Could not initialize an inotify object on the alert log file" ); _dpd.fatalMsg ( "Could not initialize an inotify object on the alert log file" );
} }
if ( stat ( conf->alertfile, &st ) < 0 ) if ( stat ( config->alertfile, &st ) < 0 )
{ {
if (( wd = inotify_add_watch ( ifd, conf->alertfile, IN_CREATE )) < 0 ) if (( wd = inotify_add_watch ( ifd, config->alertfile, IN_CREATE )) < 0 )
{ {
_dpd.fatalMsg ( "Could not initialize a watch descriptor on the alert log file" ); _dpd.fatalMsg ( "Could not initialize a watch descriptor on the alert log file" );
} }
@ -194,14 +187,14 @@ AI_file_alertparser_thread ( void* arg )
} else { } else {
if ( !alert_fp ) if ( !alert_fp )
{ {
if ( ! (alert_fp = fopen ( conf->alertfile, "r" )) ) if ( ! (alert_fp = fopen ( config->alertfile, "r" )) )
{ {
_dpd.fatalMsg ( "Could not open alert log file for reading" ); _dpd.fatalMsg ( "Could not open alert log file for reading" );
} }
} }
} }
if (( wd = inotify_add_watch ( ifd, conf->alertfile, IN_MODIFY )) < 0 ) if (( wd = inotify_add_watch ( ifd, config->alertfile, IN_MODIFY )) < 0 )
{ {
_dpd.fatalMsg ( "Could not initialize a watch descriptor on the alert log file" ); _dpd.fatalMsg ( "Could not initialize a watch descriptor on the alert log file" );
} }
@ -217,7 +210,7 @@ AI_file_alertparser_thread ( void* arg )
*/ */
if ( !alert_fp ) if ( !alert_fp )
{ {
if ( ! (alert_fp = fopen ( conf->alertfile, "r" )) ) if ( ! (alert_fp = fopen ( config->alertfile, "r" )) )
{ {
_dpd.fatalMsg ( "Could not open alert log file for reading" ); _dpd.fatalMsg ( "Could not open alert log file for reading" );
} }
@ -291,7 +284,7 @@ AI_file_alertparser_thread ( void* arg )
tmp->next = alert; tmp->next = alert;
} }
if ( pthread_create ( &serializer_thread, NULL, _AI_serializer_thread, alert ) != 0 ) if ( pthread_create ( &serializer_thread, NULL, AI_serializer_thread, alert ) != 0 )
_dpd.fatalMsg ( "Failed to create the alerts' serializer thread\n" ); _dpd.fatalMsg ( "Failed to create the alerts' serializer thread\n" );
in_alert = false; in_alert = false;
@ -452,7 +445,6 @@ AI_file_alertparser_thread ( void* arg )
} }
pthread_mutex_unlock ( &alert_mutex ); pthread_mutex_unlock ( &alert_mutex );
/* AI_alert_serialize ( alert, conf ); */
} }
free ( alerts_pool ); free ( alerts_pool );

View file

@ -51,7 +51,6 @@ typedef struct {
PRIVATE hierarchy_node *h_root[CLUSTER_TYPES] = { NULL }; PRIVATE hierarchy_node *h_root[CLUSTER_TYPES] = { NULL };
PRIVATE AI_config *_config = NULL;
PRIVATE AI_snort_alert *alert_log = NULL; PRIVATE AI_snort_alert *alert_log = NULL;
PRIVATE pthread_mutex_t mutex; PRIVATE pthread_mutex_t mutex;
@ -450,7 +449,7 @@ _AI_cluster_thread ( void* arg )
while ( 1 ) while ( 1 )
{ {
/* Between an execution of the thread and the next one, sleep for alert_clustering_interval seconds */ /* Between an execution of the thread and the next one, sleep for alert_clustering_interval seconds */
sleep ( _config->alertClusteringInterval ); sleep ( config->alertClusteringInterval );
/* Set the lock over the alert log until it's done with the clustering operation */ /* Set the lock over the alert log until it's done with the clustering operation */
pthread_mutex_lock ( &mutex ); pthread_mutex_lock ( &mutex );
@ -565,7 +564,7 @@ _AI_cluster_thread ( void* arg )
pthread_mutex_unlock ( &mutex ); pthread_mutex_unlock ( &mutex );
if ( !( cluster_fp = fopen ( _config->clusterfile, "w" )) ) if ( !( cluster_fp = fopen ( config->clusterfile, "w" )) )
{ {
pthread_exit ((void*) 0 ); pthread_exit ((void*) 0 );
return (void*) 0; return (void*) 0;
@ -610,20 +609,18 @@ _AI_check_duplicate ( hierarchy_node *node, hierarchy_node *root )
/** /**
* \brief Build the clustering hierarchy trees * \brief Build the clustering hierarchy trees
* \param conf Reference to the configuration of the module
* \param nodes Nodes containing the information about the clustering ranges * \param nodes Nodes containing the information about the clustering ranges
* \param n_nodes Number of nodes * \param n_nodes Number of nodes
*/ */
void void
AI_hierarchies_build ( AI_config *conf, hierarchy_node **nodes, int n_nodes ) AI_hierarchies_build ( hierarchy_node **nodes, int n_nodes )
{ {
int i, j; int i, j;
int min_range = 0; int min_range = 0;
pthread_t cluster_thread; pthread_t cluster_thread;
hierarchy_node *root = NULL; hierarchy_node *root = NULL;
hierarchy_node *cover = NULL; hierarchy_node *cover = NULL;
_config = conf;
for ( i=0; i < n_nodes; i++ ) for ( i=0; i < n_nodes; i++ )
{ {

View file

@ -67,7 +67,6 @@ typedef struct {
} AI_alert_correlation; } AI_alert_correlation;
PRIVATE AI_hyperalert_info *hyperalerts = NULL; PRIVATE AI_hyperalert_info *hyperalerts = NULL;
PRIVATE AI_config *conf = NULL;
PRIVATE AI_snort_alert *alerts = NULL; PRIVATE AI_snort_alert *alerts = NULL;
PRIVATE AI_alert_correlation *correlation_table = NULL; PRIVATE AI_alert_correlation *correlation_table = NULL;
PRIVATE pthread_mutex_t mutex; PRIVATE pthread_mutex_t mutex;
@ -566,7 +565,7 @@ _AI_hyperalert_from_XML ( AI_hyperalert_key key )
hyp->key = key; hyp->key = key;
snprintf ( hyperalert_file, sizeof ( hyperalert_file ), "%s/%d-%d-%d.xml", snprintf ( hyperalert_file, sizeof ( hyperalert_file ), "%s/%d-%d-%d.xml",
conf->corr_rules_dir, key.gid, key.sid, key.rev ); config->corr_rules_dir, key.gid, key.sid, key.rev );
if ( stat ( hyperalert_file, &st ) < 0 ) if ( stat ( hyperalert_file, &st ) < 0 )
return NULL; return NULL;
@ -679,7 +678,6 @@ _AI_hyperalert_from_XML ( AI_hyperalert_key key )
/** /**
* \brief Thread for correlating clustered alerts * \brief Thread for correlating clustered alerts
* \param arg Void pointer to module's configuration
*/ */
void* void*
@ -712,17 +710,16 @@ AI_alert_correlation_thread ( void *arg )
graph_t *g = NULL; graph_t *g = NULL;
#endif #endif
conf = (AI_config*) arg;
pthread_mutex_init ( &mutex, NULL ); pthread_mutex_init ( &mutex, NULL );
while ( 1 ) while ( 1 )
{ {
sleep ( conf->correlationGraphInterval ); sleep ( config->correlationGraphInterval );
if ( stat ( conf->corr_rules_dir, &st ) < 0 ) if ( stat ( config->corr_rules_dir, &st ) < 0 )
{ {
_dpd.errMsg ( "AIPreproc: Correlation rules directory '%s' not found, the correlation thread won't be active\n", _dpd.errMsg ( "AIPreproc: Correlation rules directory '%s' not found, the correlation thread won't be active\n",
conf->corr_rules_dir ); config->corr_rules_dir );
pthread_exit (( void* ) 0 ); pthread_exit (( void* ) 0 );
return ( void* ) 0; return ( void* ) 0;
} }
@ -829,18 +826,18 @@ AI_alert_correlation_thread ( void *arg )
} }
std_deviation = sqrt ( std_deviation / (double) HASH_COUNT ( correlation_table )); std_deviation = sqrt ( std_deviation / (double) HASH_COUNT ( correlation_table ));
corr_threshold = avg_correlation + ( conf->correlationThresholdCoefficient * std_deviation ); corr_threshold = avg_correlation + ( config->correlationThresholdCoefficient * std_deviation );
corr_strong_threshold = avg_correlation + ( 2.0 * conf->correlationThresholdCoefficient * std_deviation ); corr_strong_threshold = avg_correlation + ( 2.0 * config->correlationThresholdCoefficient * std_deviation );
snprintf ( corr_dot_file, sizeof ( corr_dot_file ), "%s/correlated_alerts.dot", conf->corr_alerts_dir ); snprintf ( corr_dot_file, sizeof ( corr_dot_file ), "%s/correlated_alerts.dot", config->corr_alerts_dir );
if ( stat ( conf->corr_alerts_dir, &st ) < 0 ) if ( stat ( config->corr_alerts_dir, &st ) < 0 )
{ {
if ( mkdir ( conf->corr_alerts_dir, 0755 ) < 0 ) if ( mkdir ( config->corr_alerts_dir, 0755 ) < 0 )
{ {
_dpd.fatalMsg ( "AIPreproc: Unable to create directory '%s'\n", conf->corr_alerts_dir ); _dpd.fatalMsg ( "AIPreproc: Unable to create directory '%s'\n", config->corr_alerts_dir );
} }
} else if ( !S_ISDIR ( st.st_mode )) { } else if ( !S_ISDIR ( st.st_mode )) {
_dpd.fatalMsg ( "AIPreproc: '%s' found but it's not a directory\n", conf->corr_alerts_dir ); _dpd.fatalMsg ( "AIPreproc: '%s' found but it's not a directory\n", config->corr_alerts_dir );
} }
if ( !( fp = fopen ( corr_dot_file, "w" ))) if ( !( fp = fopen ( corr_dot_file, "w" )))
@ -873,8 +870,8 @@ AI_alert_correlation_thread ( void *arg )
fclose ( fp ); fclose ( fp );
#ifdef HAVE_LIBGVC #ifdef HAVE_LIBGVC
snprintf ( corr_png_file, sizeof ( corr_png_file ), "%s/correlated_alerts.png", conf->corr_alerts_dir ); snprintf ( corr_png_file, sizeof ( corr_png_file ), "%s/correlated_alerts.png", config->corr_alerts_dir );
snprintf ( corr_ps_file , sizeof ( corr_ps_file ), "%s/correlated_alerts.ps" , conf->corr_alerts_dir ); snprintf ( corr_ps_file , sizeof ( corr_ps_file ), "%s/correlated_alerts.ps" , config->corr_alerts_dir );
if ( !( gvc = gvContext() )) if ( !( gvc = gvContext() ))
continue; continue;

32
db.c
View file

@ -30,22 +30,23 @@
* @{ */ * @{ */
PRIVATE AI_config *config;
PRIVATE AI_snort_alert *alerts = NULL; PRIVATE AI_snort_alert *alerts = NULL;
PRIVATE pthread_mutex_t mutex; PRIVATE pthread_mutex_t mutex;
/** /**
* \brief Thread for parsing alerts from a database * \brief Thread for parsing alerts from a database
* \param arg void* pointer to the module configuration
*/ */
void* void*
AI_db_alertparser_thread ( void *arg ) AI_db_alertparser_thread ( void *arg )
{ {
char query[1024]; unsigned int i = 0;
char query[1024] = { 0 };
int rows = 0; int rows = 0;
int latest_cid = 0; int latest_cid = 0;
time_t latest_time = time ( NULL ); time_t latest_time = time ( NULL );
pthread_t alerts_pool_thread;
pthread_t serializer_thread;
DB_result res, res2; DB_result res, res2;
DB_row row, row2; DB_row row, row2;
@ -55,21 +56,25 @@ AI_db_alertparser_thread ( void *arg )
AI_snort_alert *alert = NULL; AI_snort_alert *alert = NULL;
AI_snort_alert *tmp = NULL; AI_snort_alert *tmp = NULL;
if ( !arg )
{
pthread_exit ((void*) 0 );
return (void*) 0;
}
config = ( AI_config* ) arg;
pthread_mutex_init ( &mutex, NULL ); pthread_mutex_init ( &mutex, NULL );
if ( !DB_init ( config )) if ( !DB_init() )
{ {
_dpd.fatalMsg ( "AIPreproc: Unable to connect to the database '%s' @ '%s'\n", _dpd.fatalMsg ( "AIPreproc: Unable to connect to the database '%s' @ '%s'\n",
config->dbname, config->dbhost ); config->dbname, config->dbhost );
} }
/* Initialize the pool of alerts to be passed to the serialization thread */
if ( !( alerts_pool = ( AI_snort_alert** ) malloc ( config->alert_bufsize * sizeof ( AI_snort_alert* ))))
_dpd.fatalMsg ( "Dynamic memory allocation error at %s:%d\n", __FILE__, __LINE__ );
for ( i=0; i < config->alert_bufsize; i++ )
alerts_pool[i] = NULL;
/* Initialize the thread for managing the serialization of alerts' pool */
if ( pthread_create ( &alerts_pool_thread, NULL, AI_alerts_pool_thread, NULL ) != 0 )
_dpd.fatalMsg ( "Failed to create the alerts' pool management thread\n" );
while ( 1 ) while ( 1 )
{ {
sleep ( config->databaseParsingInterval ); sleep ( config->databaseParsingInterval );
@ -220,6 +225,9 @@ AI_db_alertparser_thread ( void *arg )
pthread_mutex_unlock ( &mutex ); pthread_mutex_unlock ( &mutex );
DB_free_result ( res ); DB_free_result ( res );
latest_time = time ( NULL ); latest_time = time ( NULL );
if ( pthread_create ( &serializer_thread, NULL, AI_serializer_thread, alert ) != 0 )
_dpd.fatalMsg ( "Failed to create the alerts' serializer thread\n" );
} }
DB_close(); DB_close();
@ -276,5 +284,5 @@ AI_db_get_alerts ()
/** @} */ /** @} */
#endif #endif /* HAVE_DB */

2
db.h
View file

@ -62,7 +62,7 @@
DB_result DB_query ( const char* ); DB_result DB_query ( const char* );
#endif #endif
void* DB_init ( AI_config* ); void* DB_init();
void DB_close(); void DB_close();
#endif #endif

View file

@ -28,7 +28,7 @@
PRIVATE MYSQL *db = NULL; PRIVATE MYSQL *db = NULL;
void* void*
mysql_do_init ( AI_config *config ) mysql_do_init ()
{ {
if ( !( db = (MYSQL*) malloc ( sizeof ( MYSQL )))) if ( !( db = (MYSQL*) malloc ( sizeof ( MYSQL ))))
return NULL; return NULL;

View file

@ -30,7 +30,7 @@
PRIVATE PGconn *db = NULL; PRIVATE PGconn *db = NULL;
void* void*
postgresql_do_init ( AI_config *config ) postgresql_do_init ()
{ {
char *conninfo = NULL; char *conninfo = NULL;
int conninfo_max_length = int conninfo_max_length =

View file

@ -28,6 +28,7 @@
* @{ */ * @{ */
AI_snort_alert* (*get_alerts)(void); AI_snort_alert* (*get_alerts)(void);
AI_config *config = NULL;
tSfPolicyUserContextId ex_config = NULL; tSfPolicyUserContextId ex_config = NULL;
static void* (*alertparser_thread)(void*) = NULL; static void* (*alertparser_thread)(void*) = NULL;
@ -71,8 +72,6 @@ void AI_setup(void)
static void AI_init(char *args) static void AI_init(char *args)
{ {
AI_config *config;
pthread_t cleanup_thread, pthread_t cleanup_thread,
logparse_thread, logparse_thread,
correlation_thread; correlation_thread;
@ -183,8 +182,6 @@ static AI_config * AI_parse(char *args)
has_database_log = false, has_database_log = false,
has_alert_history_file = false; has_alert_history_file = false;
AI_config *config = NULL;
if ( !( config = ( AI_config* ) malloc ( sizeof( AI_config )) )) if ( !( config = ( AI_config* ) malloc ( sizeof( AI_config )) ))
_dpd.fatalMsg("Could not allocate configuration struct.\n"); _dpd.fatalMsg("Could not allocate configuration struct.\n");
memset ( config, 0, sizeof ( AI_config )); memset ( config, 0, sizeof ( AI_config ));
@ -863,7 +860,7 @@ static AI_config * AI_parse(char *args)
config->alertClusteringInterval = DEFAULT_ALERT_CLUSTERING_INTERVAL; config->alertClusteringInterval = DEFAULT_ALERT_CLUSTERING_INTERVAL;
} }
AI_hierarchies_build ( config, hierarchy_nodes, n_hierarchy_nodes ); AI_hierarchies_build ( hierarchy_nodes, n_hierarchy_nodes );
} }
if ( ! has_corr_rules_dir ) if ( ! has_corr_rules_dir )
@ -923,12 +920,12 @@ static AI_config * AI_parse(char *args)
void AI_process(void *pkt, void *context) void AI_process(void *pkt, void *context)
{ {
SFSnortPacket *p = (SFSnortPacket *) pkt; SFSnortPacket *p = (SFSnortPacket *) pkt;
AI_config *config; AI_config *_config;
sfPolicyUserPolicySet(ex_config, _dpd.getRuntimePolicy()); sfPolicyUserPolicySet(ex_config, _dpd.getRuntimePolicy());
config = (AI_config * ) sfPolicyUserDataGetCurrent (ex_config); _config = (AI_config * ) sfPolicyUserDataGetCurrent (ex_config);
if (config == NULL) if (_config == NULL)
return; return;
if (!p->ip4_header || p->ip4_header->proto != IPPROTO_TCP || !p->tcp_header) if (!p->ip4_header || p->ip4_header->proto != IPPROTO_TCP || !p->tcp_header)
@ -943,7 +940,7 @@ void AI_process(void *pkt, void *context)
#ifdef SNORT_RELOAD #ifdef SNORT_RELOAD
static void AI_reload(char *args) static void AI_reload(char *args)
{ {
AI_config *config; /* AI_config *config; */
tSfPolicyId policy_id = _dpd.getParserPolicy(); tSfPolicyId policy_id = _dpd.getParserPolicy();
_dpd.logMsg("AI dynamic preprocessor configuration\n"); _dpd.logMsg("AI dynamic preprocessor configuration\n");

View file

@ -316,18 +316,29 @@ void* AI_db_alertparser_thread ( void* );
void AI_pkt_enqueue ( SFSnortPacket* ); void AI_pkt_enqueue ( SFSnortPacket* );
void AI_set_stream_observed ( struct pkt_key key ); void AI_set_stream_observed ( struct pkt_key key );
void AI_hierarchies_build ( AI_config*, hierarchy_node**, int ); void AI_hierarchies_build ( hierarchy_node**, int );
void AI_free_alerts ( AI_snort_alert *node ); void AI_free_alerts ( AI_snort_alert *node );
struct pkt_info* AI_get_stream_by_key ( struct pkt_key ); struct pkt_info* AI_get_stream_by_key ( struct pkt_key );
AI_snort_alert* AI_get_alerts ( void ); AI_snort_alert* AI_get_alerts ( void );
AI_snort_alert* AI_get_clustered_alerts ( void ); AI_snort_alert* AI_get_clustered_alerts ( void );
void AI_serialize_alerts ( AI_snort_alert**, unsigned int, AI_config* ); void AI_serialize_alerts ( AI_snort_alert**, unsigned int );
void* AI_deserialize_alerts ( AI_config* ); void* AI_deserialize_alerts ();
void* AI_alerts_pool_thread ( void *arg );
void* AI_serializer_thread ( void *arg );
/** Function pointer to the function used for getting the alert list (from log file, db, ...) */ /** Function pointer to the function used for getting the alert list (from log file, db, ...) */
extern AI_snort_alert* (*get_alerts)(void); extern AI_snort_alert* (*get_alerts)(void);
/** Buffer containing the alerts to be serialized on the binary history file */
extern AI_snort_alert **alerts_pool;
/** Number of alerts contained in the buffer to be serialized */
extern unsigned int alerts_pool_count;
/** Configuration of the module */
extern AI_config *config;
#endif /* _SPP_AI_H */ #endif /* _SPP_AI_H */

View file

@ -92,7 +92,6 @@ _AI_stream_free ( struct pkt_info* stream )
/** /**
* \brief Thread called for cleaning up the hash table from the traffic streams older than * \brief Thread called for cleaning up the hash table from the traffic streams older than
* a certain threshold * a certain threshold
* \param arg Pointer to the AI_config struct
*/ */
void* void*
@ -100,11 +99,10 @@ AI_hashcleanup_thread ( void* arg )
{ {
struct pkt_info *h, *stream; struct pkt_info *h, *stream;
time_t max_timestamp; time_t max_timestamp;
AI_config* conf = (AI_config*) arg;
while ( 1 ) { while ( 1 ) {
/* Sleep for the specified number of seconds */ /* Sleep for the specified number of seconds */
sleep ( conf->hashCleanupInterval ); sleep ( config->hashCleanupInterval );
/* If the hash is empty, come back to sleep */ /* If the hash is empty, come back to sleep */
if ( !hash || !HASH_COUNT(hash) ) if ( !hash || !HASH_COUNT(hash) )
@ -122,7 +120,7 @@ AI_hashcleanup_thread ( void* arg )
} }
/* If the most recent packet in the stream is older than the specified threshold, remove that stream */ /* If the most recent packet in the stream is older than the specified threshold, remove that stream */
if ( time(NULL) - max_timestamp > conf->streamExpireInterval ) { if ( time(NULL) - max_timestamp > config->streamExpireInterval ) {
stream = h; stream = h;
if ( stream ) if ( stream )