ossec-hids: config.c (NEW) db_op.c (NEW) db_op.h (NEW) dbd.h (NEW) rules.c (NEW) [dcid]

8 views
Skip to first unread message

OSSEC CVS

unread,
Aug 12, 2007, 10:14:19 PM8/12/07
to osse...@ossec.net

Module name: ossec-hids
Changes by: dcid 07/08/12 23:14:16

Added files:
config.c db_op.c db_op.h dbd.h rules.c

Log message:
Description: Adding new ossec_dbd daemon. Yes, yes, I got convinced :)

--- NEW FILE: config.c ---
/* @(#) $Id: config.c,v 1.1 2007/08/13 02:14:16 dcid Exp $ */

/* Copyright (C) 2003-2006 Daniel B. Cid <dc...@ossec.net>
* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation
*/


#include "dbd.h"
#include "config/global-config.h"
#include "config/config.h"


int OS_ReadDBConf(int test_config, char *cfgfile, DBConfig *db_config)
{
int modules = 0;
_Config *tmp_config;


/* Modules for the configuration */
modules|= CDBD;
modules|= CRULES;


/* Allocating config just to get the rules. */
os_calloc(1, sizeof(_Config), tmp_config);


/* Clearing configuration variables */
tmp_config->includes = NULL;
db_config->includes = NULL;
db_config->host = NULL;
db_config->user = NULL;
db_config->pass = NULL;
db_config->db = NULL;


/* Reading configuration */
if(ReadConfig(modules, cfgfile, tmp_config, db_config) < 0)
return(OS_INVALID);


/* Here, we assign the rules to db_config and free the rest
* of the Config.
*/
db_config->includes = tmp_config->includes;
free(tmp_config);

return(0);
}

/* EOF */

--- NEW FILE: db_op.c ---
/* @(#) $Id: db_op.c,v 1.1 2007/08/13 02:14:16 dcid Exp $ */

/* Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>
* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation.
*
* License details at the LICENSE file included with OSSEC or
* online at: http://www.ossec.net/en/licensing.html
*/

/* Common lib for dealing with databases */


#ifdef DBD
#include "shared.h"

/* Using Mysql */
#ifdef UMYSQL
#include <mysql.h>
#endif


/* Create the tree
* Return NULL on error
*/
void *osdb_connect(char *host, char *user, char *pass, char *db)
{
MYSQL *conn;
conn = mysql_init(NULL);
if (conn == NULL)
{
merror(DBINIT_ERROR, ARGV0);
return(NULL);
}
if(mysql_real_connect(conn, host, user, pass, db, 0, NULL, 0) == NULL)
{
merror(DBCONN_ERROR, ARGV0, host, db, mysql_error(conn));
mysql_close(conn);
return(NULL);
}

return(conn);
}


void osdb_close(void *db_conn)
{
mysql_close(db_conn);
}


int osdb_query(void *db_conn, char *query)
{
if(mysql_query(db_conn, query) != 0)
{
/* failure; report error */
merror(DBQUERY_ERROR, ARGV0, query, mysql_error(db_conn));
return(0);
}

return(1);
}


#endif /* DBD */

/* EOF */

--- NEW FILE: db_op.h ---
/* @(#) $Id: db_op.h,v 1.1 2007/08/13 02:14:16 dcid Exp $ */

/* Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>
* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation.
*
* License details at the LICENSE file included with OSSEC or
* online at: http://www.ossec.net/en/licensing.html
*/

/* Common API for dealing with databases */


#ifndef _OS_DBOP_H
#define _OS_DBOP_H


/* Connects to the database */
void *osdb_connect(char *host, char *user, char *pass, char *db);
int osdb_query(void *db_conn, char *query);


#endif

/* EOF */

--- NEW FILE: dbd.h ---
/* @(#) $Id: dbd.h,v 1.1 2007/08/13 02:14:16 dcid Exp $ */

/* Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>
* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation.
*
* License details at the LICENSE file included with OSSEC or
* online at: http://www.ossec.net/en/licensing.html
*/


#ifndef _DBD_H
#define _DBD_H


#include "shared.h"
#include "db_op.h"
#include "config/dbd-config.h"


/** Prototypes **/

/* Read database config */
int OS_ReadDBConf(int test_config, char *cfgfile, DBConfig *db_config);


/* Insert rules in to the database */
int OS_InsertRulesDB(DBConfig *db_config);


/* Database inserting main function */
void OS_DBD(DBConfig *db_config);

#endif

--- NEW FILE: rules.c ---
/* @(#) $Id: rules.c,v 1.1 2007/08/13 02:14:16 dcid Exp $ */

/* Copyright (C) 2003-2006 Daniel B. Cid <dc...@ossec.net>
* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation
*/


#include "dbd.h"
#include "config/config.h"
#include "rules_op.h"


void *_Rules_ReadInsertDB(RuleInfo *rule, void *db_config)
{
DBConfig *dbc = (DBConfig *)db_config;
char sql_query[OS_SIZE_1024];
memset(sql_query, '\0', OS_SIZE_1024);


merror("XXX inserting: %d", rule->sigid);


/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,
"INSERT INTO "
"signature(id, rule_id, level, category, description) "
"VALUES (NULL, '%u','%u','%s','%s') "
"ON DUPLICATE KEY UPDATE level='%u'",
rule->sigid, rule->level, rule->group, rule->comment,
rule->level);

if(!osdb_query(dbc->conn, sql_query))
{
merror(DB_MAINERROR, ARGV0);
}

return(NULL);
}


int OS_InsertRulesDB(DBConfig *db_config)
{
char **rulesfiles;

rulesfiles = db_config->includes;
while(rulesfiles && *rulesfiles)
{
debug1("%s: Reading rules file: '%s'", ARGV0, *rulesfiles);

if(OS_ReadXMLRules(*rulesfiles, _Rules_ReadInsertDB, db_config) < 0)
{
merror(RULES_ERROR, ARGV0, *rulesfiles);
return(-1);
}

free(*rulesfiles);
rulesfiles++;
}

free(db_config->includes);
db_config->includes = NULL;


return(0);
}


/* EOF */

OSSEC CVS

unread,
Aug 13, 2007, 8:29:37 PM8/13/07
to osse...@ossec.net
Module name: ossec-hids
Changes by: dcid 07/08/13 21:29:34

Modified files:
config.c db_op.c db_op.h rules.c
Added files:
Makefile dbd.c main.c mysql.schema

Log message:
Description: Working alpha of the database support. the basic stuff should be working now, but we still need to improve the tables and a few other things.
Reviewed by: dcid
Example config:
<database_output>
<hostname>1.2.3.4</hostname>
<username>user</username>
<password>mypass</password>
<database>test1</database>
</database_output>
Bug:

--- NEW FILE: Makefile ---
# Makefile for dbd
# Daniel B. Cid <dc...@ossec.net>

PT=../
NAME=ossec-dbd
DBFLAGS=-I/usr/local/include/mysql -L/usr/local/lib/mysql -lmysqlclient

include ../Config.Make

LOCAL = *.c

OBJS = ${OS_CONFIG} ${OS_SHARED} ${OS_NET} ${OS_REGEX} ${OS_XML}

dbd:
${CC} ${CFLAGS} ${DBFLAGS} -DDBD -DUMYSQL ${LOCAL} ${OBJS} -o ${NAME}
clean:
${CLEAN}
build:
${BUILD}

--- NEW FILE: dbd.c ---
/* @(#) $Id: dbd.c,v 1.1 2007/08/14 00:29:34 dcid Exp $ */

/* Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>
* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation.
*
* License details at the LICENSE file included with OSSEC or
* online at: http://www.ossec.net/en/licensing.html
*/


#ifndef DBD
#define DBD
#endif

#ifndef ARGV0
#define ARGV0 "ossec-dbd"
#endif

#include "shared.h"
#include "dbd.h"

/* OS_DBD: Monitor the alerts and insert them into the database.
* Only return in case of error.
*/
void OS_DBD(DBConfig *db_config)
{
unsigned int s_ip, d_ip;

time_t tm;
struct tm *p;

char sql_query[OS_SIZE_2048 +1];
file_queue *fileq;
alert_data *al_data;


/* Getting currently time before starting */
tm = time(NULL);
p = localtime(&tm);


/* Initating file queue - to read the alerts */
os_calloc(1, sizeof(file_queue), fileq);
Init_FileQueue(fileq, p, 0);


memset(sql_query, '\0', OS_SIZE_2048 +1);


/* Infinite loop reading the alerts and inserting them. */
while(1)
{
tm = time(NULL);
p = localtime(&tm);

s_ip = 0;
d_ip = 0;


/* Get message if available (timeout of 5 seconds) */
al_data = Read_FileMon(fileq, p, 5);
if(!al_data)
{
continue;
}


debug2("%s: DEBUG: Got data: %d, %d, %s, %s",
ARGV0,
al_data->rule,
al_data->level,
al_data->location,
al_data->group);


/* Converting srcip to int */
if(al_data->srcip)
{
struct in_addr net;

/* Extracting ip address */
if(inet_aton(al_data->srcip, &net))
{
debug2("%s: DEBUG: found ip: %u for %s", ARGV0, net.s_addr,
al_data->srcip);
s_ip = net.s_addr;
}
}

/* Escaping strings */
osdb_escapestr(al_data->user);
osdb_escapestr(al_data->log[0]);

/* Generating SQL */
snprintf(sql_query, OS_SIZE_2048,
"INSERT INTO "
"alert(id,signature_id,timestamp,src_ip,user,full_log) "
"VALUES (NULL, '%u','%u','%lu', '%s', '%s') ",
al_data->rule, time(0),
(unsigned long)ntohl(s_ip), al_data->user,
al_data->log[0]);


/* Inserting into the db */
if(!osdb_query(db_config->conn, sql_query))
{
merror(DB_MAINERROR, ARGV0);
}


/* Clearing the memory */
FreeAlertData(al_data);
}
}

/* EOF */

--- NEW FILE: main.c ---
/* @(#) $Id: main.c,v 1.1 2007/08/14 00:29:34 dcid Exp $ */

/* Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>
* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation.
*
* License details at the LICENSE file included with OSSEC or
* online at: http://www.ossec.net/en/licensing.html
*/


#ifndef DBD
#define DBD
#endif

#ifndef ARGV0
#define ARGV0 "ossec-dbd"
#endif

#include "shared.h"
#include "dbd.h"

int main(int argc, char **argv)
{
int c, test_config = 0;
int uid = 0,gid = 0;

/* Using MAILUSER (read only) */
char *dir = DEFAULTDIR;
char *user = MAILUSER;
char *group = GROUPGLOBAL;
char *cfg = DEFAULTCPATH;


/* Database Structure */
DBConfig db_config;


/* Setting the name */
OS_SetName(ARGV0);

while((c = getopt(argc, argv, "Vdhtu:g:D:c:")) != -1){
switch(c){
case 'V':
print_version();
break;
case 'h':
help();
break;
case 'd':
nowDebug();
break;
case 'u':
if(!optarg)
ErrorExit("%s: -u needs an argument",ARGV0);
user=optarg;
break;
case 'g':
if(!optarg)
ErrorExit("%s: -g needs an argument",ARGV0);
group=optarg;
break;
case 'D':
if(!optarg)
ErrorExit("%s: -D needs an argument",ARGV0);
dir=optarg;
case 'c':
if(!optarg)
ErrorExit("%s: -c needs an argument",ARGV0);
cfg = optarg;
break;
case 't':
test_config = 1;
break;
default:
help();
break;
}

}


/* Starting daemon */
debug1(STARTED_MSG, ARGV0);


/* Check if the user/group given are valid */
uid = Privsep_GetUser(user);
gid = Privsep_GetGroup(group);
if((uid < 0)||(gid < 0))
{
ErrorExit(USER_ERROR, ARGV0, user, group);
}


/* Reading configuration */
if(OS_ReadDBConf(test_config, cfg, &db_config) < 0)
{
ErrorExit(CONFIG_ERROR, ARGV0, cfg);
}


/* Maybe disable this debug? */
debug1("%s: DEBUG: Connecting to '%s', using '%s', '%s', '%s'.",
ARGV0, db_config.host, db_config.user,
db_config.pass, db_config.db);


/* Connecting to the database */
db_config.conn = osdb_connect(db_config.host, db_config.user,
db_config.pass, db_config.db);
if(!db_config.conn)
{
merror(DB_CONFIGERR, ARGV0);
ErrorExit(CONFIG_ERROR, ARGV0, cfg);
}


/* Going on daemon mode */
if(!test_config)
{
nowDaemon();
goDaemon();
}


/* Privilege separation */
if(Privsep_SetGroup(gid) < 0)
ErrorExit(SETGID_ERROR,ARGV0,group);


/* chrooting */
if(Privsep_Chroot(dir) < 0)
ErrorExit(CHROOT_ERROR,ARGV0,dir);


/* Now on chroot */
nowChroot();


/* Read rules and insert into the db */
if(OS_InsertRulesDB(&db_config) < 0)
{
ErrorExit(CONFIG_ERROR, ARGV0, cfg);
}


/* Exit here if test config is set */
if(test_config)
exit(0);


/* Changing user */
if(Privsep_SetUser(uid) < 0)
ErrorExit(SETUID_ERROR,ARGV0,user);


/* Basic start up completed. */
debug1(PRIVSEP_MSG,ARGV0,dir,user);


/* Signal manipulation */
StartSIG(ARGV0);


/* Creating PID files */
if(CreatePID(ARGV0, getpid()) < 0)
ErrorExit(PID_ERROR,ARGV0);


/* Start up message */
verbose(STARTUP_MSG, ARGV0, getpid());

/* the real daemon now */
OS_DBD(&db_config);
exit(0);
}


/* EOF */

--- NEW FILE: mysql.schema ---
CREATE TABLE category
(
cat_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
cat_name VARCHAR(32) NOT NULL UNIQUE,
PRIMARY KEY (cat_id),
INDEX (cat_name)
);

CREATE TABLE signature
(
id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
rule_id MEDIUMINT UNSIGNED NOT NULL UNIQUE,
level TINYINT UNSIGNED,
category VARCHAR(64) NOT NULL,
description VARCHAR(255) NOT NULL,
PRIMARY KEY (id),
INDEX (level),
INDEX (rule_id)
);

CREATE TABLE alert
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
signature_id SMALLINT UNSIGNED NOT NULL,
timestamp INT UNSIGNED NOT NULL,
src_ip INT UNSIGNED,
dst_ip INT UNSIGNED,
src_port SMALLINT UNSIGNED,
dst_port SMALLINT UNSIGNED,
user VARCHAR(32),
full_log VARCHAR(255),
PRIMARY KEY (id,signature_id),
INDEX time (timestamp),
INDEX (src_ip)
);

Index: config.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/config.c,v
diff -u -r1.1 -r1.2
--- config.c 13 Aug 2007 02:14:16 -0000 1.1
+++ config.c 14 Aug 2007 00:29:34 -0000 1.2
@@ -49,6 +49,18 @@


*/
db_config->includes = tmp_config->includes;
free(tmp_config);

+
+
+ /* Checking for a valid config. */
+ if(!db_config->host ||
+ !db_config->user ||
+ !db_config->pass ||
+ !db_config->db)
+ {
+ merror(DB_MISS_CONFIG, ARGV0);
+ return(OS_INVALID);
+ }
+

return(0);
}

Index: db_op.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/db_op.c,v
diff -u -r1.1 -r1.2
--- db_op.c 13 Aug 2007 02:14:16 -0000 1.1
+++ db_op.c 14 Aug 2007 00:29:34 -0000 1.2
@@ -18,6 +18,7 @@

#ifdef DBD
#include "shared.h"
+#include "db_op.h"



/* Using Mysql */
#ifdef UMYSQL

@@ -25,6 +26,28 @@
#endif


+/** void osdb_escapestr
+ * Escapes a null terminated string before inserting into the database.
+ * We built a white list of allowed characters at insert_map. Everything
+ * not allowed will become spaces.
+ */
+void osdb_escapestr(char *str)
+{
+ while(*str)
+ {
+ if(*str == '\'')
+ {
+ *str = '`';
+ }
+ else if(insert_map[(unsigned char)*str] != '\001')
+ {
+ *str = ' ';
+ }
+ str++;
+ }
+}
+
+


/* Create the tree
* Return NULL on error
*/

@@ -54,6 +77,9 @@
}


+/** int osdb_query(void *db_conn, char *query)
+ * Sends query to database.
+ */


int osdb_query(void *db_conn, char *query)
{
if(mysql_query(db_conn, query) != 0)

Index: db_op.h
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/db_op.h,v
diff -u -r1.1 -r1.2
--- db_op.h 13 Aug 2007 02:14:16 -0000 1.1
+++ db_op.h 14 Aug 2007 00:29:34 -0000 1.2
@@ -21,7 +21,55 @@



/* Connects to the database */
void *osdb_connect(char *host, char *user, char *pass, char *db);

+
+/* Queries the database */
int osdb_query(void *db_conn, char *query);
+
+/* escape strings before inserting. */
+void osdb_escapestr(char *str);
+
+
+/* Allowed characters */
+/* Insert charmap.
+ * Available chars: a-z, A-Z, 0-9, -, _, ., %, $, @, (, ), +, *, <space> /
+ * Basically: 040-046 (oct)
+ * 050-176 (oct)
+ */
+static const unsigned char insert_map[] =
+{
+ '\000', '\000', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\047',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\001',
+ '\001', '\001', '\001', '\001', '\001', '\001', '\001', '\177',
+ '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
+ '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
+ '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+ '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+ '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
+ '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
+ '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
+ '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
+ '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
+ '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
+ '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
+ '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+};


#endif

Index: rules.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/rules.c,v
diff -u -r1.1 -r1.2
--- rules.c 13 Aug 2007 02:14:16 -0000 1.1
+++ rules.c 14 Aug 2007 00:29:34 -0000 1.2
@@ -22,7 +22,28 @@
memset(sql_query, '\0', OS_SIZE_1024);


- merror("XXX inserting: %d", rule->sigid);
+ /* Escaping strings */
+ osdb_escapestr(rule->group);
+ osdb_escapestr(rule->comment);
+
+
+ /* Checking level limit */
+ if(rule->level > 20)
+ rule->level = 20;
+ if(rule->level < 0)
+ rule->level = 0;
+
+
+
+ /* Checking rule limit */
+ if(rule->sigid < 0 || rule->sigid > 9999999)
+ {
+ merror("%s: Invalid rule id: %u", rule->sigid);
+ return(NULL);
+ }
+
+
+ debug2("%s: DEBUG: Inserting: %d", ARGV0, rule->sigid);


/* Generating SQL */
@@ -34,6 +55,8 @@


rule->sigid, rule->level, rule->group, rule->comment,
rule->level);

+
+ /* Checking return code. */

OSSEC CVS

unread,
Aug 17, 2007, 9:07:53 PM8/17/07
to osse...@ossec.net
Module name: ossec-hids
Changes by: dcid 07/08/17 22:07:50

Modified files:
Makefile db_op.c db_op.h dbd.c dbd.h main.c mysql.schema rules.c
Added files:
server.c

Log message:
Description: Improving the db schema, adding servers information ,etc. Still not ready to be used yet. Some fixes to the windows application list by mdmonk.
Reviewed by: dcid
Bug:

--- NEW FILE: server.c ---
/* @(#) $Id: server.c,v 1.1 2007/08/18 01:07:49 dcid Exp $ */

/* Copyright (C) 2003-2006 Daniel B. Cid <dc...@ossec.net>


* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation

*
* License details at the LICENSE file included with OSSEC or
* online at: http://www.ossec.net/en/licensing.html
*/

#include "dbd.h"
#include "config/config.h"
#include "rules_op.h"


/** int __DBSelectServer(char *server, DBConfig *db_config)
* Selects the server ID from the db.
* Returns 0 if not found.
*/
int __DBSelectServer(char *server, DBConfig *db_config)
{
int result = 0;
char sql_query[OS_SIZE_1024];

memset(sql_query, '\0', OS_SIZE_1024);


/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,
"SELECT id FROM "
"server WHERE hostname = '%s'",
server);


/* Checking return code. */

result = osdb_query_select(db_config->conn, sql_query);

return(result);
}


/** int __DBInsertServer(char *server, char *info, DBConfig *db_config)
* Inserts server in to the db.
*/
int __DBInsertServer(char *server, char *info, DBConfig *db_config)
{


char sql_query[OS_SIZE_1024];

memset(sql_query, '\0', OS_SIZE_1024);

/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,
"INSERT INTO "
"server(id, last_contact, version, hostname, information) "
"VALUES (NULL, '%u', '%s', '%s', '%s') ON DUPLICATE KEY UPDATE "
"last_contact='%u',version='%s',information='%s'",
time(0), __version, server, info, time(0), __version, info);


/* Checking return code. */

if(!osdb_query_insert(db_config->conn, sql_query))
{
merror(DB_MAINERROR, ARGV0);
}

return(0);
}

/** int OS_Server_ReadInsertDB(void *db_config)
* Insert server info to the db.
* Returns server ID or 0 on error.
*/
int OS_Server_ReadInsertDB(void *db_config)
{
int server_id = 0;
char *info;


/* Getting servers hostname */
memset(__shost, '\0', 512);
memset(info, '\0', 512);
if(gethostname(__shost, 512 -1) != 0)
{
merror("%s: Error: gethostname() failed", ARGV0);
return(0);
}


/* Getting system uname */
info = getuname();
if(!info)
{
merror(MEM_ERROR, ARGV0);
return(0);
}


/* Escaping strings */
osdb_escapestr(info);
osdb_escapestr(__shost);


/* Inserting server */
__DBInsertServer(__shost, info, (DBConfig *)db_config);


/* Getting server id */
server_id = __DBSelectServer(__shost, (DBConfig *)db_config);


return(server_id);
}


/* EOF */

Index: Makefile
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/Makefile,v
diff -u -r1.1 -r1.2
--- Makefile 14 Aug 2007 00:29:34 -0000 1.1
+++ Makefile 18 Aug 2007 01:07:49 -0000 1.2
@@ -3,16 +3,33 @@

PT=../
NAME=ossec-dbd
-DBFLAGS=-I/usr/local/include/mysql -L/usr/local/lib/mysql -lmysqlclient
+
+# Uncomment the following if you know what you are doing.
+#DBFLAGS=-I/usr/local/include/mysql -L/usr/local/lib/mysql -lmysqlclient



include ../Config.Make

LOCAL = *.c

+
+# Getting database cflags
+DBCHECK = `./dbmake.sh`
+DBMYSQL = `./dbmake.sh mysql 2> /dev/null`
+DBPOSTGRES = `./dbmake.sh postgres 2> /dev/null`
+
+


OBJS = ${OS_CONFIG} ${OS_SHARED} ${OS_NET} ${OS_REGEX} ${OS_XML}

-dbd:
- ${CC} ${CFLAGS} ${DBFLAGS} -DDBD -DUMYSQL ${LOCAL} ${OBJS} -o ${NAME}
+default:
+ @if [ "X${DBMYSQL}" = "X" -a "X${DBPOSTGRES}" = "X" ]; then ./dbmake.sh mysql; exit 1; fi;
+ @echo "Compiling DB support with: ${DBMYSQL} ${DBPOSTGRES}"
+ ${CC} ${CFLAGS} ${DBFLAGS} ${DBMYSQL} ${DBPOSTGRES} ${LOCAL} ${OBJS} -o ${NAME}
+mysql:
+ @if [ "X${DBMYSQL}" = "X" ]; then ./dbmake.sh mysql; exit 1; fi;
+ @echo "Compiling MySQL DB support with: ${DBVAL}"
+ ${CC} ${CFLAGS} ${DBFLAGS} ${DBVAL} ${LOCAL} ${OBJS} -o ${NAME}
+postgres:
+ ${CC} ${CFLAGS} ${DBFLAGS} -DDBD -DUPOSTGRES ${LOCAL} ${OBJS} -o ${NAME}
clean:
${CLEAN}
build:

Index: db_op.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/db_op.c,v
diff -u -r1.2 -r1.3
--- db_op.c 14 Aug 2007 00:29:34 -0000 1.2
+++ db_op.c 18 Aug 2007 01:07:49 -0000 1.3
@@ -45,6 +45,12 @@
}
str++;
}
+
+ /* It can not end with \\ */
+ if(*(str -1) == '\\')
+ {
+ *(str-1) = '\0';
+ }
}


@@ -77,10 +83,10 @@
}


-/** int osdb_query(void *db_conn, char *query)
- * Sends query to database.
+/** int osdb_query_insert(void *db_conn, char *query)
+ * Sends insert query to database.
*/
-int osdb_query(void *db_conn, char *query)
+int osdb_query_insert(void *db_conn, char *query)
{
if(mysql_query(db_conn, query) != 0)
{
@@ -93,6 +99,52 @@
}


+
+/** int osdb_query_select(void *db_conn, char *query)
+ * Sends a select query to database. Returns the value of it.
+ * Returns 0 on error (not found).
+ */
+int osdb_query_select(void *db_conn, char *query)
+{
+ int result_int = 0;
+ MYSQL_RES *result_data;
+ MYSQL_ROW result_row;
+
+ /* Sending the query. It can not fail. */
+ if(mysql_query(db_conn, query) != 0)
+ {
+ /* failure; report error */
+ merror(DBQUERY_ERROR, ARGV0, query, mysql_error(db_conn));
+ return(0);
+ }
+
+
+ /* Getting result */
+ result_data = mysql_use_result(db_conn);
+ if(result_data == NULL)
+ {
+ /* failure; report error */
+ merror(DBQUERY_ERROR, ARGV0, query, mysql_error(db_conn));
+ return(0);
+ }
+
+
+ /* Getting row. We only care about the first result. */
+ result_row = mysql_fetch_row(result_data);
+ if(result_row[0] != NULL)
+ {
+ result_int = atoi(result_row[0]);
+ }
+
+ mysql_free_result(result_data);
+
+
+ return(result_int);
+}
+
+
#endif /* DBD */
+
+

/* EOF */

Index: db_op.h
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/db_op.h,v

diff -u -r1.2 -r1.3
--- db_op.h 14 Aug 2007 00:29:34 -0000 1.2
+++ db_op.h 18 Aug 2007 01:07:49 -0000 1.3
@@ -22,8 +22,11 @@


/* Connects to the database */
void *osdb_connect(char *host, char *user, char *pass, char *db);

-/* Queries the database */
-int osdb_query(void *db_conn, char *query);
+/* Sends insert query to the database */
+int osdb_query_insert(void *db_conn, char *query);
+
+/* Sends select query to the database */
+int osdb_query_select(void *db_conn, char *query);



/* escape strings before inserting. */

void osdb_escapestr(char *str);

Index: dbd.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/dbd.c,v
diff -u -r1.1 -r1.2
--- dbd.c 14 Aug 2007 00:29:34 -0000 1.1
+++ dbd.c 18 Aug 2007 01:07:49 -0000 1.2
@@ -100,6 +100,9 @@
osdb_escapestr(al_data->log[0]);


+ /* We first need to insert the location */
+
+


/* Generating SQL */
snprintf(sql_query, OS_SIZE_2048,
"INSERT INTO "

@@ -111,7 +114,7 @@




/* Inserting into the db */

- if(!osdb_query(db_config->conn, sql_query))
+ if(!osdb_query_insert(db_config->conn, sql_query))
{
merror(DB_MAINERROR, ARGV0);
}

Index: dbd.h
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/dbd.h,v
diff -u -r1.1 -r1.2
--- dbd.h 13 Aug 2007 02:14:16 -0000 1.1
+++ dbd.h 18 Aug 2007 01:07:49 -0000 1.2
@@ -28,11 +28,23 @@
int OS_ReadDBConf(int test_config, char *cfgfile, DBConfig *db_config);


+/* Inserts server info to the db. */
+int OS_Server_ReadInsertDB(void *db_config);
+
+


/* Insert rules in to the database */
int OS_InsertRulesDB(DBConfig *db_config);


/* Database inserting main function */
void OS_DBD(DBConfig *db_config);

+
+
+
+/** Global vars **/
+
+/* System hostname */
+char __shost[512];
+

#endif

Index: main.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/main.c,v
diff -u -r1.1 -r1.2
--- main.c 14 Aug 2007 00:29:34 -0000 1.1
+++ main.c 18 Aug 2007 01:07:49 -0000 1.2
@@ -145,6 +145,14 @@
nowChroot();


+ /* Inserting server info into the db */
+ db_config.server_id = OS_Server_ReadInsertDB(&db_config);
+ if(db_config.server_id <= 0)
+ {
+ ErrorExit(CONFIG_ERROR, ARGV0, cfg);
+ }
+
+


/* Read rules and insert into the db */
if(OS_InsertRulesDB(&db_config) < 0)
{

Index: mysql.schema
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/mysql.schema,v
diff -u -r1.1 -r1.2
--- mysql.schema 14 Aug 2007 00:29:34 -0000 1.1
+++ mysql.schema 18 Aug 2007 01:07:49 -0000 1.2
@@ -1,7 +1,7 @@


CREATE TABLE category
(
cat_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,

- cat_name VARCHAR(32) NOT NULL UNIQUE,
+ cat_name VARCHAR(32) NOT NULL UNIQUE,


PRIMARY KEY (cat_id),
INDEX (cat_name)
);

@@ -11,25 +11,71 @@


id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
rule_id MEDIUMINT UNSIGNED NOT NULL UNIQUE,
level TINYINT UNSIGNED,

- category VARCHAR(64) NOT NULL,


description VARCHAR(255) NOT NULL,
PRIMARY KEY (id),
INDEX (level),
INDEX (rule_id)
);

+CREATE TABLE signature_category_mapping
+ (
+ id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
+ rule_id MEDIUMINT UNSIGNED NOT NULL,
+ cat_id SMALLINT UNSIGNED NOT NULL,
+ PRIMARY KEY (id, rule_id, cat_id)
+ );
+
+CREATE TABLE server
+ (
+ id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
+ last_contact INT UNSIGNED NOT NULL,
+ version VARCHAR(32) NOT NULL,
+ hostname VARCHAR(64) NOT NULL UNIQUE,
+ information VARCHAR(128) NOT NULL,
+ PRIMARY KEY (id)
+ );
+
+CREATE TABLE agent
+ (
+ id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
+ server_id SMALLINT UNSIGNED NOT NULL,
+ last_contact INT UNSIGNED NOT NULL,
+ ip_address INT UNSIGNED NOT NULL,
+ version VARCHAR(32) NOT NULL,
+ name VARCHAR(64) NOT NULL,
+ information VARCHAR(128) NOT NULL,
+ PRIMARY KEY (id, server_id)
+ );
+
+CREATE TABLE location
+ (
+ id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
+ server_id SMALLINT UNSIGNED NOT NULL,
+ name VARCHAR(128) NOT NULL,
+ PRIMARY KEY (id, server_id)
+ );
+
+CREATE TABLE data
+ (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ user TEXT NOT NULL,
+ full_log TEXT NOT NULL
+ PRIMARY KEY (id)
+ );
+

CREATE TABLE alert
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,

- signature_id SMALLINT UNSIGNED NOT NULL,
+ server_id SMALLINT UNSIGNED NOT NULL,
+ rule_id SMALLINT UNSIGNED NOT NULL,

timestamp INT UNSIGNED NOT NULL,

+ location_id SMALLINT UNSIGNED NOT NULL,


src_ip INT UNSIGNED,
dst_ip INT UNSIGNED,
src_port SMALLINT UNSIGNED,
dst_port SMALLINT UNSIGNED,

- user VARCHAR(32),
- full_log VARCHAR(255),
- PRIMARY KEY (id,signature_id),
+ PRIMARY KEY (id,rule_id),


INDEX time (timestamp),
INDEX (src_ip)
);

+

Index: rules.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/rules.c,v

diff -u -r1.2 -r1.3
--- rules.c 14 Aug 2007 00:29:34 -0000 1.2
+++ rules.c 18 Aug 2007 01:07:49 -0000 1.3
@@ -1,12 +1,15 @@
/* @(#) $Id$ */

-/* Copyright (C) 2003-2006 Daniel B. Cid <dc...@ossec.net>
+/* Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>


* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation

+ *
+ * License details at the LICENSE file included with OSSEC or
+ * online at: http://www.ossec.net/en/licensing.html
*/


@@ -15,6 +18,195 @@
#include "rules_op.h"


+
+/** int __Groups_SelectGroup(char *group, DBConfig *db_config)
+ * Select group (categories) from to the db.
+ * Returns 0 if not found.
+ */
+int __Groups_SelectGroup(char *group, DBConfig *db_config)
+{
+ int result = 0;
+ char sql_query[OS_SIZE_1024];
+
+ memset(sql_query, '\0', OS_SIZE_1024);
+
+
+ /* Generating SQL */
+ snprintf(sql_query, OS_SIZE_1024 -1,
+ "SELECT cat_id FROM "
+ "category WHERE cat_name = '%s'",
+ group);
+
+
+ /* Checking return code. */
+ result = osdb_query_select(db_config->conn, sql_query);
+
+ return(result);
+}
+
+
+/** int __Groups_InsertGroup(char *group, DBConfig *db_config)
+ * Insert group (categories) in to the db.
+ */
+int __Groups_InsertGroup(char *group, DBConfig *db_config)
+{
+ char sql_query[OS_SIZE_1024];
+
+ memset(sql_query, '\0', OS_SIZE_1024);
+
+ /* Generating SQL */
+ snprintf(sql_query, OS_SIZE_1024 -1,
+ "INSERT INTO "
+ "category(cat_id, cat_name) "
+ "VALUES (NULL, '%s')",
+ group);
+
+
+ /* Checking return code. */
+ if(!osdb_query_insert(db_config->conn, sql_query))
+ {
+ merror(DB_MAINERROR, ARGV0);
+ }
+
+ return(0);
+}
+
+
+/** int __Groups_SelectGroupMapping()
+ * Select group (categories) from to the db.
+ * Returns 0 if not found.
+ */
+int __Groups_SelectGroupMapping(int cat_id, int rule_id, DBConfig *db_config)
+{
+ int result = 0;
+ char sql_query[OS_SIZE_1024];
+
+ memset(sql_query, '\0', OS_SIZE_1024);
+
+
+ /* Generating SQL */
+ snprintf(sql_query, OS_SIZE_1024 -1,
+ "SELECT id FROM signature_category_mapping "
+ "WHERE cat_id = '%u' AND rule_id = '%u'",
+ cat_id, rule_id);
+
+
+ /* Checking return code. */
+ result = osdb_query_select(db_config->conn, sql_query);
+
+ return(result);
+}
+
+
+/** int __Groups_InsertGroup(int cat_id, int rule_id, DBConfig *db_config)
+ * Insert group (categories) in to the db.
+ */
+int __Groups_InsertGroupMapping(int cat_id, int rule_id, DBConfig *db_config)
+{
+ char sql_query[OS_SIZE_1024];
+
+ memset(sql_query, '\0', OS_SIZE_1024);
+
+ /* Generating SQL */
+ snprintf(sql_query, OS_SIZE_1024 -1,
+ "INSERT INTO "
+ "signature_category_mapping(id, cat_id, rule_id) "
+ "VALUES (NULL, '%u', '%u')",
+ cat_id, rule_id);
+
+
+ /* Checking return code. */
+ if(!osdb_query_insert(db_config->conn, sql_query))
+ {
+ merror(DB_MAINERROR, ARGV0);
+ }
+
+ return(0);
+}
+
+
+
+/** void *_Groups_ReadInsertDB(RuleInfo *rule, DBConfig *db_config)
+ * Insert groups (categories) in to the db.
+ */
+void *_Groups_ReadInsertDB(RuleInfo *rule, DBConfig *db_config)
+{
+ /* We must insert each group separately. */
+ int cat_id;
+ char *tmp_group;
+ char *tmp_str;
+
+ tmp_str = strchr(rule->group, ',');
+ tmp_group = rule->group;
+
+
+ /* Groups are separated by comma */
+ while(tmp_group)
+ {
+ if(tmp_str)
+ {
+ *tmp_str = '\0';
+ tmp_str++;
+ }
+
+ /* Removing white spaces */
+ while(*tmp_group == ' ')
+ tmp_group++;
+
+
+ /* Checking for empty group */
+ if(*tmp_group == '\0')
+ {
+ tmp_group = tmp_str;
+ if(tmp_group)
+ {
+ tmp_str = strchr(tmp_group, ',');
+ }
+ continue;
+ }
+
+ cat_id = __Groups_SelectGroup(tmp_group, db_config);
+
+
+ /* We firt check if we have this group in the db already.
+ * If not, we add it.
+ */
+ if(cat_id == 0)
+ {
+ __Groups_InsertGroup(tmp_group, db_config);
+ cat_id = __Groups_SelectGroup(tmp_group, db_config);
+ }
+
+
+ /* If our cat_id is valid (not zero), we need to insert
+ * the mapping between the category and the rule. */
+ if(cat_id != 0)
+ {
+ /* But, we first check if the mapping is already not there. */
+ if(!__Groups_SelectGroupMapping(cat_id, rule->sigid, db_config))
+ {
+ /* If not, we add it */
+ __Groups_InsertGroupMapping(cat_id, rule->sigid, db_config);
+ }
+ }
+
+
+ /* Getting next category */
+ tmp_group = tmp_str;
+ if(tmp_group)
+ {
+ tmp_str = strchr(tmp_group, ',');
+ }
+ }
+

+ return(NULL);
+}
+
+
+

+/** void *_Rules_ReadInsertDB(RuleInfo *rule, void *db_config)
+ * Insert rules in to the db.
+ */


void *_Rules_ReadInsertDB(RuleInfo *rule, void *db_config)
{
DBConfig *dbc = (DBConfig *)db_config;

@@ -42,6 +234,11 @@
return(NULL);
}

+
+ /* Inserting group into the signature mapping */
+ _Groups_ReadInsertDB(rule, db_config);


+
+

debug2("%s: DEBUG: Inserting: %d", ARGV0, rule->sigid);

@@ -49,15 +246,15 @@
/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,
"INSERT INTO "
- "signature(id, rule_id, level, category, description) "
- "VALUES (NULL, '%u','%u','%s','%s') "
+ "signature(id, rule_id, level, description) "
+ "VALUES (NULL, '%u','%u','%s') "


"ON DUPLICATE KEY UPDATE level='%u'",

- rule->sigid, rule->level, rule->group, rule->comment,
+ rule->sigid, rule->level, rule->comment,
rule->level);




/* Checking return code. */

- if(!osdb_query(dbc->conn, sql_query))
+ if(!osdb_query_insert(dbc->conn, sql_query))
{
merror(DB_MAINERROR, ARGV0);
}

OSSEC CVS

unread,
Aug 17, 2007, 11:38:37 PM8/17/07
to osse...@ossec.net
Module name: ossec-hids
Changes by: dcid 07/08/18 00:38:35

Modified files:
db_op.c dbd.c dbd.h main.c mysql.schema rules.c server.c
Added files:
README alert.c

Log message:
Description: Database seems to be working good now...
Reviewed by: dcid
Bug:

--- NEW FILE: README ---
# Simple readme with some query examples.


1- View all rules:

> SELECT rule_id, level, description FROM signature;


2- View all categories (groups)

> SELECT * FROM category;


3- View all categories of a specific rule (1002 for example):

> SELECT rule_id, cat_name from category, signature_category_mapping WHERE rule_id = 1002 AND signature_category_mapping.cat_id = category.cat_id;


4- View all alerts (without data):

> SELECT * FROM alert;


5- View all alerts (with IP as string):

> SELECT rule_id, timestamp, INET_ATON(src_ip) srcip from alert;


6- View all alerts, including locations (IP as string and time as string):

>SELECT FROM_UNIXTIME(timestamp) time, rule_id,location.name location, full_log FROM alert,location, data WHERE location.id = alert.location_id;

Output:

+---------------------+---------+---------------------------+-----------------------------------------------------+
| time | rule_id | location | full_log |
+---------------------+---------+---------------------------+-----------------------------------------------------+
| 2007-08-18 00:28:49 | 1002 | enigma->/var/log/messages | Aug 18 00:28:49 enigma dcid: Segmentation Fault 1q2 |
+---------------------+---------+---------------------------+-----------------------------------------------------+


--- NEW FILE: alert.c ---
/* @(#) $Id: alert.c,v 1.1 2007/08/18 03:38:34 dcid Exp $ */

/* Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>
* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software
* Foundation

*
* License details at the LICENSE file included with OSSEC or
* online at: http://www.ossec.net/en/licensing.html
*/


#include "dbd.h"
#include "config/config.h"
#include "rules_op.h"

/** int OS_SelectMaxID(DBConfig *db_config)
* Selects the maximum ID from the alert table.


* Returns 0 if not found.
*/

int OS_SelectMaxID(DBConfig *db_config)


{
int result = 0;
char sql_query[OS_SIZE_1024];

memset(sql_query, '\0', OS_SIZE_1024);


/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,

"SELECT MAX(id) FROM "
"alert WHERE server_id = '%u'",
db_config->server_id);


/* Checking return code. */
result = osdb_query_select(db_config->conn, sql_query);

return(result);
}


/** int __DBSelectLocation(char *locaton, DBConfig *db_config)
* Selects the location ID from the db.


* Returns 0 if not found.
*/

int __DBSelectLocation(char *location, DBConfig *db_config)


{
int result = 0;
char sql_query[OS_SIZE_1024];

memset(sql_query, '\0', OS_SIZE_1024);


/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,
"SELECT id FROM "

"location WHERE name = '%s' AND server_id = '%d'",
location, db_config->server_id);


/* Checking return code. */
result = osdb_query_select(db_config->conn, sql_query);

return(result);
}


/** int __DBInsertLocation(char *location, DBConfig *db_config)
* Inserts location in to the db.
*/
int __DBInsertLocation(char *location, DBConfig *db_config)


{
char sql_query[OS_SIZE_1024];

memset(sql_query, '\0', OS_SIZE_1024);

/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,
"INSERT INTO "

"location(id, server_id, name) "
"VALUES (NULL, '%u', '%s')",
db_config->server_id, location);


/* Checking return code. */
if(!osdb_query_insert(db_config->conn, sql_query))
{
merror(DB_MAINERROR, ARGV0);
}

return(0);
}

/** int OS_Alert_InsertDB(DBConfig *db_config)
* Insert alert into to the db.
* Returns 1 on success or 0 on error.
*/
int OS_Alert_InsertDB(alert_data *al_data, DBConfig *db_config)
{
unsigned int s_ip = 0, d_ip = 0, location_id = 0;
int *loc_id;
char sql_query[OS_SIZE_2048 +1];


/* Clearing the memory before insert */


memset(sql_query, '\0', OS_SIZE_2048 +1);

/* Converting srcip to int */
if(al_data->srcip)
{
struct in_addr net;

/* Extracting ip address */
if(inet_aton(al_data->srcip, &net))
{

s_ip = net.s_addr;
}
}
d_ip = 0;


/* Escaping strings */
osdb_escapestr(al_data->user);
osdb_escapestr(al_data->log[0]);

/* We first need to insert the location */

loc_id = OSHash_Get(db_config->location_hash, al_data->location);


/* If we dont have location id, we must select and/or insert in the db */
if(!loc_id)
{
location_id = __DBSelectLocation(al_data->location, db_config);
if(location_id == 0)
{
/* Insert it */
__DBInsertLocation(al_data->location, db_config);
location_id = __DBSelectLocation(al_data->location, db_config);
}

if(!location_id)
{
merror("%s: Unable to insert location.", ARGV0);
return(0);
}


/* Adding to hash */
os_calloc(1, sizeof(int), loc_id);
*loc_id = location_id;
OSHash_Add(db_config->location_hash, al_data->location, loc_id);
}

/* Inserting data */
snprintf(sql_query, OS_SIZE_2048,
"INSERT INTO "
"data(id, server_id, user,full_log) "
"VALUES ('%u', '%u', '%s', '%s') ",
db_config->alert_id, db_config->server_id,

al_data->user, al_data->log[0]);

/* Inserting into the db */

if(!osdb_query_insert(db_config->conn, sql_query))
{
merror(DB_MAINERROR, ARGV0);
}


/* Generating final SQL */
snprintf(sql_query, OS_SIZE_2048,
"INSERT INTO "
"alert(id,server_id,rule_id,timestamp,location_id,src_ip) "
"VALUES ('%u', '%u', '%u','%u', '%u', '%lu')",
db_config->alert_id, db_config->server_id, al_data->rule,
time(0), *loc_id, (unsigned long)ntohl(s_ip));


/* Inserting into the db */

if(!osdb_query_insert(db_config->conn, sql_query))
{
merror(DB_MAINERROR, ARGV0);
}


db_config->alert_id++;
return(1);
}


/* EOF */

Index: db_op.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/db_op.c,v

diff -u -r1.3 -r1.4
--- db_op.c 18 Aug 2007 01:07:49 -0000 1.3
+++ db_op.c 18 Aug 2007 03:38:34 -0000 1.4
@@ -110,6 +110,7 @@
MYSQL_RES *result_data;
MYSQL_ROW result_row;



+
/* Sending the query. It can not fail. */

if(mysql_query(db_conn, query) != 0)
{
@@ -131,11 +132,12 @@



/* Getting row. We only care about the first result. */

result_row = mysql_fetch_row(result_data);
- if(result_row[0] != NULL)
+ if(result_row && (result_row[0] != NULL))
{


result_int = atoi(result_row[0]);
}

+

mysql_free_result(result_data);

Index: dbd.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/dbd.c,v

diff -u -r1.2 -r1.3
--- dbd.c 18 Aug 2007 01:07:49 -0000 1.2
+++ dbd.c 18 Aug 2007 03:38:34 -0000 1.3
@@ -31,12 +31,9 @@
*/
void OS_DBD(DBConfig *db_config)
{
- unsigned int s_ip, d_ip;
-

time_t tm;
struct tm *p;

- char sql_query[OS_SIZE_2048 +1];
file_queue *fileq;
alert_data *al_data;

@@ -51,7 +48,17 @@
Init_FileQueue(fileq, p, 0);


- memset(sql_query, '\0', OS_SIZE_2048 +1);
+ /* Creating location hash */
+ db_config->location_hash = OSHash_Create();
+ if(!db_config)
+ {
+ ErrorExit(MEM_ERROR, ARGV0);
+ }
+
+
+ /* Getting maximum ID */
+ db_config->alert_id = OS_SelectMaxID(db_config);
+ db_config->alert_id++;




/* Infinite loop reading the alerts and inserting them. */

@@ -60,10 +67,7 @@


tm = time(NULL);
p = localtime(&tm);

- s_ip = 0;
- d_ip = 0;

-

/* Get message if available (timeout of 5 seconds) */
al_data = Read_FileMon(fileq, p, 5);
if(!al_data)

@@ -72,54 +76,10 @@
}


- debug2("%s: DEBUG: Got data: %d, %d, %s, %s",
- ARGV0,
- al_data->rule,
- al_data->level,
- al_data->location,
- al_data->group);
-
-
- /* Converting srcip to int */
- if(al_data->srcip)
- {
- struct in_addr net;
-
- /* Extracting ip address */
- if(inet_aton(al_data->srcip, &net))
- {
- debug2("%s: DEBUG: found ip: %u for %s", ARGV0, net.s_addr,
- al_data->srcip);
- s_ip = net.s_addr;
- }
- }
-
-
- /* Escaping strings */
- osdb_escapestr(al_data->user);
- osdb_escapestr(al_data->log[0]);
-
-
- /* We first need to insert the location */
-
-
- /* Generating SQL */
- snprintf(sql_query, OS_SIZE_2048,
- "INSERT INTO "
- "alert(id,signature_id,timestamp,src_ip,user,full_log) "
- "VALUES (NULL, '%u','%u','%lu', '%s', '%s') ",
- al_data->rule, time(0),
- (unsigned long)ntohl(s_ip), al_data->user,
- al_data->log[0]);
-
-


/* Inserting into the db */

- if(!osdb_query_insert(db_config->conn, sql_query))
- {
- merror(DB_MAINERROR, ARGV0);
- }
+ OS_Alert_InsertDB(al_data, db_config);
+

-

/* Clearing the memory */
FreeAlertData(al_data);
}

Index: dbd.h
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/dbd.h,v
diff -u -r1.2 -r1.3
--- dbd.h 18 Aug 2007 01:07:49 -0000 1.2
+++ dbd.h 18 Aug 2007 03:38:34 -0000 1.3
@@ -36,6 +36,14 @@
int OS_InsertRulesDB(DBConfig *db_config);


+/* Get maximum ID */
+int OS_SelectMaxID(DBConfig *db_config);
+
+
+/* Insert alerts in to the database */
+int OS_Alert_InsertDB(alert_data *al_data, DBConfig *db_config);
+
+


/* Database inserting main function */
void OS_DBD(DBConfig *db_config);

Index: main.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/main.c,v

diff -u -r1.2 -r1.3
--- main.c 18 Aug 2007 01:07:49 -0000 1.2
+++ main.c 18 Aug 2007 03:38:34 -0000 1.3
@@ -121,6 +121,7 @@


merror(DB_CONFIGERR, ARGV0);
ErrorExit(CONFIG_ERROR, ARGV0, cfg);
}

+ debug1("%s: DEBUG: db connected.", ARGV0);




/* Going on daemon mode */

Index: mysql.schema
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/mysql.schema,v
diff -u -r1.2 -r1.3
--- mysql.schema 18 Aug 2007 01:07:49 -0000 1.2
+++ mysql.schema 18 Aug 2007 03:38:34 -0000 1.3
@@ -57,15 +57,16 @@

CREATE TABLE data
(
- id INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ id INT UNSIGNED NOT NULL,


+ server_id SMALLINT UNSIGNED NOT NULL,

user TEXT NOT NULL,
- full_log TEXT NOT NULL
- PRIMARY KEY (id)
+ full_log TEXT NOT NULL,


+ PRIMARY KEY (id, server_id)

);

CREATE TABLE alert
(

- id INT UNSIGNED NOT NULL AUTO_INCREMENT,
+ id INT UNSIGNED NOT NULL,

server_id SMALLINT UNSIGNED NOT NULL,

rule_id SMALLINT UNSIGNED NOT NULL,
timestamp INT UNSIGNED NOT NULL,

@@ -74,7 +75,7 @@


dst_ip INT UNSIGNED,
src_port SMALLINT UNSIGNED,
dst_port SMALLINT UNSIGNED,

- PRIMARY KEY (id,rule_id),
+ PRIMARY KEY (id, rule_id, server_id),


INDEX time (timestamp),
INDEX (src_ip)
);

Index: rules.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/rules.c,v
diff -u -r1.3 -r1.4
--- rules.c 18 Aug 2007 01:07:49 -0000 1.3
+++ rules.c 18 Aug 2007 03:38:34 -0000 1.4
@@ -126,16 +126,26 @@



-/** void *_Groups_ReadInsertDB(RuleInfo *rule, DBConfig *db_config)
+/** void _Groups_ReadInsertDB(RuleInfo *rule, DBConfig *db_config)


* Insert groups (categories) in to the db.

*/
-void *_Groups_ReadInsertDB(RuleInfo *rule, DBConfig *db_config)
+void _Groups_ReadInsertDB(RuleInfo *rule, DBConfig *db_config)
{


/* We must insert each group separately. */

int cat_id;
char *tmp_group;
char *tmp_str;

+
+ debug1("%s: DEBUG: entering _Groups_ReadInsertDB", ARGV0);
+
+
+ /* If group is null, just return */
+ if(rule->group == NULL)
+ {
+ return;


+ }
+
tmp_str = strchr(rule->group, ',');

tmp_group = rule->group;

@@ -199,7 +209,7 @@
}
}

- return(NULL);
+ return;
}


@@ -225,6 +235,8 @@
if(rule->level < 0)


rule->level = 0;

+

+ debug1("%s: DEBUG: entering _Rules_ReadInsertDB()", ARGV0);




/* Checking rule limit */

Index: server.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/server.c,v
diff -u -r1.1 -r1.2
--- server.c 18 Aug 2007 01:07:49 -0000 1.1
+++ server.c 18 Aug 2007 03:38:34 -0000 1.2
@@ -83,9 +83,11 @@
char *info;


+ debug1("%s: DEBUG: entering OS_Server_ReadInsertDB()", ARGV0);
+
+

/* Getting servers hostname */
memset(__shost, '\0', 512);

- memset(info, '\0', 512);

OSSEC CVS

unread,
Aug 25, 2007, 9:24:07 AM8/25/07
to osse...@ossec.net
Module name: ossec-hids
Changes by: dcid 07/08/25 10:24:04

Modified files:
Makefile alert.c config.c db_op.c db_op.h main.c server.c
Added files:
dbmake.sh

Log message:
Description: Adding support for mysql logs (.err and .log). Adding support for PostgreSQL as a database output. A few more fixes for the hostinfo stuff... (yes, long morning -- you got to love
saturdays)
Reviewed by: dcid
Bug:

--- NEW FILE: dbmake.sh ---
#!/bin/sh


MI=""
ML=""
PI=""
PL=""


# Looking for mysql
ls "`which mysql`" > /dev/null 2>&1
if [ $? = 0 ]; then
for i in /usr /usr/local $1
do
for j in $i/include/mysql/mysql.h $i/include/mysql.h
do
ls $j > /dev/null 2>&1
if [ $? = 0 ]; then
MI=`dirname $j`;
break;
fi
done

for j in $i/lib/mysql
do
ls $j > /dev/null 2>&1
if [ $? = 0 ]; then
ML="$j -lmysqlclient";
break
fi
done
done
fi


# Looking for postgresql
ls "`which psql`" > /dev/null 2>&1
if [ $? = 0 ]; then
for i in /usr /usr/local /usr/pgsql /usr/postgresql $1
do
for j in $i/include/pgsql/libpq-fe.h $i/include/libpq-fe.h $i/include/postgresql/libpq-fe.h
do
ls $j > /dev/null 2>&1
if [ $? = 0 ]; then
PI=`dirname $j`;
break;
fi
done

for j in $i/lib/pgsql $i/lib/postgresql
do
ls $j > /dev/null 2>&1
if [ $? = 0 ]; then
PL="$j -lpq";
break
fi
done
done
fi


# Printing error if mysql is not found
if [ "X$1" = "Xmysql" -a "X$MI" = "X" -a "X$ML" = "X" ]; then
echo "" >&2
echo "Error: MySQL client libraries not installed." >&2
echo "" >&2
exit 1;
fi

# Printing error if postgresql is not found
if [ "X$1" = "Xpostgresql" -a "X$PI" = "X" -a "X$PL" = "X" ]; then
echo "" >&2
echo "Error: PostgreSQL client libraries not installed." >&2
echo "" >&2
exit 1;
fi


# Final cflags -- can not be empty.
if [ "X$MI" = "X" -o "X$ML" = "X" ]; then
MYSQL_FINAL=""
else
MYSQL_FINAL="-I$MI -L$ML -DDBD -DUMYSQL"
fi

# For postgresql
if [ "X$PI" = "X" -o "X$PL" = "X" ]; then
POSTGRES_FINAL=""
else
POSTGRES_FINAL="-I$PI -L$PL -DDBD -DUPOSTGRES"
fi


echo "${MYSQL_FINAL} ${POSTGRES_FINAL}"

exit 0;


Index: Makefile
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/Makefile,v

diff -u -r1.3 -r1.4
--- Makefile 22 Aug 2007 00:39:33 -0000 1.3
+++ Makefile 25 Aug 2007 13:24:04 -0000 1.4
@@ -15,7 +15,7 @@
# Getting database cflags
DBCHECK = `./dbmake.sh`


DBMYSQL = `./dbmake.sh mysql 2> /dev/null`

-DBPOSTGRES = `./dbmake.sh postgres 2> /dev/null`
+DBPOSTGRES = `./dbmake.sh postgresql 2> /dev/null`



OBJS = ${OS_CONFIG} ${OS_SHARED} ${OS_NET} ${OS_REGEX} ${OS_XML}

@@ -25,10 +25,12 @@
${CC} ${CFLAGS} ${DBFLAGS} ${DBCHECK} ${LOCAL} ${OBJS} -o ${NAME}
mysql:


@if [ "X${DBMYSQL}" = "X" ]; then ./dbmake.sh mysql; exit 1; fi;

- @echo "Compiling MySQL DB support with: ${DBVAL}"
- ${CC} ${CFLAGS} ${DBFLAGS} ${DBVAL} ${LOCAL} ${OBJS} -o ${NAME}
-postgres:
- ${CC} ${CFLAGS} ${DBFLAGS} -DDBD -DUPOSTGRES ${LOCAL} ${OBJS} -o ${NAME}
+ @echo "Compiling MySQL DB support with: ${DBMYSQL}"
+ ${CC} ${CFLAGS} ${DBFLAGS} ${DBMYSQL} ${LOCAL} ${OBJS} -o ${NAME}
+postgresql:
+ @if [ "X${DBPOSTGRES}" = "X" ]; then ./dbmake.sh postgresql; exit 1; fi;
+ @echo "Compiling PostgreSQL DB support with: ${DBPOSTGRES}"
+ ${CC} ${CFLAGS} ${DBFLAGS} ${DBPOSTGRES} ${LOCAL} ${OBJS} -o ${NAME}
clean:
${CLEAN}
build:

Index: alert.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/alert.c,v
diff -u -r1.1 -r1.2
--- alert.c 18 Aug 2007 03:38:34 -0000 1.1
+++ alert.c 25 Aug 2007 13:24:04 -0000 1.2
@@ -184,7 +184,7 @@


"alert(id,server_id,rule_id,timestamp,location_id,src_ip) "
"VALUES ('%u', '%u', '%u','%u', '%u', '%lu')",
db_config->alert_id, db_config->server_id, al_data->rule,

- time(0), *loc_id, (unsigned long)ntohl(s_ip));
+ (unsigned int)time(0), *loc_id, (unsigned long)ntohl(s_ip));




/* Inserting into the db */

Index: config.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/config.c,v
diff -u -r1.3 -r1.4
--- config.c 23 Aug 2007 00:01:44 -0000 1.3
+++ config.c 25 Aug 2007 13:24:04 -0000 1.4


@@ -1,12 +1,15 @@
/* @(#) $Id$ */

-/* Copyright (C) 2003-2006 Daniel B. Cid <dc...@ossec.net>

+/* Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>


* All rights reserved.
*
* This program is a free software; you can redistribute it
* and/or modify it under the terms of the GNU General Public
* License (version 3) as published by the FSF - Free Software

- * Foundation
+ * Foundation.
+ *
+ * License details at the LICENSE file included with OSSEC or
+ * online at: http://www.ossec.net/en/licensing.html
*/


@@ -15,6 +18,9 @@
#include "config/config.h"


+/** int OS_ReadDBConf(int test_config, char *cfgfile, DBConfig *db_config)
+ * Reads database configuration.
+ */


int OS_ReadDBConf(int test_config, char *cfgfile, DBConfig *db_config)

{
int modules = 0;
@@ -73,8 +79,37 @@
merror(DB_MISS_CONFIG, ARGV0);
return(OS_INVALID);
}
-
+
+ osdb_connect = NULL;
+
+ /* Assigning the proper location for the function calls */
+ #ifdef UMYSQL
+ if(db_config->db_type == MYSQLDB)
+ {
+ osdb_connect = mysql_osdb_connect;
+ osdb_query_insert = mysql_osdb_query_insert;
+ osdb_query_select = mysql_osdb_query_select;
+ osdb_close = mysql_osdb_close;
+ }
+ #endif
+
+ #ifdef UPOSTGRES
+ if(db_config->db_type == POSTGDB)
+ {
+ osdb_connect = postgresql_osdb_connect;
+ osdb_query_insert = postgresql_osdb_query_insert;
+ osdb_query_select = postgresql_osdb_query_select;
+ osdb_close = postgresql_osdb_close;
+ }
+ #endif

+
+ if(osdb_connect == NULL)
+ {
+ merror("%s: Invalid DB configuration (Internal error?). ", ARGV0);
+ return(OS_INVALID);
+ }
+
return(1);
}

Index: db_op.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/db_op.c,v

diff -u -r1.5 -r1.6
--- db_op.c 22 Aug 2007 00:39:33 -0000 1.5
+++ db_op.c 25 Aug 2007 13:24:04 -0000 1.6
@@ -24,6 +24,12 @@
#include <mysql.h>
#endif

+/* Using PostgreSQL */
+#ifdef UPOSTGRES
+#include <libpq-fe.h>
+#endif
+
+

/** void osdb_escapestr


* Escapes a null terminated string before inserting into the database.

@@ -53,14 +59,15 @@
}


+
/** MySQL calls **/
#ifdef UMYSQL


-/* Create the tree
- * Return NULL on error
+/* Create the database connection.
+ * Returns NULL on error
*/
-void *osdb_connect(char *host, char *user, char *pass, char *db)
+void *mysql_osdb_connect(char *host, char *user, char *pass, char *db)


{
MYSQL *conn;
conn = mysql_init(NULL);

@@ -80,16 +87,21 @@
}


-void osdb_close(void *db_conn)
+
+/* Closes the database connection.
+ */
+void *mysql_osdb_close(void *db_conn)
{
mysql_close(db_conn);
+ return(NULL);
}


-/** int osdb_query_insert(void *db_conn, char *query)
+
+/** int mysql_osdb_query_insert(void *db_conn, char *query)


* Sends insert query to database.
*/

-int osdb_query_insert(void *db_conn, char *query)
+int mysql_osdb_query_insert(void *db_conn, char *query)
{
if(mysql_query(db_conn, query) != 0)
{
@@ -103,11 +115,11 @@



-/** int osdb_query_select(void *db_conn, char *query)
+/** int mysql_osdb_query_select(void *db_conn, char *query)


* Sends a select query to database. Returns the value of it.

* Returns 0 on error (not found).

*/
-int osdb_query_select(void *db_conn, char *query)
+int mysql_osdb_query_select(void *db_conn, char *query)
{
int result_int = 0;
MYSQL_RES *result_data;
@@ -146,24 +158,114 @@

return(result_int);
}
+#endif
/** End of MYSQL calls **/


+
+
/** PostGRES Calls **/
-#elif defined UPOSTGRES
+#if defined UPOSTGRES
+
+
+/** void *postgresql_osdb_connect(char *host, char *user, char *pass, char *db)
+ * Create the PostgreSQL database connection.
+ * Return NULL on error
+ */
+void *postgresql_osdb_connect(char *host, char *user, char *pass, char *db)
+{
+ PGconn *conn;
+
+
+ conn = PQsetdbLogin(host, NULL, NULL, NULL,db,user,pass);
+ if(PQstatus(conn) == CONNECTION_BAD)
+ {
+ merror(DBCONN_ERROR, ARGV0, host, db, PQerrorMessage(conn));
+ PQfinish(conn);
+ return(NULL);
+ }
+
+ return(conn);
+}
+
+
+
+/** void postgresql_osdb_close(void *db_conn)
+ * Terminates db connection.
+ */
+void *postgresql_osdb_close(void *db_conn)
+{
+ PQfinish(db_conn);


+ return(NULL);
+}
+
+
+

+/** int postgresql_osdb_query_insert(void *db_conn, char *query)


+ * Sends insert query to database.

+ */
+int postgresql_osdb_query_insert(void *db_conn, char *query)
+{
+ PGresult *result;
+
+
+ result = PQexec(db_conn,query);
+ if(PQresultStatus(result) != PGRES_COMMAND_OK)
+ {
+ merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn));
+ PQclear(result);
+ return(0);
+ }

+
+ PQclear(result);
+ return(1);
+}


+
+/** int postgresql_osdb_query_select(void *db_conn, char *query)


+ * Sends a select query to database. Returns the value of it.
+ * Returns 0 on error (not found).
+ */

+int postgresql_osdb_query_select(void *db_conn, char *query)


+{
+ int result_int = 0;

+ PGresult *result;
+
+ result = PQexec(db_conn,query);
+ if((PQresultStatus(result) == PGRES_TUPLES_OK))
+ {
+ if(PQntuples(result) == 1)
+ {
+ result_int = atoi(PQgetvalue(result,0,0));
+ }
+ }
+
+
+ /* Report error */
+ if(result_int == 0)
+ {
+ merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn));
+ }
+
+
+ PQclear(result);


+
+
+ return(result_int);
+}

/** End of PostGRES calls **/
+#endif



/* Everything else when db is not defined. */
-#else
+#if !defined(UPOSTGRES) && !defined(UMYSQL)



-void *osdb_connect(char *host, char *user, char *pass, char *db)
+void *none_osdb_connect(char *host, char *user, char *pass, char *db)
{
char *tmp;

@@ -175,15 +277,15 @@
merror("%s: ERROR: Database support not enabled. Exiting.", ARGV0);
return(NULL);
}
-void osdb_close(void *db_conn)
+void *none_osdb_close(void *db_conn)
{
void *tmp;

tmp = db_conn;
merror("%s: ERROR: Database support not enabled. Exiting.", ARGV0);
- return;
+ return(NULL);
}
-int osdb_query_insert(void *db_conn, char *query)
+void *none_osdb_query_insert(void *db_conn, char *query)
{
void *tmp;

@@ -192,7 +294,7 @@
merror("%s: ERROR: Database support not enabled. Exiting.", ARGV0);
return(0);
}
-int osdb_query_select(void *db_conn, char *query)
+void *none_osdb_query_select(void *db_conn, char *query)
{
void *tmp;

Index: db_op.h
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/db_op.h,v

diff -u -r1.3 -r1.4
--- db_op.h 18 Aug 2007 01:07:49 -0000 1.3
+++ db_op.h 25 Aug 2007 13:24:04 -0000 1.4
@@ -20,13 +20,25 @@




/* Connects to the database */

-void *osdb_connect(char *host, char *user, char *pass, char *db);
+void *(*osdb_connect)(char *host, char *user, char *pass, char *db);
+void *mysql_osdb_connect(char *host, char *user, char *pass, char *db);
+void *postgresql_osdb_connect(char *host, char *user, char *pass, char *db);



/* Sends insert query to the database */

-int osdb_query_insert(void *db_conn, char *query);
+int (* osdb_query_insert)(void *db_conn, char *query);
+int mysql_osdb_query_insert(void *db_conn, char *query);
+int postgresql_osdb_query_insert(void *db_conn, char *query);



/* Sends select query to the database */

-int osdb_query_select(void *db_conn, char *query);
+int (* osdb_query_select)(void *db_conn, char *query);
+int mysql_osdb_query_select(void *db_conn, char *query);
+int postgresql_osdb_query_select(void *db_conn, char *query);
+
+/* Closes connection to the database */
+void *(*osdb_close)(void *db_conn);
+void *mysql_osdb_close(void *db_conn);
+void *postgresql_osdb_close(void *db_conn);
+



/* escape strings before inserting. */
void osdb_escapestr(char *str);

Index: main.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/main.c,v
diff -u -r1.4 -r1.5
--- main.c 23 Aug 2007 00:01:44 -0000 1.4
+++ main.c 25 Aug 2007 13:24:04 -0000 1.5
@@ -65,6 +65,7 @@



/* Database Structure */
DBConfig db_config;

+ db_config.error_count = 0;


/* Setting the name */

Index: server.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/server.c,v

diff -u -r1.2 -r1.3
--- server.c 18 Aug 2007 03:38:34 -0000 1.2
+++ server.c 25 Aug 2007 13:24:04 -0000 1.3
@@ -59,7 +59,8 @@


"server(id, last_contact, version, hostname, information) "
"VALUES (NULL, '%u', '%s', '%s', '%s') ON DUPLICATE KEY UPDATE "
"last_contact='%u',version='%s',information='%s'",

- time(0), __version, server, info, time(0), __version, info);
+ (unsigned int)time(0), __version, server, info,
+ (unsigned int)time(0), __version, info);

OSSEC CVS

unread,
Aug 26, 2007, 9:49:35 PM8/26/07
to osse...@ossec.net
Module name: ossec-hids
Changes by: dcid 07/08/26 22:49:32

Modified files:
db_op.c main.c mysql.schema postgresql.schema server.c

Log message:
Description: Adding enable option to ossec-control and a few small fixes.
Reviewed by: dcid
Bug:

Index: db_op.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/db_op.c,v

diff -u -r1.6 -r1.7
--- db_op.c 25 Aug 2007 13:24:04 -0000 1.6
+++ db_op.c 27 Aug 2007 01:49:32 -0000 1.7
@@ -31,6 +31,11 @@



+/* Error count */
+int _db_err = 0;
+


+
+
/** void osdb_escapestr
* Escapes a null terminated string before inserting into the database.

* We built a white list of allowed characters at insert_map. Everything

@@ -55,6 +60,20 @@
if(*(str -1) == '\\')
{
*(str-1) = '\0';


+ }
+}
+
+
+

+/** void osdb_checkerror(void *db_conn)
+ * Checks for errors and handle it appropriately.
+ */
+void osdb_checkerror(void *db_conn)
+{
+ /* If error count is too large, we try to reconnect. */
+ if(_db_err > 10)
+ {
+ osdb_close(db_conn);
}
}

Index: main.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/main.c,v

diff -u -r1.5 -r1.6
--- main.c 25 Aug 2007 13:24:04 -0000 1.5
+++ main.c 27 Aug 2007 01:49:32 -0000 1.6
@@ -169,7 +169,11 @@


merror(DB_CONFIGERR, ARGV0);
ErrorExit(CONFIG_ERROR, ARGV0, cfg);
}

- debug1("%s: DEBUG: db connected.", ARGV0);
+
+
+ /* We must notify that we connected -- easy debugging */
+ verbose("%s: Connected to database '%s' at '%s'.",
+ ARGV0, db_config.db, db_config.host);


/* Privilege separation */

Index: mysql.schema
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/mysql.schema,v

diff -u -r1.4 -r1.5
--- mysql.schema 19 Aug 2007 13:32:11 -0000 1.4
+++ mysql.schema 27 Aug 2007 01:49:32 -0000 1.5
@@ -1,3 +1,17 @@
+# @(#) $Id$ */
+#
+# Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>
+# All rights reserved.
+#
+# This program is a free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public
+# License (version 3) as published by the FSF - Free Software
+# Foundation.
+#
+# License details at the LICENSE file included with OSSEC or
+# online at: http://www.ossec.net/en/licensing.html
+
+


CREATE TABLE category
(
cat_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,

Index: postgresql.schema
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/postgresql.schema,v
diff -u -r1.1 -r1.2
--- postgresql.schema 25 Aug 2007 16:12:50 -0000 1.1
+++ postgresql.schema 27 Aug 2007 01:49:32 -0000 1.2
@@ -1,3 +1,17 @@
+-- @(#) $Id$ */
+--
+-- Copyright (C) 2003-2007 Daniel B. Cid <dc...@ossec.net>
+-- All rights reserved.
+--
+-- This program is a free software; you can redistribute it
+-- and/or modify it under the terms of the GNU General Public
+-- License (version 3) as published by the FSF - Free Software
+-- Foundation.
+--
+-- License details at the LICENSE file included with OSSEC or
+-- online at: http://www.ossec.net/en/licensing.html
+
+
BEGIN;

CREATE TABLE category

Index: server.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/server.c,v

diff -u -r1.3 -r1.4
--- server.c 25 Aug 2007 13:24:04 -0000 1.3
+++ server.c 27 Aug 2007 01:49:32 -0000 1.4
@@ -53,20 +53,42 @@

memset(sql_query, '\0', OS_SIZE_1024);


- /* Generating SQL */

+ /* Checking if the server is present */
snprintf(sql_query, OS_SIZE_1024 -1,
- "INSERT INTO "
- "server(id, last_contact, version, hostname, information) "
- "VALUES (NULL, '%u', '%s', '%s', '%s') ON DUPLICATE KEY UPDATE "
- "last_contact='%u',version='%s',information='%s'",
- (unsigned int)time(0), __version, server, info,
- (unsigned int)time(0), __version, info);
+ "SELECT id from server where hostname = '%s'",
+ server);
+
+ /* If not present, we insert */
+ if(osdb_query_select(db_config->conn, sql_query) == 0)
+ {


+ snprintf(sql_query, OS_SIZE_1024 -1,
+ "INSERT INTO "

+ "server(id, last_contact, version, hostname, information) "
+ "VALUES (NULL, '%u', '%s', '%s', '%s')",
+ (unsigned int)time(0), __version, server, info);



+ /* Checking return code. */
+ if(!osdb_query_insert(db_config->conn, sql_query))
+ {
+ merror(DB_MAINERROR, ARGV0);
+ }
+ }

- /* Checking return code. */
- if(!osdb_query_insert(db_config->conn, sql_query))
+ /* If it is, we update it */
+ else
{
- merror(DB_MAINERROR, ARGV0);
+
+ snprintf(sql_query, OS_SIZE_1024 -1,
+ "UPDATE server SET "
+ "last_contact='%u',version='%s',information='%s' "
+ "WHERE hostname = '%s'",
+ (unsigned int)time(0), __version, info, server);


+
+ /* Checking return code. */
+ if(!osdb_query_insert(db_config->conn, sql_query))
+ {
+ merror(DB_MAINERROR, ARGV0);
+ }
}

return(0);

OSSEC CVS

unread,
Aug 27, 2007, 11:08:18 PM8/27/07
to osse...@ossec.net
Module name: ossec-hids
Changes by: dcid 07/08/28 00:08:15

Modified files:
README alert.c config.c db_op.c dbd.h dbmake.sh main.c rules.c
server.c

Log message:
Description: Making sure it works with PostgreSQL and adding more error handling (reconnects, etc). Additional ossec rules to alert on file rotation and when a log file has the file reduced.
Reviewed by: dcid
Bug:

Index: README
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/README,v
diff -u -r1.2 -r1.3
--- README 18 Aug 2007 03:43:35 -0000 1.2
+++ README 28 Aug 2007 03:08:15 -0000 1.3
@@ -1,4 +1,5 @@


# Simple readme with some query examples.

+# Examples for MySQL and PostgreSQL


1- View all rules:
@@ -28,7 +29,11 @@



6- View all alerts, including locations (IP as string and time as string):

+MySQL:
>SELECT FROM_UNIXTIME(timestamp) time, rule_id,location.name location, INET_NTOA(src_ip) srcip, full_log FROM alert,location, data WHERE location.id = alert.location_id AND data.id = alert.id AND data.server_id = alert.server_id;
+
+PostgreSQL:
+>SELECT to_timestamp(timestamp), rule_id, location.name, full_log FROM alert,location, data WHERE location.id = alert.location_id AND data.id = alert.id AND data.server_id = alert.server_id;

Output:

Index: alert.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/alert.c,v

diff -u -r1.2 -r1.3
--- alert.c 25 Aug 2007 13:24:04 -0000 1.2
+++ alert.c 28 Aug 2007 03:08:15 -0000 1.3
@@ -83,15 +83,15 @@


/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,
"INSERT INTO "

- "location(id, server_id, name) "
- "VALUES (NULL, '%u', '%s')",
+ "location(server_id, name) "
+ "VALUES ('%u', '%s')",
db_config->server_id, location);


/* Checking return code. */

if(!osdb_query_insert(db_config->conn, sql_query))
{
- merror(DB_MAINERROR, ARGV0);
+ merror(DB_GENERROR, ARGV0);
}

return(0);
@@ -165,7 +165,7 @@


/* Inserting data */
snprintf(sql_query, OS_SIZE_2048,
"INSERT INTO "

- "data(id, server_id, user,full_log) "
+ "data(id, server_id, \"user\",full_log) "
"VALUES ('%u', '%u', '%s', '%s') ",
db_config->alert_id, db_config->server_id,

al_data->user, al_data->log[0]);

@@ -173,7 +173,7 @@


/* Inserting into the db */

if(!osdb_query_insert(db_config->conn, sql_query))
{
- merror(DB_MAINERROR, ARGV0);
+ merror(DB_GENERROR, ARGV0);
}


@@ -190,7 +190,7 @@


/* Inserting into the db */

if(!osdb_query_insert(db_config->conn, sql_query))
{
- merror(DB_MAINERROR, ARGV0);
+ merror(DB_GENERROR, ARGV0);
}

Index: config.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/config.c,v

diff -u -r1.4 -r1.5
--- config.c 25 Aug 2007 13:24:04 -0000 1.4
+++ config.c 28 Aug 2007 03:08:15 -0000 1.5
@@ -44,6 +44,7 @@


db_config->pass = NULL;
db_config->db = NULL;

db_config->db_type = 0;
+ db_config->maxreconnect = 0;


/* Reading configuration */

Index: db_op.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/db_op.c,v

diff -u -r1.7 -r1.8
--- db_op.c 27 Aug 2007 01:49:32 -0000 1.7
+++ db_op.c 28 Aug 2007 03:08:15 -0000 1.8
@@ -16,8 +16,7 @@


/* Common lib for dealing with databases */


-#include "shared.h"
-#include "db_op.h"
+#include "dbd.h"



/* Using Mysql */
#ifdef UMYSQL

@@ -31,8 +30,8 @@



-/* Error count */
-int _db_err = 0;
+/* Config pointer */
+DBConfig *db_config_pt = NULL;



@@ -65,19 +64,81 @@



-/** void osdb_checkerror(void *db_conn)
+/** void osdb_checkerror()


* Checks for errors and handle it appropriately.

*/
-void osdb_checkerror(void *db_conn)
+void osdb_checkerror()
{
+ int sleep_time = 3;
+ if(!db_config_pt)
+ {
+ ErrorExit(DB_MAINERROR, ARGV0);
+ }
+
+

/* If error count is too large, we try to reconnect. */

- if(_db_err > 10)
+ if(db_config_pt->error_count > 5)
{
- osdb_close(db_conn);
+ int i = 0;
+ if(db_config_pt->conn)
+ {
+ osdb_close(db_config_pt->conn);
+ db_config_pt->conn = NULL;
+ }
+
+ while(i <= db_config_pt->maxreconnect)
+ {
+ merror(DB_ATTEMPT, ARGV0);
+ db_config_pt->conn = osdb_connect(db_config_pt->host,
+ db_config_pt->user,
+ db_config_pt->pass,
+ db_config_pt->db);
+
+ /* If we were able to reconnect, keep going. */
+ if(db_config_pt->conn)
+ {
+ break;
+ }
+ sleep(sleep_time);
+ sleep_time *= 3;
+ i++;
+ }
+
+
+ /* If we weren't able to connect, exit */
+ if(!db_config_pt->conn)
+ {
+ ErrorExit(DB_MAINERROR, ARGV0);
+ }
+
+
+ db_config_pt->error_count = 0;


+ verbose("%s: Connected to database '%s' at '%s'.",

+ ARGV0, db_config_pt->db, db_config_pt->host);
+
}
}


+/** void osdb_seterror()
+ * Sets the error counter.
+ */
+void osdb_seterror()
+{
+ db_config_pt->error_count++;
+ osdb_checkerror();
+}
+
+
+/** void osdb_setconfig(DBConfig *db_config)
+ * Creates an internal pointer to the db configuration.
+ */
+void osdb_setconfig(DBConfig *db_config)
+{
+ db_config_pt = db_config;
+}
+


+

/** MySQL calls **/
#ifdef UMYSQL

@@ -111,6 +172,7 @@
*/
void *mysql_osdb_close(void *db_conn)
{
+ merror(DB_CLOSING, ARGV0);
mysql_close(db_conn);
return(NULL);
}
@@ -126,6 +188,7 @@
{


/* failure; report error */

merror(DBQUERY_ERROR, ARGV0, query, mysql_error(db_conn));
+ osdb_seterror();
return(0);
}

@@ -150,6 +213,7 @@
{


/* failure; report error */

merror(DBQUERY_ERROR, ARGV0, query, mysql_error(db_conn));
+ osdb_seterror();
return(0);
}

@@ -160,6 +224,7 @@
{


/* failure; report error */

merror(DBQUERY_ERROR, ARGV0, query, mysql_error(db_conn));
+ osdb_seterror();
return(0);
}

@@ -214,6 +279,7 @@
*/
void *postgresql_osdb_close(void *db_conn)
{
+ merror(DB_CLOSING, ARGV0);
PQfinish(db_conn);
return(NULL);
}
@@ -229,10 +295,19 @@


result = PQexec(db_conn,query);
+ if(!result)


+ {
+ merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn));

+ osdb_seterror();


+ return(0);
+ }
+
+

if(PQresultStatus(result) != PGRES_COMMAND_OK)
{
merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn));
PQclear(result);
+ osdb_seterror();
return(0);
}

@@ -253,6 +328,13 @@
PGresult *result;

result = PQexec(db_conn,query);
+ if(!result)


+ {
+ merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn));

+ osdb_seterror();
+ return(0);
+ }
+
if((PQresultStatus(result) == PGRES_TUPLES_OK))
{
if(PQntuples(result) == 1)
@@ -260,15 +342,15 @@
result_int = atoi(PQgetvalue(result,0,0));
}
}
-
-
- /* Report error */
- if(result_int == 0)
+ else
{
merror(DBQUERY_ERROR, ARGV0, query, PQerrorMessage(db_conn));
+ osdb_seterror();
+ return(0);
}

-
+
+ /* Clear result */
PQclear(result);

Index: dbd.h
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/dbd.h,v

diff -u -r1.3 -r1.4
--- dbd.h 18 Aug 2007 03:38:34 -0000 1.3
+++ dbd.h 28 Aug 2007 03:08:15 -0000 1.4
@@ -48,6 +48,10 @@
void OS_DBD(DBConfig *db_config);


+/* Setting config pointer for osbd_op */
+void osdb_setconfig(DBConfig *db_config);
+
+

/** Global vars **/

Index: dbmake.sh
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/dbmake.sh,v
diff -u -r1.1 -r1.2
--- dbmake.sh 25 Aug 2007 13:24:04 -0000 1.1
+++ dbmake.sh 28 Aug 2007 03:08:15 -0000 1.2
@@ -51,7 +51,8 @@


do
ls $j > /dev/null 2>&1
if [ $? = 0 ]; then

- PL="$j -lpq";
+ PG_MAIN=`dirname $j`;
+ PL="-L$j -L${PG_MAIN} -lpq";
break
fi
done
@@ -89,7 +90,7 @@


if [ "X$PI" = "X" -o "X$PL" = "X" ]; then
POSTGRES_FINAL=""
else

- POSTGRES_FINAL="-I$PI -L$PL -DDBD -DUPOSTGRES"
+ POSTGRES_FINAL="-I$PI $PL -DDBD -DUPOSTGRES"
fi

Index: main.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/main.c,v

diff -u -r1.6 -r1.7
--- main.c 27 Aug 2007 01:49:32 -0000 1.6
+++ main.c 28 Aug 2007 03:08:15 -0000 1.7
@@ -159,11 +159,35 @@


debug1("%s: DEBUG: Connecting to '%s', using '%s', '%s', '%s'.",
ARGV0, db_config.host, db_config.user,
db_config.pass, db_config.db);

+
+
+ /* Setting config pointer */
+ osdb_setconfig(&db_config);
+
+
+ /* Getting maximum reconned attempts */
+ db_config.maxreconnect = getDefine_Int("dbd",
+ "reconnect_attempts", 1, 9999);




/* Connecting to the database */

- db_config.conn = osdb_connect(db_config.host, db_config.user,
- db_config.pass, db_config.db);
+ c = 0;
+ while(c <= db_config.maxreconnect)
+ {
+ db_config.conn = osdb_connect(db_config.host, db_config.user,
+ db_config.pass, db_config.db);
+
+ /* If we are able to reconnect, keep going */
+ if(db_config.conn)
+ {
+ break;
+ }
+
+ sleep(c + 2);
+ }
+
+
+ /* If after the maxreconnect attempts, it still didn't work, exit here. */
if(!db_config.conn)
{
merror(DB_CONFIGERR, ARGV0);

Index: rules.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/rules.c,v

diff -u -r1.4 -r1.5
--- rules.c 18 Aug 2007 03:38:34 -0000 1.4
+++ rules.c 28 Aug 2007 03:08:15 -0000 1.5
@@ -57,15 +57,15 @@


/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,
"INSERT INTO "

- "category(cat_id, cat_name) "
- "VALUES (NULL, '%s')",
+ "category(cat_name) "
+ "VALUES ('%s')",
group);




/* Checking return code. */

if(!osdb_query_insert(db_config->conn, sql_query))
{
- merror(DB_MAINERROR, ARGV0);
+ merror(DB_GENERROR, ARGV0);
}

return(0);
@@ -110,15 +110,15 @@


/* Generating SQL */
snprintf(sql_query, OS_SIZE_1024 -1,
"INSERT INTO "

- "signature_category_mapping(id, cat_id, rule_id) "
- "VALUES (NULL, '%u', '%u')",
+ "signature_category_mapping(cat_id, rule_id) "
+ "VALUES ('%u', '%u')",
cat_id, rule_id);




/* Checking return code. */

if(!osdb_query_insert(db_config->conn, sql_query))
{
- merror(DB_MAINERROR, ARGV0);
+ merror(DB_GENERROR, ARGV0);
}

return(0);
@@ -257,18 +257,31 @@

/* Generating SQL */


snprintf(sql_query, OS_SIZE_1024 -1,
- "INSERT INTO "

- "signature(id, rule_id, level, description) "
- "VALUES (NULL, '%u','%u','%s') "
- "ON DUPLICATE KEY UPDATE level='%u'",
- rule->sigid, rule->level, rule->comment,
- rule->level);
-
+ "SELECT id FROM signature "
+ "where rule_id = %u",
+ rule->sigid);
+
+ if(osdb_query_select(dbc->conn, sql_query) == 0)


+ {
+ snprintf(sql_query, OS_SIZE_1024 -1,
+ "INSERT INTO "

+ "signature(rule_id, level, description) "
+ "VALUES ('%u','%u','%s')",
+ rule->sigid, rule->level, rule->comment);
+ }
+ else


+ {
+ snprintf(sql_query, OS_SIZE_1024 -1,

+ "UPDATE signature SET level='%u',description='%s' "
+ "WHERE id='%u'",
+ rule->level, rule->comment,rule->sigid);


+ }
+

/* Checking return code. */

if(!osdb_query_insert(dbc->conn, sql_query))
{
- merror(DB_MAINERROR, ARGV0);
+ merror(DB_GENERROR, ARGV0);
}

return(NULL);

Index: server.c
===================================================================
RCS file: /usr/cvsroot/ossec-hids/src/os_dbd/server.c,v

diff -u -r1.4 -r1.5
--- server.c 27 Aug 2007 01:49:32 -0000 1.4
+++ server.c 28 Aug 2007 03:08:15 -0000 1.5
@@ -63,14 +63,14 @@
{
snprintf(sql_query, OS_SIZE_1024 -1,


"INSERT INTO "
- "server(id, last_contact, version, hostname, information) "

- "VALUES (NULL, '%u', '%s', '%s', '%s')",
+ "server(last_contact, version, hostname, information) "
+ "VALUES ('%u', '%s', '%s', '%s')",


(unsigned int)time(0), __version, server, info);

/* Checking return code. */

if(!osdb_query_insert(db_config->conn, sql_query))
{
- merror(DB_MAINERROR, ARGV0);
+ merror(DB_GENERROR, ARGV0);
}
}

@@ -87,7 +87,7 @@


/* Checking return code. */

if(!osdb_query_insert(db_config->conn, sql_query))
{
- merror(DB_MAINERROR, ARGV0);
+ merror(DB_GENERROR, ARGV0);
}
}

Reply all
Reply to author
Forward
0 new messages