📄 spo_xml.c
字号:
/*
** Copyright (C) 2000,2001 Carnegie Mellon University
**
** Snort XML Output Plug-in by the CERT Coordination Center
** Jed Pickel <jpickel@cert.org> <jed@pickel.net>
** Roman Danyliw <rdd@cert.org> <roman@danyliw.com>
**
** This plugin was developed as a part of the AIRCERT project.
**
** See README.xml for instructions
**
** 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_xml.c,v 1.24 2001/01/02 08:06:01 roesch Exp $ */
#include "spo_xml.h"
extern PV pv;
#define ENABLE_SESSION_RESUME
#ifdef ENABLE_SNORT_TIMING
#define SNORT_TIMING_FILE "snort_clnt.time"
#include "snort_timing.c"
#endif
/* HTTPS response codes */
const char *https_return_messages[20] =
{
"200 OK",
"300 AUTH_CLIENT_OK", /* AUTH */
"301 AUTH_CLIENT_DENIED",
"302 AUTH_CLIENT_UNKNOWN",
"303 AUTH_CLIENT_IGNORED",
"400 INPUT_COMMIT_OK", /* DB */
"401 INPUT_COMMIT_ERROR",
"402 INPUT_EMPTY",
"403 INPUT_MALFORMED",
"404 INPUT_INVALID",
"405 INPUT_PARSER_ERROR",
"406 INPUT_INCOMPLETE",
"407 INPUT_DB_READ_FAIL",
"408 INPUT_OVERFLOW",
"409 INPUT_IGNORED",
"500 THROTTLE_OK", /* THROTTLE */
"501 THROTTLE_CONGESTION",
"502 THROTTLE_QUENCH",
"503 THROTTLE_DENIED",
"504 THROTTLE_IGNORED"
};
unsigned int packet_cnt = 0; /* counter of # of packets Snort received */
/*
* Function: SetupXml()
*
* 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 SetupXml()
{
/* link the preprocessor keyword to the init function in
the preproc list */
RegisterOutputPlugin("xml", NT_OUTPUT_LOG, XmlInit);
#ifdef DEBUG
printf(XMLMOD": Output plugin: xml is registered\n");
#endif
}
/*
* Function: XmlInit(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 XmlInit(u_char *args)
{
XmlData *d;
#ifdef ENABLE_SNORT_TIMING
SNORT_TIME_START();
#endif
/* parse the argument list from the rules file */
d = ParseXmlArgs(args);
/* - Do a DNS name lookup if logging to a server,
* - Setup a signal handler for SIGPIPE for socket errors
*/
if(d->host)
{
d->host_ipaddr = gethostbyname(d->host);
signal(SIGPIPE, BrokenNetConnection);
}
/* initialize output buffer */
d->root = NULL;
flush_data(d);
/* what timezone are we in? */
d->tz = GetLocalTimezone();
/* find the IP address we are sniffing from */
d->sensor_ip = GetIP(pv.interface);
d->sensor_hostname = GetHostname();
/* init the SSL context if using https */
#ifdef ENABLE_SSL
if(d->protocol)
if(!strcasecmp(d->protocol, "https"))
init_snort_ssl_ctx(d);
#endif
/* Add the processor function into the function list */
if(!strncasecmp(d->facility,"log",3))
{
pv.log_plugin_active = 1;
printf(XMLMOD"Using the \"log\" facility\n");
AddFuncToOutputList(LogXml, NT_OUTPUT_LOG, d);
}
else
{
pv.alert_plugin_active = 1;
printf(XMLMOD"Using the \"alert\" facility\n");
AddFuncToOutputList(LogXml, NT_OUTPUT_ALERT, d);
}
AddFuncToCleanExitList(XmlExit, d);
AddFuncToRestartList(XmlRestart, d);
}
/*
* Function: ParseXmlArgs(char *)
*
* Purpose: Process the preprocessor arguements from the rules file and
* initialize the preprocessor's data struct.
*
* Arguments: args => argument list
*
* Returns: void function
*
*/
XmlData *ParseXmlArgs(char *args)
{
XmlData *d;
char * xarg;
char * tmp;
char filename[STD_BUF+1];
time_t curr_time;
struct tm *loc_time;
char timebuf[10];
#ifdef ENABLE_SSL
FILE *server_lst;
char *ascii_cert;
X509 *tmp_cert;
EVP_PKEY *tmp_key;
#endif
if(args == NULL)
{
FatalError(XMLMOD"You must supply arguments for xml plugin\n");
}
d = (XmlData *)malloc(sizeof(XmlData));
/* Initialize default values */
d->slist = NULL;
d->sroot = NULL;
d->file = NULL;
d->host = NULL;
d->port = 0;
d->encoding = ENCODING_HEX;
d->detail = DETAIL_FULL;
d->protocol = NULL;
#ifdef ENABLE_SSL
d->collector_name = NULL;
d->issuer_cert = NULL;
d->session = NULL;
d->ssl_trace = 0;
#endif
xarg = strtok(args, ",");
if(xarg != NULL)
{
if((!strncasecmp(xarg,"log",3)) || (!strncasecmp(xarg,"alert",5)))
d->facility = xarg;
else
FatalError(XMLMOD"The first argument needs to be the logging facility");
}
else
FatalError(XMLMOD"Invalid format for first argment");
xarg = strtok(NULL, " =");
while(xarg != NULL)
{
tmp = NULL;
tmp = strtok(NULL, " ");
if(!strncasecmp(xarg,"file",4))
{
d->file = tmp;
printf(XMLMOD"Logging to %s\n", d->file);
}
if(!strncasecmp(xarg,"port",4))
{
d->port = atoi(tmp);
printf(XMLMOD"Port set to %i\n", d->port);
}
if(!strncasecmp(xarg,"host",4))
{
d->host = tmp;
printf(XMLMOD"Host set to %s\n", d->host);
}
if(!strncasecmp(xarg,"protocol",8))
{
d->protocol = tmp;
#ifndef ENABLE_SSL
if(!strcasecmp(d->protocol, "https"))
FatalError(XMLMOD"https support does not appear to be present in this build.\n");
#endif
if(!strcasecmp(d->protocol, "http")
#ifdef ENABLE_SSL
|| !strcasecmp(d->protocol, "https")
#endif
|| !strcasecmp(d->protocol, "iap")
|| !strcasecmp(d->protocol, "tcp"))
printf(XMLMOD"Using %s protocol\n", d->protocol);
else
FatalError(XMLMOD"The %s protocol is not supported\n", d->protocol);
}
if(!strncasecmp(xarg,"sanitize",8))
{
printf(XMLMOD"sanitizing %s\n", tmp);
if(d->slist != NULL)
{
/*d->slist->nextNode = (IPNode*)malloc(sizeof(IPNode));
d->slist = d->slist->nextNode;*/
d->slist->next = (IpAddrSet *)calloc(sizeof(IpAddrSet), sizeof(char));
d->slist = d->slist->next;
}
else
{
d->slist = (IpAddrSet *)calloc(sizeof(IpAddrSet), sizeof(char));
d->sroot = d->slist;
/*d->slist = (IPNode*)malloc(sizeof(IPNode));
d->sroot = d->slist;*/
}
ParseIP(tmp, d->slist);
}
if(!strncasecmp(xarg,"encoding",6))
{
if(!strncasecmp(tmp, "hex", 3))
{
d->encoding = ENCODING_HEX;
}
else
{
if(!strncasecmp(tmp, "base64", 6))
{
d->encoding = ENCODING_BASE64;
}
else
{
if(!strncasecmp(tmp, "ascii", 5))
{
d->encoding = ENCODING_ASCII;
}
else
{
FatalError(XMLMOD"unknown encoding (%s)", tmp);
}
}
}
printf(XMLMOD"data encoding = %s\n", tmp);
}
if(!strncasecmp(xarg,"detail",6))
{
if(!strncasecmp(tmp, "full", 4))
{
d->detail = DETAIL_FULL;
}
else
{
if(!strncasecmp(tmp, "fast", 4))
{
d->detail = DETAIL_FAST;
}
else
{
FatalError(XMLMOD"unknown detail level (%s)", tmp);
}
}
printf(XMLMOD"detail level = %s\n", tmp);
}
#ifdef ENABLE_SSL
if(!strncasecmp(xarg, "cert", 4))
{
d->client_cert_filename = tmp;
printf(XMLMOD"Certificate set to %s\n", d->client_cert_filename);
tmp_cert = load_crt(d->client_cert_filename);
if(!tmp_cert)
FatalError(XMLMOD"invalid client certificate specified\n");
X509_free(tmp_cert);
}
if(!strncasecmp(xarg, "key", 3))
{
d->client_key_filename = tmp;
printf(XMLMOD"Private key set to %s\n", d->client_key_filename);
tmp_key = load_key(d->client_key_filename);
if(!tmp_key)
FatalError(XMLMOD"invalid client key specified\n");
EVP_PKEY_free(tmp_key);
}
if(!strncasecmp(xarg, "ca", 7))
{
d->issuer_filename = tmp;
printf(XMLMOD"Issuer (CA) key set to %s\n", d->issuer_filename);
/* Load the X.509 certificate of the issuer from disk */
d->issuer_cert = load_crt(d->issuer_filename);
if(!d->issuer_cert)
FatalError(XMLMOD"invalid issuer certificate specified\n");
ascii_cert = X509_NAME_oneline (X509_get_subject_name (d->issuer_cert),0,0);
if(!ascii_cert)
FatalError (XMLMOD"invalid issuer certificate\n");
else
printf(XMLMOD"[Issuer]=%s\n", ascii_cert);
free(ascii_cert);
}
if(!strncasecmp(xarg, "server", 6))
{
printf(XMLMOD"Logging server list in %s\n", tmp);
if((server_lst = fopen ( tmp, "r")) == NULL)
FatalError(XMLMOD"Could not open server list file (server): %s\n", tmp);
else
{
d->collector_name = (char *) malloc(400);
fgets(d->collector_name, 399, server_lst);
if(d->collector_name[strlen(d->collector_name)-1] == '\n')
d->collector_name[strlen(d->collector_name)-1] = 0;
}
fclose(server_lst);
if(d->collector_name)
printf(XMLMOD"[Server]=%s\n", d->collector_name);
else
FatalError(XMLMOD"No valid servers found in (server) %s\n", tmp);
}
if(!strncasecmp(xarg, "https_trace", 11))
{
printf(XMLMOD"HTTPS trace logging file is %s\n", tmp);
if((d->ssl_trace = fopen ( tmp, "a")) == NULL)
FatalError(XMLMOD"Could not open HTTPS trace file: %s\n", tmp);
}
#endif
#ifndef ENABLE_SSL
/* catch requests for HTTPS support when it was _not_ built into snort */
if(!strncasecmp(xarg, "cert", 4) || !strncasecmp(xarg, "key", 3) ||
!strncasecmp(xarg, "ca", 7) || !strncasecmp(xarg, "server", 6))
FatalError(XMLMOD"Attempting to use an HTTPS parameter ('%s') when this build does not appear to support it\n", xarg);
#endif
xarg = strtok(NULL, "=");
}
if(d->host != NULL)
{
if(d->protocol != NULL)
{
if(!d->port)
{
#ifdef ENABLE_SSL
if(!strcasecmp(d->protocol, "https"))
d->port = 443;
#endif
if(!strcasecmp(d->protocol, "http"))
d->port = 80;
if(!strcasecmp(d->protocol, "iap"))
d->port = 8000;
}
/* Attempt to connect and post a heartbeat as a test */
}
else
FatalError(XMLMOD"If you supply a host arguement you must also supply a protocol\n");
}
else if(d->file != NULL)
{
if(d->protocol != NULL) FatalError(XMLMOD"can not use a protocol argument with a file argument\n");
if(d->port) FatalError(XMLMOD"can not use a port argument with a file argument\n");
/* generate the unique string to append to the filename.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -