SOURCES: snort-2.4.3-clamonly.diff (NEW) - adds support for ClamAV...

mguevara mguevara at pld-linux.org
Mon Jun 12 18:41:09 CEST 2006


Author: mguevara                     Date: Mon Jun 12 16:41:09 2006 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- adds support for ClamAV (antivirus) preprocessor support for snort
  taken from:
  http://www.bleedingsnort.com/staticpages/index.php?page=snort-clamav

---- Files affected:
SOURCES:
   snort-2.4.3-clamonly.diff (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/snort-2.4.3-clamonly.diff
diff -u /dev/null SOURCES/snort-2.4.3-clamonly.diff:1.1
--- /dev/null	Mon Jun 12 18:41:09 2006
+++ SOURCES/snort-2.4.3-clamonly.diff	Mon Jun 12 18:41:04 2006
@@ -0,0 +1,1042 @@
+diff -uNr snort-2.4.3/configure.in snort-2.4.3-clamav/configure.in
+--- snort-2.4.3/configure.in	2005-10-16 17:21:08.000000000 -0500
++++ snort-2.4.3-clamav/configure.in	2005-10-23 22:28:16.000000000 -0500
+@@ -859,7 +859,59 @@
+ 		AC_CHECK_TYPE(u_int32_t, uint32_t)
+ 	fi
+ fi
++AC_ARG_ENABLE(clamav,
++[  --enable-clamav          Enable the clamav preprocessor],
++                enable_clamav="$enableval", enable_clamav="no")
++if test "$enable_clamav" = "yes"; then
++    CFLAGS="$CFLAGS -DCLAMAV"
++
++    AC_ARG_WITH(clamav_includes,
++        [  --with-clamav-includes=DIR   clamav include directory],
++        [with_clamav_includes="$withval"],[with_clamav_includes=no])
++
++    AC_ARG_WITH(clamav_defdir,
++        [  --with-clamav-defdir=DIR   clamav virusdefinitions directory],
++        [with_clamav_defdir="$withval"],[with_clamav_defdir=no])
++
++
++    if test "$with_clamav_defdir" != "no"; then
++        echo "Virusdefs: $with_clamav_defdir"
++        CFLAGS="$CFLAGS -DCLAMAV_DEFDIR=\"$with_clamav_defdir\""
++    fi
++
++    if test "$with_clamav_includes" != "no"; then
++        CPPFLAGS="${CPPFLAGS} -I${with_clamav_includes}"
++    fi       
++
++    LCLAM=""
++    AC_CHECK_HEADERS(clamav.h,, LCLAM="no")
++    if test "$LCLAM" = "no"; then
++        echo
++        echo "   ERROR!  clamav.h header not found, go get it from"
++        echo "   http://www.clamav.net/ or use the --with-clamav-includes"
++        echo "   options, if you have it installed in an unusual place"
++        exit
++    fi
++
++    LCLAM=""
++    AC_CHECK_LIB(clamav,cl_scanbuff,, LCLAM="no")
++    if test "$LCLAM" = "no"; then
++        echo
++        echo "   ERROR!  libclamav library not found, go get it from"
++        echo "   http://www.clamav.net/ or make sure that the place"
++        echo "   you installed it is in the library path."
++        exit
++    fi
++
++    # in 0.80 cl_buildtrie is renamed to cl_build
++    LCLAM=""
++    AC_CHECK_LIB(clamav, cl_build,, LCLAM="no")
++    if test "$LCLAM" != "no"; then
++        CFLAGS="$CFLAGS -DCLAMAV_HAVE_CL_BUILD"
++    fi
+ 
++    LIBS="${LIBS} -lclamav"
++fi
+ 
+ # let's make some fixes..
+ 
+diff -uNr snort-2.4.3/src/debug.h snort-2.4.3-clamav/src/debug.h
+--- snort-2.4.3/src/debug.h	2005-03-16 15:52:17.000000000 -0600
++++ snort-2.4.3-clamav/src/debug.h	2005-10-23 22:28:16.000000000 -0500
+@@ -49,7 +49,7 @@
+ #define DEBUG_HTTPINSPECT     0x00400000  /* 4194304 */
+ #define DEBUG_STREAM_STATE    0x00800000  /* 8388608 */
+ #define DEBUG_ASN1            0x01000000  /* 16777216 */
+-
++#define DEBUG_CLAMAV          0x04000000  /* 67108864 */
+ #ifdef DEBUG
+ 
+     extern char *DebugMessageFile;
+diff -uNr snort-2.4.3/src/generators.h snort-2.4.3-clamav/src/generators.h
+--- snort-2.4.3/src/generators.h	2005-10-16 13:55:29.000000000 -0500
++++ snort-2.4.3-clamav/src/generators.h	2005-10-23 22:28:17.000000000 -0500
+@@ -253,6 +253,9 @@
+ 
+ #define GENERATOR_SMTP                             124
+ 
++#define GENERATOR_SPP_CLAMAV                       125 
++#define     CLAMAV_VIRUSFOUND                        1
++
+ /*  This is where all the alert messages will be archived for each
+     internal alerts */
+ 
+@@ -439,4 +442,5 @@
+ 
+ #define PSNG_OPEN_PORT_STR "(portscan) Open Port"
+ 
++#define CLAMAV_VIRUSFOUND_STR "(spp_clamav) Virus Found:"
+ #endif /* __GENERATORS_H__ */
+diff -uNr snort-2.4.3/src/plugbase.c snort-2.4.3-clamav/src/plugbase.c
+--- snort-2.4.3/src/plugbase.c	2005-08-23 10:52:19.000000000 -0500
++++ snort-2.4.3-clamav/src/plugbase.c	2005-10-23 22:28:16.000000000 -0500
+@@ -63,6 +63,7 @@
+ #include "preprocessors/spp_sfportscan.h"
+ #include "preprocessors/spp_frag3.h"
+ #include "preprocessors/spp_xlink2state.h"
++#include "preprocessors/spp_clamav.h"
+ 
+ /* built-in detection plugins */
+ #include "detection-plugins/sp_pattern_match.h"
+@@ -421,6 +422,9 @@
+     SetupPsng();
+     SetupFrag3();
+     SetupXLINK2STATE();
++#ifdef CLAMAV
++    SetupClamAV();
++#endif
+ }
+ 
+ /****************************************************************************
+diff -uNr snort-2.4.3/src/preprocessors/Makefile.am snort-2.4.3-clamav/src/preprocessors/Makefile.am
+--- snort-2.4.3/src/preprocessors/Makefile.am	2005-04-22 17:11:53.000000000 -0500
++++ snort-2.4.3-clamav/src/preprocessors/Makefile.am	2005-10-23 22:28:17.000000000 -0500
+@@ -27,6 +27,7 @@
+ spp_xlink2state.c spp_xlink2state.h \
+ xlink2state.c xlink2state.h \
+ str_search.c str_search.h \
+-stream.h
++stream.h \
++spp_clamav.c spp_clamav.h
+ 
+ INCLUDES = @INCLUDES@
+diff -uNr snort-2.4.3/src/preprocessors/spp_clamav.c snort-2.4.3-clamav/src/preprocessors/spp_clamav.c
+--- snort-2.4.3/src/preprocessors/spp_clamav.c	1969-12-31 18:00:00.000000000 -0600
++++ snort-2.4.3-clamav/src/preprocessors/spp_clamav.c	2005-10-23 22:28:16.000000000 -0500
+@@ -0,0 +1,888 @@
++/* $Id$ */
++/* Snort Preprocessor for Antivirus Checking with ClamAV */
++
++/*
++** Copyright (C) 1998-2002 Martin Roesch <roesch at sourcefire.com>
++** Copyright (C) 2003 Sourcefire, Inc.
++** Copyright (C) 2004 William Metcalf <William_Metcalf at kcmo.org> and
++**                    Victor Julien <victor at nk.nl>
++**
++** 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.
++*/
++
++#ifdef CLAMAV
++
++/* spp_clamav.c 
++ * 
++ * Purpose: Sends packet p to ClamAV for Antivirus checking.
++ *
++ * Arguments: None
++ *   
++ * Effect: Who needs virus.rules??? : -)
++ *
++ * Comments:
++ *
++ *
++ * TODO:
++ * - documentation
++ * - are the defaultports in ParseClamAVArgs ok?
++ * - options structure like s4data in Stream4 for cl_root, VirusScanPorts, drop/reject/alert, defs dirlocation **IN PROGRESS**
++ *
++ *
++ * Changes:
++ * 
++ * 2004/11/10: added code for the automatic reloading of the virusdefs
++ *             added support for ClamAV 0.80 
++ *
++ */
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#ifndef DEBUG
++    #ifndef INLINE
++        #define INLINE inline
++    #endif
++#else
++    #ifdef INLINE
++        #undef INLINE
++    #endif
++    #define INLINE
++#endif /* DEBUG */
++
++
++#include <sys/types.h>
++#include <stdlib.h>
++#include <ctype.h>
++#include <rpc/types.h>
++#include <errno.h>
++#include "generators.h"
++#include "event_wrapper.h"
++#include "util.h"
++#include "plugbase.h"
++#include "parser.h"
++#include "decode.h"
++#include "debug.h"
++#include "mstring.h"
++#include "log.h"
++#include "spp_clamav.h"
++#include "preprocessors/spp_stream4.h"
++#ifdef GIDS
++#include "inline.h"
++#endif
++
++#include "snort.h"
++#include <clamav.h>
++
++#ifdef HAVE_STRINGS_H
++#include <strings.h>
++#endif
++
++
++/* we need this to stringify the CLAMAV_DEFDIR which is supplied at compiletime see:
++   http://gcc.gnu.org/onlinedocs/gcc-3.4.1/cpp/Stringification.html#Stringification */
++#define xstr(s) str(s)
++#define str(s) #s
++
++/* the config struct */
++struct ClamAVConfig
++{
++     /* scan mode */
++    char file_descriptor_mode;
++
++    /* scan limitations */
++    char toclientonly; /* if set to 1 scan only traffic to the client */
++    char toserveronly; /* if set to 1 scan only traffic to the server */
++    char VirusScanPorts[65536/8]; /* array containing info about which ports we care about */
++
++    /* actions */
++    char drop;
++    char reset;
++    
++    /* virdef dir */
++    char dbdir[255];
++    
++    /* temp dir for file descriptors */
++    char desctmpdir[255];
++
++    /* reload time in seconds */
++    u_int16_t reloadtime;
++    u_int32_t next_reload_time;
++
++} clamcnf;
++
++/* pointer to ClamAV's in-memory virusdatabase */
++struct cl_node *cl_root;
++/* scanner limits */
++struct cl_limits clam_limits;
++ssize_t writepacket(int, const void *, size_t);
++static void ClamAVInit(u_char *);
++extern void SetupClamAV();
++static int VirusInPacket(Packet *);
++static void VirusChecker(Packet *,void *);
++extern u_int32_t event_id;
++
++/* db reloading */
++struct cl_stat dbstat; 
++
++
++/*
++ * Function: SetupClamAV()
++ *
++ * Purpose: Registers the preprocessor.
++ *
++ * Arguments: None.
++ *
++ * Returns: void function
++ *
++ */
++void SetupClamAV()
++{
++    RegisterPreprocessor("ClamAV", ClamAVInit);
++}
++
++
++/*
++ * Function: ProcessPorts(u_char *)
++ *
++ * Purpose: Sets the port limits
++ *
++ * Arguments: pointer to string with portlist.
++ *
++ * Returns: void function
++ *
++ */
++static void ProcessPorts(u_char *portlist)
++{
++    int j = 0;
++    int i = 0;
++    char **ports;
++    int num_ports;
++    char *port;
++    u_int32_t portnum;
++
++    /* reset the ports array */
++    bzero(&clamcnf.VirusScanPorts, sizeof(clamcnf.VirusScanPorts));
++
++    ports = mSplit(portlist, " ", 40, &num_ports, 0);
++
++    /* run through the ports */
++    for(j = 0; j < num_ports; j++)
++    {
++        port = ports[j];
++
++        /* we need to set this port */
++        if(isdigit((int)port[0]))
++        {
++            portnum = atoi(port);
++            if(portnum > 65535)
++            {
++                FatalError("%s(%d) => Bad port list to scan: "
++                    "port '%d' out of range\n", portnum, file_name, file_line);
++            }
++
++            /* mark this port as being interesting using some portscan2-type voodoo, 
++               and also add it to the port list string while we're at it so we can
++               later print out all the ports with a single LogMessage() */
++            clamcnf.VirusScanPorts[(portnum/8)] |= 1<<(portnum%8);
++        }
++        /* we need to unset this port */
++        else if(port[0] == '!')
++        {
++            for(i = 0; i < strlen(port) && port[i+1] != '\0'; i++)
++            {
++                port[i] = port[i+1];
++            }
++            port[i] = '\0';
++
++            if(isdigit((int)port[0]))
++            {
++                portnum = atoi(port);
++                if(portnum > 65535)
++                {
++                    FatalError("%s(%d) => Bad port list to scan: "
++                        "port '%d' out of range\n", portnum, file_name, file_line);
++                }
++
++                /* clear the bit - this removes the port from the array */
++                clamcnf.VirusScanPorts[(portnum/8)] &= ~(1<<(portnum%8));
++            }
++            else
++            {
++                FatalError("%s(%d) => Bad port list to scan: "
++                           "bad port\n", file_name, file_line);
++            }
++        }
++        /* we need to set all ports */
++        else if(!strncasecmp(port, "all", 3))
++        {
++            /* enable all ports */
++            for(portnum = 0; portnum <= 65535; portnum++)
++                clamcnf.VirusScanPorts[(portnum/8)] |= 1<<(portnum%8);
++        }
++        else if(!strncasecmp(port, "ports", 5));
++        else
++        {
++            FatalError("%s(%d) => Bad port list to scan: "
++                       "bad port\n", file_name, file_line);
++        }
++    }
++
++    mSplitFree(&ports, num_ports);
++
++    /* some pretty printing */
++    if(!pv.quiet_flag)
++    {
++        /* print the portlist */
++        LogMessage("    Ports: ");       
++
++        for(portnum = 0, j = 0; portnum <= 65535; portnum++)
++        {
++            if((clamcnf.VirusScanPorts[(portnum/8)] & (1<<(portnum%8))))
++            {
++                LogMessage("%d ", portnum);
++                j++;
++            }
++
++            if(j > 20)
++            { 
++                LogMessage("...\n");
++                return;
++            }
++        }
++    }
++}
++
++
++ /*
++  * Function: ParseClamAVArgs(u_char *)
++  *
++  * Purpose: reads the options.
++  *
++  * Arguments: pointer to string with options
++  *
++  * Returns: void function
++  */
++void ParseClamAVArgs(u_char *args)
++{
++    char **toks;
++    int num_toks;
++    int i = 0;
++    char *index;
++    int ports_done = 0;
++    char **dbdirtoks;
++    int num_dbdirtoks = 0;
++    char **dbtimetoks;
++    int num_dbtimetoks = 0;
++    char **desctmptoks;
++    int num_desctmptoks = 0;
++
++
++    /* ftp, smtp, http, pop3, nntp, samba (2x), imap */
++    u_char *default_ports = "21 25 80 81 110 119 139 445 143";
++    
++    /* set the default values */
++    clamcnf.file_descriptor_mode = 0;
++
++#ifdef GIDS
++    clamcnf.drop = 0;
++    clamcnf.reset = 0;
++#endif /* GIDS */
++    clamcnf.toclientonly = 0;
++    clamcnf.toserveronly = 0;
++    
++#ifdef CLAMAV_DEFDIR
++    /* copy the default that was set at compile time, if any */
++    if(strlcpy(clamcnf.dbdir, xstr(CLAMAV_DEFDIR), sizeof(clamcnf.dbdir)) >= sizeof(clamcnf.dbdir))
++#else
++    /* otherwise a buildin default */
++    if(strlcpy(clamcnf.dbdir, "/var/lib/clamav/", sizeof(clamcnf.dbdir)) >= sizeof(clamcnf.dbdir))
++#endif
++    {
++	FatalError("The defdir supplied at compile time is too long\n");
++    }    
++
++
++
++    /* reload time default to 10 minutes */
++    clamcnf.reloadtime = 600;
++
++
++    if(!pv.quiet_flag)
++    {
++        LogMessage("ClamAV config:\n");
++    }
++
++
++    /* if no args, load the default config */
++    if(args == NULL)
++    {
++        if(!pv.quiet_flag)
++        {
++            LogMessage("    no options, using defaults.\n");
++        }
++    }
++    /* process the args */
++    else
++    {
++        toks = mSplit(args, ",", 12, &num_toks, 0);
++
++        for(i = 0; i < num_toks; i++)
++        {
++            index = toks[i];
++            while(isspace((int)*index)) index++;
++
++            if(!strncasecmp(index, "ports", 5))
++            {
++                ProcessPorts(toks[i]);
++                ports_done = 1;
++            }
++#ifdef GIDS
++            else if(!strncasecmp(index, "action-reset", 12))
++            {
++               clamcnf.reset = 1;
++            }
++            else if(!strncasecmp(index, "action-drop", 11))
++            {
++               clamcnf.drop = 1;
++            }
++#endif /* GIDS */ 
++            else if(!strncasecmp(index, "file-descriptor-mode", 20))
++            {
++               clamcnf.file_descriptor_mode = 1;
++
++               if(strlcpy(clamcnf.desctmpdir, "/tmp", sizeof(clamcnf.desctmpdir)) >= sizeof(clamcnf.desctmpdir))
++               {
++	          FatalError("argument is to long, Somebody wrote some really bad code because this should never happen\n");
++               }
++            }
++            else if(!strncasecmp(index, "toclientonly", 12))
++            {
++               clamcnf.toclientonly = 1;
++            }
++            else if(!strncasecmp(index, "toserveronly", 12))
++            {
++               clamcnf.toserveronly = 1;
++            }
++            else if(!strncasecmp(index, "dbdir", 5))
++            {
++		/* get the argument for the option */
++		dbdirtoks = mSplit(index, " ", 1, &num_dbdirtoks, 0);
++
++		/* copy it to the clamcnf */
++	        if(strlcpy(clamcnf.dbdir, dbdirtoks[1], sizeof(clamcnf.dbdir)) >= sizeof(clamcnf.dbdir))
++	        {
++		    FatalError("The defdir supplied in the config is too long\n");
++	        }
++              mSplitFree(&dbdirtoks, num_dbdirtoks);    
++            }
++            else if(!strncasecmp(index, "dbreload-time", 13))
++            {
++                /* get the argument for the option */
++                dbtimetoks = mSplit(index, " ", 1, &num_dbtimetoks, 0);
++                
++                if(isdigit((int)dbtimetoks[1][0]))
++                {
++                    clamcnf.reloadtime  = atoi(dbtimetoks[1]);
++                }
++                else
++                {
++                    FatalError("We need an integer in seconds for dbreload interval\n");
++                }
++              mSplitFree(&dbtimetoks, num_dbtimetoks);
++            }
++            else if((!strncasecmp(index, "descriptor-temp-dir", 19) && (clamcnf.file_descriptor_mode)))
++            {
++		/* get the argument for the option */
++		desctmptoks = mSplit(index, " ", 1, &num_desctmptoks, 0);
++
++		/* copy it to the clamcnf */
++	        if(strlcpy(clamcnf.desctmpdir, desctmptoks[1], sizeof(clamcnf.desctmpdir)) >= sizeof(clamcnf.desctmpdir))
++	        {
++		    FatalError("The tmpdir supplied in the config is too long\n");
++	        }
++              mSplitFree(&desctmptoks, num_desctmptoks);    
++            }
++            else
++            {
++                FatalError("%s(%d) => Bad ClamAV option specified: "
++                           "\"%s\"\n", file_name, file_line, toks[i]);
++            }
++        }
++
++        mSplitFree(&toks, num_toks);
++    }
++
++#ifdef GIDS
++    /* sanety checks */
++    if(clamcnf.drop && clamcnf.reset)
++    {
++	FatalError("Can't set action-drop and action-reset together!\n");
++    }
++#endif /* GIDS */
++    if(clamcnf.toclientonly && clamcnf.toserveronly)
++    {
++	FatalError("Can't set toclientonly and toserveronly together!\n");
++    }
++
++
++    /* if at this stage the ports are not yet done, load the default ports */
++    if(!ports_done)
++        ProcessPorts(default_ports);
++
++
++    /* some pretty printing */
++    if(!pv.quiet_flag)
++    {
++	/* action */
++#ifdef GIDS
++        if(clamcnf.drop == 1)
++            LogMessage("    Virus found action: DROP\n");
++        else if(clamcnf.reset == 1)
++            LogMessage("    Virus found action: RESET\n");
++        else
++            LogMessage("    Virus found action: ALERT\n");
++#endif /* GIDS */	
++        /* dbdir */
++        LogMessage("    Virus definitions dir: '%s'\n", clamcnf.dbdir);    
++	/* limits */
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list