📄 spo_log_database.c
字号:
/*
** Copyright (C) 2000 Carnegie Mellon University
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: spo_log_database.c,v 1.5 2000/06/03 04:56:04 roesch Exp $ */
/* Snort Database Output Plug-in by Jed Pickel <jed@pickel.net>
*
* Contributions: Todd Schrub <tls@cert.org>
* * Initial code for MySQL
* * Helped design database architecture
*
* See http://www.incident.org/snortdb for the most up to date
* information, code, and documentation about this plug-in
*
* spo_log_database
*
* Purpose:
*
* This plug-in enables snort to log to Postgresql, MySQL, or
* any unixODBC database.
*
* Setup:
*
* To get this plug-in working take the following steps. Although
* it seems like a lot of steps but it only takes a couple minutes
* to get things working.
*
* 1) Install MySQL, Postgresql, or (unixODBC + some other RDBMS)
* MySQL => http://www.mysql.org
* Postgresql => http://www.postgesql.org
* unixODBC => http://www.unixodbc.org
*
* 2) Follow directions from your database vendor to be sure your
* RDBMS is properly configured and secured.
*
* 3) Follow directions from your vendor to create a database for
* snort.
* MySQL example
* % echo "CREATE DATABASE snort;" | mysql -u root -p
*
* 4) Create a user that has privileges to INSERT and SELECT
* on that database.
* example
* - First create a user - for this example we will use "jed"
* - now grant the right privliges for that user
* > grant INSERT,SELECT on snort.* to jed@localhost;
*
* 5) Build the structure of the database according to files supplied
* with snort in the "contrib" directory as the user created in
* step 4.
*
* Do this while in the snort source directory.
*
* For MySQL
* % mysql < ./contrib/create_mysql
*
* For Postgresql
* % psql < ./contrib/create_postgresql
*
* If you are using unixODBC, be sure to properly configure and
* test that you can connect to your data source (DSN) with isql
* before trying to run snort.
*
* For RDBMS other than MySQL and Postgresql that are accessed
* through ODBC you will need to create the database
* structure yourself because datatypes vary for different
* databases. You will need to have the same column names and
* functionality for each column as in the mysql and
* postgresql examples. The mysql file is the best example to
* follow since it is optimized (given that mysql supports tiny
* ints and unsigned ints). I intend to document this process
* better in the future to make this process easier.
*
* As you create database structure files for new RDBMS mail
* them in so they can be included as part of the distribution.
*
* 6) Add configuration information to the snort configuration file
* as detailed in the "Arguments" section below.
*
* Arguments:
*
* output log_database: [type of database], [parameter list]
*
* For the first argument, you must supply the type of database.
* The possible values are mysql, postgresql, and unixodbc.
*
* The parameter list consists of key value pairs. The proper
* format is a list of key=value pairs each separated a space.
*
* The only parameter that is absolutely necessary is "dbname".
* All other parameters are optional but may be necessary
* depending on how you have configured your RDBMS.
*
* dbname - the name of the database you are connecting to
*
* host - the host the RDBMS is on
*
* port - the port number the RDBMS is listening on
*
* user - connect to the database as this user
*
* password - the password for given user
*
* The configuration I am currently using is MySQL with the database
* name of "snort". The user "jed@localhost" has INSERT and SELECT
* privileges on the "snort" database and does not require a password.
* The following line enables snort to log to this database.
*
* output log_database: mysql, dbname=snort user=jed host=localhost
*
* Effect:
*
* Logs are written to a database for later analysis by other applications.
*
* Comments:
*
* Depending on your RDBMS and the number of alerts generated by
* snort over a small interval of time using this module could
* cause an impact on the snort detection engine. When snort
* becomes multi-threaded, performance will increase significantly.
*
* Based on my testing, MySQL far outperforms Postgresql for this
* application.
*
* Change Log:
*
* 2000-05-09: Bugfixes, documentation fixes, and added some
* better error reporting
* 2000-04-13: Released new version
* 2000-04-03: Updated database structure
* 2000-03-28: Added unixODBC support
* Added MySQL support
* Changed database structure
* 2000-03-08: Added new table "sensor" and a new field to event table
* to represent the sensor
* 2000-03-08: Added locking on inserts to eliminate concurrency problem
* 2000-03-08: Changed "type" and "code" in icmphdr to int2 instead of char
* 2000-03-01: Added extra argument to RegisterOutputPlugin
* 2000-02-28: First release
*
* TODO:
*
* - Figure out the best way to handle fragments (currently fragments
* are not logged)
* - Add a configuration to optionally log
* - the data portion of packets in a text field
* - raw packets */
#include "spo_log_database.h"
extern PV pv;
/*#define DEBUG*/
/*
* Function: SetupLogDatabase()
*
* Purpose: Registers the output plugin keyword and initialization
* function into the output plugin list. This is the function that
* gets called from InitOutputPlugins() in plugbase.c.
*
* Arguments: None.
*
* Returns: void function
*
*/
void SetupLogDatabase()
{
/* link the preprocessor keyword to the init function in
the preproc list */
RegisterOutputPlugin("log_database", NT_OUTPUT_LOG, LogDatabaseInit);
#ifdef DEBUG
printf("Output plugin: Log-Database is setup...\n");
#endif
}
/*
* Function: LogDatabaseInit(u_char *)
*
* Purpose: Calls the argument parsing function, performs final setup on data
* structs, links the preproc function into the function list.
*
* Arguments: args => ptr to argument string
*
* Returns: void function
*
*/
void LogDatabaseInit(u_char *args)
{
char * select0;
char * select1;
char * insert0;
/* tell command line loggers to go away */
pv.log_plugin_active = 1;
/* parse the argument list from the rules file */
ParseDatabaseArgs((char *)args);
/* setup sensor id queries */
select0 = (char *)malloc(MAX_QUERY_LENGTH);
select1 = (char *)malloc(MAX_QUERY_LENGTH);
insert0 = (char *)malloc(MAX_QUERY_LENGTH);
/* Thank you Bill Marquett for pointing out the need for this fix */
if (pv.pcap_cmd == NULL)
{
sprintf(insert0,
"INSERT INTO sensor (hostname, interface) VALUES ('%s','%s')", getenv("HOSTNAME"), pv.interface);
sprintf(select0,
"SELECT sid FROM sensor WHERE hostname = '%s' AND interface = '%s' AND filter IS NULL", getenv("HOSTNAME"), pv.interface);
}
else
{
sprintf(select0,
"SELECT sid FROM sensor WHERE hostname = '%s' and interface = '%s' and filter ='%s';", getenv("HOSTNAME"), pv.interface, pv.pcap_cmd);
sprintf(insert0,
"INSERT INTO sensor (hostname, interface, filter) VALUES ('%s','%s','%s');", getenv("HOSTNAME"), pv.interface, pv.pcap_cmd);
}
Connect();
sid = Select(select0);
if (sid == 0)
{
Insert(insert0);
sid = Select(select0);
if (sid == 0)
{
FatalError("Problem obtaining SENSOR ID (sid) from %s->%s->event\n",dbtype,dbname);
}
}
sprintf(select1,
"SELECT max(cid) FROM event WHERE sid = '%i'", sid);
cid = Select(select1);
cid++;
/* free memory */
free(select0);
free(select1);
free(insert0);
/* Add the processor function into the function list */
AddFuncToOutputList(LogDatabase, NT_OUTPUT_LOG, NULL);
}
/*
* Function: ParseDatabaseArgs(char *)
*
* Purpose: Process the preprocessor arguements from the rules file and
* initialize the preprocessor's data struct.
*
* Arguments: args => argument list
*
* Returns: void function
*
*/
void ParseDatabaseArgs(char *args)
{
char * dbarg;
char * a1;
if (args == NULL)
{
FatalError("log_database: Must supply arguments for database plugin\n");
}
dbtype = strtok(args, ", ");
if (dbtype == NULL)
{
FatalError("log_database: Must enter database type in configuration file\n");
}
printf("log_database: Database type is %s\n", dbtype);
dbarg = strtok(NULL, " =");
while(dbarg != NULL)
{
a1 = NULL;
a1 = strtok(NULL, " ");
if(!strncasecmp(dbarg,"host",4))
{
host = a1;
printf("log_database: Host set to %s\n", host);
}
if(!strncasecmp(dbarg,"port",4))
{
port = a1;
printf("log_database: Port set to %s\n", port);
}
if(!strncasecmp(dbarg,"user",4))
{
user = a1;
printf("log_database: User set to %s\n", user);
}
if(!strncasecmp(dbarg,"password",8))
{
password = a1;
}
if(!strncasecmp(dbarg,"dbname",6))
{
dbname = a1;
printf("log_database: Database name is %s\n", dbname);
}
dbarg = strtok(NULL, "=");
}
if (dbname == NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -