(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

2
db.h
View file

@ -64,11 +64,13 @@
#define DB_num_rows postgresql_num_rows #define DB_num_rows postgresql_num_rows
#define DB_fetch_row postgresql_fetch_row #define DB_fetch_row postgresql_fetch_row
#define DB_free_result postgresql_free_result #define DB_free_result postgresql_free_result
#define DB_escape_string postgresql_do_escape_string
#define DB_close postgresql_do_close #define DB_close postgresql_do_close
#define DB_out_init postgresql_do_out_init #define DB_out_init postgresql_do_out_init
#define DB_is_out_init postgresql_is_out_init #define DB_is_out_init postgresql_is_out_init
#define DB_out_query postgresql_do_out_query #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 #define DB_out_close postgresql_do_out_close
int DB_num_rows ( PSQL_result *res ); int DB_num_rows ( PSQL_result *res );

55
outdb.c
View file

@ -71,8 +71,10 @@ AI_outdb_mutex_initialize ()
void* void*
AI_store_alert_to_db_thread ( void *arg ) AI_store_alert_to_db_thread ( void *arg )
{ {
char query[65535] = { 0 }; char query[65535] = { 0 },
char srcip[INET_ADDRSTRLEN], iphdr_id_str[20] = { 0 },
tcphdr_id_str[20] = { 0 },
srcip[INET_ADDRSTRLEN],
dstip[INET_ADDRSTRLEN]; dstip[INET_ADDRSTRLEN];
unsigned char *pkt_data = NULL; unsigned char *pkt_data = NULL;
@ -166,10 +168,24 @@ AI_store_alert_to_db_thread ( void *arg )
DB_free_result ( res ); 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 )); 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], outdb_config[ALERTS_TABLE],
((latest_ip_hdr_id != 0) ? ", ip_hdr" : ""),
((latest_tcp_hdr_id != 0) ? ", tcp_hdr" : ""),
alert->gid, alert->gid,
alert->sid, alert->sid,
alert->rev, alert->rev,
@ -177,8 +193,24 @@ AI_store_alert_to_db_thread ( void *arg )
((alert->desc) ? alert->desc : ""), ((alert->desc) ? alert->desc : ""),
((alert->classification) ? alert->classification : ""), ((alert->classification) ? alert->classification : ""),
alert->timestamp, alert->timestamp,
latest_ip_hdr_id, iphdr_id_str,
((alert->ip_proto == IPPROTO_TCP || alert->ip_proto == IPPROTO_UDP) ? latest_tcp_hdr_id : 0)); 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 )); 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 ); pkt->pkt->pcap_header->len + pkt->pkt->payload_size );
memset ( query, 0, sizeof ( query )); memset ( query, 0, sizeof ( query ));
#ifdef HAVE_LIBMYSQLCLIENT
snprintf ( query, sizeof ( query ), "INSERT INTO %s (alert_id, pkt_len, timestamp, content) " snprintf ( query, sizeof ( query ), "INSERT INTO %s (alert_id, pkt_len, timestamp, content) "
"VALUES (%lu, %u, from_unixtime('%lu'), '%s')", "VALUES (%lu, %u, from_unixtime('%lu'), '%s')",
outdb_config[PACKET_STREAMS_TABLE], 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->pkt->pcap_header->len + pkt->pkt->payload_size,
pkt->timestamp, pkt->timestamp,
pkt_data ); 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 )); DB_free_result ((DB_result) DB_out_query ( query ));
} }

View file

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

View file

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

View file

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

View file

@ -663,9 +663,9 @@ static AI_config * AI_parse(char *args)
free ( match ); 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 ); _dpd.logMsg(" Reading alerts from the database %s\n", config->dbname );
@ -759,9 +759,9 @@ static AI_config * AI_parse(char *args)
free ( match ); 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(); AI_outdb_mutex_initialize();