SOURCES: snort-2.6.0.2-clamav.diff (NEW) - raw patch for snort 2.6...

mguevara mguevara at pld-linux.org
Fri Mar 9 15:30:24 CET 2007


Author: mguevara                     Date: Fri Mar  9 14:30:24 2007 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- raw patch for snort 2.6 - clamav support

---- Files affected:
SOURCES:
   snort-2.6.0.2-clamav.diff (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/snort-2.6.0.2-clamav.diff
diff -u /dev/null SOURCES/snort-2.6.0.2-clamav.diff:1.1
--- /dev/null	Fri Mar  9 15:30:24 2007
+++ SOURCES/snort-2.6.0.2-clamav.diff	Fri Mar  9 15:30:19 2007
@@ -0,0 +1,1238 @@
+diff -uNr snort-2.6.0.2/autojunk.sh snort-2.6.0.2.clam/autojunk.sh
+--- snort-2.6.0.2/autojunk.sh	1970-01-01 01:00:00.000000000 +0100
++++ snort-2.6.0.2.clam/autojunk.sh	2006-11-06 08:24:08.000000000 +0100
+@@ -0,0 +1,7 @@
++#!/bin/sh
++# the list of commands that need to run before we do a compile
++aclocal -I m4
++autoheader
++automake --add-missing --copy
++autoconf
++
+diff -uNr snort-2.6.0.2/configure.in snort-2.6.0.2.clam/configure.in
+--- snort-2.6.0.2/configure.in	2006-08-29 21:22:16.000000000 +0200
++++ snort-2.6.0.2.clam/configure.in	2006-11-06 08:24:08.000000000 +0100
+@@ -1033,6 +1033,59 @@
+ 	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.6.0.2/doc/README.clamav snort-2.6.0.2.clam/doc/README.clamav
+--- snort-2.6.0.2/doc/README.clamav	1970-01-01 01:00:00.000000000 +0100
++++ snort-2.6.0.2.clam/doc/README.clamav	2006-11-06 08:24:08.000000000 +0100
+@@ -0,0 +1,34 @@
+++Known limitations
+++=================
++- Please note that detection depends on ClamAV. If clam doesn't know a virus, it will not be detected. So keep your defs up-to-date.
++- Archives are not scanned, unless so small that it fits in one packet/uber-packet.
++- OLE2 virusses are not detected.
++- Attachments to email that are in some way encoded are not scanned.
++- As the clam guy's make there detection more specific it is harder for us to detect viri in on the fly packets.  Much work needs to be done to create application layer decoders - i.e. strip out actual packet payload and remove things such as http headers from packets.
++- turn on clamav by going into snort_inline.conf
++- If you don't configure an action and we detect a vrius, the virus is logged and detection is disabled for the rest of snort, and we flush the stream containing the packet in stream4. We have to do this due to logging restrictions and stream4 reassembly.
++
++preprocessor clamav
++
++This turns on the defaults for clamav which are to listen on ports 21 25 80 81 110 119 139 445 143
++uses the default database location of /var/lib/clamav unless another dbdir was specified at ./configure
++Alerts are written to alert logs no packets are rejected or dropped.
++
++options are 
++
++preprocessor clamav:  ports {portlist separated by " "}, {flow can be toclientonly or toserveronly or defaults to both} {action can be action-drop or  action-reset otherwise default to writing to alert file},{dbdir},{dbreload-time time in seconds to refresh the read of the AV signatures}, {tmpdir for fd mode}
++
++so 
++
++preprocessor clamav: ports all !25 !443 !22, action-reset
++
++
++will turn on clamav will listen for virus activity on all ports except 25 443 22 and send a reset and drop the packet if a virus is detected.
++
++
++preprocessor clamav: ports 139 445 21, toclientonly, action-drop, dbdir /var/lib2/clamav
++
++will turn on clamav, will listen for virus activity on ports 129 445 21 will only watch traffic that flows to the client, will drop the packet, sets the virus-sig database path to /var/lib2/clamav 
++
++to scan uberpackets from stream4 reassembly make sure that stream4 is initialized before ClamAV in your snort_inline.conf
++
+diff -uNr snort-2.6.0.2/src/generators.h snort-2.6.0.2.clam/src/generators.h
+--- snort-2.6.0.2/src/generators.h	2006-08-29 18:59:37.000000000 +0200
++++ snort-2.6.0.2.clam/src/generators.h	2006-11-06 08:24:08.000000000 +0100
+@@ -297,6 +297,9 @@
+ 
+ #define GENERATOR_DNS                             131
+ 
++#define GENERATOR_SPP_CLAMAV                       132
++#define     CLAMAV_VIRUSFOUND                       1
++
+ /*  This is where all the alert messages will be archived for each
+     internal alerts */
+ 
+@@ -472,4 +475,6 @@
+ 
+ #define PSNG_OPEN_PORT_STR "(portscan) Open Port"
+ 
++#define CLAMAV_VIRUSFOUND_STR "(spp_clamav) Virus Found:"
++
+ #endif /* __GENERATORS_H__ */
+diff -uNr snort-2.6.0.2/src/plugbase.c snort-2.6.0.2.clam/src/plugbase.c
+--- snort-2.6.0.2/src/plugbase.c	2006-02-20 20:02:35.000000000 +0100
++++ snort-2.6.0.2.clam/src/plugbase.c	2006-11-06 08:24:08.000000000 +0100
+@@ -60,6 +60,10 @@
+ #include "preprocessors/spp_sfportscan.h"
+ #include "preprocessors/spp_frag3.h"
+ 
++#ifdef CLAMAV
++#include "preprocessors/spp_clamav.h"
++#endif /* CLAMAV */
++
+ /* built-in detection plugins */
+ #include "detection-plugins/sp_pattern_match.h"
+ #include "detection-plugins/sp_tcp_flag_check.h"
+@@ -429,6 +433,9 @@
+     SetupFlow();
+     SetupPsng();
+     SetupFrag3();
++#ifdef CLAMAV
++    SetupClamAV();
++#endif /* CLAMAV */
+ }
+ 
+ void CheckPreprocessorsConfig()
+diff -uNr snort-2.6.0.2/src/preprocessors/Makefile.am snort-2.6.0.2.clam/src/preprocessors/Makefile.am
+--- snort-2.6.0.2/src/preprocessors/Makefile.am	2006-02-03 15:11:46.000000000 +0100
++++ snort-2.6.0.2.clam/src/preprocessors/Makefile.am	2006-11-06 08:24:08.000000000 +0100
+@@ -25,7 +25,8 @@
+ spp_frag2.c spp_frag2.h \
+ spp_frag3.c spp_frag3.h \
+ str_search.c str_search.h \
+-stream_api.c stream_api.h
++stream_api.c stream_api.h \
++spp_clamav.c spp_clamav.h
+ 
+ 
+ INCLUDES = @INCLUDES@
+diff -uNr snort-2.6.0.2/src/preprocessors/spp_clamav.c snort-2.6.0.2.clam/src/preprocessors/spp_clamav.c
+--- snort-2.6.0.2/src/preprocessors/spp_clamav.c	1970-01-01 01:00:00.000000000 +0100
++++ snort-2.6.0.2.clam/src/preprocessors/spp_clamav.c	2006-11-06 08:53:57.000000000 +0100
+@@ -0,0 +1,1031 @@
++/* $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**
++ * - maybe more protocol specific support for less false negatives?
++ *
++ *
++ * Changes:
++ *
++ * 2004/11/10: added code for the automatic reloading of the virusdefs
++ *             added support for ClamAV 0.80
++ * 2006/02/03: added check for http traffic so we better handle http downloads
++ *             removed cl_scanbuf since it was broken anyway
++ *             cleanups and comments added.
++ *             added 8080 to the default ports
++ *
++ */
++#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 */
++
++// enable if this is included in the Snort_inline project as opposed to normal Snort
++//#define SNORTINLINE_SF_NET
++#ifdef SNORTINLINE_SF_NET
++#define STICKYDROP
++#endif
++
++#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 "stream_api.h"
++#include "preprocessors/spp_stream4.h"
++#ifdef GIDS
++#ifdef STICKYDROP
++#include "preprocessors/spp_stickydrop.h"
++#endif
++#include "inline.h"
++#endif
++
++#include "snort.h"
++#include <clamav.h>
++
++#ifdef HAVE_STRINGS_H
++#include <strings.h>
++#endif
++
++#ifdef GIDS
++#ifdef STICKYDROP
++/* stickydrop */
++extern SDtimeout sdt;
++//extern Stream4Data s4data;
++#endif /* STICKYDROP */
++#endif /* GIDS */
++
++/* 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 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;
++#ifdef SNORTINLINE_SF_NET
++   char rboth;
++#endif /* SNORTINLINE_SF_NET */
++
++   /* 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;
++static void ClamAVInit(u_char *);
++extern void SetupClamAV();
++static int VirusInPacket(Packet *);
++int check_4_http_headers(u_int8_t *, int);
++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 and sets the defaults.
++ *
++ * 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 8080";
++
++#ifdef GIDS
++   clamcnf.drop = 0;
++   clamcnf.reset = 0;
++#ifdef SNORTINLINE_SF_NET
++   clamcnf.rboth = 0;
++#endif /* SNORTINLINE_SF_NET */
++#endif /* GIDS */
++   clamcnf.toclientonly = 0;
++   clamcnf.toserveronly = 0;
++
++   /* default tmp dir */
++   if(strlcpy(clamcnf.desctmpdir, "/tmp", sizeof(clamcnf.desctmpdir)) >= sizeof(clamcnf.desctmpdir))
++   {
++       FatalError("The tempdir supplied at compile time is too long\n");
++   }
++
++#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;
++           }
++#ifdef SNORTINLINE_SF_NET
++           else if(!strncasecmp(index, "action-rboth", 12))
++           {
++              clamcnf.rboth = 1;
++           }
++#endif /* SNORTINLINE_SF_NET */
++           else if(!strncasecmp(index, "action-drop", 11))
++           {
++              clamcnf.drop = 1;
++           }
++#endif /* GIDS */
++           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);
++
<<Diff was trimmed, longer than 597 lines>>


More information about the pld-cvs-commit mailing list