diff options
Diffstat (limited to 'config/snort-dev/patches')
-rw-r--r-- | config/snort-dev/patches/SnortSam/TODAO.txt | 1 | ||||
-rw-r--r-- | config/snort-dev/patches/SnortSam/snortsam-2.8.6.1.diff | 3021 | ||||
-rw-r--r-- | config/snort-dev/patches/inlinemode_options_flags.txt | 0 | ||||
-rw-r--r-- | config/snort-dev/patches/spoink_patch/2.8.6/Makefile.am | 17 | ||||
-rw-r--r-- | config/snort-dev/patches/spoink_patch/2.8.6/Makefile.in | 445 | ||||
-rw-r--r-- | config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c | 1544 | ||||
-rw-r--r-- | config/snort-dev/patches/spoink_patch/2.8.6/util.c | 3233 | ||||
-rw-r--r-- | config/snort-dev/patches/spoink_patch/spo_pf.c | 462 | ||||
-rw-r--r-- | config/snort-dev/patches/spoink_patch/spo_pf.h | 60 |
9 files changed, 0 insertions, 8783 deletions
diff --git a/config/snort-dev/patches/SnortSam/TODAO.txt b/config/snort-dev/patches/SnortSam/TODAO.txt deleted file mode 100644 index 3abf0303..00000000 --- a/config/snort-dev/patches/SnortSam/TODAO.txt +++ /dev/null @@ -1 +0,0 @@ -Patch current snort 2.9
\ No newline at end of file diff --git a/config/snort-dev/patches/SnortSam/snortsam-2.8.6.1.diff b/config/snort-dev/patches/SnortSam/snortsam-2.8.6.1.diff deleted file mode 100644 index 983165e1..00000000 --- a/config/snort-dev/patches/SnortSam/snortsam-2.8.6.1.diff +++ /dev/null @@ -1,3021 +0,0 @@ -Index: snort-2.8.6.1/src/twofish.c -=================================================================== ---- snort-2.8.6.1/src/twofish.c (Revision 0) -+++ snort-2.8.6.1/src/twofish.c (Revision 3) -@@ -0,0 +1,971 @@ -+/* $Id: twofish.c,v 2.1 2008/12/15 20:36:05 fknobbe Exp $ -+ * -+ * -+ * Copyright (C) 1997-2000 The Cryptix Foundation Limited. -+ * Copyright (C) 2000 Farm9. -+ * Copyright (C) 2001 Frank Knobbe. -+ * All rights reserved. -+ * -+ * For Cryptix code: -+ * Use, modification, copying and distribution of this software is subject -+ * the terms and conditions of the Cryptix General Licence. You should have -+ * received a copy of the Cryptix General Licence along with this library; -+ * if not, you can download a copy from http://www.cryptix.org/ . -+ * -+ * For Farm9: -+ * --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and -+ * ciphertext stealing technique, added AsciiTwofish class for easy encryption -+ * decryption of text strings -+ * -+ * Frank Knobbe <frank@knobbe.us>: -+ * --- April 2001, converted from C++ to C, prefixed global variables -+ * with TwoFish, substituted some defines, changed functions to make use of -+ * variables supplied in a struct, modified and added routines for modular calls. -+ * Cleaned up the code so that defines are used instead of fixed 16's and 32's. -+ * Created two general purpose crypt routines for one block and multiple block -+ * encryption using Joh's CBC code. -+ * Added crypt routines that use a header (with a magic and data length). -+ * (Basically a major rewrite). -+ * -+ * Note: Routines labeled _TwoFish are private and should not be used -+ * (or with extreme caution). -+ * -+ */ -+ -+#ifndef __TWOFISH_LIBRARY_SOURCE__ -+#define __TWOFISH_LIBRARY_SOURCE__ -+ -+#include <string.h> -+#include <stdlib.h> -+#include <time.h> -+#include <ctype.h> -+#include <sys/types.h> -+ -+#ifdef WIN32 -+ -+#ifndef u_long -+typedef unsigned long u_long; -+#endif -+#ifndef u_int32_t -+typedef unsigned long u_int32_t; -+#endif -+#ifndef u_word -+typedef unsigned short u_word; -+#endif -+#ifndef u_int16_t -+typedef unsigned short u_int16_t; -+#endif -+#ifndef u_char -+typedef unsigned char u_char; -+#endif -+#ifndef u_int8_t -+typedef unsigned char u_int8_t; -+#endif -+ -+#endif /* WIN32 */ -+ -+#include "twofish.h" -+ -+ -+bool TwoFish_srand=TRUE; /* if TRUE, first call of TwoFishInit will seed rand(); */ -+ /* of TwoFishInit */ -+ -+/* Fixed 8x8 permutation S-boxes */ -+static const u_int8_t TwoFish_P[2][256] = -+{ -+ { /* p0 */ -+ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, -+ 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, -+ 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, -+ 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, -+ 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, -+ 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, -+ 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, -+ 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, -+ 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, -+ 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, -+ 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, -+ 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, -+ 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, -+ 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, -+ 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, -+ 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, -+ 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, -+ 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, -+ 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, -+ 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, -+ 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, -+ 0x4A, 0x5E, 0xC1, 0xE0 -+ }, -+ { /* p1 */ -+ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, -+ 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, -+ 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, -+ 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, -+ 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, -+ 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, -+ 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, -+ 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, -+ 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, -+ 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, -+ 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, -+ 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, -+ 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, -+ 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, -+ 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, -+ 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, -+ 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, -+ 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, -+ 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, -+ 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, -+ 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, -+ 0x55, 0x09, 0xBE, 0x91 -+ } -+}; -+ -+static bool TwoFish_MDSready=FALSE; -+static u_int32_t TwoFish_MDS[4][256]; /* TwoFish_MDS matrix */ -+ -+ -+#define TwoFish_LFSR1(x) (((x)>>1)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/2:0)) -+#define TwoFish_LFSR2(x) (((x)>>2)^(((x)&0x02)?TwoFish_MDS_GF_FDBK/2:0)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/4:0)) -+ -+#define TwoFish_Mx_1(x) ((u_int32_t)(x)) /* force result to dword so << will work */ -+#define TwoFish_Mx_X(x) ((u_int32_t)((x)^TwoFish_LFSR2(x))) /* 5B */ -+#define TwoFish_Mx_Y(x) ((u_int32_t)((x)^TwoFish_LFSR1(x)^TwoFish_LFSR2(x))) /* EF */ -+#define TwoFish_RS_rem(x) { u_int8_t b=(u_int8_t)(x>>24); u_int32_t g2=((b<<1)^((b&0x80)?TwoFish_RS_GF_FDBK:0))&0xFF; u_int32_t g3=((b>>1)&0x7F)^((b&1)?TwoFish_RS_GF_FDBK>>1:0)^g2; x=(x<<8)^(g3<<24)^(g2<<16)^(g3<<8)^b; } -+ -+/*#define TwoFish__b(x,N) (((u_int8_t *)&x)[((N)&3)^TwoFish_ADDR_XOR])*/ /* pick bytes out of a dword */ -+ -+#define TwoFish_b0(x) TwoFish__b(x,0) /* extract LSB of u_int32_t */ -+#define TwoFish_b1(x) TwoFish__b(x,1) -+#define TwoFish_b2(x) TwoFish__b(x,2) -+#define TwoFish_b3(x) TwoFish__b(x,3) /* extract MSB of u_int32_t */ -+ -+u_int8_t TwoFish__b(u_int32_t x,int n) -+{ n&=3; -+ while(n-->0) -+ x>>=8; -+ return (u_int8_t)x; -+} -+ -+ -+/* TwoFish Initialization -+ * -+ * This routine generates a global data structure for use with TwoFish, -+ * initializes important values (such as subkeys, sBoxes), generates subkeys -+ * and precomputes the MDS matrix if not already done. -+ * -+ * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') -+ * -+ * Output: Pointer to TWOFISH structure. This data structure contains key dependent data. -+ * This pointer is used with all other crypt functions. -+ */ -+ -+TWOFISH *TwoFishInit(char *userkey) -+{ TWOFISH *tfdata; -+ int i,x,m; -+ char tkey[TwoFish_KEY_LENGTH+40]; -+ -+ tfdata=malloc(sizeof(TWOFISH)); /* allocate the TwoFish structure */ -+ if(tfdata!=NULL) -+ { if(*userkey) -+ { strncpy(tkey,userkey,TwoFish_KEY_LENGTH); /* use first 32 chars of user supplied password */ -+ tkey[TwoFish_KEY_LENGTH]=0; /* make sure it wasn't more */ -+ } -+ else -+ strcpy(tkey,TwoFish_DEFAULT_PW); /* if no key defined, use default password */ -+ for(i=0,x=0,m=strlen(tkey);i<TwoFish_KEY_LENGTH;i++) /* copy into data structure */ -+ { tfdata->key[i]=tkey[x++]; /* fill the whole keyspace with repeating key. */ -+ if(x==m) -+ x=0; -+ } -+ -+ if(!TwoFish_MDSready) -+ _TwoFish_PrecomputeMDSmatrix(); /* "Wake Up, Neo" */ -+ _TwoFish_MakeSubKeys(tfdata); /* generate subkeys */ -+ _TwoFish_ResetCBC(tfdata); /* reset the CBC */ -+ tfdata->output=NULL; /* nothing to output yet */ -+ tfdata->dontflush=FALSE; /* reset decrypt skip block flag */ -+ if(TwoFish_srand) -+ { TwoFish_srand=FALSE; -+ srand(time(NULL)); -+ } -+ } -+ return tfdata; /* return the data pointer */ -+} -+ -+ -+void TwoFishDestroy(TWOFISH *tfdata) -+{ if(tfdata!=NULL) -+ free(tfdata); -+} -+ -+ -+/* en/decryption with CBC mode */ -+unsigned long _TwoFish_CryptRawCBC(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata) -+{ unsigned long rl; -+ -+ rl=len; /* remember how much data to crypt. */ -+ while(len>TwoFish_BLOCK_SIZE) /* and now we process block by block. */ -+ { _TwoFish_BlockCrypt(in,out,TwoFish_BLOCK_SIZE,decrypt,tfdata); /* de/encrypt it. */ -+ in+=TwoFish_BLOCK_SIZE; /* adjust pointers. */ -+ out+=TwoFish_BLOCK_SIZE; -+ len-=TwoFish_BLOCK_SIZE; -+ } -+ if(len>0) /* if we have less than a block left... */ -+ _TwoFish_BlockCrypt(in,out,len,decrypt,tfdata); /* ...then we de/encrypt that too. */ -+ if(tfdata->qBlockDefined && !tfdata->dontflush) /* in case len was exactly one block... */ -+ _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); /* ...we need to write the... */ -+ /* ...remaining bytes of the buffer */ -+ return rl; -+} -+ -+/* en/decryption on one block only */ -+unsigned long _TwoFish_CryptRaw16(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata) -+{ /* qBlockPlain already zero'ed through ResetCBC */ -+ memcpy(tfdata->qBlockPlain,in,len); /* toss the data into it. */ -+ _TwoFish_BlockCrypt16(tfdata->qBlockPlain,tfdata->qBlockCrypt,decrypt,tfdata); /* encrypt just that block without CBC. */ -+ memcpy(out,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE); /* and return what we got */ -+ return TwoFish_BLOCK_SIZE; -+} -+ -+/* en/decryption without reset of CBC and output assignment */ -+unsigned long _TwoFish_CryptRaw(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata) -+{ -+ if(in!=NULL && out!=NULL && len>0 && tfdata!=NULL) /* if we have valid data, then... */ -+ { if(len>TwoFish_BLOCK_SIZE) /* ...check if we have more than one block. */ -+ return _TwoFish_CryptRawCBC(in,out,len,decrypt,tfdata); /* if so, use the CBC routines... */ -+ else -+ return _TwoFish_CryptRaw16(in,out,len,decrypt,tfdata); /* ...otherwise just do one block. */ -+ } -+ return 0; -+} -+ -+ -+/* TwoFish Raw Encryption -+ * -+ * Does not use header, but does use CBC (if more than one block has to be encrypted). -+ * -+ * Input: Pointer to the buffer of the plaintext to be encrypted. -+ * Pointer to the buffer receiving the ciphertext. -+ * The length of the plaintext buffer. -+ * The TwoFish structure. -+ * -+ * Output: The amount of bytes encrypted if successful, otherwise 0. -+ */ -+ -+unsigned long TwoFishEncryptRaw(char *in, -+ char *out, -+ unsigned long len, -+ TWOFISH *tfdata) -+{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ -+ tfdata->output=out; /* output straight into output buffer. */ -+ return _TwoFish_CryptRaw(in,out,len,FALSE,tfdata); /* and go for it. */ -+} -+ -+/* TwoFish Raw Decryption -+ * -+ * Does not use header, but does use CBC (if more than one block has to be decrypted). -+ * -+ * Input: Pointer to the buffer of the ciphertext to be decrypted. -+ * Pointer to the buffer receiving the plaintext. -+ * The length of the ciphertext buffer (at least one cipher block). -+ * The TwoFish structure. -+ * -+ * Output: The amount of bytes decrypted if successful, otherwise 0. -+ */ -+ -+unsigned long TwoFishDecryptRaw(char *in, -+ char *out, -+ unsigned long len, -+ TWOFISH *tfdata) -+{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */ -+ tfdata->output=out; /* output straight into output buffer. */ -+ return _TwoFish_CryptRaw(in,out,len,TRUE,tfdata); /* and go for it. */ -+} -+ -+/* TwoFish Free -+ * -+ * Free's the allocated buffer. -+ * -+ * Input: Pointer to the TwoFish structure -+ * -+ * Output: (none) -+ */ -+ -+void TwoFishFree(TWOFISH *tfdata) -+{ if(tfdata->output!=NULL) /* if a valid buffer is present... */ -+ { free(tfdata->output); /* ...then we free it for you... */ -+ tfdata->output=NULL; /* ...and mark as such. */ -+ } -+} -+ -+/* TwoFish Set Output -+ * -+ * If you want to allocate the output buffer yourself, -+ * then you can set it with this function. -+ * -+ * Input: Pointer to your output buffer -+ * Pointer to the TwoFish structure -+ * -+ * Output: (none) -+ */ -+ -+void TwoFishSetOutput(char *outp,TWOFISH *tfdata) -+{ tfdata->output=outp; /* (do we really need a function for this?) */ -+} -+ -+/* TwoFish Alloc -+ * -+ * Allocates enough memory for the output buffer that would be required -+ * -+ * Input: Length of the plaintext. -+ * Boolean flag for BinHex Output. -+ * Pointer to the TwoFish structure. -+ * -+ * Output: Returns a pointer to the memory allocated. -+ */ -+ -+void *TwoFishAlloc(unsigned long len,bool binhex,bool decrypt,TWOFISH *tfdata) -+{ -+/* TwoFishFree(tfdata); */ /* (don't for now) discard whatever was allocated earlier. */ -+ if(decrypt) /* if decrypting... */ -+ { if(binhex) /* ...and input is binhex encoded... */ -+ len/=2; /* ...use half as much for output. */ -+ len-=TwoFish_BLOCK_SIZE; /* Also, subtract the size of the header. */ -+ } -+ else -+ { len+=TwoFish_BLOCK_SIZE; /* the size is just increased by the header... */ -+ if(binhex) -+ len*=2; /* ...and doubled if output is to be binhexed. */ -+ } -+ tfdata->output=malloc(len+TwoFish_BLOCK_SIZE);/* grab some memory...plus some extra (it's running over somewhere, crashes without extra padding) */ -+ -+ return tfdata->output; /* ...and return to caller. */ -+} -+ -+/* bin2hex and hex2bin conversion */ -+void _TwoFish_BinHex(u_int8_t *buf,unsigned long len,bool bintohex) -+{ u_int8_t *pi,*po,c; -+ -+ if(bintohex) -+ { for(pi=buf+len-1,po=buf+(2*len)-1;len>0;pi--,po--,len--) /* let's start from the end of the bin block. */ -+ { c=*pi; /* grab value. */ -+ c&=15; /* use lower 4 bits. */ -+ if(c>9) /* convert to ascii. */ -+ c+=('a'-10); -+ else -+ c+='0'; -+ *po--=c; /* set the lower nibble. */ -+ c=*pi; /* grab value again. */ -+ c>>=4; /* right shift 4 bits. */ -+ c&=15; /* make sure we only have 4 bits. */ -+ if(c>9) /* convert to ascii. */ -+ c+=('a'-10); -+ else -+ c+='0'; -+ *po=c; /* set the higher nibble. */ -+ } /* and keep going. */ -+ } -+ else -+ { for(pi=buf,po=buf;len>0;pi++,po++,len-=2) /* let's start from the beginning of the hex block. */ -+ { c=tolower(*pi++)-'0'; /* grab higher nibble. */ -+ if(c>9) /* convert to value. */ -+ c-=('0'-9); -+ *po=c<<4; /* left shit 4 bits. */ -+ c=tolower(*pi)-'0'; /* grab lower nibble. */ -+ if(c>9) /* convert to value. */ -+ c-=('0'-9); -+ *po|=c; /* and add to value. */ -+ } -+ } -+} -+ -+ -+/* TwoFish Encryption -+ * -+ * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, -+ * this routine will alloc the memory. In addition, it will include a small 'header' -+ * containing the magic and some salt. That way the decrypt routine can check if the -+ * packet got decrypted successfully, and return 0 instead of garbage. -+ * -+ * Input: Pointer to the buffer of the plaintext to be encrypted. -+ * Pointer to the pointer to the buffer receiving the ciphertext. -+ * The pointer either points to user allocated output buffer space, or to NULL, in which case -+ * this routine will set the pointer to the buffer allocated through the struct. -+ * The length of the plaintext buffer. -+ * Can be -1 if the input is a null terminated string, in which case we'll count for you. -+ * Boolean flag for BinHex Output (if used, output will be twice as large as input). -+ * Note: BinHex conversion overwrites (converts) input buffer! -+ * The TwoFish structure. -+ * -+ * Output: The amount of bytes encrypted if successful, otherwise 0. -+ */ -+ -+unsigned long TwoFishEncrypt(char *in, -+ char **out, -+ signed long len, -+ bool binhex, -+ TWOFISH *tfdata) -+{ unsigned long ilen,olen; -+ -+ -+ if(len== -1) /* if we got -1 for len, we'll assume IN is a... */ -+ ilen=strlen(in); /* ...\0 terminated string and figure len out ourselves... */ -+ else -+ ilen=len; /* ...otherwise we trust you supply a correct length. */ -+ -+ if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ -+ { if(*out==NULL) /* if OUT points to a NULL pointer... */ -+ *out=TwoFishAlloc(ilen,binhex,FALSE,tfdata); /* ...we'll (re-)allocate buffer space. */ -+ if(*out!=NULL) -+ { tfdata->output=*out; /* set output buffer. */ -+ tfdata->header.salt=rand()*65536+rand(); /* toss in some salt. */ -+ tfdata->header.length[0]= (u_int8_t)(ilen); -+ tfdata->header.length[1]= (u_int8_t)(ilen>>8); -+ tfdata->header.length[2]= (u_int8_t)(ilen>>16); -+ tfdata->header.length[3]= (u_int8_t)(ilen>>24); -+ memcpy(tfdata->header.magic,TwoFish_MAGIC,TwoFish_MAGIC_LEN); /* set the magic. */ -+ olen=TwoFish_BLOCK_SIZE; /* set output counter. */ -+ _TwoFish_ResetCBC(tfdata); /* reset the CBC flag */ -+ _TwoFish_BlockCrypt((u_int8_t *)&(tfdata->header),*out,olen,FALSE,tfdata); /* encrypt first block (without flush on 16 byte boundary). */ -+ olen+=_TwoFish_CryptRawCBC(in,*out+TwoFish_BLOCK_SIZE,ilen,FALSE,tfdata); /* and encrypt the rest (we do not reset the CBC flag). */ -+ if(binhex) /* if binhex... */ -+ { _TwoFish_BinHex(*out,olen,TRUE); /* ...convert output to binhex... */ -+ olen*=2; /* ...and size twice as large. */ -+ } -+ tfdata->output=*out; -+ return olen; -+ } -+ } -+ return 0; -+} -+ -+/* TwoFish Decryption -+ * -+ * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, -+ * this routine will alloc the memory. In addition, it will check the small 'header' -+ * containing the magic. If magic does not match we return 0. Otherwise we return the -+ * amount of bytes decrypted (should be the same as the length in the header). -+ * -+ * Input: Pointer to the buffer of the ciphertext to be decrypted. -+ * Pointer to the pointer to the buffer receiving the plaintext. -+ * The pointer either points to user allocated output buffer space, or to NULL, in which case -+ * this routine will set the pointer to the buffer allocated through the struct. -+ * The length of the ciphertext buffer. -+ * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. -+ * Boolean flag for BinHex Input (if used, plaintext will be half as large as input). -+ * Note: BinHex conversion overwrites (converts) input buffer! -+ * The TwoFish structure. -+ * -+ * Output: The amount of bytes decrypted if successful, otherwise 0. -+ */ -+ -+unsigned long TwoFishDecrypt(char *in, -+ char **out, -+ signed long len, -+ bool binhex, -+ TWOFISH *tfdata) -+{ unsigned long ilen,elen,olen; -+ const u_int8_t cmagic[TwoFish_MAGIC_LEN]=TwoFish_MAGIC; -+ u_int8_t *tbuf; -+ -+ -+ -+ if(len== -1) /* if we got -1 for len, we'll assume IN is... */ -+ ilen=strlen(in); /* ...\0 terminated binhex and figure len out ourselves... */ -+ else -+ ilen=len; /* ...otherwise we trust you supply a correct length. */ -+ -+ if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */ -+ { if(*out==NULL) /* if OUT points to a NULL pointer... */ -+ *out=TwoFishAlloc(ilen,binhex,TRUE,tfdata); /* ...we'll (re-)allocate buffer space. */ -+ if(*out!=NULL) -+ { if(binhex) /* if binhex... */ -+ { _TwoFish_BinHex(in,ilen,FALSE); /* ...convert input to values... */ -+ ilen/=2; /* ...and size half as much. */ -+ } -+ _TwoFish_ResetCBC(tfdata); /* reset the CBC flag. */ -+ -+ tbuf=(u_int8_t *)malloc(ilen+TwoFish_BLOCK_SIZE); /* get memory for data and header. */ -+ if(tbuf==NULL) -+ return 0; -+ tfdata->output=tbuf; /* set output to temp buffer. */ -+ -+ olen=_TwoFish_CryptRawCBC(in,tbuf,ilen,TRUE,tfdata)-TwoFish_BLOCK_SIZE; /* decrypt the whole thing. */ -+ memcpy(&(tfdata->header),tbuf,TwoFish_BLOCK_SIZE); /* copy first block into header. */ -+ tfdata->output=*out; -+ for(elen=0;elen<TwoFish_MAGIC_LEN;elen++) /* compare magic. */ -+ if(tfdata->header.magic[elen]!=cmagic[elen]) -+ break; -+ if(elen==TwoFish_MAGIC_LEN) /* if magic matches then... */ -+ { elen=(tfdata->header.length[0]) | -+ (tfdata->header.length[1])<<8 | -+ (tfdata->header.length[2])<<16 | -+ (tfdata->header.length[3])<<24; /* .. we know how much to expect. */ -+ if(elen>olen) /* adjust if necessary. */ -+ elen=olen; -+ memcpy(*out,tbuf+TwoFish_BLOCK_SIZE,elen); /* copy data into intended output. */ -+ free(tbuf); -+ return elen; -+ } -+ free(tbuf); -+ } -+ } -+ return 0; -+} -+ -+void _TwoFish_PrecomputeMDSmatrix(void) /* precompute the TwoFish_MDS matrix */ -+{ u_int32_t m1[2]; -+ u_int32_t mX[2]; -+ u_int32_t mY[2]; -+ u_int32_t i, j; -+ -+ for (i = 0; i < 256; i++) -+ { j = TwoFish_P[0][i] & 0xFF; /* compute all the matrix elements */ -+ m1[0] = j; -+ mX[0] = TwoFish_Mx_X( j ) & 0xFF; -+ mY[0] = TwoFish_Mx_Y( j ) & 0xFF; -+ -+ j = TwoFish_P[1][i] & 0xFF; -+ m1[1] = j; -+ mX[1] = TwoFish_Mx_X( j ) & 0xFF; -+ mY[1] = TwoFish_Mx_Y( j ) & 0xFF; -+ -+ TwoFish_MDS[0][i] = m1[TwoFish_P_00] | /* fill matrix w/ above elements */ -+ mX[TwoFish_P_00] << 8 | -+ mY[TwoFish_P_00] << 16 | -+ mY[TwoFish_P_00] << 24; -+ TwoFish_MDS[1][i] = mY[TwoFish_P_10] | -+ mY[TwoFish_P_10] << 8 | -+ mX[TwoFish_P_10] << 16 | -+ m1[TwoFish_P_10] << 24; -+ TwoFish_MDS[2][i] = mX[TwoFish_P_20] | -+ mY[TwoFish_P_20] << 8 | -+ m1[TwoFish_P_20] << 16 | -+ mY[TwoFish_P_20] << 24; -+ TwoFish_MDS[3][i] = mX[TwoFish_P_30] | -+ m1[TwoFish_P_30] << 8 | -+ mY[TwoFish_P_30] << 16 | -+ mX[TwoFish_P_30] << 24; -+ } -+ TwoFish_MDSready=TRUE; -+} -+ -+ -+void _TwoFish_MakeSubKeys(TWOFISH *tfdata) /* Expand a user-supplied key material into a session key. */ -+{ u_int32_t k64Cnt = TwoFish_KEY_LENGTH / 8; -+ u_int32_t k32e[4]; /* even 32-bit entities */ -+ u_int32_t k32o[4]; /* odd 32-bit entities */ -+ u_int32_t sBoxKey[4]; -+ u_int32_t offset,i,j; -+ u_int32_t A, B, q=0; -+ u_int32_t k0,k1,k2,k3; -+ u_int32_t b0,b1,b2,b3; -+ -+ /* split user key material into even and odd 32-bit entities and */ -+ /* compute S-box keys using (12, 8) Reed-Solomon code over GF(256) */ -+ -+ -+ for (offset=0,i=0,j=k64Cnt-1;i<4 && offset<TwoFish_KEY_LENGTH;i++,j--) -+ { k32e[i] = tfdata->key[offset++]; -+ k32e[i]|= tfdata->key[offset++]<<8; -+ k32e[i]|= tfdata->key[offset++]<<16; -+ k32e[i]|= tfdata->key[offset++]<<24; -+ k32o[i] = tfdata->key[offset++]; -+ k32o[i]|= tfdata->key[offset++]<<8; -+ k32o[i]|= tfdata->key[offset++]<<16; -+ k32o[i]|= tfdata->key[offset++]<<24; -+ sBoxKey[j] = _TwoFish_RS_MDS_Encode( k32e[i], k32o[i] ); /* reverse order */ -+ } -+ -+ /* compute the round decryption subkeys for PHT. these same subkeys */ -+ /* will be used in encryption but will be applied in reverse order. */ -+ i=0; -+ while(i < TwoFish_TOTAL_SUBKEYS) -+ { A = _TwoFish_F32( k64Cnt, q, k32e ); /* A uses even key entities */ -+ q += TwoFish_SK_BUMP; -+ -+ B = _TwoFish_F32( k64Cnt, q, k32o ); /* B uses odd key entities */ -+ q += TwoFish_SK_BUMP; -+ -+ B = B << 8 | B >> 24; -+ -+ A += B; -+ tfdata->subKeys[i++] = A; /* combine with a PHT */ -+ -+ A += B; -+ tfdata->subKeys[i++] = A << TwoFish_SK_ROTL | A >> (32-TwoFish_SK_ROTL); -+ } -+ -+ /* fully expand the table for speed */ -+ k0 = sBoxKey[0]; -+ k1 = sBoxKey[1]; -+ k2 = sBoxKey[2]; -+ k3 = sBoxKey[3]; -+ -+ for (i = 0; i < 256; i++) -+ { b0 = b1 = b2 = b3 = i; -+ switch (k64Cnt & 3) -+ { case 1: /* 64-bit keys */ -+ tfdata->sBox[ 2*i ] = TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0]) ^ TwoFish_b0(k0)]; -+ tfdata->sBox[ 2*i+1] = TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1]) ^ TwoFish_b1(k0)]; -+ tfdata->sBox[0x200+2*i ] = TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2]) ^ TwoFish_b2(k0)]; -+ tfdata->sBox[0x200+2*i+1] = TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3]) ^ TwoFish_b3(k0)]; -+ break; -+ case 0: /* 256-bit keys (same as 4) */ -+ b0 = (TwoFish_P[TwoFish_P_04][b0]) ^ TwoFish_b0(k3); -+ b1 = (TwoFish_P[TwoFish_P_14][b1]) ^ TwoFish_b1(k3); -+ b2 = (TwoFish_P[TwoFish_P_24][b2]) ^ TwoFish_b2(k3); -+ b3 = (TwoFish_P[TwoFish_P_34][b3]) ^ TwoFish_b3(k3); -+ case 3: /* 192-bit keys */ -+ b0 = (TwoFish_P[TwoFish_P_03][b0]) ^ TwoFish_b0(k2); -+ b1 = (TwoFish_P[TwoFish_P_13][b1]) ^ TwoFish_b1(k2); -+ b2 = (TwoFish_P[TwoFish_P_23][b2]) ^ TwoFish_b2(k2); -+ b3 = (TwoFish_P[TwoFish_P_33][b3]) ^ TwoFish_b3(k2); -+ case 2: /* 128-bit keys */ -+ tfdata->sBox[ 2*i ]= -+ TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0]) ^ -+ TwoFish_b0(k1)]) ^ TwoFish_b0(k0)]; -+ -+ tfdata->sBox[ 2*i+1]= -+ TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1]) ^ -+ TwoFish_b1(k1)]) ^ TwoFish_b1(k0)]; -+ -+ tfdata->sBox[0x200+2*i ]= -+ TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2]) ^ -+ TwoFish_b2(k1)]) ^ TwoFish_b2(k0)]; -+ -+ tfdata->sBox[0x200+2*i+1]= -+ TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3]) ^ -+ TwoFish_b3(k1)]) ^ TwoFish_b3(k0)]; -+ } -+ } -+} -+ -+ -+/** -+ * Encrypt or decrypt exactly one block of plaintext in CBC mode. -+ * Use "ciphertext stealing" technique described on pg. 196 -+ * of "Applied Cryptography" to encrypt the final partial -+ * (i.e. <16 byte) block if necessary. -+ * -+ * jojo: the "ciphertext stealing" requires we read ahead and have -+ * special handling for the last two blocks. Because of this, the -+ * output from the TwoFish algorithm is handled internally here. -+ * It would be better to have a higher level handle this as well as -+ * CBC mode. Unfortunately, I've mixed the two together, which is -+ * pretty crappy... The Java version separates these out correctly. -+ * -+ * fknobbe: I have reduced the CBC mode to work on memory buffer only. -+ * Higher routines should use an intermediate buffer and handle -+ * their output seperately (mainly so the data can be flushed -+ * in one chunk, not seperate 16 byte blocks...) -+ * -+ * @param in The plaintext. -+ * @param out The ciphertext -+ * @param size how much to encrypt -+ * @param tfdata: Pointer to the global data structure containing session keys. -+ * @return none -+ */ -+void _TwoFish_BlockCrypt(u_int8_t *in,u_int8_t *out,unsigned long size,int decrypt,TWOFISH *tfdata) -+{ u_int8_t PnMinusOne[TwoFish_BLOCK_SIZE]; -+ u_int8_t CnMinusOne[TwoFish_BLOCK_SIZE]; -+ u_int8_t CBCplusCprime[TwoFish_BLOCK_SIZE]; -+ u_int8_t Pn[TwoFish_BLOCK_SIZE]; -+ u_int8_t *p,*pout; -+ unsigned long i; -+ -+ /* here is where we implement CBC mode and cipher block stealing */ -+ if(size==TwoFish_BLOCK_SIZE) -+ { /* if we are encrypting, CBC means we XOR the plain text block with the */ -+ /* previous cipher text block before encrypting */ -+ if(!decrypt && tfdata->qBlockDefined) -+ { for(p=in,i=0;i<TwoFish_BLOCK_SIZE;i++,p++) -+ Pn[i]=*p ^ tfdata->qBlockCrypt[i]; /* FK: I'm copying the xor'ed input into Pn... */ -+ } -+ else -+ memcpy(Pn,in,TwoFish_BLOCK_SIZE); /* FK: same here. we work of Pn all the time. */ -+ -+ /* TwoFish block level encryption or decryption */ -+ _TwoFish_BlockCrypt16(Pn,out,decrypt,tfdata); -+ -+ /* if we are decrypting, CBC means we XOR the result of the decryption */ -+ /* with the previous cipher text block to get the resulting plain text */ -+ if(decrypt && tfdata->qBlockDefined) -+ { for (p=out,i=0;i<TwoFish_BLOCK_SIZE;i++,p++) -+ *p^=tfdata->qBlockPlain[i]; -+ } -+ -+ /* save the input and output blocks, since CBC needs these for XOR */ -+ /* operations */ -+ _TwoFish_qBlockPush(Pn,out,tfdata); -+ } -+ else -+ { /* cipher block stealing, we are at Pn, */ -+ /* but since Cn-1 must now be replaced with CnC' */ -+ /* we pop it off, and recalculate Cn-1 */ -+ -+ if(decrypt) -+ { /* We are on an odd block, and had to do cipher block stealing, */ -+ /* so the PnMinusOne has to be derived differently. */ -+ -+ /* First we decrypt it into CBC and C' */ -+ _TwoFish_qBlockPop(CnMinusOne,PnMinusOne,tfdata); -+ _TwoFish_BlockCrypt16(CnMinusOne,CBCplusCprime,decrypt,tfdata); -+ -+ /* we then xor the first few bytes with the "in" bytes (Cn) */ -+ /* to recover Pn, which we put in out */ -+ for(p=in,pout=out,i=0;i<size;i++,p++,pout++) -+ *pout=*p ^ CBCplusCprime[i]; -+ -+ /* We now recover the original CnMinusOne, which consists of */ -+ /* the first "size" bytes of "in" data, followed by the */ -+ /* "Cprime" portion of CBCplusCprime */ -+ for(p=in,i=0;i<size;i++,p++) -+ CnMinusOne[i]=*p; -+ for(;i<TwoFish_BLOCK_SIZE;i++) -+ CnMinusOne[i]=CBCplusCprime[i]; -+ -+ /* we now decrypt CnMinusOne to get PnMinusOne xored with Cn-2 */ -+ _TwoFish_BlockCrypt16(CnMinusOne,PnMinusOne,decrypt,tfdata); -+ -+ for(i=0;i<TwoFish_BLOCK_SIZE;i++) -+ PnMinusOne[i]=PnMinusOne[i] ^ tfdata->prevCipher[i]; -+ -+ /* So at this point, out has PnMinusOne */ -+ _TwoFish_qBlockPush(CnMinusOne,PnMinusOne,tfdata); -+ _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); -+ _TwoFish_FlushOutput(out,size,tfdata); -+ } -+ else -+ { _TwoFish_qBlockPop(PnMinusOne,CnMinusOne,tfdata); -+ memset(Pn,0,TwoFish_BLOCK_SIZE); -+ memcpy(Pn,in,size); -+ for(i=0;i<TwoFish_BLOCK_SIZE;i++) -+ Pn[i]^=CnMinusOne[i]; -+ _TwoFish_BlockCrypt16(Pn,out,decrypt,tfdata); -+ _TwoFish_qBlockPush(Pn,out,tfdata); /* now we officially have Cn-1 */ -+ _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); -+ _TwoFish_FlushOutput(CnMinusOne,size,tfdata); /* old Cn-1 becomes new partial Cn */ -+ } -+ tfdata->qBlockDefined=FALSE; -+ } -+} -+ -+void _TwoFish_qBlockPush(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata) -+{ if(tfdata->qBlockDefined) -+ _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); -+ memcpy(tfdata->prevCipher,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE); -+ memcpy(tfdata->qBlockPlain,p,TwoFish_BLOCK_SIZE); -+ memcpy(tfdata->qBlockCrypt,c,TwoFish_BLOCK_SIZE); -+ tfdata->qBlockDefined=TRUE; -+} -+ -+void _TwoFish_qBlockPop(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata) -+{ memcpy(p,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE ); -+ memcpy(c,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE ); -+ tfdata->qBlockDefined=FALSE; -+} -+ -+/* Reset's the CBC flag and zero's PrevCipher (through qBlockPlain) (important) */ -+void _TwoFish_ResetCBC(TWOFISH *tfdata) -+{ tfdata->qBlockDefined=FALSE; -+ memset(tfdata->qBlockPlain,0,TwoFish_BLOCK_SIZE); -+} -+ -+void _TwoFish_FlushOutput(u_int8_t *b,unsigned long len,TWOFISH *tfdata) -+{ unsigned long i; -+ -+ for(i=0;i<len && !tfdata->dontflush;i++) -+ *tfdata->output++ = *b++; -+ tfdata->dontflush=FALSE; -+} -+ -+void _TwoFish_BlockCrypt16(u_int8_t *in,u_int8_t *out,bool decrypt,TWOFISH *tfdata) -+{ u_int32_t x0,x1,x2,x3; -+ u_int32_t k,t0,t1,R; -+ -+ -+ x0=*in++; -+ x0|=(*in++ << 8 ); -+ x0|=(*in++ << 16); -+ x0|=(*in++ << 24); -+ x1=*in++; -+ x1|=(*in++ << 8 ); -+ x1|=(*in++ << 16); -+ x1|=(*in++ << 24); -+ x2=*in++; -+ x2|=(*in++ << 8 ); -+ x2|=(*in++ << 16); -+ x2|=(*in++ << 24); -+ x3=*in++; -+ x3|=(*in++ << 8 ); -+ x3|=(*in++ << 16); -+ x3|=(*in++ << 24); -+ -+ if(decrypt) -+ { x0 ^= tfdata->subKeys[4]; /* swap input and output whitening keys when decrypting */ -+ x1 ^= tfdata->subKeys[5]; -+ x2 ^= tfdata->subKeys[6]; -+ x3 ^= tfdata->subKeys[7]; -+ -+ k = 7+(TwoFish_ROUNDS*2); -+ for (R = 0; R < TwoFish_ROUNDS; R += 2) -+ { t0 = _TwoFish_Fe320( tfdata->sBox, x0); -+ t1 = _TwoFish_Fe323( tfdata->sBox, x1); -+ x3 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; -+ x3 = x3 >> 1 | x3 << 31; -+ x2 = x2 << 1 | x2 >> 31; -+ x2 ^= t0 + t1 + tfdata->subKeys[k--]; -+ -+ t0 = _TwoFish_Fe320( tfdata->sBox, x2); -+ t1 = _TwoFish_Fe323( tfdata->sBox, x3); -+ x1 ^= t0 + (t1<<1) + tfdata->subKeys[k--]; -+ x1 = x1 >> 1 | x1 << 31; -+ x0 = x0 << 1 | x0 >> 31; -+ x0 ^= t0 + t1 + tfdata->subKeys[k--]; -+ } -+ -+ x2 ^= tfdata->subKeys[0]; -+ x3 ^= tfdata->subKeys[1]; -+ x0 ^= tfdata->subKeys[2]; -+ x1 ^= tfdata->subKeys[3]; -+ } -+ else -+ { x0 ^= tfdata->subKeys[0]; -+ x1 ^= tfdata->subKeys[1]; -+ x2 ^= tfdata->subKeys[2]; -+ x3 ^= tfdata->subKeys[3]; -+ -+ k = 8; -+ for (R = 0; R < TwoFish_ROUNDS; R += 2) -+ { t0 = _TwoFish_Fe320( tfdata->sBox, x0); -+ t1 = _TwoFish_Fe323( tfdata->sBox, x1); -+ x2 ^= t0 + t1 + tfdata->subKeys[k++]; -+ x2 = x2 >> 1 | x2 << 31; -+ x3 = x3 << 1 | x3 >> 31; -+ x3 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; -+ -+ t0 = _TwoFish_Fe320( tfdata->sBox, x2); -+ t1 = _TwoFish_Fe323( tfdata->sBox, x3); -+ x0 ^= t0 + t1 + tfdata->subKeys[k++]; -+ x0 = x0 >> 1 | x0 << 31; -+ x1 = x1 << 1 | x1 >> 31; -+ x1 ^= t0 + (t1<<1) + tfdata->subKeys[k++]; -+ } -+ -+ x2 ^= tfdata->subKeys[4]; -+ x3 ^= tfdata->subKeys[5]; -+ x0 ^= tfdata->subKeys[6]; -+ x1 ^= tfdata->subKeys[7]; -+ } -+ -+ *out++ = (u_int8_t)(x2 ); -+ *out++ = (u_int8_t)(x2 >> 8); -+ *out++ = (u_int8_t)(x2 >> 16); -+ *out++ = (u_int8_t)(x2 >> 24); -+ -+ *out++ = (u_int8_t)(x3 ); -+ *out++ = (u_int8_t)(x3 >> 8); -+ *out++ = (u_int8_t)(x3 >> 16); -+ *out++ = (u_int8_t)(x3 >> 24); -+ -+ *out++ = (u_int8_t)(x0 ); -+ *out++ = (u_int8_t)(x0 >> 8); -+ *out++ = (u_int8_t)(x0 >> 16); -+ *out++ = (u_int8_t)(x0 >> 24); -+ -+ *out++ = (u_int8_t)(x1 ); -+ *out++ = (u_int8_t)(x1 >> 8); -+ *out++ = (u_int8_t)(x1 >> 16); -+ *out++ = (u_int8_t)(x1 >> 24); -+} -+ -+/** -+ * Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box -+ * 32-bit entity from two key material 32-bit entities. -+ * -+ * @param k0 1st 32-bit entity. -+ * @param k1 2nd 32-bit entity. -+ * @return Remainder polynomial generated using RS code -+ */ -+u_int32_t _TwoFish_RS_MDS_Encode(u_int32_t k0,u_int32_t k1) -+{ u_int32_t i,r; -+ -+ for(r=k1,i=0;i<4;i++) /* shift 1 byte at a time */ -+ TwoFish_RS_rem(r); -+ r ^= k0; -+ for(i=0;i<4;i++) -+ TwoFish_RS_rem(r); -+ -+ return r; -+} -+ -+u_int32_t _TwoFish_F32(u_int32_t k64Cnt,u_int32_t x,u_int32_t *k32) -+{ u_int8_t b0,b1,b2,b3; -+ u_int32_t k0,k1,k2,k3,result = 0; -+ -+ b0=TwoFish_b0(x); -+ b1=TwoFish_b1(x); -+ b2=TwoFish_b2(x); -+ b3=TwoFish_b3(x); -+ k0=k32[0]; -+ k1=k32[1]; -+ k2=k32[2]; -+ k3=k32[3]; -+ -+ switch (k64Cnt & 3) -+ { case 1: /* 64-bit keys */ -+ result = -+ TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0] & 0xFF) ^ TwoFish_b0(k0)] ^ -+ TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1] & 0xFF) ^ TwoFish_b1(k0)] ^ -+ TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2] & 0xFF) ^ TwoFish_b2(k0)] ^ -+ TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3] & 0xFF) ^ TwoFish_b3(k0)]; -+ break; -+ case 0: /* 256-bit keys (same as 4) */ -+ b0 = (TwoFish_P[TwoFish_P_04][b0] & 0xFF) ^ TwoFish_b0(k3); -+ b1 = (TwoFish_P[TwoFish_P_14][b1] & 0xFF) ^ TwoFish_b1(k3); -+ b2 = (TwoFish_P[TwoFish_P_24][b2] & 0xFF) ^ TwoFish_b2(k3); -+ b3 = (TwoFish_P[TwoFish_P_34][b3] & 0xFF) ^ TwoFish_b3(k3); -+ -+ case 3: /* 192-bit keys */ -+ b0 = (TwoFish_P[TwoFish_P_03][b0] & 0xFF) ^ TwoFish_b0(k2); -+ b1 = (TwoFish_P[TwoFish_P_13][b1] & 0xFF) ^ TwoFish_b1(k2); -+ b2 = (TwoFish_P[TwoFish_P_23][b2] & 0xFF) ^ TwoFish_b2(k2); -+ b3 = (TwoFish_P[TwoFish_P_33][b3] & 0xFF) ^ TwoFish_b3(k2); -+ case 2: /* 128-bit keys (optimize for this case) */ -+ result = -+ TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0] & 0xFF) ^ TwoFish_b0(k1)] & 0xFF) ^ TwoFish_b0(k0)] ^ -+ TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1] & 0xFF) ^ TwoFish_b1(k1)] & 0xFF) ^ TwoFish_b1(k0)] ^ -+ TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2] & 0xFF) ^ TwoFish_b2(k1)] & 0xFF) ^ TwoFish_b2(k0)] ^ -+ TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3] & 0xFF) ^ TwoFish_b3(k1)] & 0xFF) ^ TwoFish_b3(k0)]; -+ break; -+ } -+ return result; -+} -+ -+u_int32_t _TwoFish_Fe320(u_int32_t *lsBox,u_int32_t x) -+{ return lsBox[ TwoFish_b0(x)<<1 ]^ -+ lsBox[ ((TwoFish_b1(x)<<1)|1)]^ -+ lsBox[0x200+ (TwoFish_b2(x)<<1) ]^ -+ lsBox[0x200+((TwoFish_b3(x)<<1)|1)]; -+} -+ -+u_int32_t _TwoFish_Fe323(u_int32_t *lsBox,u_int32_t x) -+{ return lsBox[ (TwoFish_b3(x)<<1) ]^ -+ lsBox[ ((TwoFish_b0(x)<<1)|1)]^ -+ lsBox[0x200+ (TwoFish_b1(x)<<1) ]^ -+ lsBox[0x200+((TwoFish_b2(x)<<1)|1)]; -+} -+ -+u_int32_t _TwoFish_Fe32(u_int32_t *lsBox,u_int32_t x,u_int32_t R) -+{ return lsBox[ 2*TwoFish__b(x,R ) ]^ -+ lsBox[ 2*TwoFish__b(x,R+1)+1]^ -+ lsBox[0x200+2*TwoFish__b(x,R+2) ]^ -+ lsBox[0x200+2*TwoFish__b(x,R+3)+1]; -+} -+ -+ -+#endif - -Index: snort-2.8.6.1/src/twofish.h -=================================================================== ---- snort-2.8.6.1/src/twofish.h (Revision 0) -+++ snort-2.8.6.1/src/twofish.h (Revision 3) -@@ -0,0 +1,276 @@ -+/* $Id: twofish.h,v 2.1 2008/12/15 20:36:05 fknobbe Exp $ -+ * -+ * -+ * Copyright (C) 1997-2000 The Cryptix Foundation Limited. -+ * Copyright (C) 2000 Farm9. -+ * Copyright (C) 2001 Frank Knobbe. -+ * All rights reserved. -+ * -+ * For Cryptix code: -+ * Use, modification, copying and distribution of this software is subject -+ * the terms and conditions of the Cryptix General Licence. You should have -+ * received a copy of the Cryptix General Licence along with this library; -+ * if not, you can download a copy from http://www.cryptix.org/ . -+ * -+ * For Farm9: -+ * --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and -+ * ciphertext stealing technique, added AsciiTwofish class for easy encryption -+ * decryption of text strings -+ * -+ * Frank Knobbe <frank@knobbe.us>: -+ * --- April 2001, converted from C++ to C, prefixed global variables -+ * with TwoFish, substituted some defines, changed functions to make use of -+ * variables supplied in a struct, modified and added routines for modular calls. -+ * Cleaned up the code so that defines are used instead of fixed 16's and 32's. -+ * Created two general purpose crypt routines for one block and multiple block -+ * encryption using Joh's CBC code. -+ * Added crypt routines that use a header (with a magic and data length). -+ * (Basically a major rewrite). -+ * -+ * Note: Routines labeled _TwoFish are private and should not be used -+ * (or with extreme caution). -+ * -+ */ -+ -+#ifndef __TWOFISH_LIBRARY_HEADER__ -+#define __TWOFISH_LIBRARY_HEADER__ -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+#ifndef TRUE -+#define TRUE !FALSE -+#endif -+#ifndef bool -+#define bool int -+#endif -+ -+ -+/* Constants */ -+ -+#define TwoFish_DEFAULT_PW "SnortHas2FishEncryptionRoutines!" /* default password (not more than 32 chars) */ -+#define TwoFish_MAGIC "TwoFish" /* to indentify a successful decryption */ -+ -+enum -+{ TwoFish_KEY_SIZE = 256, /* Valid values: 64, 128, 192, 256 */ -+ /* User 256, other key sizes have not been tested. */ -+ /* (But should work. I substituted as much as */ -+ /* I could with this define.) */ -+ TwoFish_ROUNDS = 16, -+ TwoFish_BLOCK_SIZE = 16, /* bytes in a data-block */ -+ TwoFish_KEY_LENGTH = TwoFish_KEY_SIZE/8, /* 32= 256-bit key */ -+ TwoFish_TOTAL_SUBKEYS = 4+4+2*TwoFish_ROUNDS, -+ TwoFish_MAGIC_LEN = TwoFish_BLOCK_SIZE-8, -+ TwoFish_SK_BUMP = 0x01010101, -+ TwoFish_SK_ROTL = 9, -+ TwoFish_P_00 = 1, -+ TwoFish_P_01 = 0, -+ TwoFish_P_02 = 0, -+ TwoFish_P_03 = TwoFish_P_01 ^ 1, -+ TwoFish_P_04 = 1, -+ TwoFish_P_10 = 0, -+ TwoFish_P_11 = 0, -+ TwoFish_P_12 = 1, -+ TwoFish_P_13 = TwoFish_P_11 ^ 1, -+ TwoFish_P_14 = 0, -+ TwoFish_P_20 = 1, -+ TwoFish_P_21 = 1, -+ TwoFish_P_22 = 0, -+ TwoFish_P_23 = TwoFish_P_21 ^ 1, -+ TwoFish_P_24 = 0, -+ TwoFish_P_30 = 0, -+ TwoFish_P_31 = 1, -+ TwoFish_P_32 = 1, -+ TwoFish_P_33 = TwoFish_P_31 ^ 1, -+ TwoFish_P_34 = 1, -+ TwoFish_GF256_FDBK = 0x169, -+ TwoFish_GF256_FDBK_2 = 0x169 / 2, -+ TwoFish_GF256_FDBK_4 = 0x169 / 4, -+ TwoFish_RS_GF_FDBK = 0x14D, /* field generator */ -+ TwoFish_MDS_GF_FDBK = 0x169 /* primitive polynomial for GF(256) */ -+}; -+ -+ -+/* Global data structure for callers */ -+ -+typedef struct -+{ u_int32_t sBox[4 * 256]; /* Key dependent S-box */ -+ u_int32_t subKeys[TwoFish_TOTAL_SUBKEYS]; /* Subkeys */ -+ u_int8_t key[TwoFish_KEY_LENGTH]; /* Encryption Key */ -+ u_int8_t *output; /* Pointer to output buffer */ -+ u_int8_t qBlockPlain[TwoFish_BLOCK_SIZE]; /* Used by CBC */ -+ u_int8_t qBlockCrypt[TwoFish_BLOCK_SIZE]; -+ u_int8_t prevCipher[TwoFish_BLOCK_SIZE]; -+ struct /* Header for crypt functions. Has to be at least one block long. */ -+ { u_int32_t salt; /* Random salt in first block (will salt the rest through CBC) */ -+ u_int8_t length[4]; /* The amount of data following the header */ -+ u_int8_t magic[TwoFish_MAGIC_LEN]; /* Magic to identify successful decryption */ -+ } header; -+ bool qBlockDefined; -+ bool dontflush; -+} TWOFISH; -+ -+#ifndef __TWOFISH_LIBRARY_SOURCE__ -+ -+extern bool TwoFish_srand; /* if set to TRUE (default), first call of TwoFishInit will seed rand(); */ -+ /* call of TwoFishInit */ -+#endif -+ -+ -+/**** Public Functions ****/ -+ -+/* TwoFish Initialization -+ * -+ * This routine generates a global data structure for use with TwoFish, -+ * initializes important values (such as subkeys, sBoxes), generates subkeys -+ * and precomputes the MDS matrix if not already done. -+ * -+ * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!') -+ * -+ * Output: Pointer to TWOFISH structure. This data structure contains key dependent data. -+ * This pointer is used with all other crypt functions. -+ */ -+TWOFISH *TwoFishInit(char *userkey); -+ -+ -+/* TwoFish Destroy -+ * -+ * Nothing else but a free... -+ * -+ * Input: Pointer to the TwoFish structure. -+ * -+ */ -+void TwoFishDestroy(TWOFISH *tfdata); -+ -+ -+/* TwoFish Alloc -+ * -+ * Allocates enough memory for the output buffer as required. -+ * -+ * Input: Length of the plaintext. -+ * Boolean flag for BinHex Output. -+ * Pointer to the TwoFish structure. -+ * -+ * Output: Returns a pointer to the memory allocated. -+ */ -+void *TwoFishAlloc(unsigned long len,bool binhex,bool decrypt,TWOFISH *tfdata); -+ -+ -+/* TwoFish Free -+ * -+ * Free's the allocated buffer. -+ * -+ * Input: Pointer to the TwoFish structure -+ * -+ * Output: (none) -+ */ -+void TwoFishFree(TWOFISH *tfdata); -+ -+ -+/* TwoFish Set Output -+ * -+ * If you want to allocate the output buffer yourself, -+ * then you can set it with this function. -+ * -+ * Input: Pointer to your output buffer -+ * Pointer to the TwoFish structure -+ * -+ * Output: (none) -+ */ -+void TwoFishSetOutput(char *outp,TWOFISH *tfdata); -+ -+ -+/* TwoFish Raw Encryption -+ * -+ * Does not use header, but does use CBC (if more than one block has to be encrypted). -+ * -+ * Input: Pointer to the buffer of the plaintext to be encrypted. -+ * Pointer to the buffer receiving the ciphertext. -+ * The length of the plaintext buffer. -+ * The TwoFish structure. -+ * -+ * Output: The amount of bytes encrypted if successful, otherwise 0. -+ */ -+unsigned long TwoFishEncryptRaw(char *in,char *out,unsigned long len,TWOFISH *tfdata); -+ -+/* TwoFish Raw Decryption -+ * -+ * Does not use header, but does use CBC (if more than one block has to be decrypted). -+ * -+ * Input: Pointer to the buffer of the ciphertext to be decrypted. -+ * Pointer to the buffer receiving the plaintext. -+ * The length of the ciphertext buffer (at least one cipher block). -+ * The TwoFish structure. -+ * -+ * Output: The amount of bytes decrypted if successful, otherwise 0. -+ */ -+unsigned long TwoFishDecryptRaw(char *in,char *out,unsigned long len,TWOFISH *tfdata); -+ -+ -+/* TwoFish Encryption -+ * -+ * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, -+ * this routine will alloc the memory. In addition, it will include a small 'header' -+ * containing the magic and some salt. That way the decrypt routine can check if the -+ * packet got decrypted successfully, and return 0 instead of garbage. -+ * -+ * Input: Pointer to the buffer of the plaintext to be encrypted. -+ * Pointer to the pointer to the buffer receiving the ciphertext. -+ * The pointer either points to user allocated output buffer space, or to NULL, in which case -+ * this routine will set the pointer to the buffer allocated through the struct. -+ * The length of the plaintext buffer. -+ * Can be -1 if the input is a null terminated string, in which case we'll count for you. -+ * Boolean flag for BinHex Output (if used, output will be twice as large as input). -+ * Note: BinHex conversion overwrites (converts) input buffer! -+ * The TwoFish structure. -+ * -+ * Output: The amount of bytes encrypted if successful, otherwise 0. -+ */ -+unsigned long TwoFishEncrypt(char *in,char **out,signed long len,bool binhex,TWOFISH *tfdata); -+ -+ -+/* TwoFish Decryption -+ * -+ * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc, -+ * this routine will alloc the memory. In addition, it will check the small 'header' -+ * containing the magic. If magic does not match we return 0. Otherwise we return the -+ * amount of bytes decrypted (should be the same as the length in the header). -+ * -+ * Input: Pointer to the buffer of the ciphertext to be decrypted. -+ * Pointer to the pointer to the buffer receiving the plaintext. -+ * The pointer either points to user allocated output buffer space, or to NULL, in which case -+ * this routine will set the pointer to the buffer allocated through the struct. -+ * The length of the ciphertext buffer. -+ * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you. -+ * Boolean flag for BinHex Input (if used, plaintext will be half as large as input). -+ * Note: BinHex conversion overwrites (converts) input buffer! -+ * The TwoFish structure. -+ * -+ * Output: The amount of bytes decrypted if successful, otherwise 0. -+ */ -+unsigned long TwoFishDecrypt(char *in,char **out,signed long len,bool binhex,TWOFISH *tfdata); -+ -+ -+/**** Private Functions ****/ -+ -+u_int8_t TwoFish__b(u_int32_t x,int n); -+void _TwoFish_BinHex(u_int8_t *buf,unsigned long len,bool bintohex); -+unsigned long _TwoFish_CryptRawCBC(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata); -+unsigned long _TwoFish_CryptRaw16(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata); -+unsigned long _TwoFish_CryptRaw(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata); -+void _TwoFish_PrecomputeMDSmatrix(void); -+void _TwoFish_MakeSubKeys(TWOFISH *tfdata); -+void _TwoFish_qBlockPush(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata); -+void _TwoFish_qBlockPop(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata); -+void _TwoFish_ResetCBC(TWOFISH *tfdata); -+void _TwoFish_FlushOutput(u_int8_t *b,unsigned long len,TWOFISH *tfdata); -+void _TwoFish_BlockCrypt(u_int8_t *in,u_int8_t *out,unsigned long size,int decrypt,TWOFISH *tfdata); -+void _TwoFish_BlockCrypt16(u_int8_t *in,u_int8_t *out,bool decrypt,TWOFISH *tfdata); -+u_int32_t _TwoFish_RS_MDS_Encode(u_int32_t k0,u_int32_t k1); -+u_int32_t _TwoFish_F32(u_int32_t k64Cnt,u_int32_t x,u_int32_t *k32); -+u_int32_t _TwoFish_Fe320(u_int32_t *lsBox,u_int32_t x); -+u_int32_t _TwoFish_Fe323(u_int32_t *lsBox,u_int32_t x); -+u_int32_t _TwoFish_Fe32(u_int32_t *lsBox,u_int32_t x,u_int32_t R); -+ -+ -+#endif - -Index: snort-2.8.6.1/src/plugin_enum.h -=================================================================== ---- snort-2.8.6.1/src/plugin_enum.h (Revision 1) -+++ snort-2.8.6.1/src/plugin_enum.h (Revision 3) -@@ -60,6 +60,7 @@ - PLUGIN_URILEN_CHECK, - PLUGIN_DYNAMIC, - PLUGIN_FLOWBIT, -+ PLUGIN_FWSAM, - PLUGIN_MAX /* sentinel value */ - }; - -Index: snort-2.8.6.1/src/fatal.h -=================================================================== ---- snort-2.8.6.1/src/fatal.h (Revision 0) -+++ snort-2.8.6.1/src/fatal.h (Revision 3) -@@ -0,0 +1,40 @@ -+/* $Id$ */ -+/* -+** Copyright (C) 2002-2008 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. -+*/ -+ -+#ifndef __FATAL_H__ -+#define __FATAL_H__ -+ -+ -+/* -+ * in debugging mode print out the filename and the line number where the -+ * failure have occured -+ */ -+ -+ -+#ifdef DEBUG -+ #define FATAL(msg) { printf("%s:%d: ", __FILE__, __LINE__); FatalError( (char *) msg); } -+#else -+ #define FATAL(msg) FatalError( (char *) msg) -+#endif -+ -+ -+ -+#endif /* __FATAL_H__ */ - -Index: snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.c -=================================================================== ---- snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.c (Revision 0) -+++ snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.c (Revision 3) -@@ -0,0 +1,1380 @@ -+/* $id: snortpatchb,v 1.2 2002/10/26 03:32:35 fknobbe Exp $ -+** -+** spo_alert_fwsam.c -+** -+** Copyright (c) 2001-2004 Frank Knobbe <frank@knobbe.us> -+** -+** 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. -+*/ -+ -+/* -+ * Purpose: -+ * -+ * This module sends alerts to a remote service on a host running SnortSam -+ * (the agent) which will block the intruding IP address on a variety of -+ * host and network firewalls. -+ * -+ * SnortSam also performs checks against a white-list of never-to-be-blocked IP addresses, -+ * can override block durations (for example for known proxies), and can detect attack conditions -+ * where too many blocks are received within a defined interval. If an attack is detected -+ * it will unblock the last x blocks and wait for the attack to end. -+ * -+ * See the SnortSam documentation for more information. -+ * -+ * -+ * Output Plugin Parameters: -+ *************************** -+ * -+ * output alert_fwsam: <SnortSam Station>:<port>/<key> -+ * -+ * <FW Mgmt Station>: The IP address or host name of the host running SnortSam. -+ * <port>: The port the remote SnortSam service listens on (default 898). -+ * <key>: The key used for authentication (encryption really) -+ * of the communication to the remote service. -+ * -+ * Examples: -+ * -+ * output alert_fwsam: snortsambox/idspassword -+ * output alert_fwsam: fw1.domain.tld:898/mykey -+ * output alert_fwsam: 192.168.0.1/borderfw 192.168.1.254/wanfw -+ * -+ * -+ * Rule Options: -+ *************** -+ * -+ * fwsam: who[how],time; -+ * -+ * who: src, source, dst, dest, destination -+ * IP address to be blocked according to snort rule (some rules -+ * are reversed, i.e. homenet -> any [and you want to block any]). -+ * src denotes IP to the left of -> and dst denotes IP to the right -+ * -+ * how: Optional. In, out, src, dest, either, both, this, conn, connection -+ * Tells FW-1 to block packets INcoming from host, OUTgoing to host, -+ * EITHERway, or only THIS connection (IP/Service pair). -+ * See 'fw sam' for more information. May be ignored by other plugins. -+ * -+ * time: Duration of block in seconds. (Accepts 'days', 'months', 'weeks', -+ * 'years', 'minutes', 'seconds', 'hours'. Alternatively, a value of -+ * 0, or the keyword PERManent, INFinite, or ALWAYS, will block the -+ * host permanently. Be careful with this! -+ * Tells FW-1 (and others) how long to inhibit packets from the host. -+ * -+ * Examples: -+ * -+ * fwsam: src[either],15min; -+ * or dst[in], 2 days 4 hours -+ * or src, 1 hour -+ * -+ * (default: src[either],5min) -+ * -+ * -+ * Effect: -+ * -+ * Alerts are sent to the remote SnortSam services on Firewall-1 Management Stations -+ * or other hosts running SnortSam (as required for Cisco Routers and PIX). -+ * The remote services will invoke the SAM configuration via the fw sam -+ * command line, or by sending a packet to the SAM port 18183, or by using the official -+ * OPSEC API calls, or by telnetting into Cisco routers or PIX firewalls. -+ * The communication over the network is encrypted using two-fish. -+ * (Implementation ripped from CryptCat by Farm9 with permission.) -+ * -+ * Future Plans: -+ * -+ * - Custom alert trigger per rule (x alerts in y secs) --> Seems to exist in Snort 1.9 now. -+ * - Enable/Allow tagged fwsam: arguments to provide different values to -+ * different stations. --> Seems to be accomplished with custom rule-types -+ * -+ * -+ * Comments: -+ * -+ * It seem that above wishes can be implemented with todays setup. Feedback concerning -+ * these is greatly appreciated. -+ * -+*/ -+ -+ -+#include "spo_alert_fwsam.h" -+#include "twofish.h" -+/* external globals from rules.c */ -+extern char *file_name; -+extern int file_line; -+extern OptTreeNode *otn_tmp; -+extern char *snort_conf_dir; /* extern PV pv; */ -+ -+ -+/* my globals */ -+ -+FWsamList *FWsamStationList=NULL; /* Global (for all alert-types) list of snortsam stations */ -+FWsamOptions *FWsamOptionField=NULL; -+unsigned long FWsamMaxOptions=0; -+ -+ -+/* -+ * Function: AlertFWsamSetup() -+ * -+ * 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. -+ * It also registers itself as a plugin in order to parse every rule -+ * and to set the appropiate flags from fwsam: option. -+ * -+ * Arguments: None. -+ * -+ * Returns: void function -+ * -+*/ -+void AlertFWsamSetup(void) -+{ -+ /* link the preprocessor keyword to the init function in -+ the preproc list */ -+ RegisterOutputPlugin("alert_fwsam", OUTPUT_TYPE_FLAG__ALERT, AlertFWsamInit); -+ RegisterRuleOption("fwsam", AlertFWsamOptionInit, NULL, OPT_TYPE_ACTION, NULL); -+ -+#ifdef FWSAMDEBUG /* This allows debugging of fwsam only */ -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamSetup) Output plugin is plugged in...\n"); -+#endif -+} -+ -+ -+/* This function checks if a given snortsam station is already in -+ * a given list. -+*/ -+int FWsamStationExists(FWsamStation *who,FWsamList *list) -+{ -+ while(list) -+ { -+ if(list->station) { -+// if( who->stationip.s_addr==list->station->stationip.s_addr && -+ if(IP_EQUALITY(&who->stationip, &list->station->stationip) && -+ who->stationport==list->station->stationport) -+ return TRUE; -+ } -+ list=list->next; -+ } -+ return FALSE; -+} -+ -+/* -+ * Function: AlertFWsamInit(char *args) -+ * -+ * 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 AlertFWsamInit(char *args) -+{ char *ap; -+ unsigned long statip,cnt,again,i; -+ char *stathost,*statport,*statpass; -+ FWsamStation *station; -+ FWsamList *fwsamlist=NULL; /* alert-type dependent list of snortsam stations */ -+ FWsamList *listp,*newlistp; -+ struct hostent *hoste; -+ char buf[1024]=""; -+ FILE *fp; -+ FWsamOptions tempopt; -+ -+#ifdef FWSAMDEBUG -+ unsigned long hostcnt=0; -+ -+ -+ -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Output plugin initializing...\n"); -+#endif -+ -+ /* pv.alert_plugin_active = 1; */ -+ -+ /* parse the argument list from the rules file */ -+ -+ if(args == NULL) -+ FatalError("ERROR %s (%d) => [Alert_FWsam](AlertFWsamInit) No arguments to alert_fwsam preprocessor!\n", file_name, file_line); -+ -+ if(!FWsamOptionField && !FWsamMaxOptions) -+ { strncpy(buf,snort_conf_dir,sizeof(buf)-1); -+ strncpy(buf+strlen(buf),SID_MAPFILE,sizeof(buf)-strlen(buf)-1); -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamSetup) Using file: %s\n",buf); -+#endif -+ fp=fopen(buf,"rt"); -+ if(!fp) -+ { strncpy(buf,snort_conf_dir,sizeof(buf)-1); -+ strncpy(buf+strlen(buf),SID_ALT_MAPFILE,sizeof(buf)-strlen(buf)-1); -+ fp=fopen(buf,"rt"); -+ } -+ if(fp) /* Check for presence of map file and read those in, sorted. */ -+ { LogMessage("INFO => [Alert_FWsam](AlertFWsamSetup) Using sid-map file: %s\n",buf); -+ -+ while(FWsamReadLine(buf,sizeof(buf),fp)) -+ if(*buf) -+ FWsamMaxOptions++; -+ if(FWsamMaxOptions) -+ { if((FWsamOptionField=(FWsamOptions *)malloc(sizeof(FWsamOptions)*FWsamMaxOptions))==NULL) -+ FatalError("ERROR => [Alert_FWsam](AlertFWsamSetup) malloc failed for OptionField!\n"); -+ fseek(fp,0,SEEK_SET); -+ for(cnt=0;cnt<FWsamMaxOptions;) -+ { FWsamReadLine(buf,sizeof(buf),fp); -+ if(*buf) -+ FWsamParseLine(&(FWsamOptionField[cnt++]),buf); -+ } -+ if(FWsamMaxOptions>1) -+ { for(again=TRUE,cnt=FWsamMaxOptions-1;cnt>=1 && again;cnt--) -+ { for(again=FALSE,i=0;i<cnt;i++) -+ { if(FWsamOptionField[i].sid>FWsamOptionField[i+1].sid) -+ { memcpy(&tempopt,&(FWsamOptionField[i]),sizeof(FWsamOptions)); -+ memcpy(&(FWsamOptionField[i]),&(FWsamOptionField[i+1]),sizeof(FWsamOptions)); -+ memcpy(&(FWsamOptionField[i+1]),&tempopt,sizeof(FWsamOptions)); -+ again=TRUE; -+ } -+ } -+ } -+ } -+ } -+ else -+ FWsamMaxOptions=1; -+ fclose(fp); -+ } -+ else -+ FWsamMaxOptions=1; -+ } -+ -+ -+ ap=args; /* start at the beginning of the argument */ -+ while(*ap && isspace(*ap)) ap++; -+ while(*ap) -+ { stathost=ap; /* first argument should be host */ -+ statport=NULL; -+ statpass=NULL; -+ while(*ap && *ap!=':' && *ap!='/' && !isspace(*ap)) ap++; /* find token */ -+ switch(*ap) -+ { case ':': *ap++=0; /* grab the port */ -+ statport=ap; -+ while(*ap && *ap!='/' && !isspace(*ap)) ap++; -+ if(*ap!='/') -+ break; -+ case '/': *ap++=0; /* grab the key */ -+ statpass=ap; -+ while(*ap && !isspace(*ap)) ap++; -+ default: break; -+ } -+ if(*ap) -+ { *ap++=0; -+ while(isspace(*ap)) ap++; -+ } -+ /* now we have the first host with port and password (key) */ -+ /* next we check for valid/blank password/port */ -+ if(statpass!=NULL) -+ if(!*statpass) -+ statpass=NULL; -+ if(statport!=NULL) -+ if(!*statport) -+ statport=NULL; -+ statip=0; -+ /* now we check if a valid host was specified */ -+ if(inet_addr(stathost)==INADDR_NONE) -+ { hoste=gethostbyname(stathost); -+ if (!hoste) -+ LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWsamInit) Unable to resolve host '%s'!\n",file_name,file_line,stathost); -+ else -+ statip=*(unsigned long *)hoste->h_addr; -+ } -+ else -+ { statip=inet_addr(stathost); -+ if(!statip) -+ LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWsamInit) Invalid host address '%s'!\n",file_name,file_line,stathost); -+ } -+ if(statip) -+ { /* groovie, a valid host. Let's alloc and assemble the structure for it. */ -+ if((station=(FWsamStation *)malloc(sizeof(FWsamStation)))==NULL) -+ FatalError("ERROR => [Alert_FWsam](AlertFWsamInit) malloc failed for station!\n"); -+ -+// station->stationip.s_addr=statip; /* the IP address */ -+ station->stationip.ip32[0] = statip; /* the IP address */ -+ if(statport!=NULL && atoi(statport)>0) /* if the user specified one */ -+ station->stationport=atoi(statport); /* use users setting */ -+ else -+ station->stationport=FWSAM_DEFAULTPORT; /* set the default port */ -+ -+ if(statpass!=NULL) /* if specified by user */ -+ strncpy(station->stationkey,statpass,TwoFish_KEY_LENGTH); /* use defined key */ -+ else -+ station->stationkey[0]=0; -+ station->stationkey[TwoFish_KEY_LENGTH]=0; /* make sure it's terminated. (damn strncpy...) */ -+ -+ strcpy(station->initialkey,station->stationkey); -+ station->stationfish=TwoFishInit(station->stationkey); -+ -+ station->localsocketaddr.sin_port=htons(0); /* let's use dynamic ports for now */ -+ station->localsocketaddr.sin_addr.s_addr=0; -+ station->localsocketaddr.sin_family=AF_INET; -+ station->stationsocketaddr.sin_port=htons(station->stationport); -+ //station->stationsocketaddr.sin_addr=station->stationip; -+ station->stationsocketaddr.sin_addr.s_addr=station->stationip.ip32[0]; -+ station->stationsocketaddr.sin_family=AF_INET; /* load all socket crap and keep for later */ -+ -+ do -+ station->myseqno=rand(); /* the seqno this host will use */ -+ while(station->myseqno<20 || station->myseqno>65500); -+ station->mykeymod[0]=rand(); -+ station->mykeymod[1]=rand(); -+ station->mykeymod[2]=rand(); -+ station->mykeymod[3]=rand(); -+ station->stationseqno=0; /* peer hasn't answered yet. */ -+ -+ -+ if(!FWsamStationExists(station,FWsamStationList)) /* If we don't have the station already in global list....*/ -+ { if(FWsamCheckIn(station)) /* ...and we can talk to the agent... */ -+ { if((newlistp=(FWsamList *)malloc(sizeof(FWsamList)))==NULL) -+ FatalError("ERROR => [Alert_FWsam](AlertFWsamInit) malloc failed for global newlistp!\n"); -+ newlistp->station=station; -+ newlistp->next=NULL; -+ -+ if(!FWsamStationList) /* ... add it to the global list/ */ -+ FWsamStationList=newlistp; -+ else -+ { listp=FWsamStationList; -+ while(listp->next) -+ listp=listp->next; -+ listp->next=newlistp; -+ } -+ } -+ else -+ { TwoFishDestroy(station->stationfish); /* if not, we trash it. */ -+ free(station); -+ station=NULL; -+ } -+ } -+#ifdef FWSAMDEBUG -+ else -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Host %s:%i already in global list, skipping CheckIn.\n", sfip_ntoa(&station->stationip),station->stationport); -+#endif -+ -+ if(station) -+ { if(!FWsamStationExists(station,fwsamlist)) /* If we don't have the station already in local list....*/ -+ { if((newlistp=(FWsamList *)malloc(sizeof(FWsamList)))==NULL) -+ FatalError("ERROR => [Alert_FWsam](AlertFWsamInit) malloc failed for local newlistp!\n"); -+ newlistp->station=station; -+ newlistp->next=NULL; -+ -+ if(!fwsamlist) /* ... add it to the local list/ */ -+ fwsamlist=newlistp; -+ else -+ { listp=fwsamlist; -+ while(listp->next) -+ listp=listp->next; -+ listp->next=newlistp; -+ } -+ } -+ -+#ifdef FWSAMDEBUG -+ else -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Host %s:%i already in local list, skipping.\n",sfip_ntoa(&station->stationip),station->stationport); -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) #%i: Host %s [%s] port %i password %s\n",++hostcnt,stathost,sfip_ntoa(&station->stationip),station->stationport,station->stationkey); -+#endif -+ } -+ -+ } -+ } /* next one */ -+ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Linking fwsam alert function to call list...\n"); -+#endif -+ -+ /* Set the preprocessor function into the function list */ -+ AddFuncToOutputList(AlertFWsam, OUTPUT_TYPE_FLAG__ALERT, fwsamlist); -+ AddFuncToCleanExitList(AlertFWsamCleanExitFunc, fwsamlist); -+ AddFuncToRestartList(AlertFWsamRestartFunc, fwsamlist); -+} -+ -+ -+/* This routine reads in a str from a file, snips white-spaces -+ * off the front and back, removes comments, and pretties the -+ * string. Returns true or false if a line was read or not. -+*/ -+int FWsamReadLine(char *buf,unsigned long bufsize,FILE *fp) -+{ char *p; -+ -+ if(fgets(buf,bufsize-1,fp)) -+ { buf[bufsize-1]=0; -+ -+#ifdef FWSAMDEBUG_off -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamReadLine) Line: %s\n",buf); -+#endif -+ -+ p=buf; -+ while(isspace(*p)) -+ p++; -+ if(p>buf); -+ strcpy(buf,p); -+ if(*buf) -+ { p=buf+strlen(buf)-1; /* remove leading and trailing spaces */ -+ while(isspace(*p)) -+ *p-- =0; -+ } -+ p=buf; -+ if(*p=='#' || *p==';') -+ *p=0; -+ else -+ p++; -+ while(*p) /* remove inline comments (except escaped #'s and ;'s) */ -+ { if(*p=='#' || *p==';') -+ { if(*(p-1)=='\\') -+ strcpy(p-1,p); -+ else -+ *p=0; -+ } -+ else -+ p++; -+ } -+ return TRUE; -+ } -+ return FALSE; -+} -+ -+ -+/* Parses the duration of the argument, recognizing minutes, hours, etc.. -+*/ -+unsigned long FWsamParseDuration(char *p) -+{ unsigned long dur=0,tdu; -+ char *tok,c1,c2; -+ -+ while(*p) -+ { tok=p; -+ while(*p && isdigit(*p)) -+ p++; -+ if(*p) -+ { c1=tolower(*p); -+ *p=0; -+ p++; -+ if(*p && !isdigit(*p)) -+ { c2=tolower(*p++); -+ while(*p && !isdigit(*p)) -+ p++; -+ } -+ else -+ c2=0; -+ tdu=atol(tok); -+ switch(c1) -+ { case 'm': if(c2=='o') /* month */ -+ tdu*=(60*60*24*30); /* use 30 days */ -+ else -+ tdu*=60; /* minutes */ -+ case 's': break; /* seconds */ -+ case 'h': tdu*=(60*60); /* hours */ -+ break; -+ case 'd': tdu*=(60*60*24); /* days */ -+ break; -+ case 'w': tdu*=(60*60*24*7); /* week */ -+ break; -+ case 'y': tdu*=(60*60*24*365); /* year */ -+ break; -+ } -+ dur+=tdu; -+ } -+ else -+ dur+=atol(tok); -+ } -+ -+ return dur; -+} -+ -+ -+/* This routine parses an option line. It is called by FWsamParseLine, -+ * which parses the sid-block.map file, and also by AlertFWsamOptionInit, -+ * which is called by Snort when processing fwsam: options in rules. -+ * It returns TRUE it there is a possible option problem, otherwise FALSE. -+*/ -+int FWsamParseOption(FWsamOptions *optp,char *ap) -+{ int possprob=FALSE; -+ -+ /* set defaults */ -+ -+ optp->duration=300; /* default of 5 minute block */ -+ optp->how=FWSAM_HOW_INOUT; /* inbound and outbound block */ -+ optp->who=FWSAM_WHO_SRC; /* the source */ -+ optp->loglevel=FWSAM_LOG_LONGALERT; /* the log level default */ -+ /* parse the fwsam keywords */ -+ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWamOptionInit) Parse Options Args: %s\n",ap); -+#endif -+ -+ if(*ap) /* should be dst/src (the WHO) or duration */ -+ { if(isdigit(*ap)) -+ optp->duration=FWsamParseDuration(ap); -+ else -+ { switch(*ap) /* yeah, we're lazy and check only the first character */ -+ { case 'p': ; /* permanent, perm */ -+ case 'f': ; /* forever */ -+ case 'i': optp->duration=0; /* infinite, inf */ -+ break; -+ case 'd': optp->who=FWSAM_WHO_DST; /* destination, dest, dst */ -+ break; -+ case 's': optp->who=FWSAM_WHO_SRC; /* source, src */ -+ break; -+ default: possprob=TRUE; -+ } -+ while(*ap && *ap!=',' && *ap!='[') -+ ap++; -+ if(*ap=='[') -+ { ap++; /* now we have the HOW */ -+ switch(*ap) -+ { case 'i': ; /* in */ -+ case 's': optp->how=FWSAM_HOW_IN; /* source, src */ -+ break; -+ case 'o': ; /* out */ -+ case 'd': optp->how=FWSAM_HOW_OUT; /* destination, dest, dst */ -+ break; -+ case 'b': ; /* both */ -+ case 'e': optp->how=FWSAM_HOW_INOUT; /* either */ -+ break; -+ case 't': ; /* this */ -+ case 'c': optp->how=FWSAM_HOW_THIS; /* connection, conn */ -+ break; -+ default: possprob=TRUE; -+ } -+ while(*ap && *ap!=',') -+ ap++; -+ } -+ if(*ap==',') -+ { ap++; -+ if(isdigit(*ap)) /* and figure out how long to block */ -+ optp->duration=FWsamParseDuration(ap); -+ else if(*ap=='p' || *ap=='f' || *ap=='i') -+ optp->duration=0; -+ else -+ possprob=TRUE; -+ } -+ else if(!*ap) -+ possprob=TRUE; -+ } -+ } -+ else -+ possprob=TRUE; -+ -+ return possprob; -+} -+ -+ -+/* This goes through the lines of sid-block.map and sets the -+ * options for fwsam if the file is being used. -+*/ -+void FWsamParseLine(FWsamOptions *optp,char *buf) -+{ char *ap; -+ -+ ap=buf; /* start at the beginning of the argument */ -+ -+ while(*ap) -+ { if(isspace(*ap)) /* normalize spaces (tabs into space, etc) */ -+ *ap=' '; -+ if(isupper(*ap)) /* and set to lower case */ -+ *ap=tolower(*ap); -+ ap++; -+ } -+ while((ap=strrchr(buf,' '))!=NULL) /* remove spaces */ -+ strcpy(ap,ap+1); -+ -+ ap=buf; -+ if(*ap) -+ { while(*ap && *ap!=':' && *ap!='|') -+ ap++; -+ *ap++ =0; -+ while(*ap && (*ap==':' || *ap=='|')) -+ ap++; -+ -+ optp->sid=(unsigned long)atol(buf); -+ -+ if(FWsamParseOption(optp,ap)) -+ LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWamOptionInit) Possible option problem. Using %s[%s],%lu.\n",file_name,file_line,(optp->who==FWSAM_WHO_SRC)?"src":"dst",(optp->how==FWSAM_HOW_IN)?"in":((optp->how==FWSAM_HOW_OUT)?"out":"either"),optp->duration); -+ } -+ else -+ optp->sid=0; -+} -+ -+ -+ -+/* -+ * Function: AlertFWsamOptionInit(char *data, OptTreeNode *otn, int protocol) -+ * -+ * Purpose: Parses each rule and sets the option flags in the tree. -+ * -+ * Arguments: args => ptr to argument string -+ * -+ * Returns: void function -+ * -+*/ -+void AlertFWsamOptionInit(char *args,OptTreeNode *otn,int protocol) -+{ -+ FWsamOptions *optp; -+ char *ap; -+ -+ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWamOptionInit) FWsamOptionInit is parsing...\n"); -+#endif -+ -+ if((optp=(FWsamOptions *)malloc(sizeof(FWsamOptions)))==NULL) -+ FatalError("ERROR => [Alert_FWsam](AlertFWamOptionInit) malloc failed for opt!\n"); -+ -+ -+ ap=args; /* start at the beginning of the argument */ -+ -+ while(*ap) -+ { if(isspace(*ap)) /* normalize spaces (tabs into space, etc) */ -+ *ap=' '; -+ if(isupper(*ap)) /* and set to lower case */ -+ *ap=tolower(*ap); -+ ap++; -+ } -+ while((ap=strrchr(args,' '))!=NULL) /* remove spaces */ -+ strcpy(ap,ap+1); -+ -+ -+ if(FWsamParseOption(optp,args)) -+ LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWamOptionInit) Possible option problem. Using %s[%s],%lu.\n",file_name,file_line,(optp->who==FWSAM_WHO_SRC)?"src":"dst",(optp->how==FWSAM_HOW_IN)?"in":((optp->how==FWSAM_HOW_OUT)?"out":"either"),optp->duration); -+ -+ otn->ds_list[PLUGIN_FWSAM]=(FWsamOptions *)optp; -+} -+ -+ -+/* Generates a new encryption key for TwoFish based on seq numbers and a random that -+ * the SnortSam agents send on checkin (in protocol) -+*/ -+void FWsamNewStationKey(FWsamStation *station,FWsamPacket *packet) -+{ -+ //unsigned char newkey[TwoFish_KEY_LENGTH+2]; -+ char newkey[TwoFish_KEY_LENGTH+2]; -+ int i; -+ -+ newkey[0]=packet->snortseqno[0]; /* current snort seq # (which both know) */ -+ newkey[1]=packet->snortseqno[1]; -+ newkey[2]=packet->fwseqno[0]; /* current SnortSam seq # (which both know) */ -+ newkey[3]=packet->fwseqno[1]; -+ newkey[4]=packet->protocol[0]; /* the random SnortSam chose */ -+ newkey[5]=packet->protocol[1]; -+ -+ strncpy(newkey+6,station->stationkey,TwoFish_KEY_LENGTH-6); /* append old key */ -+ newkey[TwoFish_KEY_LENGTH]=0; -+ -+ newkey[0]^=station->mykeymod[0]; /* modify key with key modifiers which were */ -+ newkey[1]^=station->mykeymod[1]; /* exchanged during the check-in handshake. */ -+ newkey[2]^=station->mykeymod[2]; -+ newkey[3]^=station->mykeymod[3]; -+ newkey[4]^=station->fwkeymod[0]; -+ newkey[5]^=station->fwkeymod[1]; -+ newkey[6]^=station->fwkeymod[2]; -+ newkey[7]^=station->fwkeymod[3]; -+ -+ for(i=0;i<=7;i++) -+ if(newkey[i]==0) -+ newkey[i]++; -+ -+ strcpy(station->stationkey,newkey); -+ TwoFishDestroy(station->stationfish); -+ station->stationfish=TwoFishInit(newkey); -+} -+ -+ -+/* This routine will search the option list as defined -+ * by the sid-block.map file and return a pointer -+ * to the matching record. -+*/ -+FWsamOptions *FWsamGetOption(unsigned long sid) -+{ signed long i,step,diff,o,o2; -+ -+#ifdef FWSAM_FANCYFETCH /* Fancy-fetch jumps in decreasing n/2 steps and takes much less lookups */ -+ o=o2= -1; -+ i=step=FWsamMaxOptions>>1; -+ while(i>=0 && i<FWsamMaxOptions && i!=o2) -+ { diff=sid-FWsamOptionField[i].sid; -+ if(!diff) -+ return &(FWsamOptionField[i]); -+ if(step>1) -+ step=step>>1; -+ o2=o; -+ o=i; -+ if(diff>0) -+ i+=step; -+ else -+ i-=step; -+ } -+#else /* This is just a sequential list lookup */ -+ for(i=0;i<FWsamMaxOptions;i++) -+ if(FWsamOptionField[i].sid==sid) -+ return &(FWsamOptionField[i]); -+#endif -+ return NULL; -+} -+ -+ -+/**************************************************************************** -+ * -+ * Function: AlertFWsam(Packet *, char *) -+ * -+ * Purpose: Send the current alert to a remote module on a FW-1 mgmt station -+ * -+ * Arguments: p => pointer to the packet data struct -+ * msg => the message to print in the alert -+ * -+ * Returns: void function -+ * -+ ***************************************************************************/ -+void AlertFWsam(Packet *p, char *msg, void *arg, Event *event) -+{ FWsamOptions *optp; -+ FWsamPacket sampacket; -+ FWsamStation *station=NULL; -+ FWsamList *fwsamlist; -+ SOCKET stationsocket; -+ int i,len,deletestation,stationtry=0; -+ //unsigned char *encbuf,*decbuf; -+ char *encbuf,*decbuf; -+ static unsigned long lastbsip[FWSAM_REPET_BLOCKS],lastbdip[FWSAM_REPET_BLOCKS], -+ lastbduration[FWSAM_REPET_BLOCKS],lastbtime[FWSAM_REPET_BLOCKS]; -+ static unsigned short lastbsp[FWSAM_REPET_BLOCKS],lastbdp[FWSAM_REPET_BLOCKS], -+ lastbproto[FWSAM_REPET_BLOCKS],lastbpointer; -+ static unsigned char lastbmode[FWSAM_REPET_BLOCKS]; -+ static unsigned long btime=0; -+ -+ -+ if(otn_tmp==NULL) -+ { -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] NULL otn_tmp!\n"); -+#endif -+ return; -+ } -+ if(p == NULL) -+ { -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] NULL packet!\n"); -+#endif -+ return; -+ } -+ if(arg == NULL) -+ { -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] NULL arg!\n"); -+#endif -+ return; -+ } -+ -+ /* SnortSam does no IPv6 */ -+ if (!IS_IP4(p)) { -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] not acting on non-IP4 packet!\n"); -+#endif -+ return; -+ } -+ -+ optp=NULL; -+ -+ if(FWsamOptionField) /* If using the file (field present), let's use that */ -+ optp=FWsamGetOption(event->sig_id); -+ -+ if(!optp) /* If file not present, check if an fwsam option was defined on the triggering rule */ -+ optp=otn_tmp->ds_list[PLUGIN_FWSAM]; -+ -+ if(optp) /* if options specified for this rule */ -+ { if(!btime) /* if this is the first time this function is */ -+ { for(i=0;i<FWSAM_REPET_BLOCKS;i++) /* called, reset the time and protocol to 0. */ -+ { lastbproto[i]=0; -+ lastbtime[i]=0; -+ } -+ } -+ -+ fwsamlist=(FWsamList *)arg; -+ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] Alert -> Msg=\"%s\"\n",msg); -+ -+ LogMessage("DEBUG => [Alert_FWsam] Alert -> Option: %s[%s],%lu.\n",(optp->who==FWSAM_WHO_SRC)?"src":"dst",(optp->how==FWSAM_HOW_IN)?"in":((optp->how==FWSAM_HOW_OUT)?"out":"either"),optp->duration); -+#endif -+ -+ len=TRUE; -+ btime=(unsigned long)time(NULL); /* get current time */ -+ /* This is a cheap check to see if the blocking request matches any of the previous requests. */ -+ for(i=0;i<FWSAM_REPET_BLOCKS && len;i++) -+ { if( ((optp->how==FWSAM_HOW_THIS)? /* if blocking mode SERVICE, check for src and dst */ -+ ( lastbsip[i]==p->iph->ip_src.s_addr && lastbdip[i]==p->iph->ip_dst.s_addr &&lastbproto[i]==p->iph->ip_proto && -+ ((p->iph->ip_proto==IPPROTO_TCP || p->iph->ip_proto==IPPROTO_UDP)? /* check port only of TCP or UDP */ -+/* ((optp->who==FWSAM_WHO_SRC)?(lastbsp[i]==p->sp):(lastbdp[i]==p->dp)):TRUE) ): */ -+ lastbdp[i]==p->dp:TRUE) ): -+ ((optp->who==FWSAM_WHO_SRC)?(lastbsip[i]==p->iph->ip_src.s_addr):(lastbdip[i]==p->iph->ip_dst.s_addr))) && /* otherwise if we block source, only compare source. Same for dest. */ -+ lastbduration[i]==optp->duration && -+ (lastbmode[i]&(FWSAM_HOW|FWSAM_WHO))==(optp->how|optp->who) && -+ (btime-lastbtime[i]<((optp->duration>FWSAM_REPET_TIME)?FWSAM_REPET_TIME:optp->duration))) -+ { len=FALSE; /* If so, we don't need to block again. */ -+ } -+ } -+ if(len) -+ { if(++lastbpointer>=FWSAM_REPET_BLOCKS) /* increase repetitive check pointer */ -+ lastbpointer=0; -+ lastbsip[lastbpointer]=p->iph->ip_src.s_addr; /* and note packet details */ -+ lastbdip[lastbpointer]=p->iph->ip_dst.s_addr; -+ lastbduration[lastbpointer]=optp->duration; -+ lastbmode[lastbpointer]=optp->how|optp->who|optp->loglevel; -+ lastbproto[lastbpointer]=p->iph->ip_proto; -+ if(p->iph->ip_proto==IPPROTO_TCP || p->iph->ip_proto==IPPROTO_UDP) -+ { lastbsp[lastbpointer]=p->sp; /* set ports if TCP or UDP */ -+ lastbdp[lastbpointer]=p->dp; -+ } -+ lastbtime[lastbpointer]=btime; -+ -+ -+ while(fwsamlist!=NULL) -+ { station=fwsamlist->station; -+ //if(station->stationip.s_addr) -+ if(station->stationip.ip32[0]) -+ { deletestation=FALSE; -+ stationtry++; /* first try */ -+ /* create a socket for the station */ -+ stationsocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); -+ if(stationsocket==INVALID_SOCKET) -+ FatalError("ERROR => [Alert_FWsam] Funky socket error (socket)!\n"); -+ if(bind(stationsocket,(struct sockaddr *)&(station->localsocketaddr),sizeof(struct sockaddr))) -+ FatalError("ERROR => [Alert_FWsam] Could not bind socket!\n"); -+ -+ /* let's connect to the agent */ -+ if(connect(stationsocket,(struct sockaddr *)&station->stationsocketaddr,sizeof(struct sockaddr))) -+ { -+ LogMessage("WARNING => [Alert_FWsam] Could not send block to host %s. Will try later.\n",sfip_ntoa(&station->stationip)); -+#ifdef WIN32 -+ closesocket(stationsocket); -+#else -+ close(stationsocket); -+#endif -+ stationtry=0; -+ } -+ else -+ { -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] Connected to host %s.\n",sfip_ntoa(&station->stationip)); -+#endif -+ /* now build the packet */ -+ station->myseqno+=station->stationseqno; /* increase my seqno by adding agent seq no */ -+ sampacket.endiancheck=1; /* This is an endian indicator for Snortsam */ -+ sampacket.snortseqno[0]=(char)station->myseqno; -+ sampacket.snortseqno[1]=(char)(station->myseqno>>8); -+ sampacket.fwseqno[0]=(char)station->stationseqno;/* fill station seqno */ -+ sampacket.fwseqno[1]=(char)(station->stationseqno>>8); -+ sampacket.status=FWSAM_STATUS_BLOCK; /* set block mode */ -+ sampacket.version=FWSAM_PACKETVERSION; /* set packet version */ -+ sampacket.duration[0]=(char)optp->duration; /* set duration */ -+ sampacket.duration[1]=(char)(optp->duration>>8); -+ sampacket.duration[2]=(char)(optp->duration>>16); -+ sampacket.duration[3]=(char)(optp->duration>>24); -+ sampacket.fwmode=optp->how|optp->who|optp->loglevel; /* set the mode */ -+ sampacket.dstip[0]=(char)p->iph->ip_dst.s_addr; /* destination IP */ -+ sampacket.dstip[1]=(char)(p->iph->ip_dst.s_addr>>8); -+ sampacket.dstip[2]=(char)(p->iph->ip_dst.s_addr>>16); -+ sampacket.dstip[3]=(char)(p->iph->ip_dst.s_addr>>24); -+ sampacket.srcip[0]=(char)p->iph->ip_src.s_addr; /* source IP */ -+ sampacket.srcip[1]=(char)(p->iph->ip_src.s_addr>>8); -+ sampacket.srcip[2]=(char)(p->iph->ip_src.s_addr>>16); -+ sampacket.srcip[3]=(char)(p->iph->ip_src.s_addr>>24); -+ sampacket.protocol[0]=(char)p->iph->ip_proto; /* protocol */ -+ sampacket.protocol[1]=(char)(p->iph->ip_proto>>8);/* protocol */ -+ -+ if(p->iph->ip_proto==IPPROTO_TCP || p->iph->ip_proto==IPPROTO_UDP) -+ { sampacket.srcport[0]=(char)p->sp; /* set ports */ -+ sampacket.srcport[1]=(char)(p->sp>>8); -+ sampacket.dstport[0]=(char)p->dp; -+ sampacket.dstport[1]=(char)(p->dp>>8); -+ } -+ else -+ sampacket.srcport[0]=sampacket.srcport[1]=sampacket.dstport[0]=sampacket.dstport[1]=0; -+ -+ sampacket.sig_id[0]=(char)event->sig_id; /* set signature ID */ -+ sampacket.sig_id[1]=(char)(event->sig_id>>8); -+ sampacket.sig_id[2]=(char)(event->sig_id>>16); -+ sampacket.sig_id[3]=(char)(event->sig_id>>24); -+ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] Sending BLOCK\n"); -+ LogMessage("DEBUG => [Alert_FWsam] Snort SeqNo: %x\n",station->myseqno); -+ LogMessage("DEBUG => [Alert_FWsam] Mgmt SeqNo : %x\n",station->stationseqno); -+ LogMessage("DEBUG => [Alert_FWsam] Status : %i\n",FWSAM_STATUS_BLOCK); -+ LogMessage("DEBUG => [Alert_FWsam] Mode : %i\n",optp->how|optp->who|optp->loglevel); -+ LogMessage("DEBUG => [Alert_FWsam] Duration : %li\n",optp->duration); -+ LogMessage("DEBUG => [Alert_FWsam] Protocol : %i\n",GET_IPH_PROTO(p)); -+#ifdef SUP_IP6 -+ LogMessage("DEBUG => [Alert_FWsam] Src IP : %s\n",sfip_ntoa(GET_SRC_IP(p))); -+ LogMessage("DEBUG => [Alert_FWsam] Dest IP : %s\n",sfip_ntoa(GET_DST_IP(p))); -+#else -+ LogMessage("DEBUG => [Alert_FWsam] Src IP : %s\n",inet_ntoa(p->iph->ip_src)); -+ LogMessage("DEBUG => [Alert_FWsam] Dest IP : %s\n",inet_ntoa(p->iph->ip_dst)); -+#endif -+ LogMessage("DEBUG => [Alert_FWsam] Src Port : %i\n",p->sp); -+ LogMessage("DEBUG => [Alert_FWsam] Dest Port : %i\n",p->dp); -+ LogMessage("DEBUG => [Alert_FWsam] Sig_ID : %lu\n",event->sig_id); -+ -+#endif -+ -+ encbuf=TwoFishAlloc(sizeof(FWsamPacket),FALSE,FALSE,station->stationfish); /* get the encryption buffer */ -+ len=TwoFishEncrypt((char *)&sampacket,&encbuf,sizeof(FWsamPacket),FALSE,station->stationfish); /* encrypt the packet with current key */ -+ -+ if(send(stationsocket,encbuf,len,0)!=len) /* weird...could not send */ -+ { LogMessage("WARNING => [Alert_FWsam] Could not send to host %s. Will try again later.\n",sfip_ntoa(&station->stationip)); -+#ifdef WIN32 -+ closesocket(stationsocket); -+#else -+ close(stationsocket); -+#endif -+ stationtry=0; -+ } -+ else -+ { i=FWSAM_NETWAIT; -+#ifdef WIN32 -+ ioctlsocket(stationsocket,FIONBIO,&i); /* set non blocking and wait for */ -+#else -+ ioctl(stationsocket,FIONBIO,&i); /* set non blocking and wait for */ -+#endif -+ while(i-- >1) /* the response packet */ -+ { waitms(10); /* wait for response (default maximum 3 secs */ -+ if(recv(stationsocket,encbuf,len,0)==len) -+ i=0; /* if we received packet we set the counter to 0. */ -+ /* by the time we check with if, it's already dec'ed to -1 */ -+ } -+ if(!i) /* id we timed out (i was one, then dec'ed)... */ -+ { LogMessage("WARNING => [Alert_FWsam] Did not receive response from host %s. Will try again later.\n",sfip_ntoa(&station->stationip)); -+#ifdef WIN32 -+ closesocket(stationsocket); -+#else -+ close(stationsocket); -+#endif -+ stationtry=0; -+ } -+ else /* got a packet */ -+ { decbuf=(char *)&sampacket; /* get the pointer to the packet struct */ -+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try to decrypt the packet with current key */ -+ -+ if(len!=sizeof(FWsamPacket)) /* invalid decryption */ -+ { strcpy(station->stationkey,station->initialkey); /* try the intial key */ -+ TwoFishDestroy(station->stationfish); -+ station->stationfish=TwoFishInit(station->stationkey); /* re-initialize the TwoFish with the intial key */ -+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try again to decrypt */ -+ LogMessage("INFO => [Alert_FWsam] Had to use initial key!\n"); -+ } -+ if(len==sizeof(FWsamPacket)) /* valid decryption */ -+ { if(sampacket.version==FWSAM_PACKETVERSION)/* master speaks my language */ -+ { if(sampacket.status==FWSAM_STATUS_OK || sampacket.status==FWSAM_STATUS_NEWKEY -+ || sampacket.status==FWSAM_STATUS_RESYNC || sampacket.status==FWSAM_STATUS_HOLD) -+ { station->stationseqno=sampacket.fwseqno[0] | (sampacket.fwseqno[1]<<8); /* get stations seqno */ -+ station->lastcontact=(unsigned long)time(NULL); /* set the last contact time (not used yet) */ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] Received %s\n",sampacket.status==FWSAM_STATUS_OK?"OK": -+ sampacket.status==FWSAM_STATUS_NEWKEY?"NEWKEY": -+ sampacket.status==FWSAM_STATUS_RESYNC?"RESYNC": -+ sampacket.status==FWSAM_STATUS_HOLD?"HOLD":"ERROR"); -+ LogMessage("DEBUG => [Alert_FWsam] Snort SeqNo: %x\n",sampacket.snortseqno[0]|(sampacket.snortseqno[1]<<8)); -+ LogMessage("DEBUG => [Alert_FWsam] Mgmt SeqNo : %x\n",station->stationseqno); -+ LogMessage("DEBUG => [Alert_FWsam] Status : %i\n",sampacket.status); -+ LogMessage("DEBUG => [Alert_FWsam] Version : %i\n",sampacket.version); -+#endif -+ if(sampacket.status==FWSAM_STATUS_HOLD) -+ { i=FWSAM_NETHOLD; /* Stay on hold for a maximum of 60 secs (default) */ -+ while(i-- >1) /* the response packet */ -+ { waitms(10); /* wait for response */ -+ if(recv(stationsocket,encbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,0)==sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE) -+ i=0; /* if we received packet we set the counter to 0. */ -+ } -+ if(!i) /* id we timed out (i was one, then dec'ed)... */ -+ { LogMessage("WARNING => [Alert_FWsam] Did not receive response from host %s. Will try again later.\n",sfip_ntoa(&station->stationip)); -+ stationtry=0; -+ sampacket.status=FWSAM_STATUS_ERROR; -+ } -+ else /* got a packet */ -+ { decbuf=(char *)&sampacket; /* get the pointer to the packet struct */ -+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try to decrypt the packet with current key */ -+ -+ if(len!=sizeof(FWsamPacket)) /* invalid decryption */ -+ { strcpy(station->stationkey,station->initialkey); /* try the intial key */ -+ TwoFishDestroy(station->stationfish); -+ station->stationfish=TwoFishInit(station->stationkey); /* re-initialize the TwoFish with the intial key */ -+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try again to decrypt */ -+ LogMessage("INFO => [Alert_FWsam] Had to use initial key again!\n"); -+ } -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] Received %s\n",sampacket.status==FWSAM_STATUS_OK?"OK": -+ sampacket.status==FWSAM_STATUS_NEWKEY?"NEWKEY": -+ sampacket.status==FWSAM_STATUS_RESYNC?"RESYNC": -+ sampacket.status==FWSAM_STATUS_HOLD?"HOLD":"ERROR"); -+ LogMessage("DEBUG => [Alert_FWsam] Snort SeqNo: %x\n",sampacket.snortseqno[0]|(sampacket.snortseqno[1]<<8)); -+ LogMessage("DEBUG => [Alert_FWsam] Mgmt SeqNo : %x\n",station->stationseqno); -+ LogMessage("DEBUG => [Alert_FWsam] Status : %i\n",sampacket.status); -+ LogMessage("DEBUG => [Alert_FWsam] Version : %i\n",sampacket.version); -+#endif -+ if(len!=sizeof(FWsamPacket)) /* invalid decryption */ -+ { ErrorMessage("ERROR => [Alert_FWsam] Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+ deletestation=TRUE; -+ sampacket.status=FWSAM_STATUS_ERROR; -+ } -+ else if(sampacket.version!=FWSAM_PACKETVERSION) /* invalid protocol version */ -+ { ErrorMessage("ERROR => [Alert_FWsam] Protocol version error! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+ deletestation=TRUE; -+ sampacket.status=FWSAM_STATUS_ERROR; -+ } -+ else if(sampacket.status!=FWSAM_STATUS_OK && sampacket.status!=FWSAM_STATUS_NEWKEY && sampacket.status!=FWSAM_STATUS_RESYNC) -+ { ErrorMessage("ERROR => [Alert_FWsam] Funky handshake error! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+ deletestation=TRUE; -+ sampacket.status=FWSAM_STATUS_ERROR; -+ } -+ } -+ } -+ if(sampacket.status==FWSAM_STATUS_RESYNC) /* if station want's to resync... */ -+ { strcpy(station->stationkey,station->initialkey); /* ...we use the intial key... */ -+ memcpy(station->fwkeymod,sampacket.duration,4); /* and note the random key modifier */ -+ } -+ if(sampacket.status==FWSAM_STATUS_NEWKEY || sampacket.status==FWSAM_STATUS_RESYNC) -+ { -+ FWsamNewStationKey(station,&sampacket); /* generate new TwoFish keys */ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] Generated new encryption key...\n"); -+#endif -+ } -+#ifdef WIN32 -+ closesocket(stationsocket); -+#else -+ close(stationsocket); -+#endif -+ stationtry=0; -+ } -+ else if(sampacket.status==FWSAM_STATUS_ERROR) /* if SnortSam reports an error on second try, */ -+ { -+#ifdef WIN32 -+ closesocket(stationsocket); /* something is messed up and ... */ -+#else -+ close(stationsocket); -+#endif -+ if(stationtry>1) /* we ignore that station. */ -+ { deletestation=TRUE; /* flag for deletion */ -+ ErrorMessage("ERROR => [Alert_FWsam] Could not renegotiate key! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+ } -+ else /* if we get an error on the first try, */ -+ { if(!FWsamCheckIn(station)) /* we first try to check in again. */ -+ { deletestation=TRUE; -+ ErrorMessage("ERROR => [Alert_FWsam] Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+ } -+ } -+ } -+ else /* an unknown status means trouble... */ -+ { ErrorMessage("ERROR => [Alert_FWsam] Funky handshake error! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+#ifdef WIN32 -+ closesocket(stationsocket); -+#else -+ close(stationsocket); -+#endif -+ deletestation=TRUE; -+ } -+ } -+ else /* if the SnortSam agent uses a different packet version, we have no choice but to ignore it. */ -+ { ErrorMessage("ERROR => [Alert_FWsam] Protocol version error! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+#ifdef WIN32 -+ closesocket(stationsocket); -+#else -+ close(stationsocket); -+#endif -+ deletestation=TRUE; -+ } -+ } -+ else /* if the intial key failed to decrypt as well, the keys are not configured the same, and we ignore that SnortSam station. */ -+ { ErrorMessage("ERROR => [Alert_FWsam] Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+#ifdef WIN32 -+ closesocket(stationsocket); -+#else -+ close(stationsocket); -+#endif -+ deletestation=TRUE; -+ } -+ } -+ } -+ free(encbuf); /* release of the TwoFishAlloc'ed encryption buffer */ -+ } -+ if(stationtry==0 || deletestation) /* if everything went real well, or real bad... */ -+ { if(deletestation){ /* If it went bad, we remove the station from the list by marking the IP */ -+// station->stationip.s_addr=0; -+ station->stationip.ip32[0]=0; -+ } -+ fwsamlist=fwsamlist->next; -+ } -+ } -+ else -+ fwsamlist=fwsamlist->next; -+ } -+ } -+ else -+ { -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam] Skipping repetitive block.\n"); -+#endif -+ } -+ } -+} -+ -+/* FWsamCheckOut will be called when Snort exists. It de-registeres this snort sensor -+ * from the list of sensor that the SnortSam agent keeps. -+ */ -+void FWsamCheckOut(FWsamStation *station) -+{ FWsamPacket sampacket; -+ SOCKET stationsocket; -+ int i,len; -+ char *encbuf,*decbuf; -+ //unsigned char *encbuf,*decbuf; -+ -+ -+ stationsocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); -+ if(stationsocket==INVALID_SOCKET) -+ FatalError("ERROR => [Alert_FWsam](FWsamCheckOut) Funky socket error (socket)!\n"); -+ if(bind(stationsocket,(struct sockaddr *)&(station->localsocketaddr),sizeof(struct sockaddr))) -+ FatalError("ERROR => [Alert_FWsam](FWsamCheckOut) Could not bind socket!\n"); -+ -+ /* let's connect to the agent */ -+ if(!connect(stationsocket,(struct sockaddr *)&station->stationsocketaddr,sizeof(struct sockaddr))) -+ { LogMessage("INFO => [Alert_FWsam](FWsamCheckOut) Disconnecting from host %s.\n",sfip_ntoa(&station->stationip)); -+ /* now build the packet */ -+ station->myseqno+=station->stationseqno; /* increase my seqno */ -+ sampacket.endiancheck=1; -+ sampacket.snortseqno[0]=(char)station->myseqno; -+ sampacket.snortseqno[1]=(char)(station->myseqno>>8); -+ sampacket.fwseqno[0]=(char)station->stationseqno; /* fill station seqno */ -+ sampacket.fwseqno[1]=(char)(station->stationseqno>>8); -+ sampacket.status=FWSAM_STATUS_CHECKOUT; /* checking out... */ -+ sampacket.version=FWSAM_PACKETVERSION; -+ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Sending CHECKOUT\n"); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Snort SeqNo: %x\n",station->myseqno); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Mgmt SeqNo : %x\n",station->stationseqno); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Status : %i\n",sampacket.status); -+ -+#endif -+ -+ encbuf=TwoFishAlloc(sizeof(FWsamPacket),FALSE,FALSE,station->stationfish); /* get encryption buffer */ -+ len=TwoFishEncrypt((char *)&sampacket,&encbuf,sizeof(FWsamPacket),FALSE,station->stationfish); /* encrypt packet with current key */ -+ -+ if(send(stationsocket,encbuf,len,0)==len) -+ { i=FWSAM_NETWAIT; -+#ifdef WIN32 -+ ioctlsocket(stationsocket,FIONBIO,&i); /* set non blocking and wait for */ -+#else -+ ioctl(stationsocket,FIONBIO,&i); /* set non blocking and wait for */ -+#endif -+ while(i-- >1) -+ { waitms(10); /* ...wait a maximum of 3 secs for response... */ -+ if(recv(stationsocket,encbuf,len,0)==len) /* ... for the status packet */ -+ i=0; -+ } -+ if(i) /* if we got the packet */ -+ { decbuf=(char *)&sampacket; -+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); -+ -+ if(len!=sizeof(FWsamPacket)) /* invalid decryption */ -+ { strcpy(station->stationkey,station->initialkey); /* try initial key */ -+ TwoFishDestroy(station->stationfish); /* toss this fish */ -+ station->stationfish=TwoFishInit(station->stationkey); /* re-initialze TwoFish with initial key */ -+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* and try to decrypt again */ -+ LogMessage("INFO => [Alert_FWsam](FWsamCheckOut) Had to use initial key!\n"); -+ } -+ if(len==sizeof(FWsamPacket)) /* valid decryption */ -+ { if(sampacket.version!=FWSAM_PACKETVERSION) /* but don't really care since we are on the way out */ -+ ErrorMessage("WARNING => [Alert_FWsam](FWsamCheckOut) Protocol version error! What the hell, we're quitting anyway! :)\n"); -+ } -+ else -+ ErrorMessage("WARNING => [Alert_FWsam](FWsamCheckOut) Password mismatch! What the hell, we're quitting anyway! :)\n"); -+ } -+ } -+ free(encbuf); /* release TwoFishAlloc'ed buffer */ -+ } -+ else -+ LogMessage("WARNING => [Alert_FWsam] Could not connect to host %s for CheckOut. What the hell, we're quitting anyway! :)\n",sfip_ntoa(&station->stationip)); -+#ifdef WIN32 -+ closesocket(stationsocket); -+#else -+ close(stationsocket); -+#endif -+} -+ -+ -+/* FWSamFree: Disconnects all FW-1 management stations, -+ * closes sockets, and frees the structures. -+ */ -+void FWsamFree(FWsamList *list) -+{ -+ FWsamList *next; -+ -+ while(list) /* Free pointer list for rule type */ -+ { -+ next=list->next; -+ free(list); -+ list=next; -+ } -+ list=FWsamStationList; -+ -+ while(list) /* Free global pointer list and stations */ -+ { -+ next=list->next; -+ if (list->station) -+ { -+ if(list->station->stationip.ip32[0]) -+ //if(list->station->stationip.s_addr) -+ FWsamCheckOut(list->station); /* Send a Check-Out to SnortSam, */ -+ -+ TwoFishDestroy(list->station->stationfish); /* toss the fish, */ -+ free(list->station); /* free station, */ -+ } -+ free(list); /* free pointer, */ -+ list=next; /* and move to next. */ -+ } -+ FWsamStationList=NULL; -+ if(FWsamOptionField) -+ free(FWsamOptionField); -+} -+ -+void AlertFWsamCleanExitFunc(int signal, void *arg) -+{ FWsamList *fwsamlist; -+ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamCleanExitFunc) Exiting...\n"); -+#endif -+ -+ fwsamlist=(FWsamList *)arg; -+ FWsamFree(fwsamlist); /* Free all elements */ -+} -+ -+void AlertFWsamRestartFunc(int signal, void *arg) -+{ FWsamList *fwsamlist; -+ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamRestartFunc) Restarting...\n"); -+#endif -+ -+ fwsamlist=(FWsamList *)arg; -+ FWsamFree(fwsamlist); /* Free all elements */ -+} -+ -+/* This routine registers this Snort sensor with SnortSam. -+ * It will also change the encryption key based on some variables. -+ */ -+int FWsamCheckIn(FWsamStation *station) -+{ int i,len,stationok=TRUE; -+ FWsamPacket sampacket; -+ char *encbuf,*decbuf; -+ //unsigned char *encbuf,*decbuf; -+ SOCKET stationsocket; -+ -+ -+ /* create a socket for the station */ -+ stationsocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); -+ if(stationsocket==INVALID_SOCKET) -+ FatalError("ERROR => [Alert_FWsam](FWsamCheckIn) Funky socket error (socket)!\n"); -+ if(bind(stationsocket,(struct sockaddr *)&(station->localsocketaddr),sizeof(struct sockaddr))) -+ FatalError("ERROR => [Alert_FWsam](FWsamCheckIn) Could not bind socket!\n"); -+ -+ i=TRUE; -+ /* let's connect to the agent */ -+ if(connect(stationsocket,(struct sockaddr *)&station->stationsocketaddr,sizeof(struct sockaddr))) -+ LogMessage("WARNING => [Alert_FWsam](FWsamCheckIn) Could not connect to host %s. Will try later.\n",sfip_ntoa(&station->stationip)); -+ else -+ { LogMessage("INFO => [Alert_FWsam](FWsamCheckIn) Connected to host %s.\n",sfip_ntoa(&station->stationip)); -+ /* now build the packet */ -+ sampacket.endiancheck=1; -+ sampacket.snortseqno[0]=(char)station->myseqno; /* fill my sequence number number */ -+ sampacket.snortseqno[1]=(char)(station->myseqno>>8); /* fill my sequence number number */ -+ sampacket.status=FWSAM_STATUS_CHECKIN; /* let's check in */ -+ sampacket.version=FWSAM_PACKETVERSION; /* set the packet version */ -+ memcpy(sampacket.duration,station->mykeymod,4); /* we'll send SnortSam our key modifier in the duration slot */ -+ /* (the checkin packet is just the plain initial key) */ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Sending CheckIn\n"); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Snort SeqNo: %x\n",station->myseqno); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Mode : %i\n",sampacket.status); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Version : %i\n",sampacket.version); -+#endif -+ encbuf=TwoFishAlloc(sizeof(FWsamPacket),FALSE,FALSE,station->stationfish); /* get buffer for encryption */ -+ len=TwoFishEncrypt((char *)&sampacket,&encbuf,sizeof(FWsamPacket),FALSE,station->stationfish); /* encrypt with initial key */ -+ if(send(stationsocket,encbuf,len,0)!=len) /* weird...could not send */ -+ LogMessage("WARNING => [Alert_FWsam](FWsamCheckIn) Could not send to host %s. Will try again later.\n",sfip_ntoa(&station->stationip)); -+ else -+ { i=FWSAM_NETWAIT; -+#ifdef WIN32 -+ ioctlsocket(stationsocket,FIONBIO,&i); /* set non blocking and wait for */ -+#else -+ ioctl(stationsocket,FIONBIO,&i); /* set non blocking and wait for */ -+#endif -+ while(i-- >1) -+ { waitms(10); /* wait a maximum of 3 secs for response */ -+ if(recv(stationsocket,encbuf,len,0)==len) -+ i=0; -+ } -+ if(!i) /* time up? */ -+ LogMessage("WARNING => [Alert_FWsam](FWsamCheckIn) Did not receive response from host %s. Will try again later.\n",sfip_ntoa(&station->stationip)); -+ else -+ { decbuf=(char *)&sampacket; /* got status packet */ -+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try to decrypt with initial key */ -+ if(len==sizeof(FWsamPacket)) /* valid decryption */ -+ { -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Received %s\n",sampacket.status==FWSAM_STATUS_OK?"OK": -+ sampacket.status==FWSAM_STATUS_NEWKEY?"NEWKEY": -+ sampacket.status==FWSAM_STATUS_RESYNC?"RESYNC": -+ sampacket.status==FWSAM_STATUS_HOLD?"HOLD":"ERROR"); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Snort SeqNo: %x\n",sampacket.snortseqno[0]|(sampacket.snortseqno[1]<<8)); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Mgmt SeqNo : %x\n",sampacket.fwseqno[0]|(sampacket.fwseqno[1]<<8)); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Status : %i\n",sampacket.status); -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Version : %i\n",sampacket.version); -+#endif -+ if(sampacket.version==FWSAM_PACKETVERSION) /* master speaks my language */ -+ { if(sampacket.status==FWSAM_STATUS_OK || sampacket.status==FWSAM_STATUS_NEWKEY || sampacket.status==FWSAM_STATUS_RESYNC) -+ { station->stationseqno=sampacket.fwseqno[0]|(sampacket.fwseqno[1]<<8); /* get stations seqno */ -+ station->lastcontact=(unsigned long)time(NULL); -+ -+ if(sampacket.status==FWSAM_STATUS_NEWKEY || sampacket.status==FWSAM_STATUS_RESYNC) /* generate new keys */ -+ { memcpy(station->fwkeymod,sampacket.duration,4); /* note the key modifier */ -+ FWsamNewStationKey(station,&sampacket); /* and generate new TwoFish keys (with key modifiers) */ -+#ifdef FWSAMDEBUG -+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Generated new encryption key...\n"); -+#endif -+ } -+ } -+ else /* weird, got a strange status back */ -+ { ErrorMessage("ERROR => [Alert_FWsam](FWsamCheckIn) Funky handshake error! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+ stationok=FALSE; -+ } -+ } -+ else /* packet version does not match */ -+ { ErrorMessage("ERROR =>[Alert_FWsam](FWsamCheckIn) Protocol version error! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+ stationok=FALSE; -+ } -+ } -+ else /* key does not match */ -+ { ErrorMessage("ERROR => [Alert_FWsam](FWsamCheckIn) Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip)); -+ stationok=FALSE; -+ } -+ } -+ } -+ free(encbuf); /* release TwoFishAlloc'ed buffer */ -+ } -+#ifdef WIN32 -+ closesocket(stationsocket); -+#else -+ close(stationsocket); -+#endif -+ return stationok; -+} -+#undef FWSAMDEBUG -+ - -Index: snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.h -=================================================================== ---- snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.h (Revision 0) -+++ snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.h (Revision 3) -@@ -0,0 +1,216 @@ -+/* $Id: snortpatchb,v 1.5 2005/10/06 08:50:39 fknobbe Exp $ -+** -+** spo_alert_fwsam.h -+** -+** Copyright (c) 2001-2004 Frank Knobbe <frank@knobbe.us> -+** -+** 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. -+*/ -+ -+/* This file gets included in plugbase.c when it is integrated into the rest -+ * of the program. -+ * -+ * For more info, see the beginning of spo_alert_fwsam.c -+ * -+ */ -+ -+#ifndef __SPO_FWSAM_H__ -+#define __SPO_FWSAM_H__ -+ -+#include "snort.h" -+#include "rules.h" -+#include "plugbase.h" -+#include "plugin_enum.h" -+#include "fatal.h" -+#include "util.h" -+#include "twofish.h" -+ -+#include <stdlib.h> -+#include <stdio.h> -+#include <time.h> -+#include <string.h> -+#include <ctype.h> -+#include <unistd.h> -+ -+ -+/* just some compatibility stuff */ -+#ifdef WIN32 -+#if !defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) -+#include <winsock.h> -+#endif -+#define waitms(x) Sleep(x) -+ -+#else -+ -+#include <sys/socket.h> -+#include <netinet/in.h> -+#include <arpa/inet.h> -+#include <sys/ioctl.h> -+#include <netdb.h> -+ -+#ifdef SOLARIS -+#include <sys/filio.h> -+#endif -+ -+typedef int SOCKET; -+ -+#ifndef INVALID_SOCKET -+#define INVALID_SOCKET -1 -+#endif -+ -+#define waitms(x) usleep((x)*1000) -+ -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+#ifndef TRUE -+#define TRUE !FALSE -+#endif -+#ifndef bool -+#define bool int -+#endif -+ -+ -+#if defined(_DEBUG) || defined(DEBUG) -+#ifndef FWSAMDEBUG -+#define FWSAMDEBUG -+#endif -+#else -+#endif -+ -+ -+/* Official Snort PlugIn Number has been moved into plugin_enum.h */ -+ -+ -+/* fixed defines */ -+ -+#define FWSAM_DEFAULTPORT 898 /* Default port if user does not specify one in snort.conf */ -+ /* (Was unused last time I checked...) */ -+#define FWSAM_PACKETVERSION 14 /* version of the packet. Will increase with enhancements. */ -+ -+#define FWSAM_STATUS_CHECKIN 1 /* snort to fw */ -+#define FWSAM_STATUS_CHECKOUT 2 -+#define FWSAM_STATUS_BLOCK 3 -+#define FWSAM_STATUS_UNBLOCK 9 -+ -+#define FWSAM_STATUS_OK 4 /* fw to snort */ -+#define FWSAM_STATUS_ERROR 5 -+#define FWSAM_STATUS_NEWKEY 6 -+#define FWSAM_STATUS_RESYNC 7 -+#define FWSAM_STATUS_HOLD 8 -+ -+#define FWSAM_LOG_NONE 0 -+#define FWSAM_LOG_SHORTLOG 1 -+#define FWSAM_LOG_SHORTALERT 2 -+#define FWSAM_LOG_LONGLOG 3 -+#define FWSAM_LOG_LONGALERT 4 -+#define FWSAM_LOG (FWSAM_LOG_SHORTLOG|FWSAM_LOG_SHORTALERT|FWSAM_LOG_LONGLOG|FWSAM_LOG_LONGALERT) -+#define FWSAM_WHO_DST 8 -+#define FWSAM_WHO_SRC 16 -+#define FWSAM_WHO (FWSAM_WHO_DST|FWSAM_WHO_SRC) -+#define FWSAM_HOW_IN 32 -+#define FWSAM_HOW_OUT 64 -+#define FWSAM_HOW_INOUT (FWSAM_HOW_IN|FWSAM_HOW_OUT) -+#define FWSAM_HOW_THIS 128 -+#define FWSAM_HOW (FWSAM_HOW_IN|FWSAM_HOW_OUT|FWSAM_HOW_THIS) -+ -+ -+/* user adjustable defines */ -+ -+#define FWSAM_REPET_BLOCKS 10 /* Snort remembers this amount of last blocks and... */ -+#define FWSAM_REPET_TIME 20 /* ...checks if they fall within this time. If so,... */ -+ /* ...the blocking request is not send. */ -+ -+#define FWSAM_NETWAIT 300 /* 100th of a second. 3 sec timeout for network connections */ -+#define FWSAM_NETHOLD 6000 /* 100th of a second. 60 sec timeout for holding */ -+ -+#define SID_MAPFILE "sid-block.map" -+#define SID_ALT_MAPFILE "sid-fwsam.map" -+ -+#define FWSAM_FANCYFETCH /* This will invoke a fast sid lookup routine */ -+ -+ -+/* vars */ -+ -+typedef struct _FWsamstation /* structure of a mgmt station */ -+{ unsigned short myseqno; -+ unsigned short stationseqno; -+ unsigned char mykeymod[4]; -+ unsigned char fwkeymod[4]; -+ unsigned short stationport; -+ //struct in_addr stationip; -+ sfip_t stationip; -+ struct sockaddr_in localsocketaddr; -+ struct sockaddr_in stationsocketaddr; -+ TWOFISH *stationfish; -+ char initialkey[TwoFish_KEY_LENGTH+2]; -+ char stationkey[TwoFish_KEY_LENGTH+2]; -+ time_t lastcontact; -+/* time_t sleepstart; */ -+} FWsamStation; -+ -+typedef struct _FWsampacket /* 2 blocks (3rd block is header from TwoFish) */ -+{ unsigned short endiancheck; /* 0 */ -+ unsigned char srcip[4]; /* 2 */ -+ unsigned char dstip[4]; /* 6 */ -+ unsigned char duration[4]; /* 10 */ -+ unsigned char snortseqno[2]; /* 14 */ -+ unsigned char fwseqno[2]; /* 16 */ -+ unsigned char srcport[2]; /* 18 */ -+ unsigned char dstport[2]; /* 20 */ -+ unsigned char protocol[2]; /* 22 */ -+ unsigned char fwmode; /* 24 */ -+ unsigned char version; /* 25 */ -+ unsigned char status; /* 26 */ -+ unsigned char sig_id[4]; /* 27 */ -+ unsigned char fluff; /* 31 */ -+} FWsamPacket; /* 32 bytes in size */ -+ -+typedef struct _FWsamoptions /* snort rule options */ -+{ unsigned long sid; -+ unsigned long duration; -+ unsigned char who; -+ unsigned char how; -+ unsigned char loglevel; -+} FWsamOptions; -+ -+typedef struct _FWsamlistpointer -+{ FWsamStation *station; -+ struct _FWsamlistpointer *next; -+} FWsamList; -+ -+ -+/* functions */ -+void AlertFWsamSetup(void); -+void AlertFWsamInit(char *args); -+void AlertFWsamOptionInit(char *args,OptTreeNode *otn,int protocol); -+void AlertFWsamCleanExitFunc(int signal, void *arg); -+void AlertFWsamRestartFunc(int signal, void *arg); -+void AlertFWsam(Packet *p, char *msg, void *arg, Event *event); -+int FWsamCheckIn(FWsamStation *station); -+void FWsamCheckOut(FWsamStation *station); -+void FWsamNewStationKey(FWsamStation *station,FWsamPacket *packet); -+void FWsamFixPacketEndian(FWsamPacket *p); -+unsigned long FWsamParseDuration(char *p); -+void FWsamFree(FWsamList *fwsamlist); -+int FWsamStationExists(FWsamStation *who,FWsamList *list); -+int FWsamReadLine(char *,unsigned long,FILE *); -+void FWsamParseLine(FWsamOptions *,char *); -+FWsamOptions *FWsamGetOption(unsigned long); -+int FWsamParseOption(FWsamOptions *,char *); -+ -+#endif /* __SPO_FWSAM_H__ */ - -Index: snort-2.8.6.1/src/output-plugins/Makefile.am -=================================================================== ---- snort-2.8.6.1/src/output-plugins/Makefile.am (Revision 1) -+++ snort-2.8.6.1/src/output-plugins/Makefile.am (Revision 3) -@@ -11,6 +11,7 @@ - spo_log_tcpdump.h spo_unified.c spo_unified2.c spo_unified.h spo_unified2.h \ - spo_log_ascii.c spo_log_ascii.h spo_alert_sf_socket.h spo_alert_sf_socket.c \ - spo_alert_prelude.c spo_alert_prelude.h spo_alert_arubaaction.c spo_alert_arubaaction.h \ -+spo_alert_fwsam.c spo_alert_fwsam.h \ - spo_alert_test.c spo_alert_test.h - - INCLUDES = @INCLUDES@ -Index: snort-2.8.6.1/src/plugbase.c -=================================================================== ---- snort-2.8.6.1/src/plugbase.c (Revision 1) -+++ snort-2.8.6.1/src/plugbase.c (Revision 3) -@@ -125,6 +125,7 @@ - #endif - - #include "output-plugins/spo_alert_test.h" -+#include "output-plugins/spo_alert_fwsam.h" - - extern ListHead *head_tmp; - extern PreprocConfigFuncNode *preproc_config_funcs; -@@ -1240,6 +1241,7 @@ - #endif - - AlertTestSetup(); -+ AlertFWsamSetup(); - } - - /**************************************************************************** -Index: snort-2.8.6.1/src/Makefile.am -=================================================================== ---- snort-2.8.6.1/src/Makefile.am (Revision 1) -+++ snort-2.8.6.1/src/Makefile.am (Revision 3) -@@ -52,7 +52,8 @@ - detection_filter.c detection_filter.h \ - rate_filter.c rate_filter.h \ - obfuscation.c obfuscation.h \ --rule_option_types.h -+rule_option_types.h \ -+twofish.c twofish.h - - snort_LDADD = output-plugins/libspo.a \ - detection-plugins/libspd.a \ -Index: snort-2.8.6.1/autojunk.sh -=================================================================== ---- snort-2.8.6.1/autojunk.sh (Revision 0) -+++ snort-2.8.6.1/autojunk.sh (Revision 3) -@@ -0,0 +1,7 @@ -+#!/bin/sh -+# the list of commands that need to run before we do a compile -+libtoolize --automake --copy -+aclocal -I m4 -+autoheader -+automake --add-missing --copy -+autoconf - -Index: snort-2.8.6.1/etc/snort.conf -=================================================================== ---- snort-2.8.6.1/etc/snort.conf (Revision 1) -+++ snort-2.8.6.1/etc/snort.conf (Revision 3) -@@ -277,6 +277,32 @@ - # prelude - # output alert_prelude - -+# snortsam -+# In order to cause Snort to send a blocking request to the SnortSam agent, -+# that agent has to be listed, including the port it listens on, -+# and the encryption key it is using. The statement for that is: -+# -+# output alert_fwsam: {SnortSam Station}:{port}/{password} -+# -+# {SnortSam Station}: IP address or host name of the host where SnortSam is running. -+# {port}: The port the remote SnortSam agent listens on. -+# {password}: The password, or key, used for encryption of the -+# communication to the remote agent. -+# -+# At the very least, the IP address or host name of the host running SnortSam -+# needs to be specified. If the port is omitted, it defaults to TCP port 898. -+# If the password is omitted, it defaults to a preset password. -+# (In which case it needs to be omitted on the SnortSam agent as well) -+# -+# More than one host can be specified, but has to be done on the same line. -+# Just separate them with one or more spaces. -+# -+# Examples: -+# -+# output alert_fwsam: firewall/idspassword -+# output alert_fwsam: fw1.domain.tld:898/mykey -+# output alert_fwsam: 192.168.0.1/borderfw 192.168.1.254/wanfw -+ - # metadata reference data. do not modify these lines - include classification.config - include reference.config diff --git a/config/snort-dev/patches/inlinemode_options_flags.txt b/config/snort-dev/patches/inlinemode_options_flags.txt deleted file mode 100644 index e69de29b..00000000 --- a/config/snort-dev/patches/inlinemode_options_flags.txt +++ /dev/null diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.am b/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.am deleted file mode 100644 index 0879c6e3..00000000 --- a/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -## $Id -AUTOMAKE_OPTIONS=foreign no-dependencies - -noinst_LIBRARIES = libspo.a - -libspo_a_SOURCES = spo_alert_fast.c spo_alert_fast.h \ -spo_alert_full.c spo_alert_full.h \ -spo_alert_syslog.c spo_alert_syslog.h spo_alert_unixsock.c \ -spo_alert_unixsock.h spo_csv.c spo_csv.h spo_database.c spo_database.h \ -spo_log_null.c spo_log_null.h spo_log_tcpdump.c \ -spo_log_tcpdump.h spo_unified.c spo_unified2.c spo_unified.h spo_unified2.h \ -spo_log_ascii.c spo_log_ascii.h spo_alert_sf_socket.h spo_alert_sf_socket.c \ -spo_alert_prelude.c spo_alert_prelude.h spo_alert_arubaaction.c spo_alert_arubaaction.h \ -spo_alert_test.c spo_alert_test.h \ -spo_pf.h spo_pf.c - -INCLUDES = @INCLUDES@ diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.in b/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.in deleted file mode 100644 index 3f06cc31..00000000 --- a/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.in +++ /dev/null @@ -1,445 +0,0 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = ../.. -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/output-plugins -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/libprelude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -LIBRARIES = $(noinst_LIBRARIES) -ARFLAGS = cru -libspo_a_AR = $(AR) $(ARFLAGS) -libspo_a_LIBADD = -am_libspo_a_OBJECTS = spo_alert_fast.$(OBJEXT) \ - spo_alert_full.$(OBJEXT) spo_alert_syslog.$(OBJEXT) \ - spo_alert_unixsock.$(OBJEXT) spo_csv.$(OBJEXT) \ - spo_database.$(OBJEXT) spo_log_null.$(OBJEXT) \ - spo_log_tcpdump.$(OBJEXT) spo_unified.$(OBJEXT) \ - spo_unified2.$(OBJEXT) spo_log_ascii.$(OBJEXT) \ - spo_alert_sf_socket.$(OBJEXT) spo_alert_prelude.$(OBJEXT) \ - spo_alert_arubaaction.$(OBJEXT) spo_alert_test.$(OBJEXT) \ - spo_pf.$(OBJEXT) -libspo_a_OBJECTS = $(am_libspo_a_OBJECTS) -DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) -depcomp = -am__depfiles_maybe = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(libspo_a_SOURCES) -DIST_SOURCES = $(libspo_a_SOURCES) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMDEP_FALSE = @AMDEP_FALSE@ -AMDEP_TRUE = @AMDEP_TRUE@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BUILD_DYNAMIC_EXAMPLES_FALSE = @BUILD_DYNAMIC_EXAMPLES_FALSE@ -BUILD_DYNAMIC_EXAMPLES_TRUE = @BUILD_DYNAMIC_EXAMPLES_TRUE@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO = @ECHO@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ -HAVE_DYNAMIC_PLUGINS_FALSE = @HAVE_DYNAMIC_PLUGINS_FALSE@ -HAVE_DYNAMIC_PLUGINS_TRUE = @HAVE_DYNAMIC_PLUGINS_TRUE@ -HAVE_SUP_IP6_FALSE = @HAVE_SUP_IP6_FALSE@ -HAVE_SUP_IP6_TRUE = @HAVE_SUP_IP6_TRUE@ -HAVE_TARGET_BASED_FALSE = @HAVE_TARGET_BASED_FALSE@ -HAVE_TARGET_BASED_TRUE = @HAVE_TARGET_BASED_TRUE@ -HAVE_ZLIB_FALSE = @HAVE_ZLIB_FALSE@ -HAVE_ZLIB_TRUE = @HAVE_ZLIB_TRUE@ -INCLUDES = @INCLUDES@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LEX = @LEX@ -LIBOBJS = @LIBOBJS@ -LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@ -LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@ -LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@ -LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@ -LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@ -LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@ -LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ -MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ -MAKEINFO = @MAKEINFO@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -YACC = @YACC@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ -am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ -am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ -am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@ -am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -datadir = @datadir@ -exec_prefix = @exec_prefix@ -extra_incl = @extra_incl@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -AUTOMAKE_OPTIONS = foreign no-dependencies -noinst_LIBRARIES = libspo.a -libspo_a_SOURCES = spo_alert_fast.c spo_alert_fast.h \ -spo_alert_full.c spo_alert_full.h \ -spo_alert_syslog.c spo_alert_syslog.h spo_alert_unixsock.c \ -spo_alert_unixsock.h spo_csv.c spo_csv.h spo_database.c spo_database.h \ -spo_log_null.c spo_log_null.h spo_log_tcpdump.c \ -spo_log_tcpdump.h spo_unified.c spo_unified2.c spo_unified.h spo_unified2.h \ -spo_log_ascii.c spo_log_ascii.h spo_alert_sf_socket.h spo_alert_sf_socket.c \ -spo_alert_prelude.c spo_alert_prelude.h spo_alert_arubaaction.c spo_alert_arubaaction.h \ -spo_alert_test.c spo_alert_test.h \ -spo_pf.h spo_pf.c - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/output-plugins/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --foreign src/output-plugins/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -libspo.a: $(libspo_a_OBJECTS) $(libspo_a_DEPENDENCIES) - -rm -f libspo.a - $(libspo_a_AR) libspo.a $(libspo_a_OBJECTS) $(libspo_a_LIBADD) - $(RANLIB) libspo.a - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -.c.o: - $(COMPILE) -c $< - -.c.obj: - $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: - $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ - if test -d $$d/$$file; then \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ - fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ - else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LIBRARIES) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-libtool distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -info: info-am - -info-am: - -install-data-am: - -install-exec-am: - -install-info: install-info-am - -install-man: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-info-am - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-exec \ - install-exec-am install-info install-info-am install-man \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags uninstall uninstall-am \ - uninstall-info-am - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c b/config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c deleted file mode 100644 index 31f381a8..00000000 --- a/config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c +++ /dev/null @@ -1,1544 +0,0 @@ -/* $Id$ */ -/* -** Copyright (C) 2002-2010 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. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif - -#ifndef WIN32 -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#endif /* !WIN32 */ -#include <time.h> -#include <errno.h> - -#include "sf_types.h" -#include "plugbase.h" -#include "spo_plugbase.h" -#include "snort.h" -#include "debug.h" -#include "util.h" -#include "log.h" -#include "detect.h" - -/* built-in preprocessors */ -#include "preprocessors/spp_rpc_decode.h" -#include "preprocessors/spp_bo.h" -#include "preprocessors/spp_stream5.h" -#include "preprocessors/spp_arpspoof.h" -#include "preprocessors/spp_perfmonitor.h" -#include "preprocessors/spp_httpinspect.h" -#include "preprocessors/spp_sfportscan.h" -#include "preprocessors/spp_frag3.h" - -/* built-in detection plugins */ -#include "detection-plugins/sp_pattern_match.h" -#include "detection-plugins/sp_tcp_flag_check.h" -#include "detection-plugins/sp_icmp_type_check.h" -#include "detection-plugins/sp_icmp_code_check.h" -#include "detection-plugins/sp_ttl_check.h" -#include "detection-plugins/sp_ip_id_check.h" -#include "detection-plugins/sp_tcp_ack_check.h" -#include "detection-plugins/sp_tcp_seq_check.h" -#include "detection-plugins/sp_dsize_check.h" -#include "detection-plugins/sp_ipoption_check.h" -#include "detection-plugins/sp_rpc_check.h" -#include "detection-plugins/sp_icmp_id_check.h" -#include "detection-plugins/sp_icmp_seq_check.h" -#include "detection-plugins/sp_session.h" -#include "detection-plugins/sp_ip_tos_check.h" -#include "detection-plugins/sp_ip_fragbits.h" -#include "detection-plugins/sp_tcp_win_check.h" -#include "detection-plugins/sp_ip_same_check.h" -#include "detection-plugins/sp_ip_proto.h" -#include "detection-plugins/sp_ip_same_check.h" -#include "detection-plugins/sp_clientserver.h" -#include "detection-plugins/sp_byte_check.h" -#include "detection-plugins/sp_byte_jump.h" -#include "detection-plugins/sp_isdataat.h" -#include "detection-plugins/sp_pcre.h" -#include "detection-plugins/sp_flowbits.h" -#include "detection-plugins/sp_file_data.h" -#include "detection-plugins/sp_asn1.h" -#ifdef ENABLE_REACT -#include "detection-plugins/sp_react.h" -#endif -#ifdef ENABLE_RESPOND -#include "detection-plugins/sp_respond.h" -#endif -#include "detection-plugins/sp_ftpbounce.h" -#include "detection-plugins/sp_urilen_check.h" -#include "detection-plugins/sp_cvs.h" - -/* built-in output plugins */ -#include "output-plugins/spo_alert_syslog.h" -#include "output-plugins/spo_log_tcpdump.h" -#include "output-plugins/spo_database.h" -#include "output-plugins/spo_alert_fast.h" -#include "output-plugins/spo_alert_full.h" -#include "output-plugins/spo_alert_unixsock.h" -#include "output-plugins/spo_csv.h" -#include "output-plugins/spo_unified.h" -#include "output-plugins/spo_log_null.h" -#include "output-plugins/spo_log_ascii.h" -#include "output-plugins/spo_unified2.h" -#include "output-plugins/spo_pf.h" - -#ifdef ARUBA -#include "output-plugins/spo_alert_arubaaction.h" -#endif - -#ifdef HAVE_LIBPRELUDE -#include "output-plugins/spo_alert_prelude.h" -#endif - -#ifdef LINUX -#include "output-plugins/spo_alert_sf_socket.h" -#endif - -#include "output-plugins/spo_alert_test.h" - -extern ListHead *head_tmp; -extern PreprocConfigFuncNode *preproc_config_funcs; -extern OutputConfigFuncNode *output_config_funcs; -extern RuleOptConfigFuncNode *rule_opt_config_funcs; -extern RuleOptOverrideInitFuncNode *rule_opt_override_init_funcs; -extern RuleOptParseCleanupNode *rule_opt_parse_cleanup_list; -extern PreprocSignalFuncNode *preproc_restart_funcs; -extern PreprocSignalFuncNode *preproc_clean_exit_funcs; -extern PreprocSignalFuncNode *preproc_shutdown_funcs; -extern PreprocSignalFuncNode *preproc_reset_funcs; -extern PreprocSignalFuncNode *preproc_reset_stats_funcs; -extern PreprocStatsFuncNode *preproc_stats_funcs; -extern PluginSignalFuncNode *plugin_shutdown_funcs; -extern PluginSignalFuncNode *plugin_clean_exit_funcs; -extern PluginSignalFuncNode *plugin_restart_funcs; -extern OutputFuncNode *AlertList; -extern OutputFuncNode *LogList; - - -/**************************** Detection Plugin API ****************************/ -/* For translation from enum to char* */ -#ifdef DEBUG -static const char *optTypeMap[OPT_TYPE_MAX] = -{ - "action", - "logging", - "detection" -}; - -#define ENUM2STR(num, map) \ - ((num < sizeof(map)/sizeof(map[0])) ? map[num] : "undefined") -#endif - - -void RegisterRuleOptions(void) -{ - LogMessage("Initializing Plug-ins!\n"); - - SetupPatternMatch(); - SetupTCPFlagCheck(); - SetupIcmpTypeCheck(); - SetupIcmpCodeCheck(); - SetupTtlCheck(); - SetupIpIdCheck(); - SetupTcpAckCheck(); - SetupTcpSeqCheck(); - SetupDsizeCheck(); - SetupIpOptionCheck(); - SetupRpcCheck(); - SetupIcmpIdCheck(); - SetupIcmpSeqCheck(); - SetupSession(); - SetupIpTosCheck(); - SetupFragBits(); - SetupFragOffset(); - SetupTcpWinCheck(); - SetupIpProto(); - SetupIpSameCheck(); - SetupClientServer(); - SetupByteTest(); - SetupByteJump(); - SetupIsDataAt(); - SetupFileData(); - SetupPcre(); - SetupFlowBits(); - SetupAsn1(); -#ifdef ENABLE_REACT - SetupReact(); -#endif -#ifdef ENABLE_RESPOND - SetupRespond(); -#endif - SetupFTPBounce(); - SetupUriLenCheck(); - SetupCvs(); -} - -/**************************************************************************** - * - * Function: RegisterRuleOption(char *, void (*func)(), enum OptionType) - * - * Purpose: Associates a rule option keyword with an option setup/linking - * function. - * - * Arguments: keyword => The option keyword to associate with the option - * handler - * *func => function pointer to the handler - * type => used to determine where keyword is allowed - * - * Returns: void function - * - ***************************************************************************/ -void RegisterRuleOption(char *opt_name, RuleOptConfigFunc config_func, - RuleOptOverrideInitFunc override_init_func, - RuleOptType opt_type, - RuleOptOtnHandler otn_handler) -{ - RuleOptConfigFuncNode *node; - - DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Registering keyword:func => %s/%s:%p\n", - ENUM2STR(opt_type, optTypeMap), opt_name, config_func);); - - node = (RuleOptConfigFuncNode *)SnortAlloc(sizeof(RuleOptConfigFuncNode)); - - if (rule_opt_config_funcs == NULL) - { - rule_opt_config_funcs = node; - } - else - { - RuleOptConfigFuncNode *tmp = rule_opt_config_funcs; - RuleOptConfigFuncNode *last; - - do - { - if (strcasecmp(tmp->keyword, opt_name) == 0) - { - free(node); - FatalError("Duplicate detection plugin keyword: %s.\n", - file_line, opt_name); - } - - last = tmp; - tmp = tmp->next; - - } while (tmp != NULL); - - last->next = node; - } - - node->keyword = SnortStrdup(opt_name); - node->type = opt_type; - node->func = config_func; - node->otn_handler = otn_handler; - - if (override_init_func != NULL) - { - RuleOptOverrideInitFuncNode *node_override = - (RuleOptOverrideInitFuncNode *)SnortAlloc(sizeof(RuleOptOverrideInitFuncNode)); - - if (rule_opt_override_init_funcs == NULL) - { - rule_opt_override_init_funcs = node_override; - } - else - { - RuleOptOverrideInitFuncNode *tmp = rule_opt_override_init_funcs; - RuleOptOverrideInitFuncNode *last; - - do - { - if (strcasecmp(tmp->keyword, opt_name) == 0) - { - free(node_override); - FatalError("RegisterRuleOption: Duplicate detection plugin keyword:" - " (%s) (%s)!\n", tmp->keyword, opt_name); - } - - last = tmp; - tmp = tmp->next; - - } while (tmp != NULL); - - last->next = node_override; - } - - node_override->keyword = SnortStrdup(opt_name); - node_override->type = opt_type; - node_override->func = override_init_func; - node_override->otn_handler = otn_handler; - } -} - -void RegisterOverrideKeyword(char *keyword, char *option, RuleOptOverrideFunc func) -{ - RuleOptOverrideInitFuncNode *node = rule_opt_override_init_funcs; - - while (node != NULL) - { - if (strcasecmp(node->keyword, keyword) == 0) - { - node->func(keyword, option, func); - break; - } - - node = node->next; - } -} - -/**************************************************************************** - * - * Function: DumpPlugIns() - * - * Purpose: Prints the keyword->function list - * - * Arguments: None. - * - * Returns: void function - * - ***************************************************************************/ -void DumpRuleOptions(void) -{ - RuleOptConfigFuncNode *node; - - node = rule_opt_config_funcs; - - LogMessage("-------------------------------------------------\n"); - LogMessage(" Keyword | Plugin Registered @\n"); - LogMessage("-------------------------------------------------\n"); - - while (node != NULL) - { - LogMessage("%-13s: %p\n", node->keyword, node->func); - node = node->next; - } - - LogMessage("-------------------------------------------------\n"); - LogMessage("\n"); -} - - -/**************************************************************************** - * - * Function: AddOptFuncToList(int (*func)(), OptTreeNode *) - * - * Purpose: Links the option detection module to the OTN - * - * Arguments: (*func)() => function pointer to the detection module - * otn => pointer to the current OptTreeNode - * - * Returns: void function - * - ***************************************************************************/ -OptFpList * AddOptFuncToList(RuleOptEvalFunc func, OptTreeNode *otn) -{ - OptFpList *ofp = (OptFpList *)SnortAlloc(sizeof(OptFpList)); - - DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding new rule to list\n");); - - /* if there are no nodes on the function list... */ - if (otn->opt_func == NULL) - { - otn->opt_func = ofp; - } - else - { - OptFpList *tmp = otn->opt_func; - - /* walk to the end of the list */ - while (tmp->next != NULL) - tmp = tmp->next; - - tmp->next = ofp; - } - - DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set OptTestFunc to %p\n", func);); - - ofp->OptTestFunc = func; - - return ofp; -} - -/**************************************************************************** - * - * Function: AddRspFuncToList(int (*func)(), OptTreeNode *) - * - * Purpose: Adds Response function to OTN - * - * Arguments: (*func)() => function pointer to the response module - * otn => pointer to the current OptTreeNode - * - * Returns: void function - * - ***************************************************************************/ -void AddRspFuncToList(ResponseFunc func, OptTreeNode *otn, void *params) -{ - RspFpList *rsp = (RspFpList *)SnortAlloc(sizeof(RspFpList)); - - DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding response to list\n");); - - /* if there are no nodes on the function list... */ - if (otn->rsp_func == NULL) - { - otn->rsp_func = rsp; - } - else - { - RspFpList *tmp = otn->rsp_func; - - /* walk to the end of the list */ - while (tmp->next != NULL) - tmp = tmp->next; - - tmp->next = rsp; - } - - DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set ResponseFunc to %p\n", func);); - - rsp->func = func; - rsp->params = params; -} - -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; - } -} - -void FreeRuleOptConfigFuncs(RuleOptConfigFuncNode *head) -{ - - while (head != NULL) - { - RuleOptConfigFuncNode *tmp = head; - - head = head->next; - - if (tmp->keyword != NULL) - free(tmp->keyword); - - free(tmp); - } -} - -void FreeRuleOptOverrideInitFuncs(RuleOptOverrideInitFuncNode *head) -{ - - while (head != NULL) - { - RuleOptOverrideInitFuncNode *tmp = head; - - head = head->next; - - if (tmp->keyword != NULL) - free(tmp->keyword); - - free(tmp); - } -} - -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); - } -} - - -/************************** Preprocessor Plugin API ***************************/ -static void AddFuncToPreprocSignalList(PreprocSignalFunc, void *, - PreprocSignalFuncNode **, uint16_t, uint32_t); - - -void RegisterPreprocessors(void) -{ - LogMessage("Initializing Preprocessors!\n"); - - SetupARPspoof(); - SetupFrag3(); - SetupStream5(); - SetupRpcDecode(); - SetupBo(); - SetupHttpInspect(); - SetupPerfMonitor(); - SetupSfPortscan(); -} - -/**************************************************************************** - * - * Function: RegisterPreprocessor(char *, void (*)(char *)) - * - * Purpose: Associates a preprocessor statement with its function. - * - * Arguments: keyword => The option keyword to associate with the - * preprocessor - * *func => function pointer to the handler - * - * Returns: void function - * - ***************************************************************************/ -#ifndef SNORT_RELOAD -void RegisterPreprocessor(char *keyword, PreprocConfigFunc func) -#else -void RegisterPreprocessor(char *keyword, PreprocConfigFunc func, - PreprocReloadFunc rfunc, PreprocReloadSwapFunc sfunc, - PreprocReloadSwapFreeFunc ffunc) -#endif -{ - PreprocConfigFuncNode *node = - (PreprocConfigFuncNode *)SnortAlloc(sizeof(PreprocConfigFuncNode)); - - DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:preproc => %s:%p\n", keyword, func);); - - if (preproc_config_funcs == NULL) - { - preproc_config_funcs = node; - } - else - { - PreprocConfigFuncNode *tmp = preproc_config_funcs; - PreprocConfigFuncNode *last; - - do - { - if (strcasecmp(tmp->keyword, keyword) == 0) - { - free(node); - FatalError("Duplicate preprocessor keyword: %s.\n", keyword); - } - - last = tmp; - tmp = tmp->next; - - } while (tmp != NULL); - - last->next = node; - } - - node->keyword = SnortStrdup(keyword); - node->config_func = func; - -#ifdef SNORT_RELOAD - node->reload_func = rfunc; - node->reload_swap_func = sfunc; - node->reload_swap_free_func = ffunc; -#endif -} - -PreprocConfigFuncNode * GetPreprocConfig(char *keyword) -{ - PreprocConfigFuncNode *head = preproc_config_funcs; - - if (keyword == NULL) - return NULL; - - while (head != NULL) - { - if (strcasecmp(head->keyword, keyword) == 0) - return head; - - head = head->next; - } - - return NULL; -} - -PreprocConfigFunc GetPreprocConfigFunc(char *keyword) -{ - PreprocConfigFuncNode *head = preproc_config_funcs; - - if (keyword == NULL) - return NULL; - - while (head != NULL) - { - if (strcasecmp(head->keyword, keyword) == 0) - return head->config_func; - - head = head->next; - } - - return NULL; -} - -/**************************************************************************** - * - * Function: RegisterPreprocStats(char *keyword, void (*func)(int)) - * - * Purpose: Registers a function for printing preprocessor final stats - * (or other if it has a use for printing final stats) - * - * Arguments: keyword => keyword (preprocessor) whose stats will print - * func => function pointer to the handler - * - * Returns: void function - * - ***************************************************************************/ -void RegisterPreprocStats(char *keyword, PreprocStatsFunc func) -{ - PreprocStatsFuncNode *node; - - DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering final stats function: " - "preproc => %s:%p\n", keyword, func);); - - node = (PreprocStatsFuncNode *)SnortAlloc(sizeof(PreprocStatsFuncNode)); - - if (preproc_stats_funcs == NULL) - { - preproc_stats_funcs = node; - } - else - { - PreprocStatsFuncNode *tmp = preproc_stats_funcs; - PreprocStatsFuncNode *last; - - do - { - if (strcasecmp(tmp->keyword, keyword) == 0) - { - free(node); - FatalError("Duplicate preprocessor keyword: %s.\n", keyword); - } - - last = tmp; - tmp = tmp->next; - - } while (tmp != NULL); - - last->next = node; - } - - node->keyword = SnortStrdup(keyword); - node->func = func; -} - -/**************************************************************************** - * - * Function: DumpPreprocessors() - * - * Purpose: Prints the keyword->preprocess list - * - * Arguments: None. - * - * Returns: void function - * - ***************************************************************************/ -void DumpPreprocessors(void) -{ - PreprocConfigFuncNode *node = preproc_config_funcs; - - LogMessage("-------------------------------------------------\n"); - LogMessage(" Keyword | Preprocessor @ \n"); - LogMessage("-------------------------------------------------\n"); - - while (node != NULL) - { - LogMessage("%-13s: %p\n", node->keyword, node->config_func); - node = node->next; - } - - LogMessage("-------------------------------------------------\n\n"); -} - -int IsPreprocEnabled(uint32_t preproc_id) -{ - PreprocEvalFuncNode *node; - SnortConfig *sc = snort_conf_for_parsing; - tSfPolicyId policy_id = getParserPolicy(); - SnortPolicy *p; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config for parsing is NULL.\n", - __FILE__, __LINE__); - } - - p = sc->targeted_policies[policy_id]; - if (p == NULL) - return 0; - - for (node = p->preproc_eval_funcs; node != NULL; node = node->next) - { - if (node->preproc_id == preproc_id) - return 1; - } - - return 0; -} - -PreprocEvalFuncNode * AddFuncToPreprocList(PreprocEvalFunc func, uint16_t priority, - uint32_t preproc_id, uint32_t proto_mask) -{ - PreprocEvalFuncNode *node; - SnortConfig *sc = snort_conf_for_parsing; - tSfPolicyId policy_id = getParserPolicy(); - SnortPolicy *p; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config for parsing is NULL.\n", - __FILE__, __LINE__); - } - - p = sc->targeted_policies[policy_id]; - if (p == NULL) - return NULL; - - DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES, - "Adding preprocessor function ID %d/bit %d/pri %d to list\n", - preproc_id, p->num_preprocs, priority);); - - node = (PreprocEvalFuncNode *)SnortAlloc(sizeof(PreprocEvalFuncNode)); - - if (p->preproc_eval_funcs == NULL) - { - p->preproc_eval_funcs = node; - } - else - { - PreprocEvalFuncNode *tmp = p->preproc_eval_funcs; - PreprocEvalFuncNode *last = NULL; - - do - { - if (tmp->preproc_id == preproc_id) - { - free(node); - FatalError("Preprocessor already registered with ID %d\n", - preproc_id); - } - - /* Insert higher priority preprocessors first. Lower priority - * number means higher priority */ - if (priority < tmp->priority) - break; - - last = tmp; - tmp = tmp->next; - - } while (tmp != NULL); - - /* Priority higher than first item in list */ - if (last == NULL) - { - node->next = tmp; - p->preproc_eval_funcs = node; - } - else - { - node->next = tmp; - last->next = node; - } - } - - node->func = func; - node->priority = priority; - node->preproc_id = preproc_id; - node->preproc_bit = (1 << preproc_id); - node->proto_mask = proto_mask; - - p->num_preprocs++; - p->preproc_proto_mask |= proto_mask; - p->preproc_bit_mask |= node->preproc_bit; - - return node; -} - -void AddFuncToPreprocPostConfigList(PreprocPostConfigFunc func, void *data) -{ - PreprocPostConfigFuncNode *node; - SnortConfig *sc = snort_conf_for_parsing; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config for parsing is NULL.\n", - __FILE__, __LINE__); - } - - node = (PreprocPostConfigFuncNode *)SnortAlloc(sizeof(PreprocPostConfigFuncNode)); - - if (sc->preproc_post_config_funcs == NULL) - { - sc->preproc_post_config_funcs = node; - } - else - { - PreprocPostConfigFuncNode *tmp = sc->preproc_post_config_funcs; - - while (tmp->next != NULL) - tmp = tmp->next; - - tmp->next = node; - } - - node->data = data; - node->func = func; -} - -void PostConfigPreprocessors(SnortConfig *sc) -{ - PreprocPostConfigFuncNode *list; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config is NULL.\n", - __FILE__, __LINE__); - } - - snort_conf_for_parsing = sc; - - list = sc->preproc_post_config_funcs; - - for (; list != NULL; list = list->next) - { - if (list->func != NULL) - list->func(list->data); - } - - snort_conf_for_parsing = NULL; -} - -#ifdef SNORT_RELOAD -void SwapPreprocConfigurations(void) -{ - PreprocConfigFuncNode *node = preproc_config_funcs; - - for (; node != NULL; node = node->next) - { - if (node->reload_swap_func != NULL) - node->swap_free_data = node->reload_swap_func(); - } -} - -void FreeSwappedPreprocConfigurations(void) -{ - PreprocConfigFuncNode *node = preproc_config_funcs; - - for (; node != NULL; node = node->next) - { - if ((node->reload_swap_free_func != NULL) && - (node->swap_free_data != NULL)) - { - node->reload_swap_free_func(node->swap_free_data); - node->swap_free_data = NULL; - } - } -} - -void AddFuncToPreprocReloadVerifyList(PreprocReloadVerifyFunc func) -{ - PreprocReloadVerifyFuncNode *node; - SnortConfig *sc = snort_conf_for_parsing; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config for parsing is NULL.\n", - __FILE__, __LINE__); - } - - node = (PreprocReloadVerifyFuncNode *)SnortAlloc(sizeof(PreprocReloadVerifyFuncNode)); - - if (sc->preproc_reload_verify_funcs == NULL) - { - sc->preproc_reload_verify_funcs = node; - } - else - { - PreprocReloadVerifyFuncNode *tmp = sc->preproc_reload_verify_funcs; - - while (tmp->next != NULL) - tmp = tmp->next; - - tmp->next = node; - } - - node->func = func; -} - -void FreePreprocReloadVerifyFuncList(PreprocReloadVerifyFuncNode *head) -{ - while (head != NULL) - { - PreprocReloadVerifyFuncNode *tmp = head; - - head = head->next; - free(tmp); - } -} -#endif - -void AddFuncToConfigCheckList(PreprocCheckConfigFunc func) -{ - PreprocCheckConfigFuncNode *node; - SnortConfig *sc = snort_conf_for_parsing; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config for parsing is NULL.\n", - __FILE__, __LINE__); - } - - node = (PreprocCheckConfigFuncNode *)SnortAlloc(sizeof(PreprocCheckConfigFuncNode)); - - if (sc->preproc_config_check_funcs == NULL) - { - sc->preproc_config_check_funcs = node; - } - else - { - PreprocCheckConfigFuncNode *tmp = sc->preproc_config_check_funcs; - - while (tmp->next != NULL) - tmp = tmp->next; - - tmp->next = node; - } - - node->func = func; -} - -/* functions to aid in cleaning up after plugins */ -void AddFuncToPreprocRestartList(PreprocSignalFunc func, void *arg, - uint16_t priority, uint32_t preproc_id) -{ - AddFuncToPreprocSignalList(func, arg, &preproc_restart_funcs, priority, preproc_id); -} - -void AddFuncToPreprocCleanExitList(PreprocSignalFunc func, void *arg, - uint16_t priority, uint32_t preproc_id) -{ - AddFuncToPreprocSignalList(func, arg, &preproc_clean_exit_funcs, priority, preproc_id); -} - -void AddFuncToPreprocShutdownList(PreprocSignalFunc func, void *arg, - uint16_t priority, uint32_t preproc_id) -{ - AddFuncToPreprocSignalList(func, arg, &preproc_shutdown_funcs, priority, preproc_id); -} - -void AddFuncToPreprocResetList(PreprocSignalFunc func, void *arg, - uint16_t priority, uint32_t preproc_id) -{ - AddFuncToPreprocSignalList(func, arg, &preproc_reset_funcs, priority, preproc_id); -} - -void AddFuncToPreprocResetStatsList(PreprocSignalFunc func, void *arg, - uint16_t priority, uint32_t preproc_id) -{ - AddFuncToPreprocSignalList(func, arg, &preproc_reset_stats_funcs, priority, preproc_id); -} - -static void AddFuncToPreprocSignalList(PreprocSignalFunc func, void *arg, - PreprocSignalFuncNode **list, - uint16_t priority, uint32_t preproc_id) -{ - PreprocSignalFuncNode *node; - - if (list == NULL) - return; - - node = (PreprocSignalFuncNode *)SnortAlloc(sizeof(PreprocSignalFuncNode)); - - if (*list == NULL) - { - *list = node; - } - else - { - PreprocSignalFuncNode *tmp = *list; - PreprocSignalFuncNode *last = NULL; - - do - { - /* Insert higher priority stuff first. Lower priority - * number means higher priority */ - if (priority < tmp->priority) - break; - - last = tmp; - tmp = tmp->next; - - } while (tmp != NULL); - - /* Priority higher than first item in list */ - if (last == NULL) - { - node->next = tmp; - *list = node; - } - else - { - node->next = tmp; - last->next = node; - } - } - - node->func = func; - node->arg = arg; - node->preproc_id = preproc_id; - node->priority = priority; -} - -void AddFuncToPreprocReassemblyPktList(PreprocReassemblyPktFunc func, uint32_t preproc_id) -{ - PreprocReassemblyPktFuncNode *node; - SnortConfig *sc = snort_conf_for_parsing; - tSfPolicyId policy_id = getParserPolicy(); - SnortPolicy *p; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config for parsing is NULL.\n", - __FILE__, __LINE__); - } - - p = sc->targeted_policies[policy_id]; - if (p == NULL) - return; - - node = (PreprocReassemblyPktFuncNode *)SnortAlloc(sizeof(PreprocReassemblyPktFuncNode)); - - if (p->preproc_reassembly_pkt_funcs == NULL) - { - p->preproc_reassembly_pkt_funcs = node; - } - else - { - PreprocReassemblyPktFuncNode *tmp = p->preproc_reassembly_pkt_funcs; - - /* just insert at front of list */ - p->preproc_reassembly_pkt_funcs = node; - node->next = tmp; - } - - node->func = func; - node->preproc_id = preproc_id; -} - -void FreePreprocConfigFuncs(void) -{ - PreprocConfigFuncNode *head = preproc_config_funcs; - PreprocConfigFuncNode *tmp; - - while (head != NULL) - { - tmp = head->next; - if (head->keyword != NULL) - free(head->keyword); - free(head); - head = tmp; - } -} - -void FreePreprocCheckConfigFuncs(PreprocCheckConfigFuncNode *head) -{ - PreprocCheckConfigFuncNode *tmp; - - while (head != NULL) - { - tmp = head->next; - free(head); - head = tmp; - } -} - -void FreePreprocPostConfigFuncs(PreprocPostConfigFuncNode *head) -{ - PreprocPostConfigFuncNode *tmp; - - while (head != NULL) - { - tmp = head->next; - free(head); - head = tmp; - } -} - -void FreePreprocStatsFuncs(PreprocStatsFuncNode *head) -{ - PreprocStatsFuncNode *tmp; - - while (head != NULL) - { - tmp = head->next; - if (head->keyword != NULL) - free(head->keyword); - free(head); - head = tmp; - } -} - -void FreePreprocEvalFuncs(PreprocEvalFuncNode *head) -{ - PreprocEvalFuncNode *tmp; - - while (head != NULL) - { - tmp = head->next; - //if (head->context) - // free(head->context); - free(head); - head = tmp; - } -} - -void FreePreprocReassemblyPktFuncs(PreprocReassemblyPktFuncNode *head) -{ - PreprocReassemblyPktFuncNode *tmp; - - while (head != NULL) - { - tmp = head->next; - free(head); - head = tmp; - } -} - -void FreePreprocSigFuncs(PreprocSignalFuncNode *head) -{ - PreprocSignalFuncNode *tmp; - - while (head != NULL) - { - tmp = head->next; - /* don't free sig->arg, that's free'd by the CleanExit/Restart func */ - free(head); - head = tmp; - } -} - -void CheckPreprocessorsConfig(SnortConfig *sc) -{ - PreprocCheckConfigFuncNode *idx; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config is NULL.\n", - __FILE__, __LINE__); - } - - snort_conf_for_parsing = sc; - - idx = sc->preproc_config_check_funcs; - - LogMessage("Verifying Preprocessor Configurations!\n"); - - while(idx != NULL) - { - idx->func(); - idx = idx->next; - } - - snort_conf_for_parsing = NULL; -} - -#ifdef SNORT_RELOAD -int VerifyReloadedPreprocessors(SnortConfig *sc) -{ - PreprocReloadVerifyFuncNode *node; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config is NULL.\n", - __FILE__, __LINE__); - } - - snort_conf_for_parsing = sc; - - node = sc->preproc_reload_verify_funcs; - while (node != NULL) - { - if (node->func != NULL) - { - if (node->func() == -1) - return -1; - } - - node = node->next; - } - - snort_conf_for_parsing = NULL; - - return 0; -} -#endif - - -/***************************** Output Plugin API *****************************/ -extern OutputConfigFuncNode *output_config_funcs; - -static void AppendOutputFuncList(OutputFunc, void *, OutputFuncNode **); - -void RegisterOutputPlugins(void) -{ - LogMessage("Initializing Output Plugins!\n"); - - AlertSyslogSetup(); - LogTcpdumpSetup(); - DatabaseSetup(); - AlertFastSetup(); - AlertFullSetup(); - AlertPfSetup(); -#ifndef WIN32 - /* Win32 doesn't support AF_UNIX sockets */ - AlertUnixSockSetup(); -#endif /* !WIN32 */ - AlertCSVSetup(); - LogNullSetup(); - UnifiedSetup(); - Unified2Setup(); - LogAsciiSetup(); - -#ifdef ARUBA - AlertArubaActionSetup(); -#endif - -#ifdef LINUX - /* This uses linux only capabilities */ - AlertSFSocket_Setup(); -#endif - -#ifdef HAVE_LIBPRELUDE - AlertPreludeSetup(); -#endif - - AlertTestSetup(); -} - -/**************************************************************************** - * - * 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; - free(tmp); - } -} - -/**************************************************************************** - * - * Function: DumpOutputPlugins() - * - * Purpose: Prints the keyword->preprocess 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: - if (head_tmp != NULL) - AppendOutputFuncList(func, arg, &head_tmp->AlertList); - else - AppendOutputFuncList(func, arg, &AlertList); - - break; - - case OUTPUT_TYPE__LOG: - if (head_tmp != NULL) - AppendOutputFuncList(func, arg, &head_tmp->LogList); - else - 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; -} - - -/************************** Miscellaneous Functions **************************/ - -/* 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) -{ - SnortConfig *sc = snort_conf_for_parsing; - - if (sc == NULL) - { - FatalError("%s(%d) Snort config for parsing is NULL.\n", - __FILE__, __LINE__); - } - - AddFuncToSignalList(func, arg, &sc->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 AddFuncToRuleOptParseCleanupList(RuleOptParseCleanupFunc func) -{ - RuleOptParseCleanupNode *node = - (RuleOptParseCleanupNode *)SnortAlloc(sizeof(RuleOptParseCleanupNode)); - - if (rule_opt_parse_cleanup_list == NULL) - { - rule_opt_parse_cleanup_list = node; - } - else - { - RuleOptParseCleanupNode *tmp = rule_opt_parse_cleanup_list; - - while (tmp->next != NULL) - tmp = tmp->next; - - tmp->next = node; - } - - node->func = func; -} - -void RuleOptParseCleanup(void) -{ - RuleOptParseCleanupNode *list = rule_opt_parse_cleanup_list; - - for (; list != NULL; list = list->next) - { - if (list->func != NULL) - list->func(); - } -} - -void FreeRuleOptParseCleanupList(RuleOptParseCleanupNode *head) -{ - while (head != NULL) - { - RuleOptParseCleanupNode *tmp = head; - - head = head->next; - free(tmp); - } -} - - diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/util.c b/config/snort-dev/patches/spoink_patch/2.8.6/util.c deleted file mode 100644 index b2d3b38b..00000000 --- a/config/snort-dev/patches/spoink_patch/2.8.6/util.c +++ /dev/null @@ -1,3233 +0,0 @@ -/* $Id$ */ -/* -** Copyright (C) 2002-2010 Sourcefire, Inc. -** Copyright (C) 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. -*/ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <sys/types.h> - -#ifndef WIN32 -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/wait.h> -#include <dirent.h> -#include <fnmatch.h> -#endif /* !WIN32 */ - -#include <stdarg.h> -#include <syslog.h> -#include <errno.h> -#include <sys/stat.h> -#include <time.h> -#include <signal.h> -#include <unistd.h> - -#ifndef WIN32 -#include <grp.h> -#include <pwd.h> -#include <netdb.h> -#include <limits.h> -#endif /* !WIN32 */ - -#include <fcntl.h> - -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif - -#ifdef ZLIB -#include <zlib.h> -#endif - -#include "snort.h" -#include "mstring.h" -#include "debug.h" -#include "util.h" -#include "parser.h" -#include "inline.h" -#include "build.h" -#include "plugbase.h" -#include "sf_types.h" -#include "sflsq.h" -#include "ipv6_port.h" - -#include "pcre.h" - -#include "mpse.h" - -#include "ppm.h" - -#ifdef TARGET_BASED -#include "sftarget_reader.h" -#endif - -#ifdef WIN32 -#include "win32/WIN32-Code/name.h" -#endif - -#include "stream5_common.h" - -#ifdef PATH_MAX -#define PATH_MAX_UTIL PATH_MAX -#else -#define PATH_MAX_UTIL 1024 -#endif /* PATH_MAX */ - -extern Stream5Stats s5stats; -extern int datalink; -extern pcap_t *pcap_handle; -extern PreprocStatsFuncNode *preproc_stats_funcs; - -static PcapPktStats pkt_stats; - -/* - * you may need to adjust this on the systems which don't have standard - * paths defined - */ -#ifndef _PATH_VARRUN -static char _PATH_VARRUN[STD_BUF]; -#endif - - -#ifdef NAME_MAX -#define NAME_MAX_UTIL NAME_MAX -#else -#define NAME_MAX_UTIL 256 -#endif /* NAME_MAX */ - -#define FILE_MAX_UTIL (PATH_MAX_UTIL + NAME_MAX_UTIL) - -/**************************************************************************** - * - * Function: CalcPct(uint64_t, uint64_t) - * - * Purpose: Calculate the percentage of a value compared to a total - * - * Arguments: cnt => the numerator in the equation - * total => the denominator in the calculation - * - * Returns: pct -> the percentage of cnt to value - * - ****************************************************************************/ -double CalcPct(uint64_t cnt, uint64_t total) -{ - double pct = 0.0; - - if (total == 0.0) - { - pct = (double)cnt; - } - else - { - pct = (double)cnt / (double)total; - } - - pct *= 100.0; - - return pct; -} - - -/**************************************************************************** - * - * Function: DisplayBanner() - * - * Purpose: Show valuable proggie info - * - * Arguments: None. - * - * Returns: 0 all the time - * - ****************************************************************************/ -int DisplayBanner(void) -{ - const char * info; - const char * pcre_ver; -#ifdef ZLIB - const char * zlib_ver; -#endif - - info = getenv("HOSTTYPE"); - if( !info ) - { - info=""; - } - - pcre_ver = pcre_version(); -#ifdef ZLIB - zlib_ver = zlib_version; -#endif - - LogMessage("\n"); - LogMessage(" ,,_ -*> Snort! <*-\n"); - LogMessage(" o\" )~ Version %s%s%s (Build %s) %s %s\n", - VERSION, -#ifdef SUP_IP6 - " IPv6", -#else - "", -#endif -#ifdef GRE - " GRE", -#else - "", -#endif - BUILD, -#ifdef GIDS - "inline", -#else - "", -#endif - info); - LogMessage(" '''' By Martin Roesch & The Snort Team: http://www.snort.org/snort/snort-team\n"); - LogMessage(" Copyright (C) 1998-2010 Sourcefire, Inc., et al.\n"); - LogMessage(" Using PCRE version: %s\n", pcre_ver); -#ifdef ZLIB - LogMessage(" Using ZLIB version: %s\n", zlib_ver); -#endif - LogMessage("\n"); - LogMessage(" ___ Built Date for Snort on Pfsense 2.0 is May 25 2010.\n"); - LogMessage(" ___/ f \\ Orion IPS Output Code Copyright (C) 2009-2010 Robert Zelaya.\n"); - LogMessage("/ p \\___/Sense\n"); - LogMessage("\\___/ \\\n"); - LogMessage(" \\___/ Using Snort.org dynamic plugins and Orion IPS source.\n"); - LogMessage("\n"); - - return 0; -} - - - -/**************************************************************************** - * - * Function: ts_print(register const struct, char *) - * - * Purpose: Generate a time stamp and stuff it in a buffer. This one has - * millisecond precision. Oh yeah, I ripped this code off from - * TCPdump, props to those guys. - * - * Arguments: timeval => clock struct coming out of libpcap - * timebuf => buffer to stuff timestamp into - * - * Returns: void function - * - ****************************************************************************/ -void ts_print(register const struct timeval *tvp, char *timebuf) -{ - register int s; - int localzone; - time_t Time; - struct timeval tv; - struct timezone tz; - struct tm *lt; /* place to stick the adjusted clock data */ - - /* if null was passed, we use current time */ - if(!tvp) - { - /* manual page (for linux) says tz is never used, so.. */ - bzero((char *) &tz, sizeof(tz)); - gettimeofday(&tv, &tz); - tvp = &tv; - } - - localzone = snort_conf->thiszone; - - /* - ** If we're doing UTC, then make sure that the timezone is correct. - */ - if (ScOutputUseUtc()) - localzone = 0; - - s = (tvp->tv_sec + localzone) % 86400; - Time = (tvp->tv_sec + localzone) - s; - - lt = gmtime(&Time); - - if (ScOutputIncludeYear()) - { - (void) SnortSnprintf(timebuf, TIMEBUF_SIZE, - "%02d/%02d/%02d-%02d:%02d:%02d.%06u ", - lt->tm_mon + 1, lt->tm_mday, lt->tm_year - 100, - s / 3600, (s % 3600) / 60, s % 60, - (u_int) tvp->tv_usec); - } - else - { - (void) SnortSnprintf(timebuf, TIMEBUF_SIZE, - "%02d/%02d-%02d:%02d:%02d.%06u ", lt->tm_mon + 1, - lt->tm_mday, s / 3600, (s % 3600) / 60, s % 60, - (u_int) tvp->tv_usec); - } -} - - - -/**************************************************************************** - * - * Function: gmt2local(time_t) - * - * Purpose: Figures out how to adjust the current clock reading based on the - * timezone you're in. Ripped off from TCPdump. - * - * Arguments: time_t => offset from GMT - * - * Returns: offset seconds from GMT - * - ****************************************************************************/ -int gmt2local(time_t t) -{ - register int dt, dir; - register struct tm *gmt, *loc; - struct tm sgmt; - - if(t == 0) - t = time(NULL); - - gmt = &sgmt; - *gmt = *gmtime(&t); - loc = localtime(&t); - - dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 + - (loc->tm_min - gmt->tm_min) * 60; - - dir = loc->tm_year - gmt->tm_year; - - if(dir == 0) - dir = loc->tm_yday - gmt->tm_yday; - - dt += dir * 24 * 60 * 60; - - return(dt); -} - - - - -/**************************************************************************** - * - * Function: copy_argv(u_char **) - * - * Purpose: Copies a 2D array (like argv) into a flat string. Stolen from - * TCPDump. - * - * Arguments: argv => 2D array to flatten - * - * Returns: Pointer to the flat string - * - ****************************************************************************/ -char *copy_argv(char **argv) -{ - char **p; - u_int len = 0; - char *buf; - char *src, *dst; - //void ftlerr(char *,...); - - p = argv; - if(*p == 0) - return 0; - - while(*p) - len += strlen(*p++) + 1; - - buf = (char *) calloc(1,len); - - if(buf == NULL) - { - FatalError("calloc() failed: %s\n", strerror(errno)); - } - p = argv; - dst = buf; - - while((src = *p++) != NULL) - { - while((*dst++ = *src++) != '\0'); - dst[-1] = ' '; - } - - dst[-1] = '\0'; - - /* Check for an empty string */ - dst = buf; - while (isspace((int)*dst)) - dst++; - - if (strlen(dst) == 0) - { - free(buf); - buf = NULL; - } - - return buf; -} - - -/**************************************************************************** - * - * Function: strip(char *) - * - * Purpose: Strips a data buffer of CR/LF/TABs. Replaces CR/LF's with - * NULL and TABs with spaces. - * - * Arguments: data => ptr to the data buf to be stripped - * - * Returns: void - * - * 3/7/07 - changed to return void - use strlen to get size of string - * - * Note that this function will turn all '\n' and '\r' into null chars - * so, e.g. 'Hello\nWorld\n' => 'Hello\x00World\x00' - * note that the string is now just 'Hello' and the length is shortened - * by more than just an ending '\n' or '\r' - ****************************************************************************/ -void strip(char *data) -{ - int size; - char *end; - char *idx; - - idx = data; - end = data + strlen(data); - size = end - idx; - - while(idx != end) - { - if((*idx == '\n') || - (*idx == '\r')) - { - *idx = 0; - size--; - } - if(*idx == '\t') - { - *idx = ' '; - } - idx++; - } -} - -/* - * Function: ErrorMessage(const char *, ...) - * - * Purpose: Print a message to stderr. - * - * Arguments: format => the formatted error string to print out - * ... => format commands/fillers - * - * Returns: void function - */ -void ErrorMessage(const char *format,...) -{ - char buf[STD_BUF+1]; - va_list ap; - - if (snort_conf == NULL) - return; - - va_start(ap, format); - - if (ScDaemonMode() || ScLogSyslog()) - { - vsnprintf(buf, STD_BUF, format, ap); - buf[STD_BUF] = '\0'; - syslog(LOG_CONS | LOG_DAEMON | LOG_ERR, "%s", buf); - } - else - { - vfprintf(stderr, format, ap); - } - va_end(ap); -} - -/* - * Function: LogMessage(const char *, ...) - * - * Purpose: Print a message to stderr or with logfacility. - * - * Arguments: format => the formatted error string to print out - * ... => format commands/fillers - * - * Returns: void function - */ -void LogMessage(const char *format,...) -{ - char buf[STD_BUF+1]; - va_list ap; - - if (snort_conf == NULL) - return; - - if (ScLogQuiet() && !ScDaemonMode() && !ScLogSyslog()) - return; - - va_start(ap, format); - - if (ScDaemonMode() || ScLogSyslog()) - { - vsnprintf(buf, STD_BUF, format, ap); - buf[STD_BUF] = '\0'; - syslog(LOG_DAEMON | LOG_NOTICE, "%s", buf); - } - else - { - vfprintf(stderr, format, ap); - } - - va_end(ap); -} - -/* - * Function: CreateApplicationEventLogEntry(const char *) - * - * Purpose: Add an entry to the Win32 "Application" EventLog - * - * Arguments: szMessage => the formatted error string to print out - * - * Returns: void function - */ -#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) -void CreateApplicationEventLogEntry(const char *msg) -{ - HANDLE hEventLog; - char* pEventSourceName = "SnortService"; - - /* prepare to write to Application log on local host - * with Event Source of SnortService - */ - AddEventSource(pEventSourceName); - hEventLog = RegisterEventSource(NULL, pEventSourceName); - if (hEventLog == NULL) - { - /* Could not register the event source. */ - return; - } - - if (!ReportEvent(hEventLog, /* event log handle */ - EVENTLOG_ERROR_TYPE, /* event type */ - 0, /* category zero */ - EVMSG_SIMPLE, /* event identifier */ - NULL, /* no user security identifier */ - 1, /* one substitution string */ - 0, /* no data */ - &msg, /* pointer to array of strings */ - NULL)) /* pointer to data */ - { - /* Could not report the event. */ - } - - DeregisterEventSource(hEventLog); -} -#endif /* WIN32 && ENABLE_WIN32_SERVICE */ - - -/* - * Function: FatalError(const char *, ...) - * - * Purpose: When a fatal error occurs, this function prints the error message - * and cleanly shuts down the program - * - * Arguments: format => the formatted error string to print out - * ... => format commands/fillers - * - * Returns: void function - */ -NORETURN void FatalError(const char *format,...) -{ - char buf[STD_BUF+1]; - va_list ap; - - va_start(ap, format); - vsnprintf(buf, STD_BUF, format, ap); - va_end(ap); - - buf[STD_BUF] = '\0'; - - if ((snort_conf != NULL) && (ScDaemonMode() || ScLogSyslog())) - { - syslog(LOG_CONS | LOG_DAEMON | LOG_ERR, "FATAL ERROR: %s", buf); - } - else - { - fprintf(stderr, "ERROR: %s", buf); - fprintf(stderr,"Fatal Error, Quitting..\n"); -#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE) - CreateApplicationEventLogEntry(buf); -#endif - } - - exit(1); -} - - -/**************************************************************************** - * - * Function: CreatePidFile(char *) - * - * Purpose: Creates a PID file - * - * Arguments: Interface opened. - * - * Returns: void function - * - ****************************************************************************/ -static FILE *pid_lockfile = NULL; -static FILE *pid_file = NULL; -void CreatePidFile(char *intf) -{ - struct stat pt; - int pid = (int) getpid(); -#ifdef WIN32 - char dir[STD_BUF + 1]; -#endif - - if (!ScReadMode()) - { - LogMessage("Checking PID path...\n"); - - if (strlen(snort_conf->pid_path) != 0) - { - if((stat(snort_conf->pid_path, &pt) == -1) || - !S_ISDIR(pt.st_mode) || access(snort_conf->pid_path, W_OK) == -1) - { -#ifndef WIN32 - /* Save this just in case it's reset with LogMessage call */ - int err = errno; - - LogMessage("WARNING: %s is invalid, trying " - "/var/run...\n", snort_conf->pid_path); - if (err) - { - LogMessage("Previous Error, errno=%d, (%s)\n", - err, strerror(err) == NULL ? "Unknown error" : strerror(err)); - } -#endif - memset(snort_conf->pid_path, 0, sizeof(snort_conf->pid_path)); - } - else - { - LogMessage("PID path stat checked out ok, " - "PID path set to %s\n", snort_conf->pid_path); - } - } - - if (strlen(snort_conf->pid_path) == 0) - { -#ifndef _PATH_VARRUN -# ifndef WIN32 - SnortStrncpy(_PATH_VARRUN, "/var/run/", sizeof(_PATH_VARRUN)); -# else - if (GetCurrentDirectory(sizeof(dir) - 1, dir)) - SnortStrncpy(_PATH_VARRUN, dir, sizeof(_PATH_VARRUN)); -# endif /* WIN32 */ -#else - LogMessage("PATH_VARRUN is set to %s on this operating " - "system\n", _PATH_VARRUN); -#endif /* _PATH_VARRUN */ - - stat(_PATH_VARRUN, &pt); - - if(!S_ISDIR(pt.st_mode) || access(_PATH_VARRUN, W_OK) == -1) - { - LogMessage("WARNING: _PATH_VARRUN is invalid, trying " - "/var/log...\n"); - SnortStrncpy(snort_conf->pid_path, "/var/log/", sizeof(snort_conf->pid_path)); - stat(snort_conf->pid_path, &pt); - - if(!S_ISDIR(pt.st_mode) || access(snort_conf->pid_path, W_OK) == -1) - { - LogMessage("WARNING: %s is invalid, logging Snort " - "PID path to log directory (%s)\n", snort_conf->pid_path, - snort_conf->log_dir); - CheckLogDir(); - SnortSnprintf(snort_conf->pid_path, sizeof(snort_conf->pid_path), - "%s/", snort_conf->log_dir); - } - } - else - { - LogMessage("PID path stat checked out ok, " - "PID path set to %s\n", _PATH_VARRUN); - SnortStrncpy(snort_conf->pid_path, _PATH_VARRUN, sizeof(snort_conf->pid_path)); - } - } - } - - if(intf == NULL || strlen(snort_conf->pid_path) == 0) - { - /* snort_conf->pid_path should have some value by now - * so let us just be sane. */ - FatalError("CreatePidFile() failed to lookup interface or pid_path is unknown!\n"); - } - - SnortSnprintf(snort_conf->pid_filename, sizeof(snort_conf->pid_filename), - "%s/snort_%s%s.pid", snort_conf->pid_path, intf, snort_conf->pidfile_suffix); - -#ifndef WIN32 - if (!ScNoLockPidFile()) - { - char pid_lockfilename[STD_BUF+1]; - int lock_fd; - - /* First, lock the PID file */ - SnortSnprintf(pid_lockfilename, STD_BUF, "%s.lck", snort_conf->pid_filename); - pid_lockfile = fopen(pid_lockfilename, "w"); - - if (pid_lockfile) - { - struct flock lock; - lock_fd = fileno(pid_lockfile); - - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - - if (fcntl(lock_fd, F_SETLK, &lock) == -1) - { - ClosePidFile(); - FatalError("Failed to Lock PID File \"%s\" for PID \"%d\"\n", snort_conf->pid_filename, pid); - } - } - } -#endif - - /* Okay, were able to lock PID file, now open and write PID */ - pid_file = fopen(snort_conf->pid_filename, "w"); - if(pid_file) - { - LogMessage("Writing PID \"%d\" to file \"%s\"\n", pid, snort_conf->pid_filename); - fprintf(pid_file, "%d\n", pid); - fflush(pid_file); - } - else - { - ErrorMessage("Failed to create pid file %s", snort_conf->pid_filename); - snort_conf->pid_filename[0] = 0; - } -} - -/**************************************************************************** - * - * Function: ClosePidFile(char *) - * - * Purpose: Releases lock on a PID file - * - * Arguments: None - * - * Returns: void function - * - ****************************************************************************/ -void ClosePidFile(void) -{ - if (pid_file) - { - fclose(pid_file); - pid_file = NULL; - } - if (pid_lockfile) - { - fclose(pid_lockfile); - pid_lockfile = NULL; - } -} - -/**************************************************************************** - * - * Function: SetUidGid() - * - * Purpose: Sets safe UserID and GroupID if needed - * - * Arguments: none - * - * Returns: void function - * - ****************************************************************************/ -void SetUidGid(int user_id, int group_id) -{ -#ifndef WIN32 - - if ((group_id != -1) && (getgid() != (gid_t)group_id)) - { - if (!InlineModeSetPrivsAllowed()) - { - ErrorMessage("Cannot set uid and gid when running Snort in " - "inline mode.\n"); - return; - } - - if (setgid(group_id) < 0) - FatalError("Cannot set gid: %d\n", group_id); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Set gid to %d\n", group_id);); - } - - if ((user_id != -1) && (getuid() != (uid_t)user_id)) - { - struct passwd *pw = getpwuid(user_id); - - if (!InlineModeSetPrivsAllowed()) - { - ErrorMessage("Cannot set uid and gid when running Snort in " - "inline mode.\n"); - return; - } - - if (pw != NULL) - { - /* getpwuid and initgroups may use the same static buffers */ - char *username = SnortStrdup(pw->pw_name); - - if ((getuid() == 0) && (initgroups(username, group_id) < 0)) - { - free(username); - FatalError("Can not initgroups(%s,%d)", - username, group_id); - } - - free(username); - } - - /** just to be on a safe side... **/ - endgrent(); - endpwent(); - - if (setuid(user_id) < 0) - FatalError("Can not set uid: %d\n", user_id); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Set uid to %d\n", user_id);); - } -#endif /* WIN32 */ -} - -#ifdef TIMESTATS - -static IntervalStats istats = {0}; -time_t start_time; - -void InitTimeStats(void) -{ - start_time = time(NULL); -} - -void ResetTimeStats(void) -{ - memset(&istats, 0, sizeof(istats)); -} - -/* This function prints out stats based on a configurable time - * interval. It is an indication on how well snort is */ -/* processing packets, including types, drops, etc */ -void DropStatsPerTimeInterval(void) -{ - double per_sec, per_minute, per_hour; - uint64_t recv, drop; - uint64_t total = 0; - uint32_t timestats_interval = ScTimestatsInterval(); - -#ifdef PCAP_CLOSE - if (UpdatePcapPktStats(0) != -1) -#else - if (UpdatePcapPktStats() != -1) -#endif - { - recv = GetPcapPktStatsRecv(); - drop = GetPcapPktStatsDrop(); - - istats.recv = recv - istats.recv_total; - istats.recv_total = recv; - - istats.drop = drop - istats.drop_total; - istats.drop_total = drop; - - /* calculate received packets by type */ - istats.tcp = pc.tcp - istats.tcp_total; - istats.tcp_total = pc.tcp; - - istats.udp = pc.udp - istats.udp_total; - istats.udp_total = pc.udp; - - istats.icmp = pc.icmp - istats.icmp_total; - istats.icmp_total = pc.icmp; - - istats.arp = pc.arp - istats.arp_total; - istats.arp_total = pc.arp; - -#ifdef GRE - istats.ip4ip4 = pc.ip4ip4 - istats.ip4ip4_total; - istats.ip4ip4_total = pc.ip4ip4; - - istats.ip4ip6 = pc.ip4ip6 - istats.ip4ip6_total; - istats.ip4ip6_total = pc.ip4ip6; - - istats.ip6ip4 = pc.ip6ip4 - istats.ip6ip4_total; - istats.ip6ip4_total = pc.ip6ip4; - - istats.ip6ip6 = pc.ip6ip6 - istats.ip6ip6_total; - istats.ip6ip6_total = pc.ip6ip6; - - istats.gre = pc.gre - istats.gre_total; - istats.gre_total = pc.gre; - - istats.gre_ip = pc.gre_ip - istats.gre_ip_total; - istats.gre_ip_total = pc.gre_ip; - - istats.gre_eth = pc.gre_eth - istats.gre_eth_total; - istats.gre_eth_total = pc.gre_eth; - - istats.gre_arp = pc.gre_arp - istats.gre_arp_total; - istats.gre_arp_total = pc.gre_arp; - - istats.gre_ipv6 = pc.gre_ipv6 - istats.gre_ipv6_total; - istats.gre_ipv6_total = pc.gre_ipv6; - - istats.gre_ipx = pc.gre_ipx - istats.gre_ipx_total; - istats.gre_ipx_total = pc.gre_ipx; - - istats.gre_loopback = pc.gre_loopback - istats.gre_loopback_total; - istats.gre_loopback_total = pc.gre_loopback; - - istats.gre_vlan = pc.gre_vlan - istats.gre_vlan_total; - istats.gre_vlan_total = pc.gre_vlan; - - istats.gre_ppp = pc.gre_ppp - istats.gre_ppp_total; - istats.gre_ppp_total = pc.gre_ppp; -#endif - -#ifdef DLT_IEEE802_11 /* if we are tracking wireless, add this to output */ - istats.wifi_mgmt = pc.wifi_mgmt - istats.wifi_mgmt_total; - istats.wifi_mgmt_total = pc.wifi_mgmt; - - istats.wifi_control = pc.wifi_control - istats.wifi_control_total; - istats.wifi_control_total = pc.wifi_control; - - istats.wifi_data = pc.wifi_data - istats.wifi_data_total; - istats.wifi_data_total = pc.wifi_data; -#endif - - istats.ipx = pc.ipx - istats.ipx_total; - istats.ipx_total = pc.ipx; - - istats.eapol = pc.eapol - istats.eapol_total; - istats.eapol_total = pc.eapol; - - istats.ipv6 = pc.ipv6 - istats.ipv6_total; - istats.ipv6_total = pc.ipv6; - - istats.ethloopback = pc.ethloopback - istats.ethloopback_total; - istats.ethloopback_total = pc.ethloopback; - - istats.other = pc.other - istats.other_total; - istats.other_total = pc.other; - - istats.discards = pc.discards - istats.discards_total; - istats.discards_total = pc.discards; - - if (pc.frags > 0) /* do we have any fragmented packets being seen? */ - { - istats.frags = pc.frags - istats.frags_total; - istats.frags_total = pc.frags; - - istats.frag_trackers = pc.frag_trackers - istats.frag_trackers_total; - istats.frag_trackers_total = pc.frag_trackers; - - istats.frag_rebuilt = pc.rebuilt_frags - istats.frag_rebuilt_total; - istats.frag_rebuilt_total = pc.rebuilt_frags; - - istats.frag_element = pc.rebuild_element - istats.frag_element_total; - istats.frag_element_total = pc.rebuild_element; - - istats.frag_incomp = pc.frag_incomp - istats.frag_incomp_total; - istats.frag_incomp_total = pc.frag_incomp; - - istats.frag_timeout = pc.frag_timeout - istats.frag_timeout_total; - istats.frag_timeout_total = pc.frag_timeout; - - istats.frag_mem_faults = pc.frag_mem_faults - istats.frag_mem_faults_total; - istats.frag_mem_faults_total = pc.frag_mem_faults; - } - - if (pc.tcp_stream_pkts > 0) /* do we have TCP stream re-assembly going on? */ - { - istats.tcp_str_packets = pc.tcp_stream_pkts - istats.tcp_str_packets_total; - istats.tcp_str_packets_total = pc.tcp_stream_pkts; - - istats.tcp_str_trackers = pc.tcp_streams - istats.tcp_str_trackers_total; - istats.tcp_str_trackers_total = pc.tcp_streams; - - istats.tcp_str_flushes = pc.rebuilt_tcp - istats.tcp_str_flushes_total; - istats.tcp_str_flushes_total = pc.rebuilt_tcp; - - istats.tcp_str_segs_used = pc.rebuilt_segs - istats.tcp_str_segs_used_total; - istats.tcp_str_segs_used_total = pc.rebuilt_segs; - - istats.tcp_str_segs_queued = pc.queued_segs - istats.tcp_str_segs_queued_total; - istats.tcp_str_segs_queued_total = pc.queued_segs; - - istats.tcp_str_mem_faults = pc.str_mem_faults - istats.tcp_str_mem_faults_total; - istats.tcp_str_mem_faults_total = pc.str_mem_faults; - } - - istats.processed = pc.total_processed - istats.processed_total; - istats.processed_total = pc.total_processed; - total = istats.processed; - - /* prepare packet type per time interval routine */ - LogMessage("================================================" - "===============================\n"); - - LogMessage("\n"); - LogMessage("Statistics Report (last %d seconds)\n", timestats_interval); - LogMessage("\n"); - - per_sec = (double)istats.recv / (double)timestats_interval; - - LogMessage("Packet Wire Totals:\n"); - LogMessage("Packets received: " FMTu64("13") "\n", istats.recv); - - if (timestats_interval >= SECONDS_PER_HOUR) - { - per_hour = (double)(istats.recv * SECONDS_PER_HOUR) / (double)timestats_interval; - LogMessage(" per hour: %13.2f\n", per_hour); - } - if (timestats_interval >= SECONDS_PER_MIN) - { - per_minute = (double)(istats.recv * SECONDS_PER_MIN) / (double)timestats_interval; - LogMessage(" per minute: %13.2f\n", per_minute); - } - LogMessage(" per second: %13.2f\n", per_sec); - LogMessage(" Packets dropped: " FMTu64("13") "\n", istats.drop); - LogMessage("\n"); - LogMessage("Packet Breakdown by Protocol (includes rebuilt packets):\n"); - - LogMessage(" TCP: " FMTu64("10") " (%.3f%%)\n", - istats.tcp, CalcPct(istats.tcp, total)); - LogMessage(" UDP: " FMTu64("10") " (%.3f%%)\n", - istats.udp, CalcPct(istats.udp, total)); - LogMessage(" ICMP: " FMTu64("10") " (%.3f%%)\n", - istats.icmp, CalcPct(istats.icmp, total)); - LogMessage(" ARP: " FMTu64("10") " (%.3f%%)\n", - istats.arp, CalcPct(istats.arp, total)); -#ifndef NO_NON_ETHER_DECODER - LogMessage(" EAPOL: " FMTu64("10") " (%.3f%%)\n", - istats.eapol, CalcPct(istats.eapol, total)); -#endif - LogMessage(" IPv6: " FMTu64("10") " (%.3f%%)\n", - istats.ipv6, CalcPct(istats.ipv6, total)); - LogMessage(" ETHLOOP: " FMTu64("10") " (%.3f%%)\n", - istats.ethloopback, CalcPct(istats.ethloopback, total)); - LogMessage(" IPX: " FMTu64("10") " (%.3f%%)\n", - istats.ipx, CalcPct(istats.ipx, total)); - -#ifdef GRE - LogMessage(" IP4/IP4: " FMTu64("-10") " (%.3f%%)\n", - istats.ip4ip4, CalcPct(istats.ip4ip4, total)); - LogMessage(" IP4/IP6: " FMTu64("-10") " (%.3f%%)\n", - istats.ip4ip6, CalcPct(istats.ip4ip6, total)); - LogMessage(" IP6/IP4: " FMTu64("-10") " (%.3f%%)\n", - istats.ip6ip4, CalcPct(istats.ip6ip4, total)); - LogMessage(" IP6/IP6: " FMTu64("-10") " (%.3f%%)\n", - istats.ip6ip6, CalcPct(istats.ip6ip6, total)); - LogMessage(" GRE: " FMTu64("10") " (%.3f%%)\n", - istats.gre, CalcPct(istats.gre, total)); - LogMessage(" GRE ETH: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_eth, CalcPct(istats.gre_eth, total)); - LogMessage("GRE VLAN: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_vlan, CalcPct(istats.gre_vlan, total)); - LogMessage(" GRE IP: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_ip, CalcPct(istats.gre_ip, total)); - LogMessage("GRE IPv6: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_ipv6, CalcPct(istats.gre_ipv6, total)); - LogMessage("GRE PPTP: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_ppp, CalcPct(istats.gre_ppp, total)); - LogMessage(" GRE ARP: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_arp, CalcPct(istats.gre_arp, total)); - LogMessage(" GRE IPX: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_ipx, CalcPct(istats.gre_ipx, total)); - LogMessage("GRE LOOP: " FMTu64("-10") " (%.3f%%)\n", - istats.gre_loopback, CalcPct(istats.gre_loopback, total)); -#endif - - LogMessage(" FRAG: " FMTu64("10") " (%.3f%%)\n", - istats.frags, CalcPct(istats.frags, total)); - LogMessage(" OTHER: " FMTu64("10") " (%.3f%%)\n", - istats.other, CalcPct(istats.other, total)); - LogMessage(" DISCARD: " FMTu64("10") " (%.3f%%)\n", - istats.discards, CalcPct(istats.discards, total)); - LogMessage(" Total: " FMTu64("10") "\n", total); - - LogMessage("\n"); - - - /* handle case where wireless is enabled... */ - -#ifndef NO_NON_ETHER_DECODER -#ifdef DLT_IEEE802_11 - if (datalink == DLT_IEEE802_11) - { - LogMessage("\n"); - LogMessage("Wireless Stats:\n\n"); - LogMessage("Management Packets: " FMTu64("10") " (%.3f%%)\n", - istats.wifi_mgmt, CalcPct(istats.wifi_mgmt, total)); - LogMessage(" Control Packets: " FMTu64("10") " (%.3f%%)\n", - istats.wifi_control, CalcPct(istats.wifi_control, total)); - LogMessage(" Data Packets: " FMTu64("10") " (%.3f%%)\n", - istats.wifi_data, CalcPct(istats.wifi_data, total)); - LogMessage("\n"); - } - -#endif /* if wireless is enabled... */ -#endif // NO_NON_ETHER_DECODER - - /* handle case where we have snort seeing fragmented packets */ - - if (pc.frags > 0) /* begin if (pc.frags > 0) */ - { - LogMessage("\n"); - LogMessage("Fragmentation Stats:\n\n"); - LogMessage("Fragmented IP Packets: " FMTu64("10") "\n", istats.frags); - LogMessage(" Fragment Trackers: " FMTu64("10") "\n", istats.frag_trackers); - LogMessage(" Rebuilt IP Packets: " FMTu64("10") "\n", istats.frag_rebuilt); - LogMessage(" Frag Elements Used: " FMTu64("10") "\n", istats.frag_element); - LogMessage("Discarded(incomplete): " FMTu64("10") "\n", istats.frag_incomp); - LogMessage(" Discarded(timeout): " FMTu64("10") "\n", istats.frag_timeout); - LogMessage(" Frag2 memory faults: " FMTu64("10") "\n", istats.frag_mem_faults); - LogMessage("\n"); - } /* end if (pc.frags > 0) */ - - /* handle TCP stream re-assy stuff here */ - - if (pc.tcp_stream_pkts > 0) - { - LogMessage("\n"); - LogMessage("TCP Stream Reassembly Stats:\n\n"); - LogMessage(" TCP Packets Used: " FMTu64("10") "\n", istats.tcp_str_packets); - LogMessage(" Stream Trackers: " FMTu64("10") "\n", istats.tcp_str_trackers); - LogMessage(" Stream Flushes: " FMTu64("10") "\n", istats.tcp_str_flushes); - LogMessage(" Stream Segments Used: " FMTu64("10") "\n", istats.tcp_str_segs_used); - LogMessage("Stream Segments Queued: " FMTu64("10") "\n", istats.tcp_str_segs_queued); - LogMessage(" Stream4 Memory Faults: " FMTu64("10") "\n", istats.tcp_str_mem_faults); - LogMessage("\n"); - } - - //mpse_print_qinfo(); - - } /* end if pcap_stats(ps, &ps) */ - - alarm(timestats_interval); /* reset the alarm to go off again */ -} - -/* print out stats on how long snort ran */ -void TimeStats(void) -{ - -/* - * variable definitions for improved statistics handling - * - * end_time = time which snort finished running (unix epoch) - * total_secs = total amount of time snort ran - * int_total_secs = used to eliminate casts from this function (temp. var) - * days = number of days snort ran - * hrs = number of hrs snort ran - * mins = number of minutes snort ran - * secs = number of seconds snort ran - * - * ival = temp. variable for integer/modulus math - * ppd = packets per day processed - * pph = packets per hour processed - * ppm = packets per minute processed - * pps = packets per second processed - * - * hflag = used to flag when hrs = zero, but days > 0 - * mflag = used to flag when min = zero, but hrs > 0 - * - */ - - time_t end_time, total_secs; - uint32_t days = 0, hrs = 0, mins = 0, secs = 0, tmp = 0; - uint64_t pps = 0, ppm = 0, pph = 0, ppd = 0; - uint32_t int_total_secs = 0; - char hflag = 0, mflag = 0; - - - end_time = time(NULL); /* grab epoch for end time value (in seconds) */ - total_secs = end_time - start_time; /* total_secs is how many seconds snort ran for */ - - tmp = (uint32_t)total_secs; - int_total_secs = tmp; /* used for cast elimination */ - - days = tmp / SECONDS_PER_DAY; /* 86400 is number of seconds in a day */ - tmp = tmp % SECONDS_PER_DAY; /* grab remainder to process hours */ - hrs = tmp / SECONDS_PER_HOUR; /* 3600 is number of seconds in a(n) hour */ - tmp = tmp % SECONDS_PER_HOUR; /* grab remainder to process minutes */ - mins = tmp / SECONDS_PER_MIN; /* 60 is number of seconds in a minute */ - secs = tmp % SECONDS_PER_MIN; /* grab remainder to process seconds */ - - if (total_secs) - pps = (pc.total_from_pcap / int_total_secs); - else - pps = pc.total_from_pcap; /* guard against division by zero */ - - /* Use ErrorMessage because this is logged whether - * or not logging quietly */ - ErrorMessage("Snort ran for %u Days %u Hours %u Minutes %u Seconds\n", - days, hrs, mins, secs); - - if (days > 0) - { - ppd = (pc.total_from_pcap / (int_total_secs / SECONDS_PER_DAY)); - ErrorMessage("Snort Analyzed " STDu64 " Packets Per Day\n", ppd); - hflag = 1; - } - - if (hrs > 0 || hflag == 1) - { - pph = (pc.total_from_pcap / (int_total_secs / SECONDS_PER_HOUR)); - ErrorMessage("Snort Analyzed " STDu64 " Packets Per Hour\n", pph); - mflag = 1; - } - - if (mins > 0 || mflag == 1) - { - ppm = (pc.total_from_pcap / (int_total_secs / SECONDS_PER_MIN)); - ErrorMessage("Snort Analyzed " STDu64 " Packets Per Minute\n", ppm); - } - - ErrorMessage("Snort Analyzed " STDu64 " Packets Per Second\n", pps); - ErrorMessage("\n"); -} -#endif /* TIMESTATS */ - - -#ifdef PCAP_CLOSE -int UpdatePcapPktStats(int cacheReturn) -#else -int UpdatePcapPktStats(void) -#endif -{ - struct pcap_stat ps; - uint32_t recv, drop; - static char not_initialized = 1; - -#ifdef PCAP_CLOSE - static int priorReturn = 0; - static int returnWasCached = 0; - - if ( !cacheReturn && returnWasCached ) - { - returnWasCached = 0; - return priorReturn; - } - priorReturn = -1; - returnWasCached = cacheReturn; -#endif - - if (not_initialized) - { - memset(&pkt_stats, 0, sizeof(PcapPktStats)); - not_initialized = 0; - } - - if ((pcap_handle == NULL) || ScReadMode()) - return -1; - - if (pcap_stats(pcap_handle, &ps) == -1) - { - pcap_perror(pcap_handle, "pcap_stats"); - return -1; - } - - recv = (uint32_t)ps.ps_recv; - drop = (uint32_t)ps.ps_drop; - -#ifdef LINUX_LIBPCAP_DOUBLES_STATS - recv /= 2; - drop /= 2; -#endif - -#ifdef LIBPCAP_ACCUMULATES - /* pcap recv wrapped */ - if (recv < pkt_stats.wrap_recv) - pkt_stats.recv += (uint64_t)UINT32_MAX; - - /* pcap drop wrapped */ - if (drop < pkt_stats.wrap_drop) - pkt_stats.drop += (uint64_t)UINT32_MAX; - - pkt_stats.wrap_recv = recv; - pkt_stats.wrap_drop = drop; -#else - pkt_stats.recv += (uint64_t)recv; - pkt_stats.drop += (uint64_t)drop; -#endif /* LIBPCAP_ACCUMULATES */ - -#ifdef PCAP_CLOSE - priorReturn = 0; -#endif - return 0; -} - -uint64_t GetPcapPktStatsRecv(void) -{ - return pkt_stats.recv + (uint64_t)pkt_stats.wrap_recv; -} - -uint64_t GetPcapPktStatsDrop(void) -{ - return pkt_stats.drop + (uint64_t)pkt_stats.wrap_drop; -} - - -#ifdef PCAP_CLOSE -/* exiting should be 0 for if not exiting, 1 if restarting, and 2 if exiting */ -#else -/* exiting should be 0 for if not exiting and 1 if exiting */ -#endif -void DropStats(int exiting) -{ - PreprocStatsFuncNode *idx; - uint64_t total = 0; - uint64_t pkts_recv; - uint64_t pkts_drop; - - total = pc.total_processed; - -#ifdef PPM_MGR - PPM_PRINT_SUMMARY(&snort_conf->ppm_cfg); -#endif - - LogMessage("================================================" - "===============================\n"); - -#ifdef TIMESTATS - TimeStats(); /* how long did snort run? */ -#endif - - if (ScReadMode() -#ifdef GIDS - || ScAdapterInlineMode() -#endif - ) - { - LogMessage("Snort processed " STDu64 " packets.\n", total); - } - else - { -#ifdef PCAP_CLOSE - if (exiting < 2 && (pcap_handle == NULL)) -#else - if (pcap_handle == NULL) -#endif - { - LogMessage("Snort received 0 packets\n"); - } - else - { -#ifdef PCAP_CLOSE - if (UpdatePcapPktStats(0) != -1) -#else - if (UpdatePcapPktStats() != -1) -#endif - { - pkts_recv = GetPcapPktStatsRecv(); - pkts_drop = GetPcapPktStatsDrop(); - - LogMessage("Packet Wire Totals:\n"); - LogMessage(" Received: " FMTu64("12") "\n", pkts_recv); - LogMessage(" Analyzed: " FMTu64("12") " (%.3f%%)\n", pc.total_from_pcap, - CalcPct(pc.total_from_pcap, pkts_recv)); - LogMessage(" Dropped: " FMTu64("12") " (%.3f%%)\n", pkts_drop, - CalcPct(pkts_drop, pkts_recv)); - LogMessage("Outstanding: " FMTu64("12") " (%.3f%%)\n", - pkts_recv - pkts_drop - pc.total_from_pcap, - CalcPct((pkts_recv - pkts_drop - pc.total_from_pcap), pkts_recv)); - } - else - { - LogMessage("Unable to calculate percentages for stats\n"); - LogMessage("Total number of packets Analyzed: " FMTu64("12") "\n", pc.total_from_pcap); - } - } - } - - LogMessage("================================================" - "===============================\n"); - - LogMessage("Breakdown by protocol (includes rebuilt packets):\n"); - - LogMessage(" ETH: " FMTu64("-10") " (%.3f%%)\n", - pc.eth, CalcPct(pc.eth, total)); - LogMessage(" ETHdisc: " FMTu64("-10") " (%.3f%%)\n", - pc.ethdisc, CalcPct(pc.ethdisc, total)); -#ifdef GIDS -#ifndef IPFW - LogMessage(" IPTables: " FMTu64("-10") " (%.3f%%)\n", - pc.iptables, CalcPct(pc.iptables, total)); -#else - LogMessage(" IPFW: " FMTu64("-10") " (%.3f%%)\n", - pc.ipfw, CalcPct(pc.ipfw, total)); -#endif /* IPFW */ -#endif /* GIDS */ - LogMessage(" VLAN: " FMTu64("-10") " (%.3f%%)\n", - pc.vlan, CalcPct(pc.vlan, total)); - - if (pc.nested_vlan != 0) - LogMessage("Nested VLAN: " FMTu64("-10") " (%.3f%%)\n", - pc.nested_vlan, CalcPct(pc.nested_vlan, total)); - - LogMessage(" IPV6: " FMTu64("-10") " (%.3f%%)\n", - pc.ipv6, CalcPct(pc.ipv6, total)); - LogMessage(" IP6 EXT: " FMTu64("-10") " (%.3f%%)\n", - pc.ip6ext, CalcPct(pc.ip6ext, total)); - LogMessage(" IP6opts: " FMTu64("-10") " (%.3f%%)\n", - pc.ipv6opts, CalcPct(pc.ipv6opts, total)); - LogMessage(" IP6disc: " FMTu64("-10") " (%.3f%%)\n", - pc.ipv6disc, CalcPct(pc.ipv6disc, total)); - - LogMessage(" IP4: " FMTu64("-10") " (%.3f%%)\n", - pc.ip, CalcPct(pc.ip, total)); - LogMessage(" IP4disc: " FMTu64("-10") " (%.3f%%)\n", - pc.ipdisc, CalcPct(pc.ipdisc, total)); - - LogMessage(" TCP 6: " FMTu64("-10") " (%.3f%%)\n", - pc.tcp6, CalcPct(pc.tcp6, total)); - LogMessage(" UDP 6: " FMTu64("-10") " (%.3f%%)\n", - pc.udp6, CalcPct(pc.udp6, total)); - LogMessage(" ICMP6: " FMTu64("-10") " (%.3f%%)\n", - pc.icmp6, CalcPct(pc.icmp6, total)); - LogMessage(" ICMP-IP: " FMTu64("-10") " (%.3f%%)\n", - pc.embdip, CalcPct(pc.embdip, total)); - - LogMessage(" TCP: " FMTu64("-10") " (%.3f%%)\n", - pc.tcp, CalcPct(pc.tcp, total)); - LogMessage(" UDP: " FMTu64("-10") " (%.3f%%)\n", - pc.udp, CalcPct(pc.udp, total)); - LogMessage(" ICMP: " FMTu64("-10") " (%.3f%%)\n", - pc.icmp, CalcPct(pc.icmp, total)); - - LogMessage(" TCPdisc: " FMTu64("-10") " (%.3f%%)\n", - pc.tdisc, CalcPct(pc.tdisc, total)); - LogMessage(" UDPdisc: " FMTu64("-10") " (%.3f%%)\n", - pc.udisc, CalcPct(pc.udisc, total)); - LogMessage(" ICMPdis: " FMTu64("-10") " (%.3f%%)\n", - pc.icmpdisc, CalcPct(pc.icmpdisc, total)); - - LogMessage(" FRAG: " FMTu64("-10") " (%.3f%%)\n", - pc.frags, CalcPct(pc.frags, total)); - LogMessage(" FRAG 6: " FMTu64("-10") " (%.3f%%)\n", - pc.frag6, CalcPct(pc.frag6, total)); - - LogMessage(" ARP: " FMTu64("-10") " (%.3f%%)\n", - pc.arp, CalcPct(pc.arp, total)); -#ifndef NO_NON_ETHER_DECODER - LogMessage(" EAPOL: " FMTu64("-10") " (%.3f%%)\n", - pc.eapol, CalcPct(pc.eapol, total)); -#endif - LogMessage(" ETHLOOP: " FMTu64("-10") " (%.3f%%)\n", - pc.ethloopback, CalcPct(pc.ethloopback, total)); - LogMessage(" IPX: " FMTu64("-10") " (%.3f%%)\n", - pc.ipx, CalcPct(pc.ipx, total)); -#ifdef GRE - LogMessage("IPv4/IPv4: " FMTu64("-10") " (%.3f%%)\n", - pc.ip4ip4, CalcPct(pc.ip4ip4, total)); - LogMessage("IPv4/IPv6: " FMTu64("-10") " (%.3f%%)\n", - pc.ip4ip6, CalcPct(pc.ip4ip6, total)); - LogMessage("IPv6/IPv4: " FMTu64("-10") " (%.3f%%)\n", - pc.ip6ip4, CalcPct(pc.ip6ip4, total)); - LogMessage("IPv6/IPv6: " FMTu64("-10") " (%.3f%%)\n", - pc.ip6ip6, CalcPct(pc.ip6ip6, total)); - LogMessage(" GRE: " FMTu64("-10") " (%.3f%%)\n", - pc.gre, CalcPct(pc.gre, total)); - LogMessage(" GRE ETH: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_eth, CalcPct(pc.gre_eth, total)); - LogMessage(" GRE VLAN: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_vlan, CalcPct(pc.gre_vlan, total)); - LogMessage(" GRE IPv4: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ip, CalcPct(pc.gre_ip, total)); - LogMessage(" GRE IPv6: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ipv6, CalcPct(pc.gre_ipv6, total)); - LogMessage("GRE IP6 E: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ipv6ext, CalcPct(pc.gre_ipv6ext, total)); - LogMessage(" GRE PPTP: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ppp, CalcPct(pc.gre_ppp, total)); - LogMessage(" GRE ARP: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_arp, CalcPct(pc.gre_arp, total)); - LogMessage(" GRE IPX: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_ipx, CalcPct(pc.gre_ipx, total)); - LogMessage(" GRE LOOP: " FMTu64("-10") " (%.3f%%)\n", - pc.gre_loopback, CalcPct(pc.gre_loopback, total)); -#endif /* GRE */ -#ifdef MPLS - LogMessage(" MPLS: " FMTu64("-10") " (%.3f%%)\n", - pc.mpls, CalcPct(pc.mpls, total)); -#endif - LogMessage(" OTHER: " FMTu64("-10") " (%.3f%%)\n", - pc.other, CalcPct(pc.other, total)); - LogMessage(" DISCARD: " FMTu64("-10") " (%.3f%%)\n", - pc.discards, CalcPct(pc.discards, total)); - LogMessage("InvChkSum: " FMTu64("-10") " (%.3f%%)\n", - pc.invalid_checksums, CalcPct(pc.invalid_checksums, total)); - - LogMessage(" S5 G 1: " FMTu64("-10") " (%.3f%%)\n", - pc.s5tcp1, CalcPct(pc.s5tcp1, total)); - LogMessage(" S5 G 2: " FMTu64("-10") " (%.3f%%)\n", - pc.s5tcp2, CalcPct(pc.s5tcp2, total)); - - LogMessage(" Total: " FMTu64("-10") "\n", total); - - LogMessage("================================================" - "===============================\n"); - - LogMessage("Action Stats:\n"); - LogMessage("ALERTS: " STDu64 "\n", pc.alert_pkts); - LogMessage("LOGGED: " STDu64 "\n", pc.log_pkts); - LogMessage("PASSED: " STDu64 "\n", pc.pass_pkts); - -#ifdef TARGET_BASED - if (ScIdsMode() && IsAdaptiveConfigured(getDefaultPolicy(), 0)) - { - LogMessage("================================================" - "===============================\n"); - LogMessage("Attribute Table Stats:\n"); - LogMessage(" Number Entries: %u\n", SFAT_NumberOfHosts()); - LogMessage(" Table Reloaded: " STDu64 "\n", pc.attribute_table_reloads); - } -#endif /* TARGET_BASED */ - - //mpse_print_qinfo(); - -#ifndef NO_NON_ETHER_DECODER -#ifdef DLT_IEEE802_11 - if(datalink == DLT_IEEE802_11) - { - LogMessage("================================================" - "===============================\n"); - LogMessage("Wireless Stats:\n"); - LogMessage("Breakdown by type:\n"); - LogMessage(" Management Packets: " FMTu64("-10") " (%.3f%%)\n", - pc.wifi_mgmt, CalcPct(pc.wifi_mgmt, total)); - LogMessage(" Control Packets: " FMTu64("-10") " (%.3f%%)\n", - pc.wifi_control, CalcPct(pc.wifi_control, total)); - LogMessage(" Data Packets: " FMTu64("-10") " (%.3f%%)\n", - pc.wifi_data, CalcPct(pc.wifi_data, total)); - } -#endif /* DLT_IEEE802_11 */ -#endif // NO_NON_ETHER_DECODER - - for (idx = preproc_stats_funcs; idx != NULL; idx = idx->next) - { - LogMessage("==============================================" - "=================================\n"); - -#ifdef PCAP_CLOSE - idx->func(exiting ? 1 : 0); -#else - idx->func(exiting); -#endif - } - - LogMessage("==============================================" - "=================================\n"); - - return; -} - -/**************************************************************************** - * - * Function: CleanupProtoNames() - * - * Purpose: Frees the protocol names - * - * Arguments: None. - * - * Returns: void function - * - ****************************************************************************/ -void CleanupProtoNames(void) -{ - int i; - - for(i = 0; i < 256; i++) - { - if( protocol_names[i] != NULL ) - { - free( protocol_names[i] ); - protocol_names[i] = NULL; - } - } -} - -/**************************************************************************** - * - * Function: read_infile(char *) - * - * Purpose: Reads the BPF filters in from a file. Ripped from tcpdump. - * - * Arguments: fname => the name of the file containing the BPF filters - * - * Returns: the processed BPF string - * - ****************************************************************************/ -char *read_infile(char *fname) -{ - register int fd, cc; - register char *cp, *cmt; - struct stat buf; - - fd = open(fname, O_RDONLY); - - if(fd < 0) - FatalError("can't open %s: %s\n", fname, pcap_strerror(errno)); - - if(fstat(fd, &buf) < 0) - FatalError("can't stat %s: %s\n", fname, pcap_strerror(errno)); - - cp = (char *)SnortAlloc(((u_int)buf.st_size + 1) * sizeof(char)); - - cc = read(fd, cp, (int) buf.st_size); - - if(cc < 0) - FatalError("read %s: %s\n", fname, pcap_strerror(errno)); - - if(cc != buf.st_size) - FatalError("short read %s (%d != %d)\n", fname, cc, (int) buf.st_size); - - cp[(int) buf.st_size] = '\0'; - - close(fd); - - /* Treat everything upto the end of the line as a space - * so that we can put comments in our BPF filters - */ - - while((cmt = strchr(cp, '#')) != NULL) - { - while (*cmt != '\r' && *cmt != '\n' && *cmt != '\0') - { - *cmt++ = ' '; - } - } - - /** LogMessage("BPF filter file: %s\n", fname); **/ - - return(cp); -} - - - /**************************************************************************** - * - * Function: CheckLogDir() - * - * Purpose: CyberPsychotic sez: basically we only check if logdir exist and - * writable, since it might screw the whole thing in the middle. Any - * other checks could be performed here as well. - * - * Arguments: None. - * - * Returns: void function - * - ****************************************************************************/ -void CheckLogDir(void) -{ - struct stat st; - - if (snort_conf->log_dir == NULL) - return; - - if (stat(snort_conf->log_dir, &st) == -1) - FatalError("Stat check on log dir failed: %s.\n", strerror(errno)); - - if (!S_ISDIR(st.st_mode) || (access(snort_conf->log_dir, W_OK) == -1)) - { - FatalError("Can not get write access to logging directory \"%s\". " - "(directory doesn't exist or permissions are set incorrectly " - "or it is not a directory at all)\n", - snort_conf->log_dir); - } -} - -/* Signal handler for child process signaling the parent - * that is is ready */ -static int parent_wait = 1; -static void SigChildReadyHandler(int signal) -{ -#ifdef DEBUG - LogMessage("Received Signal from Child\n"); -#endif - parent_wait = 0; -} - -/**************************************************************************** - * - * Function: GoDaemon() - * - * Purpose: Puts the program into daemon mode, nice and quiet like.... - * - * Arguments: None. - * - * Returns: void function - * - ****************************************************************************/ -void GoDaemon(void) -{ -#ifndef WIN32 - int exit_val = 0; - pid_t fs; - - LogMessage("Initializing daemon mode\n"); - - if (ScDaemonRestart()) - return; - - /* Don't daemonize if we've already daemonized and - * received a SIGHUP. */ - if(getppid() != 1) - { - /* Register signal handler that parent can trap signal */ - signal(SIGNAL_SNORT_CHILD_READY, SigChildReadyHandler); - if (errno != 0) errno=0; - - /* now fork the child */ - fs = fork(); - - if(fs > 0) - { - /* Parent */ - - /* Don't exit quite yet. Wait for the child - * to signal that is there and created the PID - * file. - */ - while (parent_wait) - { - /* Continue waiting until receiving signal from child */ - int status; - if (waitpid(fs, &status, WNOHANG) == fs) - { - /* If the child is gone, parent should go away, too */ - if (WIFEXITED(status)) - { - LogMessage("Child exited unexpectedly\n"); - exit_val = -1; - break; - } - - if (WIFSIGNALED(status)) - { - LogMessage("Child terminated unexpectedly\n"); - exit_val = -2; - break; - } - } -#ifdef DEBUG - LogMessage("Parent waiting for child...\n"); -#endif - - sleep(1); - } - - LogMessage("Daemon parent exiting\n"); - - exit(exit_val); /* parent */ - } - - if(fs < 0) - { - /* Daemonizing failed... */ - perror("fork"); - exit(1); - } - - /* Child */ - setsid(); - } - - close(0); - close(1); - close(2); - -#ifdef DEBUG - /* redirect stdin/stdout/stderr to a file */ - open("/tmp/snort.debug", O_CREAT | O_RDWR); /* stdin, fd 0 */ - - /* Change ownership to that which we will drop privileges to */ - if ((snort_conf->user_id != -1) || (snort_conf->group_id != -1)) - { - uid_t user_id = getuid(); - gid_t group_id = getgid(); - - if (snort_conf->user_id != -1) - user_id = snort_conf->user_id; - if (snort_conf->group_id != -1) - group_id = snort_conf->group_id; - - chown("/tmp/snort.debug", user_id, group_id); - } -#else - /* redirect stdin/stdout/stderr to /dev/null */ - (void)open("/dev/null", O_RDWR); /* stdin, fd 0 */ -#endif - - dup(0); /* stdout, fd 0 => fd 1 */ - dup(0); /* stderr, fd 0 => fd 2 */ - - SignalWaitingParent(); - -#endif /* ! WIN32 */ -} - -/* Signal the parent that child is ready */ -void SignalWaitingParent(void) -{ -#ifndef WIN32 - pid_t parentpid = getppid(); -#ifdef DEBUG - LogMessage("Signaling parent %d from child %d\n", parentpid, getpid()); -#endif - - if (kill(parentpid, SIGNAL_SNORT_CHILD_READY)) - { - LogMessage("Daemon initialized, failed to signal parent pid: %d, failure: %d, %s\n", parentpid, errno, strerror(errno)); - } - else - { - LogMessage("Daemon initialized, signaled parent pid: %d\n", parentpid); - } -#endif -} - -/* This function has been moved into mstring.c, since that -* is where the allocation actually occurs. It has been -* renamed to mSplitFree(). -* -void FreeToks(char **toks, int num_toks) -{ - if (toks) - { - if (num_toks > 0) - { - do - { - num_toks--; - free(toks[num_toks]); - } while(num_toks); - } - free(toks); - } -} -*/ - - -/* Self preserving memory allocator */ -void *SPAlloc(unsigned long size, struct _SPMemControl *spmc) -{ - void *tmp; - - spmc->mem_usage += size; - - if(spmc->mem_usage > spmc->memcap) - { - spmc->sp_func(spmc); - } - - tmp = (void *) calloc(size, sizeof(char)); - - if(tmp == NULL) - { - FatalError("Unable to allocate memory! (%lu requested, %lu in use)\n", - size, spmc->mem_usage); - } - - return tmp; -} - -/* Guaranteed to be '\0' terminated even if truncation occurs. - * - * returns SNORT_SNPRINTF_SUCCESS if successful - * returns SNORT_SNPRINTF_TRUNCATION on truncation - * returns SNORT_SNPRINTF_ERROR on error - */ -int SnortSnprintf(char *buf, size_t buf_size, const char *format, ...) -{ - va_list ap; - int ret; - - if (buf == NULL || buf_size <= 0 || format == NULL) - return SNORT_SNPRINTF_ERROR; - - /* zero first byte in case an error occurs with - * vsnprintf, so buffer is null terminated with - * zero length */ - buf[0] = '\0'; - buf[buf_size - 1] = '\0'; - - va_start(ap, format); - - ret = vsnprintf(buf, buf_size, format, ap); - - va_end(ap); - - if (ret < 0) - return SNORT_SNPRINTF_ERROR; - - if (buf[buf_size - 1] != '\0' || (size_t)ret >= buf_size) - { - /* result was truncated */ - buf[buf_size - 1] = '\0'; - return SNORT_SNPRINTF_TRUNCATION; - } - - return SNORT_SNPRINTF_SUCCESS; -} - -/* Appends to a given string - * Guaranteed to be '\0' terminated even if truncation occurs. - * - * returns SNORT_SNPRINTF_SUCCESS if successful - * returns SNORT_SNPRINTF_TRUNCATION on truncation - * returns SNORT_SNPRINTF_ERROR on error - */ -int SnortSnprintfAppend(char *buf, size_t buf_size, const char *format, ...) -{ - int str_len; - int ret; - va_list ap; - - if (buf == NULL || buf_size <= 0 || format == NULL) - return SNORT_SNPRINTF_ERROR; - - str_len = SnortStrnlen(buf, buf_size); - - /* since we've already checked buf and buf_size an error - * indicates no null termination, so just start at - * beginning of buffer */ - if (str_len == SNORT_STRNLEN_ERROR) - { - buf[0] = '\0'; - str_len = 0; - } - - buf[buf_size - 1] = '\0'; - - va_start(ap, format); - - ret = vsnprintf(buf + str_len, buf_size - (size_t)str_len, format, ap); - - va_end(ap); - - if (ret < 0) - return SNORT_SNPRINTF_ERROR; - - if (buf[buf_size - 1] != '\0' || (size_t)ret >= buf_size) - { - /* truncation occured */ - buf[buf_size - 1] = '\0'; - return SNORT_SNPRINTF_TRUNCATION; - } - - return SNORT_SNPRINTF_SUCCESS; -} - -/* Guaranteed to be '\0' terminated even if truncation occurs. - * - * Arguments: dst - the string to contain the copy - * src - the string to copy from - * dst_size - the size of the destination buffer - * including the null byte. - * - * returns SNORT_STRNCPY_SUCCESS if successful - * returns SNORT_STRNCPY_TRUNCATION on truncation - * returns SNORT_STRNCPY_ERROR on error - * - * Note: Do not set dst[0] = '\0' on error since it's possible that - * dst and src are the same pointer - it will at least be null - * terminated in any case - */ -int SnortStrncpy(char *dst, const char *src, size_t dst_size) -{ - char *ret = NULL; - - if (dst == NULL || src == NULL || dst_size <= 0) - return SNORT_STRNCPY_ERROR; - - dst[dst_size - 1] = '\0'; - - ret = strncpy(dst, src, dst_size); - - /* Not sure if this ever happens but might as - * well be on the safe side */ - if (ret == NULL) - return SNORT_STRNCPY_ERROR; - - if (dst[dst_size - 1] != '\0') - { - /* result was truncated */ - dst[dst_size - 1] = '\0'; - return SNORT_STRNCPY_TRUNCATION; - } - - return SNORT_STRNCPY_SUCCESS; -} - -char *SnortStrndup(const char *src, size_t dst_size) -{ - char *ret = SnortAlloc(dst_size + 1); - int ret_val; - - ret_val = SnortStrncpy(ret, src, dst_size + 1); - - if(ret_val == SNORT_STRNCPY_ERROR) - { - free(ret); - return NULL; - } - - return ret; -} - -/* Determines whether a buffer is '\0' terminated and returns the - * string length if so - * - * returns the string length if '\0' terminated - * returns SNORT_STRNLEN_ERROR if not '\0' terminated - */ -int SnortStrnlen(const char *buf, int buf_size) -{ - int i = 0; - - if (buf == NULL || buf_size <= 0) - return SNORT_STRNLEN_ERROR; - - for (i = 0; i < buf_size; i++) - { - if (buf[i] == '\0') - break; - } - - if (i == buf_size) - return SNORT_STRNLEN_ERROR; - - return i; -} - -char * SnortStrdup(const char *str) -{ - char *copy = NULL; - - if (!str) - { - FatalError("Unable to duplicate string: NULL!\n"); - } - - copy = strdup(str); - - if (copy == NULL) - { - FatalError("Unable to duplicate string: %s!\n", str); - } - - return copy; -} - -/* - * Find first occurrence of char of accept in s, limited by slen. - * A 'safe' version of strpbrk that won't read past end of buffer s - * in cases that s is not NULL terminated. - * - * This code assumes 'accept' is a static string. - */ -const char *SnortStrnPbrk(const char *s, int slen, const char *accept) -{ - char ch; - const char *s_end; - if (!s || !*s || !accept || slen == 0) - return NULL; - - s_end = s + slen; - while (s < s_end) - { - ch = *s; - if (strchr(accept, ch)) - return s; - s++; - } - return NULL; -} - -/* - * Find first occurrence of searchstr in s, limited by slen. - * A 'safe' version of strstr that won't read past end of buffer s - * in cases that s is not NULL terminated. - */ -const char *SnortStrnStr(const char *s, int slen, const char *searchstr) -{ - char ch, nc; - int len; - if (!s || !*s || !searchstr || slen == 0) - return NULL; - - if ((ch = *searchstr++) != 0) - { - len = strlen(searchstr); - do - { - do - { - if ((nc = *s++) == 0) - { - return NULL; - } - slen--; - if (slen == 0) - return NULL; - } while (nc != ch); - if (slen - len < 0) - return NULL; - } while (memcmp(s, searchstr, len) != 0); - s--; - slen++; - } - return s; -} - -/* - * Find first occurrence of substring in s, ignore case. -*/ -const char *SnortStrcasestr(const char *s, const char *substr) -{ - char ch, nc; - int len; - - if (!s || !*s || !substr) - return NULL; - - if ((ch = *substr++) != 0) - { - ch = tolower((char)ch); - len = strlen(substr); - do - { - do - { - if ((nc = *s++) == 0) - { - return NULL; - } - } while ((char)tolower((uint8_t)nc) != ch); - } while (strncasecmp(s, substr, len) != 0); - s--; - } - return s; -} - -void *SnortAlloc(unsigned long size) -{ - void *tmp; - - tmp = (void *) calloc(size, sizeof(char)); - - if(tmp == NULL) - { - FatalError("Unable to allocate memory! (%lu requested)\n", size); - } - - return tmp; -} - -void * SnortAlloc2(size_t size, const char *format, ...) -{ - void *tmp; - - tmp = (void *)calloc(size, sizeof(char)); - - if(tmp == NULL) - { - va_list ap; - char buf[STD_BUF]; - - buf[STD_BUF - 1] = '\0'; - - va_start(ap, format); - - vsnprintf(buf, STD_BUF - 1, format, ap); - - va_end(ap); - - FatalError("%s", buf); - } - - return tmp; -} - -/** - * Chroot and adjust the snort_conf->log_dir reference - * - * @param directory directory to chroot to - * @param logstore ptr to snort_conf->log_dir which must be dynamically allocated - */ -void SetChroot(char *directory, char **logstore) -{ -#ifdef WIN32 - FatalError("SetChroot() should not be called under Win32!\n"); -#else - char *absdir; - size_t abslen; - char *logdir; - - if(!directory || !logstore) - { - FatalError("Null parameter passed\n"); - } - - logdir = *logstore; - - if(logdir == NULL || *logdir == '\0') - { - FatalError("Null log directory\n"); - } - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"SetChroot: %s\n", - CurrentWorkingDir());); - - logdir = GetAbsolutePath(logdir); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "SetChroot: %s\n", - CurrentWorkingDir())); - - logdir = SnortStrdup(logdir); - - /* We're going to reset logstore, so free it now */ - free(*logstore); - *logstore = NULL; - - /* change to the directory */ - if(chdir(directory) != 0) - { - FatalError("SetChroot: Can not chdir to \"%s\": %s\n", directory, - strerror(errno)); - } - - /* always returns an absolute pathname */ - absdir = CurrentWorkingDir(); - - if(absdir == NULL) - { - FatalError("NULL Chroot found\n"); - } - - abslen = strlen(absdir); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "ABS: %s %d\n", absdir, abslen);); - - /* make the chroot call */ - if(chroot(absdir) < 0) - { - FatalError("Can not chroot to \"%s\": absolute: %s: %s\n", - directory, absdir, strerror(errno)); - } - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chroot success (%s ->", absdir);); - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"%s)\n ", CurrentWorkingDir());); - - /* change to "/" in the new directory */ - if(chdir("/") < 0) - { - FatalError("Can not chdir to \"/\" after chroot: %s\n", - strerror(errno)); - } - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chdir success (%s)\n", - CurrentWorkingDir());); - - - if(strncmp(absdir, logdir, strlen(absdir))) - { - FatalError("Absdir is not a subset of the logdir"); - } - - if(abslen >= strlen(logdir)) - { - *logstore = SnortStrdup("/"); - } - else - { - *logstore = SnortStrdup(logdir + abslen); - } - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"new logdir from %s to %s\n", - logdir, *logstore)); - - LogMessage("Chroot directory = %s\n", directory); - -#if 0 - /* XXX XXX */ - /* install the I can't do this signal handler */ - signal(SIGHUP, SigCantHupHandler); -#endif -#endif /* !WIN32 */ -} - - -/** - * Return a ptr to the absolute pathname of snort. This memory must - * be copied to another region if you wish to save it for later use. - */ -char *CurrentWorkingDir(void) -{ - static char buf[PATH_MAX_UTIL + 1]; - - if(getcwd((char *) buf, PATH_MAX_UTIL) == NULL) - { - return NULL; - } - - buf[PATH_MAX_UTIL] = '\0'; - - return (char *) buf; -} - -/** - * Given a directory name, return a ptr to a static - */ -char *GetAbsolutePath(char *dir) -{ - char *savedir, *dirp; - static char buf[PATH_MAX_UTIL + 1]; - - if(dir == NULL) - { - return NULL; - } - - savedir = strdup(CurrentWorkingDir()); - - if(savedir == NULL) - { - return NULL; - } - - if(chdir(dir) < 0) - { - LogMessage("Can't change to directory: %s\n", dir); - free(savedir); - return NULL; - } - - dirp = CurrentWorkingDir(); - - if(dirp == NULL) - { - LogMessage("Unable to access current directory\n"); - free(savedir); - return NULL; - } - else - { - strncpy(buf, dirp, PATH_MAX_UTIL); - buf[PATH_MAX_UTIL] = '\0'; - } - - if(chdir(savedir) < 0) - { - LogMessage("Can't change back to directory: %s\n", dir); - free(savedir); - return NULL; - } - - free(savedir); - return (char *) buf; -} - - -#ifndef WIN32 -/* very slow sort - do not use at runtime! */ -SF_LIST * SortDirectory(const char *path) -{ - SF_LIST *dir_entries; - DIR *dir; - struct dirent *direntry; - int ret = 0; - - if (path == NULL) - return NULL; - - dir_entries = sflist_new(); - if (dir_entries == NULL) - { - ErrorMessage("Could not allocate new list for directory entries\n"); - return NULL; - } - - dir = opendir(path); - if (dir == NULL) - { - ErrorMessage("Error opening directory: %s: %s\n", - path, strerror(errno)); - sflist_free_all(dir_entries, free); - return NULL; - } - - /* Reset errno since we'll be checking it unconditionally */ - errno = 0; - - while ((direntry = readdir(dir)) != NULL) - { - char *node_entry_name, *dir_entry_name; - SF_LNODE *node; - - dir_entry_name = SnortStrdup(direntry->d_name); - - for (node = sflist_first_node(dir_entries); - node != NULL; - node = sflist_next_node(dir_entries)) - { - node_entry_name = (char *)node->ndata; - if (strcmp(dir_entry_name, node_entry_name) < 0) - break; - } - - if (node == NULL) - ret = sflist_add_tail(dir_entries, (NODE_DATA)dir_entry_name); - else - ret = sflist_add_before(dir_entries, node, (NODE_DATA)dir_entry_name); - - if (ret == -1) - { - ErrorMessage("Error adding directory entry to list\n"); - sflist_free_all(dir_entries, free); - closedir(dir); - return NULL; - } - } - - if (errno != 0) - { - ErrorMessage("Error reading directory: %s: %s\n", - path, strerror(errno)); - errno = 0; - sflist_free_all(dir_entries, free); - closedir(dir); - return NULL; - } - - closedir(dir); - - return dir_entries; -} - -int GetFilesUnderDir(const char *path, SF_QUEUE *dir_queue, const char *filter) -{ - SF_LIST *dir_entries; - char *direntry; - int ret = 0; - int num_files = 0; - - if ((path == NULL) || (dir_queue == NULL)) - return -1; - - dir_entries = SortDirectory(path); - if (dir_entries == NULL) - { - ErrorMessage("Error sorting entries in directory: %s\n", path); - return -1; - } - - for (direntry = (char *)sflist_first(dir_entries); - direntry != NULL; - direntry = (char *)sflist_next(dir_entries)) - { - char path_buf[PATH_MAX]; - struct stat file_stat; - - /* Don't look at dot files */ - if (strncmp(".", direntry, 1) == 0) - continue; - - ret = SnortSnprintf(path_buf, PATH_MAX, "%s%s%s", - path, path[strlen(path) - 1] == '/' ? "" : "/", direntry); - if (ret == SNORT_SNPRINTF_TRUNCATION) - { - ErrorMessage("Error copying file to buffer: Path too long\n"); - sflist_free_all(dir_entries, free); - return -1; - } - else if (ret != SNORT_SNPRINTF_SUCCESS) - { - ErrorMessage("Error copying file to buffer\n"); - sflist_free_all(dir_entries, free); - return -1; - } - - ret = stat(path_buf, &file_stat); - if (ret == -1) - { - ErrorMessage("Could not stat file: %s: %s\n", - path_buf, strerror(errno)); - sflist_free_all(dir_entries, free); - return -1; - } - - if (file_stat.st_mode & S_IFDIR) - { - ret = GetFilesUnderDir(path_buf, dir_queue, filter); - if (ret == -1) - { - sflist_free_all(dir_entries, free); - return -1; - } - - num_files += ret; - } - else if (file_stat.st_mode & S_IFREG) - { - if ((filter == NULL) || (fnmatch(filter, direntry, 0) == 0)) - { - char *file = SnortStrdup(path_buf); - - ret = sfqueue_add(dir_queue, (NODE_DATA)file); - if (ret == -1) - { - ErrorMessage("Could not append item to list: %s\n", file); - free(file); - sflist_free_all(dir_entries, free); - return -1; - } - - num_files++; - } - } - } - - sflist_free_all(dir_entries, free); - - return num_files; -} -#endif - -/**************************************************************************** - * - * Function: GetUniqueName(char * iface) - * - * Purpose: To return a string that has a high probability of being unique - * for a given sensor. - * - * Arguments: char * iface - The network interface you are sniffing - * - * Returns: A char * -- its a static char * so you should not free it - * - ***************************************************************************/ -char *GetUniqueName(char * iface) -{ - char * rptr; - static char uniq_name[256]; - - if (iface == NULL) LogMessage("Interface is NULL. Name may not be unique for the host\n"); -#ifndef WIN32 - rptr = GetIP(iface); - if(rptr == NULL || !strcmp(rptr, "unknown")) -#endif - { - SnortSnprintf(uniq_name, 255, "%s:%s\n",GetHostname(),iface); - rptr = uniq_name; - } - if (ScLogVerbose()) LogMessage("Node unique name is: %s\n", rptr); - return rptr; -} - -/**************************************************************************** - * - * Function: GetIP(char * iface) - * - * Purpose: To return a string representing the IP address for an interface - * - * Arguments: char * iface - The network interface you want to find an IP - * address for. - * - * Returns: A char * -- make sure you call free on this when you are done - * with it. - * - ***************************************************************************/ -char *GetIP(char * iface) -{ - struct ifreq ifr; - struct sockaddr_in *addr; - int s; -#ifdef SUP_IP6 - sfip_t ret; -#endif - - if(iface) - { - /* Set up a dummy socket just so we can use ioctl to find the - ip address of the interface */ - s = socket(PF_INET, SOCK_DGRAM, 0); - if(s == -1) - { - FatalError("Problem establishing socket to find IP address for interface: %s\n", iface); - } - - SnortStrncpy(ifr.ifr_name, iface, strlen(iface) + 1); - -#ifndef WIN32 - if(ioctl(s, SIOCGIFADDR, &ifr) < 0) return NULL; - else -#endif - { - addr = (struct sockaddr_in *) &ifr.ifr_broadaddr; - } - close(s); - -#ifdef SUP_IP6 -// XXX-IPv6 uses ioctl to populate a sockaddr_in structure ... but what if the interface only has an IPv6 address? - sfip_set_raw(&ret, addr, AF_INET); - return SnortStrdup(sfip_ntoa(&ret)); -#else - return SnortStrdup(inet_ntoa(addr->sin_addr)); -#endif - } - else - { - return "unknown"; - } -} - -/**************************************************************************** - * - * Function: GetHostname() - * - * Purpose: To return a string representing the hostname - * - * Arguments: None - * - * Returns: A static char * representing the hostname. - * - ***************************************************************************/ -char *GetHostname(void) -{ -#ifdef WIN32 - DWORD bufflen = 256; - static char buff[256]; - GetComputerName(buff, &bufflen); - return buff; -#else - char * error = "unknown"; - if(getenv("HOSTNAME")) return getenv("HOSTNAME"); - else if(getenv("HOST")) return getenv("HOST"); - else return error; -#endif -} - -/**************************************************************************** - * - * Function: GetTimestamp(register const struct timeval *tvp, int tz) - * - * Purpose: Get an ISO-8601 formatted timestamp for tvp within the tz - * timezone. - * - * Arguments: tvp is a timeval pointer. tz is a timezone. - * - * Returns: char * -- You must free this char * when you are done with it. - * - ***************************************************************************/ -char *GetTimestamp(register const struct timeval *tvp, int tz) -{ - struct tm *lt; /* localtime */ - char * buf; - int msec; - - buf = (char *)SnortAlloc(SMALLBUFFER * sizeof(char)); - - msec = tvp->tv_usec / 1000; - - if (ScOutputUseUtc()) - { - lt = gmtime((time_t *)&tvp->tv_sec); - SnortSnprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec, msec); - } - else - { - lt = localtime((time_t *)&tvp->tv_sec); - SnortSnprintf(buf, SMALLBUFFER, - "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tz); - } - - return buf; -} - -/**************************************************************************** - * - * Function: GetLocalTimezone() - * - * Purpose: Find the offset from GMT for current host - * - * Arguments: none - * - * Returns: int representing the offset from GMT - * - ***************************************************************************/ -int GetLocalTimezone(void) -{ - time_t ut; - struct tm * ltm; - long seconds_away_from_utc; - - time(&ut); - ltm = localtime(&ut); - -#if defined(WIN32) || defined(SOLARIS) || defined(AIX) || defined(HPUX) - /* localtime() sets the global timezone variable, - which is defined in <time.h> */ - seconds_away_from_utc = timezone; -#else - seconds_away_from_utc = ltm->tm_gmtoff; -#endif - - return seconds_away_from_utc/3600; -} - -/**************************************************************************** - * - * Function: GetCurrentTimestamp() - * - * Purpose: Generate an ISO-8601 formatted timestamp for the current time. - * - * Arguments: none - * - * Returns: char * -- You must free this char * when you are done with it. - * - ***************************************************************************/ -char *GetCurrentTimestamp(void) -{ - struct tm *lt; - struct timezone tz; - struct timeval tv; - struct timeval *tvp; - char * buf; - int tzone; - int msec; - - buf = (char *)SnortAlloc(SMALLBUFFER * sizeof(char)); - - bzero((char *)&tz,sizeof(tz)); - gettimeofday(&tv,&tz); - tvp = &tv; - - msec = tvp->tv_usec/1000; - - if (ScOutputUseUtc()) - { - lt = gmtime((time_t *)&tvp->tv_sec); - SnortSnprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec, msec); - } - else - { - lt = localtime((time_t *)&tvp->tv_sec); - - tzone = GetLocalTimezone(); - - SnortSnprintf(buf, SMALLBUFFER, - "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i", - 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, - lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tzone); - } - - return buf; -} - -/**************************************************************************** - * Function: base64(char * xdata, int length) - * - * Purpose: Insert data into the database - * - * Arguments: xdata => pointer to data to base64 encode - * length => how much data to encode - * - * Make sure you allocate memory for the output before you pass - * the output pointer into this function. You should allocate - * (1.5 * length) bytes to be safe. - * - * Returns: data base64 encoded as a char * - * - ***************************************************************************/ -char * base64(const u_char * xdata, int length) -{ - int count, cols, bits, c, char_count; - unsigned char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* 64 bytes */ - char * payloadptr; - char * output; - char_count = 0; - bits = 0; - cols = 0; - - output = (char *)SnortAlloc( ((unsigned int) (length * 1.5 + 4)) * sizeof(char) ); - - payloadptr = output; - - for(count = 0; count < length; count++) - { - c = xdata[count]; - - if(c > 255) - { - ErrorMessage("plugbase.c->base64(): encountered char > 255 (decimal %d)\n If you see this error message a char is more than one byte on your machine\n This means your base64 results can not be trusted", c); - } - - bits += c; - char_count++; - - if(char_count == 3) - { - *output = alpha[bits >> 18]; output++; - *output = alpha[(bits >> 12) & 0x3f]; output++; - *output = alpha[(bits >> 6) & 0x3f]; output++; - *output = alpha[bits & 0x3f]; output++; - cols += 4; - if(cols == 72) - { - *output = '\n'; output++; - cols = 0; - } - bits = 0; - char_count = 0; - } - else - { - bits <<= 8; - } - } - - if(char_count != 0) - { - bits <<= 16 - (8 * char_count); - *output = alpha[bits >> 18]; output++; - *output = alpha[(bits >> 12) & 0x3f]; output++; - if(char_count == 1) - { - *output = '='; output++; - *output = '='; output++; - } - else - { - *output = alpha[(bits >> 6) & 0x3f]; - output++; *output = '='; - output++; - } - } - *output = '\0'; - return payloadptr; -} - -/**************************************************************************** - * - * Function: ascii(u_char *xdata, int length) - * - * Purpose: This function takes takes a buffer "xdata" and its length then - * returns a string of only the printable ASCII characters. - * - * Arguments: xdata is the buffer, length is the length of the buffer in - * bytes - * - * Returns: char * -- You must free this char * when you are done with it. - * - ***************************************************************************/ -char *ascii(const u_char *xdata, int length) -{ - char *d_ptr, *ret_val; - int i,count = 0; - int size; - - if(xdata == NULL) - { - return NULL; - } - - for(i=0;i<length;i++) - { - if(xdata[i] == '<') - count+=4; /* < */ - else if(xdata[i] == '&') - count+=5; /* & */ - else if(xdata[i] == '>') /* > */ - count += 4; - } - - size = length + count + 1; - ret_val = (char *) calloc(1,size); - - if(ret_val == NULL) - { - LogMessage("plugbase.c: ascii(): Out of memory, can't log anything!\n"); - return NULL; - } - - d_ptr = ret_val; - - for(i=0;i<length;i++) - { - if((xdata[i] > 0x1F) && (xdata[i] < 0x7F)) - { - if(xdata[i] == '<') - { - SnortStrncpy(d_ptr, "<", size - (d_ptr - ret_val)); - d_ptr+=4; - } - else if(xdata[i] == '&') - { - SnortStrncpy(d_ptr, "&", size - (d_ptr - ret_val)); - d_ptr += 5; - } - else if(xdata[i] == '>') - { - SnortStrncpy(d_ptr, ">", size - (d_ptr - ret_val)); - d_ptr += 4; - } - else - { - *d_ptr++ = xdata[i]; - } - } - else - { - *d_ptr++ = '.'; - } - } - - *d_ptr++ = '\0'; - - return ret_val; -} - -/**************************************************************************** - * - * Function: hex(u_char *xdata, int length) - * - * Purpose: This function takes takes a buffer "xdata" and its length then - * returns a string of hex with no spaces - * - * Arguments: xdata is the buffer, length is the length of the buffer in - * bytes - * - * Returns: char * -- You must free this char * when you are done with it. - * - ***************************************************************************/ -char *hex(const u_char *xdata, int length) -{ - int x; - char *rval = NULL; - char *buf = NULL; - - if (xdata == NULL) - return NULL; - - buf = (char *)calloc((length * 2) + 1, sizeof(char)); - - if (buf != NULL) - { - rval = buf; - - for (x = 0; x < length; x++) - { - SnortSnprintf(buf, 3, "%02X", xdata[x]); - buf += 2; - } - - rval[length * 2] = '\0'; - } - - return rval; -} - - - -char *fasthex(const u_char *xdata, int length) -{ - char conv[] = "0123456789ABCDEF"; - char *retbuf = NULL; - const u_char *index; - const u_char *end; - char *ridx; - - index = xdata; - end = xdata + length; - retbuf = (char *)SnortAlloc(((length * 2) + 1) * sizeof(char)); - ridx = retbuf; - - while(index < end) - { - *ridx++ = conv[((*index & 0xFF)>>4)]; - *ridx++ = conv[((*index & 0xFF)&0x0F)]; - index++; - } - - return retbuf; -} - -/* - * Fatal Integer Parser - * Ascii to Integer conversion with fatal error support - */ -long int xatol(const char *s , const char *etext) -{ - long int val; - char *endptr; - char *default_error = "xatol() error\n"; - - if (etext == NULL) - etext = default_error; - - if (s == NULL) - FatalError("%s: String is NULL\n", etext); - - while (isspace((int)*s)) - s++; - - if (strlen(s) == 0) - FatalError("%s: String is empty\n", etext); - - - /* - * strtoul - errors on win32 : ERANGE (VS 6.0) - * errors on linux : ERANGE, EINVAL - * (for EINVAL, unsupported base which won't happen here) - */ - val = SnortStrtol(s, &endptr, 0); - - if ((errno == ERANGE) || (*endptr != '\0')) - FatalError("%s: Invalid integer input: %s\n", etext, s); - - return val; -} - -/* - * Fatal Integer Parser - * Ascii to Integer conversion with fatal error support - */ -unsigned long int xatou(const char *s , const char *etext) -{ - unsigned long int val; - char *endptr; - char *default_error = "xatou() error\n"; - - if (etext == NULL) - etext = default_error; - - if (s == NULL) - FatalError("%s: String is NULL\n", etext); - - while (isspace((int)*s)) - s++; - - if (strlen(s) == 0) - FatalError("%s: String is empty\n", etext); - - if (*s == '-') - { - FatalError("%s: Invalid unsigned integer - negative sign found, " - "input: %s\n", etext, s); - } - - - /* - * strtoul - errors on win32 : ERANGE (VS 6.0) - * errors on linux : ERANGE, EINVAL - */ - val = SnortStrtoul(s, &endptr, 0); - - if ((errno == ERANGE) || (*endptr != '\0')) - FatalError("%s: Invalid integer input: %s\n", etext, s); - - return val; -} - -unsigned long int xatoup(const char *s , const char *etext) -{ - unsigned long int val = xatou(s, etext); - if ( !val ) - FatalError("%s: must be > 0\n", etext); - return val; -} - -#ifndef SUP_IP6 -char * ObfuscateIpToText(const struct in_addr ip_addr) -#else -char * ObfuscateIpToText(sfip_t *ip) -#endif -{ - static char ip_buf1[INET6_ADDRSTRLEN]; - static char ip_buf2[INET6_ADDRSTRLEN]; - static int buf_num = 0; - int buf_size = INET6_ADDRSTRLEN; - char *ip_buf; -#ifndef SUP_IP6 - uint32_t ip = ip_addr.s_addr; -#endif - - if (buf_num) - ip_buf = ip_buf2; - else - ip_buf = ip_buf1; - - buf_num ^= 1; - ip_buf[0] = 0; - -#ifndef SUP_IP6 - if (ip == 0) - return ip_buf; - - if (snort_conf->obfuscation_net == 0) - { - /* Fully obfuscate - just use 'x' */ - SnortSnprintf(ip_buf, buf_size, "xxx.xxx.xxx.xxx"); - } - else - { - if (snort_conf->homenet != 0) - { - if ((ip & snort_conf->netmask) == snort_conf->homenet) - ip = snort_conf->obfuscation_net | (ip & snort_conf->obfuscation_mask); - } - else - { - ip = snort_conf->obfuscation_net | (ip & snort_conf->obfuscation_mask); - } - - SnortSnprintf(ip_buf, buf_size, "%s", inet_ntoa(*((struct in_addr *)&ip))); - } - -#else - if (ip == NULL) - return ip_buf; - - if (!IS_SET(snort_conf->obfuscation_net)) - { - if (IS_IP6(ip)) - SnortSnprintf(ip_buf, buf_size, "x:x:x:x::x:x:x:x"); - else - SnortSnprintf(ip_buf, buf_size, "xxx.xxx.xxx.xxx"); - } - else - { - sfip_t tmp; - char *tmp_buf; - - IP_COPY_VALUE(tmp, ip); - - if (IS_SET(snort_conf->homenet)) - { - if (sfip_contains(&snort_conf->homenet, &tmp) == SFIP_CONTAINS) - sfip_obfuscate(&snort_conf->obfuscation_net, &tmp); - } - else - { - sfip_obfuscate(&snort_conf->obfuscation_net, &tmp); - } - - tmp_buf = sfip_to_str(&tmp); - SnortSnprintf(ip_buf, buf_size, "%s", tmp_buf); - } -#endif - - return ip_buf; -} - -void PrintPacketData(const uint8_t *data, const uint32_t len) -{ - uint32_t i, j; - uint32_t total_len = 0; - uint8_t hex_buf[16]; - uint8_t char_buf[16]; - char *length_chars = " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n" - "------------------------------------------------------\n"; - - LogMessage("%s", length_chars); - - for (i = 0; i <= len; i++) - { - if ((i%16 == 0) && (i != 0)) - { - LogMessage("%04x ", total_len); - total_len += 16; - - for (j = 0; j < 16; j++) - { - LogMessage("%02x ", hex_buf[j]); - if (j == 7) - LogMessage(" "); - } - - LogMessage(" "); - - for (j = 0; j < 16; j++) - { - LogMessage("%c", char_buf[j]); - if (j == 7) - LogMessage(" "); - } - - LogMessage("\n"); - } - - if (i == len) - break; - - hex_buf[i%16] = data[i]; - - if (isprint((int)data[i])) - char_buf[i%16] = data[i]; - else - char_buf[i%16] = '.'; - } - - if ((i-total_len) > 0) - { - LogMessage("%04x ", total_len); - - for (j = 0; j < i-total_len; j++) - { - LogMessage("%02x ", hex_buf[j]); - if (j == 7) - LogMessage(" "); - } - - if (j < 8) - LogMessage(" "); - LogMessage("%*s", (16-j)*3, ""); - LogMessage(" "); - - for (j = 0; j < i-total_len; j++) - { - LogMessage("%c", char_buf[j]); - if (j == 7) - LogMessage(" "); - } - } - - LogMessage("\n"); -} - diff --git a/config/snort-dev/patches/spoink_patch/spo_pf.c b/config/snort-dev/patches/spoink_patch/spo_pf.c deleted file mode 100644 index 121920fc..00000000 --- a/config/snort-dev/patches/spoink_patch/spo_pf.c +++ /dev/null @@ -1,462 +0,0 @@ -/* -* -* Copyright (c) 2006 Antonio Benojar <zz.stalker@gmail.com> -* Copyright (c) 2005 Antonio Benojar <zz.stalker@gmail.com> -* -* Copyright (c) 2003, 2004 Armin Wolfermann: -* -* s2c_pf_block and s2c_pf_unblock functions are based -* in Armin's Wolfermann pftabled-1.03 functions. -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -/* - TODO - - - num. max ips. - - ipwhitelisting structure - - best ip regex expr -*/ - - -#ifndef LIST_END -#define LIST_END(head) NULL -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "event.h" -#include "decode.h" -#include "plugbase.h" -#include "spo_plugbase.h" -#include "debug.h" -#include "parser.h" -#include "util.h" -#include "log.h" -#include "mstring.h" - -#include "snort.h" - -#include "spo_pf.h" - -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <arpa/inet.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/queue.h> -#include <ctype.h> -#include <fcntl.h> -#include <net/if.h> -#include <net/pfvar.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <err.h> -#include <unistd.h> -#include <regex.h> - -#define PFDEVICE "/dev/pf" - -typedef struct _SpoAlertPfData { - FILE *wlfile; - char *pftable; - int fd; - struct wlist_head head; -} SpoAlertPfData; - -void AlertPfInit(u_char *); -SpoAlertPfData *ParseAlertPfArgs(char *); -void AlertPf(Packet *, char *, void *, Event *); -void AlertPfCleanExit(int, void *); -void AlertPfRestart(int, void *); - -int s2c_pf_init(void); -int s2c_pf_block(int, char *, char *, int); -int s2c_pf_intbl(int, char *, int); - -int s2c_parse_line(char *, FILE*); -int s2c_parse_load_wl(FILE*, struct wlist_head*, int); -int s2c_parse_search_wl(char *, struct wlist_head); -int s2c_parse_free_wl(struct wlist_head*); -int s2c_parse_ip(char *, char *, int); - - -void AlertPfSetup(void) -{ - RegisterOutputPlugin("alert_pf", OUTPUT_TYPE_FLAG__ALERT, AlertPfInit); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: AlertPf is setup...\n");); -} - -void AlertPfInit(u_char *args) -{ - SpoAlertPfData *data; - DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: AlertPf Initialized\n");); - - data = ParseAlertPfArgs(args); - - DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking AlertPf functions to call lists...\n");); - - AddFuncToOutputList(AlertPf, OUTPUT_TYPE_FLAG__ALERT, data); - AddFuncToCleanExitList(AlertPfCleanExit, data); - AddFuncToRestartList(AlertPfRestart, data); -} - - -void AlertPf(Packet *p, char *msg, void *arg, Event *event) -{ - SpoAlertPfData *data = (SpoAlertPfData *)arg; - char *ip; - int ret; - - DEBUG_WRAP(DebugMessage(DEBUG_LOG, "spoink block'n!!\n");); - - ip = inet_ntoa(p->iph->ip_src); - - if (ip == NULL) - FatalError("AlertPf() => inet_ntoa() = NULL\n", strerror(errno)); - - ret = s2c_parse_search_wl(ip, data->head); - - if (ret == 0) - s2c_pf_block(data->fd, data->pftable, inet_ntoa(p->iph->ip_src), 0); - - return; -} - -SpoAlertPfData *ParseAlertPfArgs(char *args) -{ - char **toks; - int num_toks; - SpoAlertPfData *data; - - int res = 0; - - data = (SpoAlertPfData *)SnortAlloc(sizeof(SpoAlertPfData)); - - if(args == NULL) - FatalError("Unable to load pf args\n", strerror(errno)); - - data->fd = s2c_pf_init(); - - if (data->fd == -1) - FatalError("s2c_pf_init() => no pf device\n"); - - DEBUG_WRAP(DebugMessage(DEBUG_LOG,"ParseAlertPfArgs: %s\n", args);); - - toks = mSplit(args, ",", 2, &num_toks, 0); - - if(num_toks <= 1) - FatalError("snort.conf => You must supply TWO arguments for the pf plugin...\n", strerror(errno)); - - if(strstr(toks[0], "..") != NULL) - FatalError("snort.conf => File definition contains \"..\". Do not do that!\n"); - - data->wlfile = fopen(toks[0], "r"); - - if (data->wlfile == NULL) - FatalError("snort.conf => Unable to open whitelist file\n", strerror(errno)); - - if (toks[1] == NULL) - FatalError("snort.conf => No pf table defined\n", strerror(errno)); - else - data->pftable = toks[1]; - - if (s2c_pf_intbl(data->fd, data->pftable, 0) == 0) - FatalError("pf.conf => Table %s don't exists in packet filter\n", data->pftable, strerror(errno)); - - res = s2c_parse_load_wl(data->wlfile, &data->head, 0); - if (res == -1) - FatalError("snort.conf => Unable to load whitelist\n", strerror(errno)); - - return data; -} - -void AlertPfCleanExit(int signal, void *arg) -{ - SpoAlertPfData *data = (SpoAlertPfData *)arg; - DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertPfCleanExit\n");); - - s2c_parse_free_wl(&data->head); - fclose(data->wlfile); - close(data->fd); - - free(data); -} - -void AlertPfRestart(int signal, void *arg) -{ - SpoAlertPfData *data = (SpoAlertPfData *)arg; - DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertPfRestart\n");); - - s2c_parse_free_wl(&data->head); - fclose(data->wlfile); - close(data->fd); - - free(data); -} - - -int s2c_pf_init(void) -{ - return(open(PFDEVICE, O_RDWR)); -} - -int s2c_pf_block(int dev, char *tablename, char *ip, int debug) -{ - - struct pfioc_table io; - struct pfr_table table; - struct pfr_addr addr; - struct in_addr *net_addr=NULL; - - memset(&io, 0x00, sizeof(struct pfioc_table)); - memset(&table, 0x00, sizeof(struct pfr_table)); - memset(&addr, 0x00, sizeof(struct pfr_addr)); - - strlcpy(table.pfrt_name, tablename, PF_TABLE_NAME_SIZE); - net_addr=(struct in_addr*)malloc(sizeof(struct in_addr)); - - if (net_addr == NULL ) - FatalError("s2c_pf_block() => malloc()\n", strerror(errno)); - - inet_aton(ip, (struct in_addr *)&net_addr); - memcpy(&addr.pfra_ip4addr.s_addr, &net_addr, sizeof(struct in_addr)); - - addr.pfra_af = AF_INET; - addr.pfra_net = 32; - - io.pfrio_table = table; - io.pfrio_buffer = &addr; - io.pfrio_esize = sizeof(struct pfr_addr); - io.pfrio_size = 1; - - if (ioctl(dev, DIOCRADDADDRS, &io)) - FatalError("s2c_pf_block() => ioctl() DIOCRADDADDRS\n", strerror(errno)); - - return(0); -} - -int s2c_pf_intbl(int dev, char * tablename, int debug) -{ - int i; - struct pfioc_table io; - struct pfr_table *table_aux = NULL; - - memset(&io, 0x00, sizeof(struct pfioc_table)); - - io.pfrio_buffer = table_aux; - io.pfrio_esize = sizeof(struct pfr_table); - io.pfrio_size = 0; - - if(ioctl(dev, DIOCRGETTABLES, &io)) - FatalError("s2c_pf_intbl() => ioctl() DIOCRGETTABLES\n", strerror(errno)); - - table_aux = (struct pfr_table*)malloc(sizeof(struct pfr_table)*io.pfrio_size); - - if (table_aux == NULL) - FatalError("s2c_pf_intbl() => malloc()\n", strerror(errno)); - - io.pfrio_buffer = table_aux; - io.pfrio_esize = sizeof(struct pfr_table); - - if(ioctl(dev, DIOCRGETTABLES, &io)) - FatalError("s2c_pf_intbl() => ioctl() DIOCRGETTABLES\n", strerror(errno)); - - for(i=0; i< io.pfrio_size; i++) { - if (!strcmp(table_aux[i].pfrt_name, tablename)) - return 1; - } - - return 0; - -} - - -int s2c_parse_line(char buf[WLMAX] , FILE* wfile) -{ - static char next_ch = ' '; - int i = 0; - - if (feof(wfile)) { - return (0); - } - do { - next_ch = fgetc(wfile); - if (i < WLMAX) - buf[i++] = next_ch; - } while (!feof(wfile) && !isspace(next_ch)); - if (i >= WLMAX) { - return (-1); - } - - buf[i] = '\0'; - return (1); -} - - -int s2c_parse_load_wl(FILE *wfile, struct wlist_head *head, int debug) -{ - - char cad[WLMAX]; - char ret[WLMAX]; - struct ipwlist *ipw2, *ipw1 = NULL; - struct flock lock; - - if (wfile == NULL) - FatalError("s2c_parse_load_wl() => Unable to open whitelist file\n", strerror(errno)); - - memset(&lock, 0x00, sizeof(struct flock)); - lock.l_type = F_RDLCK; - fcntl(fileno(wfile), F_SETLKW, &lock); - - LIST_INIT(head); - - if (s2c_parse_line(cad, wfile) == 1) { - if (s2c_parse_ip(cad, ret, debug) == 1) { - ipw1 = (struct ipwlist*)malloc(sizeof(struct ipwlist)); - if (ipw1 == NULL) - FatalError("s2c_parse_load_wl() => malloc()\n", strerror(errno)); - inet_aton(ret, &ipw1->waddr); - LIST_INSERT_HEAD(head, ipw1, elem); - - } else { - FatalError("s2c_parse_load_wl() => Invalid data in whitelist file\n", strerror(errno)); - } - } - - while(s2c_parse_line(cad, wfile) == 1) { - if (s2c_parse_ip(cad, ret, debug) == 1) { - ipw2 = (struct ipwlist*)malloc(sizeof(struct ipwlist)); - if (ipw2 == NULL) - FatalError("s2c_parse_load_wl() => malloc()\n", strerror(errno)); - inet_aton(ret, &ipw2->waddr); - LIST_INSERT_AFTER(ipw1, ipw2, elem); - ipw1 = ipw2; - } else { - break; - } - - } - - lock.l_type = F_UNLCK; - fcntl(fileno(wfile), F_SETLKW, &lock); - - return (0); -} - -/* XXX: optimize */ - -int -s2c_parse_search_wl(char *ip, struct wlist_head wl) -{ - struct ipwlist *aux2; - char *ip_aux, ip1[IPMAX], ip2[IPMAX]; - int ret; - - strlcpy(ip1, ip, sizeof(ip1)); - - for(aux2=wl.lh_first; aux2 !=NULL; aux2=aux2->elem.le_next) { - ip_aux = inet_ntoa(aux2->waddr); - strlcpy(ip2, ip_aux, sizeof(ip2)); - ret = strcmp(ip1, ip2); - - if (ret == 0) - return 1; - } - return (0); -} - - -int s2c_parse_free_wl(struct wlist_head *wl) -{ - struct ipwlist *aux, *aux2; - for(aux = LIST_FIRST(wl); aux != LIST_END(wl); aux = aux2) { - aux2 = LIST_NEXT(aux, elem); - LIST_REMOVE(aux, elem); - free(aux); - } - if (LIST_EMPTY(wl)) { - return (1); - } else { - FatalError("s2c_parse_free_wl() => Unable to free whitelist\n", strerror(errno)); - return (0); - } -} - -/* XXX: too much complex ? */ - -int s2c_parse_ip(char *cad, char ret[WLMAX], int debug) -{ - int len; - unsigned int enc=1; - regex_t *expr; - regmatch_t *resultado; - expr = (regex_t*)malloc(sizeof(regex_t)); - - bzero(ret, WLMAX); - - if (expr == NULL) - FatalError("s2c_parse_ip() => malloc()\n", strerror(errno)); - - resultado = (regmatch_t*)malloc(sizeof(regmatch_t)); - - if (resultado == NULL) - FatalError("s2c_parse_ip() => malloc()\n", strerror(errno)); - - if (regcomp(expr, REG_ADDR, REG_EXTENDED) !=0) - FatalError("s2c_parse_ip() => regcomp()\n", strerror(errno)); - - if (regexec(expr, cad, 1, resultado, 0) !=0) - enc=0; - - if (enc !=0) { - len = resultado->rm_eo - resultado->rm_so; - memcpy(ret, cad + resultado->rm_so, len); - ret[len]='\0'; - } - - free(resultado); - regfree(expr); - - if(enc) - return (1); - else { - errno = EINVAL; - return (0); - } -} diff --git a/config/snort-dev/patches/spoink_patch/spo_pf.h b/config/snort-dev/patches/spoink_patch/spo_pf.h deleted file mode 100644 index af07dacd..00000000 --- a/config/snort-dev/patches/spoink_patch/spo_pf.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -* -* Copyright (c) 2006 Antonio Benojar <zz.stalker@gmail.com> -* Copyright (c) 2005 Antonio Benojar <zz.stalker@gmail.com> -* -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __SPO_PF_H__ -#define __SPO_PF_H__ - -#include <sys/queue.h> -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <fcntl.h> -#include <net/if.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <stdio.h> - -#define WLMAX 1024 -#define IPMAX 20 -#define REG_ADDR "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}" - - -struct ipwlist { - struct in_addr waddr; - LIST_ENTRY(ipwlist) elem; -}; - -LIST_HEAD(wlist_head, ipwlist); - -void AlertPfSetup(void); - -#endif - - |