⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spo_xml.c

📁 网络入侵检测系统
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
** 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 + -