Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

674 lines (540 sloc) 16.365 kB
/* $Id$ */
/*
** Copyright (C) 2002-2009 Sourcefire, Inc.
** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License Version 2 as
** published by the Free Software Foundation. You may not use, modify or
** distribute this program under any other version of the GNU General
** Public License.
**
** 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.
*/
/*
** Modifications by: Ian Firns <firnsy@securixlive.com>
**
** History:
** 2008-05-09 - Cleaned and amalgamated the input and output plugin API into
** the one file.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
//#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <errno.h>
#include "plugbase.h"
#include "barnyard2.h"
#include "debug.h"
#include "util.h"
/* built-in input plugins */
#include "input-plugins/spi_unified2.h"
/* built-in output plugins */
#include "output-plugins/spo_alert_arubaaction.h"
#include "output-plugins/spo_alert_bro.h"
#include "output-plugins/spo_alert_cef.h"
#include "output-plugins/spo_alert_csv.h"
#include "output-plugins/spo_alert_fast.h"
#include "output-plugins/spo_alert_full.h"
#include "output-plugins/spo_alert_fwsam.h"
#include "output-plugins/spo_alert_syslog.h"
#include "output-plugins/spo_alert_test.h"
#include "output-plugins/spo_alert_prelude.h"
#include "output-plugins/spo_alert_unixsock.h"
#include "output-plugins/spo_database.h"
#include "output-plugins/spo_log_ascii.h"
#include "output-plugins/spo_log_null.h"
#include "output-plugins/spo_log_tcpdump.h"
#include "output-plugins/spo_platypus.h"
#include "output-plugins/spo_sguil.h"
#include "output-plugins/spo_syslog_full.h"
extern InputConfigFuncNode *input_config_funcs;
extern OutputConfigFuncNode *output_config_funcs;
extern PluginSignalFuncNode *plugin_shutdown_funcs;
extern PluginSignalFuncNode *plugin_clean_exit_funcs;
extern PluginSignalFuncNode *plugin_restart_funcs;
extern InputFuncNode *InputList;
extern OutputFuncNode *AlertList;
extern OutputFuncNode *LogList;
extern Barnyard2Config *barnyard2_conf_for_parsing;
extern int file_line;
extern char *file_name;
/***************************** Input Plugin API *****************************/
/*InputKeywordList *InputKeywords;
InputFuncNode *InputList;
*/
void RegisterInputPlugins()
{
LogMessage("Initializing Input Plugins!\n");
Unified2Setup();
}
InputFuncNode *GetInputPlugin(char *keyword)
{
InputFuncNode *node = InputList;
if (keyword == NULL)
return NULL;
while ((node != NULL) && (strcasecmp(keyword, node->keyword) != 0))
{
node = node->next;
}
if (node == NULL)
{
FatalError("unknown input plugin: '%s'\n", keyword);
}
return node;
}
/****************************************************************************
*
* Function: RegisterInputPlugin(char *, InputConfigFunc *)
*
* Purpose: Associates an input statement with its function. It will also
* setup a InputFunctionNode of the same keyword which stores the
* apppropriate file processing methods.
*
* Arguments: keyword => The input keyword to associate with the
* input processor
* *func => function pointer to the handler
*
* Returns: void function
*
***************************************************************************/
void RegisterInputPlugin(char *keyword, InputConfigFunc func)
{
InputConfigFuncNode *node = (InputConfigFuncNode *)SnortAlloc(sizeof(InputConfigFuncNode));
InputFuncNode *node2 = (InputFuncNode *)SnortAlloc(sizeof(InputFuncNode));
DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:input => %s:%p\n",
keyword, func););
if (input_config_funcs == NULL)
{
input_config_funcs = node;
}
else
{
InputConfigFuncNode *tmp = input_config_funcs;
InputConfigFuncNode *last;
do
{
if (strcasecmp(tmp->keyword, keyword) == 0)
{
free(node);
FatalError("Duplicate input keyword: %s\n", keyword);
}
last = tmp;
tmp = tmp->next;
} while (tmp != NULL);
last->next = node;
}
node->keyword = SnortStrdup(keyword);
node->func = func;
if (InputList == NULL)
{
InputList = node2;
}
else
{
InputFuncNode *tmp2 = InputList;
InputFuncNode *last2;
do
{
if (strcasecmp(tmp2->keyword, keyword) == 0)
{
free(node2);
FatalError("Duplicate input keyword: %s\n", keyword);
}
last2 = tmp2;
tmp2 = tmp2->next;
} while (tmp2 != NULL);
last2->next = node2;
}
node2->keyword = SnortStrdup(keyword);
}
InputConfigFunc GetInputConfigFunc(char *keyword)
{
InputConfigFuncNode *head = input_config_funcs;
if (keyword == NULL)
return NULL;
while (head != NULL)
{
if (strcasecmp(head->keyword, keyword) == 0)
return head->func;
head = head->next;
}
return NULL;
}
/****************************************************************************
*
* Function: DumpInputPlugins()
*
* Purpose: Prints the keyword->function list
*
* Arguments: None.
*
* Returns: void function
*
***************************************************************************/
void DumpInputPlugins()
{
InputConfigFuncNode *idx = input_config_funcs;
InputFuncNode *ifn = NULL;
LogMessage("-------------------------------------------------\n");
LogMessage(" Keyword | Input @ \n");
LogMessage("-------------------------------------------------\n");
while(idx != NULL)
{
LogMessage("%-13s: init() = %p\n", idx->keyword, idx->func);
ifn = GetInputPlugin(idx->keyword);
if ((ifn != NULL) && ifn->configured_flag)
{
LogMessage("%-13s: - readRecordHeader() = %p\n",
ifn->keyword, ifn->readRecordHeader);
LogMessage("%-13s: - readRecord() = %p\n",
ifn->keyword, ifn->readRecord);
}
idx = idx->next;
}
LogMessage("-------------------------------------------------\n\n");
}
int AddArgToInputList(char *keyword, void *arg)
{
InputFuncNode *node;
if(keyword == NULL)
return -1;
node = GetInputPlugin(keyword);
node->arg = arg;
return 0;
}
int AddReadRecordHeaderFuncToInputList(char *keyword, int (*readRecordHeader)(void *))
{
InputFuncNode *node;
if(keyword == NULL)
return -1;
DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:readRecordHeader => %s:%p\n",
keyword, readRecordHeader););
node = GetInputPlugin(keyword);
node->readRecordHeader = readRecordHeader;
node->configured_flag = InputFuncNodeConfigured(node);
return 0;
}
int AddReadRecordFuncToInputList(char *keyword, int (*readRecord)(void *))
{
InputFuncNode *node;
if(keyword == NULL)
return -1;
DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:readRecord => %s:%p\n",
keyword, readRecord););
node = GetInputPlugin(keyword);
node->readRecord = readRecord;
node->configured_flag = InputFuncNodeConfigured(node);
return 0;
}
int InputFuncNodeConfigured(InputFuncNode *ifn)
{
/* if not all functions are defined then return a zero flag */
if (!ifn->readRecordHeader || !ifn->readRecord)
return 0;
return 1;
}
/***************************** Output Plugin API *****************************/
extern OutputConfigFuncNode *output_config_funcs;
static void AppendOutputFuncList(OutputFunc, void *, OutputFuncNode **);
void RegisterOutputPlugins(void)
{
LogMessage("Initializing Output Plugins!\n");
AlertCEFSetup();
AlertSyslogSetup();
LogTcpdumpSetup();
DatabaseSetup();
AlertFastSetup();
AlertFullSetup();
AlertFWsamSetup();
#ifndef WIN32
/* Win32 doesn't support AF_UNIX sockets */
AlertUnixSockSetup();
#endif /* !WIN32 */
AlertCSVSetup();
LogNullSetup();
LogAsciiSetup();
#ifdef ARUBA
AlertArubaActionSetup();
#endif
#ifdef HAVE_LIBPRELUDE
AlertPreludeSetup();
#endif
#ifdef BROCCOLI
AlertBroSetup();
#endif
AlertTestSetup();
PlatypusSetup();
SguilSetup();
OpSyslog_Setup();
}
/****************************************************************************
*
* Function: RegisterOutputPlugin(char *, void (*func)(Packet *, u_char *))
*
* Purpose: Associates an output statement with its function.
*
* Arguments: keyword => The output keyword to associate with the
* output processor
* type => alert or log types
* *func => function pointer to the handler
*
* Returns: void function
*
***************************************************************************/
void RegisterOutputPlugin(char *keyword, int type_flags, OutputConfigFunc func)
{
OutputConfigFuncNode *node = (OutputConfigFuncNode *)SnortAlloc(sizeof(OutputConfigFuncNode));
DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:output => %s:%p\n",
keyword, func););
if (output_config_funcs == NULL)
{
output_config_funcs = node;
}
else
{
OutputConfigFuncNode *tmp = output_config_funcs;
OutputConfigFuncNode *last;
do
{
if (strcasecmp(tmp->keyword, keyword) == 0)
{
free(node);
FatalError("Duplicate output keyword: %s\n", keyword);
}
last = tmp;
tmp = tmp->next;
} while (tmp != NULL);
last->next = node;
}
node->keyword = SnortStrdup(keyword);
node->func = func;
node->output_type_flags = type_flags;
}
OutputConfigFunc GetOutputConfigFunc(char *keyword)
{
OutputConfigFuncNode *head = output_config_funcs;
if (keyword == NULL)
return NULL;
while (head != NULL)
{
if (strcasecmp(head->keyword, keyword) == 0)
return head->func;
head = head->next;
}
return NULL;
}
int GetOutputTypeFlags(char *keyword)
{
OutputConfigFuncNode *head = output_config_funcs;
if (keyword == NULL)
return 0;
while (head != NULL)
{
if (strcasecmp(head->keyword, keyword) == 0)
return head->output_type_flags;
head = head->next;
}
return 0;
}
void FreeOutputConfigFuncs(void)
{
OutputConfigFuncNode *head = output_config_funcs;
OutputConfigFuncNode *tmp;
while (head != NULL)
{
tmp = head->next;
if (head->keyword != NULL)
free(head->keyword);
free(head);
head = tmp;
}
}
void FreeOutputList(OutputFuncNode *list)
{
while (list != NULL)
{
OutputFuncNode *tmp = list;
list = list->next;
if(tmp != NULL)
{
free(tmp);
}
}
}
/****************************************************************************
*
* Function: DumpOutputPlugins()
*
* Purpose: Prints the Output keyword list
*
* Arguments: None.
*
* Returns: void function
*
***************************************************************************/
void DumpOutputPlugins(void)
{
OutputConfigFuncNode *idx = output_config_funcs;
LogMessage("-------------------------------------------------\n");
LogMessage(" Keyword | Output @ \n");
LogMessage("-------------------------------------------------\n");
while(idx != NULL)
{
LogMessage("%-13s: %p\n", idx->keyword, idx->func);
idx = idx->next;
}
LogMessage("-------------------------------------------------\n\n");
}
void AddFuncToOutputList(OutputFunc func, OutputType type, void *arg)
{
switch (type)
{
case OUTPUT_TYPE__ALERT:
AppendOutputFuncList(func, arg, &AlertList);
break;
case OUTPUT_TYPE__LOG:
AppendOutputFuncList(func, arg, &LogList);
break;
default:
/* just to be error-prone */
FatalError("Unknown output type: %i. Possible bug, please "
"report.\n", type);
}
}
void AppendOutputFuncList(OutputFunc func, void *arg, OutputFuncNode **list)
{
OutputFuncNode *node;
if (list == NULL)
return;
node = (OutputFuncNode *)SnortAlloc(sizeof(OutputFuncNode));
if (*list == NULL)
{
*list = node;
}
else
{
OutputFuncNode *tmp = *list;
while (tmp->next != NULL)
tmp = tmp->next;
tmp->next = node;
}
node->func = func;
node->arg = arg;
}
void CallOutputPlugins(OutputType out_type, Packet *packet, void *event, uint32_t event_type)
{
OutputFuncNode *idx = NULL;
if (out_type == OUTPUT_TYPE__SPECIAL)
{
idx = AlertList;
while (idx != NULL)
{
idx->func(packet, event, event_type, idx->arg);
idx = idx->next;
}
idx = LogList;
while (idx != NULL)
{
idx->func(packet, event, event_type, idx->arg);
idx = idx->next;
}
}
else
{
//All those sub "Log" type will go away in the future..
//Iterate Log and Alert.
idx = LogList;
while (idx != NULL)
{
idx->func(packet, event, event_type, idx->arg);
idx = idx->next;
}
idx = AlertList;
while (idx != NULL)
{
idx->func(packet, event, event_type, idx->arg);
idx = idx->next;
}
}
}
/************************** Miscellaneous Functions **************************/
void PostConfigInitPlugins(PluginSignalFuncNode *post_config_funcs)
{
while (post_config_funcs != NULL)
{
post_config_funcs->func(0, post_config_funcs->arg);
post_config_funcs = post_config_funcs->next;
}
}
/* functions to aid in cleaning up after plugins
* Used for both rule options and output. Preprocessors have their own */
void AddFuncToRestartList(PluginSignalFunc func, void *arg)
{
AddFuncToSignalList(func, arg, &plugin_restart_funcs);
}
void AddFuncToCleanExitList(PluginSignalFunc func, void *arg)
{
AddFuncToSignalList(func, arg, &plugin_clean_exit_funcs);
}
void AddFuncToShutdownList(PluginSignalFunc func, void *arg)
{
AddFuncToSignalList(func, arg, &plugin_shutdown_funcs);
}
void AddFuncToPostConfigList(PluginSignalFunc func, void *arg)
{
Barnyard2Config *bc = barnyard2_conf_for_parsing;
if (bc == NULL)
{
FatalError("%s(%d) Barnyard2 config for parsing is NULL.\n",
__FILE__, __LINE__);
}
AddFuncToSignalList(func, arg, &bc->plugin_post_config_funcs);
}
void AddFuncToSignalList(PluginSignalFunc func, void *arg, PluginSignalFuncNode **list)
{
PluginSignalFuncNode *node;
if (list == NULL)
return;
node = (PluginSignalFuncNode *)SnortAlloc(sizeof(PluginSignalFuncNode));
if (*list == NULL)
{
*list = node;
}
else
{
PluginSignalFuncNode *tmp = *list;
while (tmp->next != NULL)
tmp = tmp->next;
tmp->next = node;
}
node->func = func;
node->arg = arg;
}
void FreePluginSigFuncs(PluginSignalFuncNode *head)
{
while (head != NULL)
{
PluginSignalFuncNode *tmp = head;
head = head->next;
/* don't free sig->arg, that's free'd by the CleanExit/Restart func */
free(tmp);
}
}
Jump to Line
Something went wrong with that request. Please try again.