(Full?) support for PostgreSQL

This commit is contained in:
BlackLight 2010-10-05 04:01:35 +02:00
parent 90b94f3b20
commit c854afe6f0
6 changed files with 129 additions and 54 deletions

24
db.h
View File

@ -58,18 +58,20 @@
typedef PSQL_result* DB_result;
typedef char** DB_row;
#define DB_init postgresql_do_init
#define DB_is_init postgresql_is_init
#define DB_query postgresql_do_query
#define DB_num_rows postgresql_num_rows
#define DB_fetch_row postgresql_fetch_row
#define DB_free_result postgresql_free_result
#define DB_close postgresql_do_close
#define DB_init postgresql_do_init
#define DB_is_init postgresql_is_init
#define DB_query postgresql_do_query
#define DB_num_rows postgresql_num_rows
#define DB_fetch_row postgresql_fetch_row
#define DB_free_result postgresql_free_result
#define DB_escape_string postgresql_do_escape_string
#define DB_close postgresql_do_close
#define DB_out_init postgresql_do_out_init
#define DB_is_out_init postgresql_is_out_init
#define DB_out_query postgresql_do_out_query
#define DB_out_close postgresql_do_out_close
#define DB_out_init postgresql_do_out_init
#define DB_is_out_init postgresql_is_out_init
#define DB_out_query postgresql_do_out_query
#define DB_out_escape_string postgresql_do_out_escape_string
#define DB_out_close postgresql_do_out_close
int DB_num_rows ( PSQL_result *res );
DB_row DB_fetch_row ( PSQL_result *res );

55
outdb.c
View File

@ -71,8 +71,10 @@ AI_outdb_mutex_initialize ()
void*
AI_store_alert_to_db_thread ( void *arg )
{
char query[65535] = { 0 };
char srcip[INET_ADDRSTRLEN],
char query[65535] = { 0 },
iphdr_id_str[20] = { 0 },
tcphdr_id_str[20] = { 0 },
srcip[INET_ADDRSTRLEN],
dstip[INET_ADDRSTRLEN];
unsigned char *pkt_data = NULL;
@ -166,10 +168,24 @@ AI_store_alert_to_db_thread ( void *arg )
DB_free_result ( res );
}
if ( latest_ip_hdr_id )
{
snprintf ( iphdr_id_str, sizeof ( iphdr_id_str ), ", %lu", latest_ip_hdr_id );
}
if ( latest_tcp_hdr_id && alert->ip_proto == IPPROTO_TCP )
{
snprintf ( tcphdr_id_str, sizeof ( tcphdr_id_str ), ", %lu", latest_tcp_hdr_id );
}
memset ( query, 0, sizeof ( query ));
snprintf ( query, sizeof ( query ), "INSERT INTO %s (gid, sid, rev, priority, description, classification, timestamp, ip_hdr, tcp_hdr) "
"VALUES (%u, %u, %u, %u, '%s', '%s', from_unixtime('%lu'), %lu, %lu)",
#ifdef HAVE_LIBMYSQLCLIENT
snprintf ( query, sizeof ( query ), "INSERT INTO %s (gid, sid, rev, priority, description, classification, timestamp%s%s) "
"VALUES (%u, %u, %u, %u, '%s', '%s', from_unixtime('%lu')%s%s)",
outdb_config[ALERTS_TABLE],
((latest_ip_hdr_id != 0) ? ", ip_hdr" : ""),
((latest_tcp_hdr_id != 0) ? ", tcp_hdr" : ""),
alert->gid,
alert->sid,
alert->rev,
@ -177,8 +193,24 @@ AI_store_alert_to_db_thread ( void *arg )
((alert->desc) ? alert->desc : ""),
((alert->classification) ? alert->classification : ""),
alert->timestamp,
latest_ip_hdr_id,
((alert->ip_proto == IPPROTO_TCP || alert->ip_proto == IPPROTO_UDP) ? latest_tcp_hdr_id : 0));
iphdr_id_str,
tcphdr_id_str );
#elif HAVE_LIBPQ
snprintf ( query, sizeof ( query ), "INSERT INTO %s (gid, sid, rev, priority, description, classification, timestamp%s%s) "
"VALUES (%u, %u, %u, %u, '%s', '%s', timestamp with time zone 'epoch' + %lu * interval '1 second'%s%s)",
outdb_config[ALERTS_TABLE],
((latest_ip_hdr_id != 0) ? ", ip_hdr" : ""),
((latest_tcp_hdr_id != 0) ? ", tcp_hdr" : ""),
alert->gid,
alert->sid,
alert->rev,
alert->priority,
((alert->desc) ? alert->desc : ""),
((alert->classification) ? alert->classification : ""),
alert->timestamp,
iphdr_id_str,
tcphdr_id_str );
#endif
DB_free_result ((DB_result) DB_out_query ( query ));
@ -219,6 +251,8 @@ AI_store_alert_to_db_thread ( void *arg )
pkt->pkt->pcap_header->len + pkt->pkt->payload_size );
memset ( query, 0, sizeof ( query ));
#ifdef HAVE_LIBMYSQLCLIENT
snprintf ( query, sizeof ( query ), "INSERT INTO %s (alert_id, pkt_len, timestamp, content) "
"VALUES (%lu, %u, from_unixtime('%lu'), '%s')",
outdb_config[PACKET_STREAMS_TABLE],
@ -226,6 +260,15 @@ AI_store_alert_to_db_thread ( void *arg )
pkt->pkt->pcap_header->len + pkt->pkt->payload_size,
pkt->timestamp,
pkt_data );
#elif HAVE_LIBPQ
snprintf ( query, sizeof ( query ), "INSERT INTO %s (alert_id, pkt_len, timestamp, content) "
"VALUES (%lu, %u, timestamp with time zone 'epoch' + %lu * interval '1 second', '%s')",
outdb_config[PACKET_STREAMS_TABLE],
latest_alert_id,
pkt->pkt->pcap_header->len + pkt->pkt->payload_size,
pkt->timestamp,
pkt_data );
#endif
DB_free_result ((DB_result) DB_out_query ( query ));
}

View File

@ -72,24 +72,54 @@ __postgresql_do_init ( PGconn **__DB, BOOL is_out )
snprintf ( conninfo, conninfo_max_length, "dbname=%s", config->outdbname );
if ( config->outdbuser )
sprintf ( conninfo, "%s user=%s", conninfo, config->outdbuser );
{
if ( strlen ( config->outdbuser ) != 0 )
{
sprintf ( conninfo, "%s user=%s", conninfo, config->outdbuser );
}
}
if ( config->outdbpass )
sprintf ( conninfo, "%s password=%s", conninfo, config->outdbpass );
{
if ( strlen ( config->outdbpass ) != 0 )
{
sprintf ( conninfo, "%s password=%s", conninfo, config->outdbpass );
}
}
if ( config->outdbhost )
sprintf ( conninfo, "%s hostaddr=%s", conninfo, config->outdbhost );
{
if ( strlen ( config->outdbhost ) != 0 )
{
sprintf ( conninfo, "%s hostaddr=%s", conninfo, config->outdbhost );
}
}
} else {
snprintf ( conninfo, conninfo_max_length, "dbname=%s", config->dbname );
if ( config->dbuser )
sprintf ( conninfo, "%s user=%s", conninfo, config->dbuser );
{
if ( strlen ( config->dbuser ) != 0 )
{
sprintf ( conninfo, "%s user=%s", conninfo, config->dbuser );
}
}
if ( config->dbpass )
sprintf ( conninfo, "%s password=%s", conninfo, config->dbpass );
{
if ( strlen ( config->dbpass ) != 0 )
{
sprintf ( conninfo, "%s password=%s", conninfo, config->dbpass );
}
}
if ( config->dbhost )
sprintf ( conninfo, "%s hostaddr=%s", conninfo, config->dbhost );
{
if ( strlen ( config->dbhost ) != 0 )
{
sprintf ( conninfo, "%s hostaddr=%s", conninfo, config->dbhost );
}
}
}
if ( PQstatus ( *__DB = PQconnectdb ( conninfo )) != CONNECTION_OK )
@ -108,10 +138,7 @@ __postgresql_do_query ( PGconn *__DB, const char *query )
AI_fatal_err ( "Fatal dynamic memory allocation error", __FILE__, __LINE__ );
if ( PQresultStatus ( res->res = PQexec( __DB, query )) != PGRES_TUPLES_OK )
{
PQfinish ( __DB );
return NULL;
}
ntuples = PQntuples ( res->res );
res->index = 0;

View File

@ -26,16 +26,15 @@ CREATE TABLE ca_tcp_headers (
primary key(tcp_hdr_id)
);
DROP TABLE IF EXISTS ca_packet_streams;
CREATE TABLE ca_packet_streams (
pkt_id integer auto_increment,
alert_id integer,
pkt_len integer,
timestamp datetime,
content longblob,
DROP TABLE IF EXISTS ca_clustered_alerts;
CREATE TABLE ca_clustered_alerts (
cluster_id integer auto_increment,
clustered_srcip varchar(255) default null,
clustered_dstip varchar(255) default null,
clustered_srcport varchar(255) default null,
clustered_dstport varchar(255) default null,
primary key(pkt_id),
foreign key(alert_id) references ca_alerts(alert_id)
primary key(cluster_id)
);
DROP TABLE IF EXISTS ca_alerts;
@ -48,8 +47,8 @@ CREATE TABLE ca_alerts (
description varchar(255),
classification varchar(255),
timestamp datetime,
ip_hdr integer,
tcp_hdr integer,
ip_hdr integer default 0,
tcp_hdr integer default 0,
cluster_id integer default 0,
primary key(alert_id),
@ -58,15 +57,16 @@ CREATE TABLE ca_alerts (
foreign key(cluster_id) references ca_clustered_alerts(cluster_id)
);
DROP TABLE IF EXISTS ca_clustered_alerts;
CREATE TABLE ca_clustered_alerts (
cluster_id integer auto_increment,
clustered_srcip varchar(255) default null,
clustered_dstip varchar(255) default null,
clustered_srcport varchar(255) default null,
clustered_dstport varchar(255) default null,
DROP TABLE IF EXISTS ca_packet_streams;
CREATE TABLE ca_packet_streams (
pkt_id integer auto_increment,
alert_id integer,
pkt_len integer,
timestamp datetime,
content longblob,
primary key(cluster_id)
primary key(pkt_id),
foreign key(alert_id) references ca_alerts(alert_id)
);
DROP TABLE IF EXISTS ca_correlated_alerts;

View File

@ -9,18 +9,20 @@ CREATE TABLE ca_ipv4_headers (
ip_src_addr varchar(32),
ip_dst_addr varchar(32)
);
INSERT INTO ca_ipv4_headers ( ip_hdr_id ) VALUES ( 0 );
DROP TABLE IF EXISTS ca_tcp_headers CASCADE;
CREATE TABLE ca_tcp_headers (
tcp_hdr_id serial primary key,
tcp_src_port integer,
tcp_dst_port integer,
tcp_seq integer,
tcp_ack integer,
tcp_seq bigint,
tcp_ack bigint,
tcp_flags integer,
tcp_window integer,
tcp_len integer
);
INSERT INTO ca_tcp_headers ( tcp_hdr_id ) VALUES ( 0 );
DROP TABLE IF EXISTS ca_clustered_alerts CASCADE;
CREATE TABLE ca_clustered_alerts (
@ -30,6 +32,7 @@ CREATE TABLE ca_clustered_alerts (
clustered_srcport varchar(255) default null,
clustered_dstport varchar(255) default null
);
INSERT INTO ca_clustered_alerts ( cluster_id ) VALUES ( 0 );
DROP TABLE IF EXISTS ca_alerts CASCADE;
CREATE TABLE ca_alerts (
@ -41,8 +44,8 @@ CREATE TABLE ca_alerts (
description varchar(255),
classification varchar(255),
timestamp timestamp,
ip_hdr integer references ca_ipv4_headers(ip_hdr_id),
tcp_hdr integer references ca_tcp_headers(tcp_hdr_id),
ip_hdr integer default 0 references ca_ipv4_headers(ip_hdr_id),
tcp_hdr integer default 0 references ca_tcp_headers(tcp_hdr_id),
cluster_id integer default 0 references ca_clustered_alerts(cluster_id)
);
@ -52,7 +55,7 @@ CREATE TABLE ca_packet_streams (
alert_id integer references ca_alerts(alert_id),
pkt_len integer,
timestamp timestamp,
content oid
content bytea
);
DROP TABLE IF EXISTS ca_correlated_alerts CASCADE;

View File

@ -663,9 +663,9 @@ static AI_config * AI_parse(char *args)
free ( match );
if ( !strlen ( config->dbhost ) || !strlen ( config->dbname ) || !strlen ( config->dbpass ) || !strlen ( config->dbuser ))
if ( !strlen ( config->dbname ))
{
AI_fatal_err ( "Database option used in config, but missing configuration option (all 'host', 'type', 'name', 'user', and 'password' option must be used)", __FILE__, __LINE__ );
AI_fatal_err ( "Database option used in config, but missing configuration option (at least 'type' and 'name' options must be used)", __FILE__, __LINE__ );
}
_dpd.logMsg(" Reading alerts from the database %s\n", config->dbname );
@ -759,9 +759,9 @@ static AI_config * AI_parse(char *args)
free ( match );
if ( !strlen ( config->outdbhost ) || !strlen ( config->outdbname ) || !strlen ( config->outdbpass ) || !strlen ( config->outdbuser ))
if ( !strlen ( config->outdbname ))
{
AI_fatal_err ( "Output database option used in config, but missing configuration option (all 'host', 'type', 'name', 'user', and 'password' options must be used)", __FILE__, __LINE__ );
AI_fatal_err ( "Output database option used in config, but missing configuration option (at least 'type' and 'name' options must be used)", __FILE__, __LINE__ );
}
AI_outdb_mutex_initialize();