mirror of
https://github.com/BlackLight/Snort_AIPreproc.git
synced 2024-11-27 22:25:12 +01:00
Alert serialization for db too, configuration fixed
This commit is contained in:
parent
4792e5bf4e
commit
0ac6af9921
11 changed files with 100 additions and 102 deletions
|
@ -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 )
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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++ )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
32
db.c
|
@ -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
2
db.h
|
@ -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
|
||||||
|
|
2
mysql.c
2
mysql.c
|
@ -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;
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
15
spp_ai.c
15
spp_ai.c
|
@ -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");
|
||||||
|
|
17
spp_ai.h
17
spp_ai.h
|
@ -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 */
|
||||||
|
|
||||||
|
|
6
stream.c
6
stream.c
|
@ -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 )
|
||||||
|
|
Loading…
Reference in a new issue