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 */
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. */
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);
}
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);
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);
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);
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);
}
}