1 /*
2 ** spo_alert_fwsam.c
3 **
4 ** Copyright (c) 2001-2005        Frank Knobbe <frank@knobbe.us>
5 ** Portions Copyright (c) 2012    Ian Firns    <firnsy@securixlive.com>
6 **
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License as published by
9 ** the Free Software Foundation; either version 2 of the License, or
10 ** (at your option) any later version.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21 
22 /*
23  * Purpose:
24  *
25  * This module sends alerts to a remote service on a host running SnortSam
26  * (the agent) which will block the intruding IP address on a variety of
27  * host and network firewalls.
28  *
29  * SnortSam also performs checks against a white-list of never-to-be-blocked IP addresses,
30  * can override block durations (for example for known proxies), and can detect attack conditions
31  * where too many blocks are received within a defined interval. If an attack is detected
32  * it will unblock the last x blocks and wait for the attack to end.
33  *
34  * See the SnortSam documentation for more information.
35  *
36  *
37  * Output Plugin Parameters:
38  ***************************
39  *
40  * output alert_fwsam: <SnortSam Station>:<port>/<key>
41  *
42  *  <FW Mgmt Station>:  IP address or host name of the host running SnortSam.
43  *  <port>:         Port the remote SnortSam service listens on (default 898).
44  *  <key>:              Key used for authentication (encryption really)
45  *              of the communication to the remote service.
46  *
47  * Examples:
48  *
49  * output alert_fwsam: snortsambox/idspassword
50  * output alert_fwsam: fw1.domain.tld:898/mykey
51  * output alert_fwsam: 192.168.0.1/borderfw  192.168.1.254/wanfw
52  *
53  *
54  * sid-fwsam Parameters:
55  ***********************
56  *
57  * <sid>:   who[how],time;
58  *
59  *  who: src, source, dst, dest, destination
60  *          IP address to be blocked according to snort rule (some rules
61  *          are reversed, i.e. homenet -> any [and you want to block any]).
62  *          src denotes IP to the left of -> and dst denotes IP to the right
63  *
64  *  how: Optional. In, out, src, dest, either, both, this, conn, connection
65  *          Tells SnortSam to block packets INcoming from host, OUTgoing to host,
66  *          EITHERway, or only THIS connection (IP/Service pair).
67  *          See 'fw sam' on Firewall-1 for more information.
68  *          This option may be ignored by other plugins.
69  *
70  * time: Duration of block in seconds. (Accepts 'days', 'months', 'weeks',
71  *       'years', 'minutes', 'seconds', 'hours'. Alternatively, a value of
72  *       0, or the keyword PERManent, INFinite, or ALWAYS, will block the
73  *       host permanently. Be careful with this!
74  *          Tells SnortSam how long to inhibit packets from the host.
75  *
76  * Examples:
77  *
78  * 1487: src[either],15min;
79  * 1292: dst[in], 2 days 4 hours
80  * 1638: src, 1 hour
81  *
82 */
83 
84 #include <stdlib.h>
85 #include <stdio.h>
86 #include <time.h>
87 #include <string.h>
88 #include <ctype.h>
89 #include <unistd.h>
90 
91 #include "barnyard2.h"
92 #include "decode.h"
93 #include "spo_alert_fwsam.h"
94 #include "twofish.h"
95 #include "plugbase.h"
96 #include "unified2.h"
97 #include "util.h"
98 
99 /* just some compatibility stuff */
100 #ifdef WIN32
101 #if !defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
102 #include <winsock.h>
103 #endif
104 #define waitms(x)               Sleep(x)
105 
106 #else
107 
108 #include <sys/socket.h>
109 #include <netinet/in.h>
110 #include <arpa/inet.h>
111 #include <sys/ioctl.h>
112 #include <netdb.h>
113 
114 #ifdef SOLARIS
115 #include <sys/filio.h>
116 #endif
117 
118 //typedef int SOCKET;
119 
120 #ifndef INVALID_SOCKET
121 #define INVALID_SOCKET  -1
122 #endif
123 
124 #define waitms(x)               usleep((x)*1000)
125 
126 #endif
127 
128 #ifndef FALSE
129 #define FALSE   0
130 #endif
131 #ifndef TRUE
132 #define TRUE    !FALSE
133 #endif
134 #ifndef bool
135 #define bool    int
136 #endif
137 
138 
139 #if defined(_DEBUG) || defined(DEBUG)
140 #ifndef FWSAMDEBUG
141 #define FWSAMDEBUG
142 #endif
143 #else
144 #endif
145 
146 
147 
148 /* fixed defines */
149 
150 #define FWSAM_DEFAULTPORT       898 /* Default port if user does not specify one in barnyard2.conf */
151                                     /* (Was unused last time I checked...) */
152 #define FWSAM_PACKETVERSION     14  /* version of the packet. Will increase with enhancements. */
153 
154 #define FWSAM_STATUS_CHECKIN    1   /* snort to fw */
155 #define FWSAM_STATUS_CHECKOUT   2
156 #define FWSAM_STATUS_BLOCK      3
157 #define FWSAM_STATUS_UNBLOCK    9
158 
159 #define FWSAM_STATUS_OK         4   /* fw to snort */
160 #define FWSAM_STATUS_ERROR      5
161 #define FWSAM_STATUS_NEWKEY     6
162 #define FWSAM_STATUS_RESYNC     7
163 #define FWSAM_STATUS_HOLD       8
164 
165 #define FWSAM_LOG_NONE          0
166 #define FWSAM_LOG_SHORTLOG      1
167 #define FWSAM_LOG_SHORTALERT    2
168 #define FWSAM_LOG_LONGLOG       3
169 #define FWSAM_LOG_LONGALERT     4
170 #define FWSAM_LOG               (FWSAM_LOG_SHORTLOG|FWSAM_LOG_SHORTALERT|FWSAM_LOG_LONGLOG|FWSAM_LOG_LONGALERT)
171 #define FWSAM_WHO_DST           8
172 #define FWSAM_WHO_SRC           16
173 #define FWSAM_WHO               (FWSAM_WHO_DST|FWSAM_WHO_SRC)
174 #define FWSAM_HOW_IN            32
175 #define FWSAM_HOW_OUT           64
176 #define FWSAM_HOW_INOUT         (FWSAM_HOW_IN|FWSAM_HOW_OUT)
177 #define FWSAM_HOW_THIS          128
178 #define FWSAM_HOW               (FWSAM_HOW_IN|FWSAM_HOW_OUT|FWSAM_HOW_THIS)
179 
180 
181 /* user adjustable defines */
182 
183 #define FWSAM_REPET_BLOCKS      10  /* Snort remembers this amount of last blocks and... */
184 #define FWSAM_REPET_TIME        20  /* ...checks if they fall within this time. If so,... */
185                                     /* ...the blocking request is not send. */
186 
187 #define FWSAM_NETWAIT           300     /* 100th of a second. 3 sec timeout for network connections */
188 #define FWSAM_NETHOLD           6000    /* 100th of a second. 60 sec timeout for holding */
189 
190 #define SID_MAPFILE             "sid-block.map"
191 #define SID_ALT_MAPFILE         "sid-fwsam.map"
192 
193 #define FWSAM_FANCYFETCH        /* This will invoke a fast sid lookup routine */
194 
195 
196 /* vars */
197 
198 typedef struct _FWsamstation            /* structure of a mgmt station */
199 {
200     unsigned short      myseqno;
201     unsigned short      stationseqno;
202     unsigned char       mykeymod[4];
203     unsigned char       fwkeymod[4];
204     unsigned short      stationport;
205     //struct in_addr        stationip;
206     sfip_t          stationip;
207     struct sockaddr_in  localsocketaddr;
208     struct sockaddr_in  stationsocketaddr;
209     TWOFISH         *stationfish;
210     char            initialkey[TwoFish_KEY_LENGTH+2];
211     char            stationkey[TwoFish_KEY_LENGTH+2];
212     time_t          lastcontact;
213 /*  time_t          sleepstart; */
214 }   FWsamStation;
215 
216 typedef struct _FWsampacket         /* 2 blocks (3rd block is header from TwoFish) */
217 {
218     unsigned short      endiancheck;    /* 0  */
219     unsigned char       srcip[4];       /* 2  */
220     unsigned char       dstip[4];       /* 6  */
221     unsigned char       duration[4];    /* 10 */
222     unsigned char       snortseqno[2];  /* 14 */
223     unsigned char       fwseqno[2];     /* 16 */
224     unsigned char       srcport[2];     /* 18 */
225     unsigned char       dstport[2];     /* 20 */
226     unsigned char       protocol[2];    /* 22 */
227     unsigned char       fwmode;         /* 24 */
228     unsigned char       version;        /* 25 */
229     unsigned char       status;         /* 26 */
230     unsigned char       sig_id[4];      /* 27 */
231     unsigned char       fluff;          /* 31 */
232 }   FWsamPacket;                        /* 32 bytes in size */
233 
234 typedef struct _FWsampacket2            /* 4 blocks (3rd block is header from TwoFish) */
235 {
236     unsigned short      endiancheck;    /* 0  */
237     unsigned char       srcip[16];      /* 2  */
238     unsigned char       dstip[16];      /* 18 */
239     unsigned char       ipver;          /* 34 */
240     unsigned char       duration[4];    /* 35 */
241     unsigned char       snortseqno[2];  /* 39 */
242     unsigned char       fwseqno[2];     /* 41 */
243     unsigned char       srcport[2];     /* 43 */
244     unsigned char       dstport[2];     /* 45 */
245     unsigned char       protocol[2];    /* 47 */
246     unsigned char       fwmode;         /* 49 */
247     unsigned char       version;        /* 50 */
248     unsigned char       status;         /* 51 */
249     unsigned char       sig_id[4];      /* 52 */
250     unsigned char       reserved[7];    /* 56 */
251 }   FWsamPacket2;                       /* 64 bytes in size */
252 
253 typedef struct _FWsamoptions    /* snort rule options */
254 {
255     unsigned long   sid;
256     unsigned long   duration;
257     unsigned char   who;
258     unsigned char   how;
259     unsigned char   loglevel;
260 }   FWsamOptions;
261 
262 typedef struct _FWsamlistpointer
263 {
264     FWsamStation *station;
265     struct _FWsamlistpointer *next;
266 }   FWsamList;
267 
268 /*
269 ** PROTOTYPES
270 */
271 void AlertFWsamInit(char *args);
272 void AlertFWsamCleanExitFunc(int signal, void *arg);
273 void AlertFWsamRestartFunc(int signal, void *arg);
274 void AlertFWsam(Packet *p, void *event, uint32_t type, void *arg);
275 int FWsamCheckIn(FWsamStation *station);
276 void FWsamCheckOut(FWsamStation *station);
277 void FWsamNewStationKey(FWsamStation *station, FWsamPacket *packet);
278 void FWsamFixPacketEndian(FWsamPacket *p);
279 unsigned long FWsamParseDuration(char *p);
280 void FWsamFree(FWsamList *fwsamlist);
281 int FWsamStationExists(FWsamStation *who, FWsamList *list);
282 int FWsamReadLine(char *, unsigned long, FILE *);
283 void FWsamParseLine(FWsamOptions *, char *);
284 FWsamOptions *FWsamGetOption(unsigned long);
285 int FWsamParseOption(FWsamOptions *, char *);
286 
287 
288 /*
289 ** GLOBALS
290 */
291 
292 /* external globals from rules.c  */
293 extern char *file_name;
294 extern int file_line;
295 
296 /* external globals from barnyard.c */
297 extern Barnyard2Config *barnyard2_conf;
298 
299 FWsamList *FWsamStationList=NULL;           /* Global (for all alert-types) list of snortsam stations */
300 FWsamOptions *FWsamOptionField=NULL;
301 unsigned long FWsamMaxOptions=0;
302 
303 
304 /*
305  * Function: AlertFWsamSetup()
306  *
307  * Purpose: Registers the output plugin keyword and initialization
308  *          function into the output plugin list.  This is the function that
309  *          gets called from InitOutputPlugins() in plugbase.c.
310  *          It also registers itself as a plugin in order to parse every rule
311  *          and to set the appropiate flags from fwsam: option.
312  *
313  * Arguments: None.
314  *
315  * Returns: void function
316  *
317 */
AlertFWsamSetup(void)318 void AlertFWsamSetup(void)
319 {
320     /* link the preprocessor keyword to the init function in the preproc list */
321     RegisterOutputPlugin("alert_fwsam", OUTPUT_TYPE_FLAG__ALERT, AlertFWsamInit);
322 
323 #ifdef FWSAMDEBUG   /* This allows debugging of fwsam only */
324     LogMessage("DEBUG => [Alert_FWsam](AlertFWsamSetup) Output plugin is plugged in...\n");
325 #endif
326 }
327 
328 
329 /*
330  * Function: AlertFWsamInit(char *args)
331  *
332  * Purpose: Calls the argument parsing function, performs final setup on data
333  *          structs, links the preproc function into the function list.
334  *
335  * Arguments: args => ptr to argument string
336  *
337  * Returns: void function
338  *
339 */
AlertFWsamInit(char * args)340 void AlertFWsamInit(char *args)
341 {
342     char *ap;
343     unsigned long statip,cnt,again,i;
344     char *stathost, *statport, *statpass;
345     FWsamStation *station;
346     FWsamList *fwsamlist=NULL;  /* alert-type dependent list of snortsam stations  */
347     FWsamList *listp,*newlistp;
348     struct hostent *hoste;
349     char buf[1024]="";
350     FILE *fp;
351     FWsamOptions tempopt;
352 
353 #ifdef FWSAMDEBUG
354     unsigned long hostcnt=0;
355     LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Output plugin initializing...\n");
356 #endif
357 
358     /* parse the argument list from the rules file */
359     if(args == NULL)
360         FatalError("[Alert_FWsam](AlertFWsamInit) No arguments to alert_fwsam preprocessor!\n");
361 
362     if(!FWsamOptionField && !FWsamMaxOptions)
363     {
364         strncpy(buf, barnyard2_conf->config_dir, sizeof(buf)-1);
365         strncpy(buf+strlen(buf), SID_MAPFILE, sizeof(buf)-strlen(buf)-1);
366 #ifdef FWSAMDEBUG
367         LogMessage("DEBUG => [Alert_FWsam](AlertFWsamSetup) Using file: %s\n",buf);
368 #endif
369         fp=fopen(buf,"rt");
370         if(!fp)
371         {
372             strncpy(buf, barnyard2_conf->config_dir, sizeof(buf)-1);
373             strncpy(buf+strlen(buf), SID_ALT_MAPFILE, sizeof(buf)-strlen(buf)-1);
374             LogMessage("DEBUG => [Alert_FWsam](AlertFWsamSetup) Using alternative file: %s\n",buf);
375             fp=fopen(buf,"rt");
376         }
377 
378         if(fp)  /* Check for presence of map file and read those in, sorted. */
379         {
380             LogMessage("INFO => [Alert_FWsam](AlertFWsamSetup) Using sid-map file: %s\n",buf);
381             while( FWsamReadLine(buf,sizeof(buf),fp) )
382                 if( *buf )
383                     FWsamMaxOptions++;
384 
385             if( FWsamMaxOptions )
386             {
387                 if( (FWsamOptionField=(FWsamOptions *)malloc(sizeof(FWsamOptions)*FWsamMaxOptions)) == NULL )
388                     FatalError("ERROR => [Alert_FWsam](AlertFWsamSetup) malloc failed for OptionField!\n");
389 
390                 fseek(fp,0,SEEK_SET);
391                 for(cnt=0; cnt<FWsamMaxOptions; )
392                 {
393                     FWsamReadLine(buf,sizeof(buf),fp);
394 
395                 if( *buf )
396                     FWsamParseLine(&(FWsamOptionField[cnt++]),buf);
397                 }
398 
399                 if( FWsamMaxOptions>1 )
400                 {
401                     for(again=TRUE,cnt=FWsamMaxOptions-1; cnt>=1 && again; cnt--)
402                     {
403                         for(again=FALSE,i=0; i<cnt; i++)
404                         {
405                             if( FWsamOptionField[i].sid>FWsamOptionField[i+1].sid )
406                             {   memcpy(&tempopt,&(FWsamOptionField[i]),sizeof(FWsamOptions));
407                                 memcpy(&(FWsamOptionField[i]),&(FWsamOptionField[i+1]),sizeof(FWsamOptions));
408                                 memcpy(&(FWsamOptionField[i+1]),&tempopt,sizeof(FWsamOptions));
409                                 again=TRUE;
410                             }
411                         }
412                     }
413                 }
414             }
415             else
416                 FWsamMaxOptions=1;
417 
418             fclose(fp);
419         }
420         else
421             FWsamMaxOptions=1;
422     }
423 
424 
425     ap=args; /* start at the beginning of the argument */
426     while(*ap && isspace(*ap)) ap++;
427     while(*ap)
428     {
429         stathost=ap; /* first argument should be host */
430         statport=NULL;
431         statpass=NULL;
432         while(*ap && *ap!=':' && *ap!='/' && !isspace(*ap)) ap++; /* find token */
433         switch(*ap)
434         {
435             case ':':
436                 *ap++=0; /* grab the port */
437                 statport=ap;
438                 while(*ap && *ap!='/' && !isspace(*ap)) ap++;
439                 if(*ap!='/')
440                     break;
441 
442             case '/':
443                 *ap++=0; /* grab the key */
444                     statpass=ap;
445                     while(*ap && !isspace(*ap)) ap++;
446                     break;
447 
448             default:
449                     break;
450         }
451 
452         if(*ap)
453         {
454             *ap++=0;
455             while(isspace(*ap)) ap++;
456         }
457 
458         /* now we have the first host with port and password (key) */
459         /* next we check for valid/blank password/port */
460         if(statpass!=NULL)
461             if(!*statpass)
462                 statpass=NULL;
463 
464         if(statport!=NULL)
465             if(!*statport)
466                 statport=NULL;
467 
468         statip=0;
469         /* now we check if a valid host was specified */
470         if(inet_addr(stathost)==INADDR_NONE)
471         {
472             hoste=gethostbyname(stathost);
473 
474             if (!hoste)
475                 LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWsamInit) Unable to resolve host '%s'!\n",file_name,file_line,stathost);
476             else
477                 statip=*(unsigned long *)hoste->h_addr;
478         }
479         else
480         {
481             statip=inet_addr(stathost);
482             if(!statip)
483                 LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWsamInit) Invalid host address '%s'!\n",file_name,file_line,stathost);
484         }
485 
486         if(statip)
487         {   /* groovie, a valid host. Let's alloc and assemble the structure for it. */
488             if((station=(FWsamStation *)malloc(sizeof(FWsamStation)))==NULL)
489                 FatalError("ERROR => [Alert_FWsam](AlertFWsamInit) malloc failed for station!\n");
490 
491             station->stationip.ip32[0] = statip; /* the IP address */
492             if(statport!=NULL && atoi(statport)>0) /* if the user specified one */
493                 station->stationport=atoi(statport); /* use users setting */
494             else
495                 station->stationport=FWSAM_DEFAULTPORT; /* set the default port */
496 
497             if(statpass!=NULL) /* if specified by user */
498                 strncpy(station->stationkey,statpass,TwoFish_KEY_LENGTH); /* use defined key */
499             else
500                 station->stationkey[0]=0;
501 
502             station->stationkey[TwoFish_KEY_LENGTH]=0; /* make sure it's terminated. (damn strncpy...) */
503 
504             strcpy(station->initialkey,station->stationkey);
505             station->stationfish=TwoFishInit(station->stationkey);
506 
507             station->localsocketaddr.sin_port=htons(0); /* let's use dynamic ports for now */
508             station->localsocketaddr.sin_addr.s_addr=0;
509             station->localsocketaddr.sin_family=AF_INET;
510             station->stationsocketaddr.sin_port=htons(station->stationport);
511 
512             station->stationsocketaddr.sin_addr.s_addr=station->stationip.ip32[0];
513             station->stationsocketaddr.sin_family=AF_INET; /* load all socket crap and keep for later */
514 
515             do
516                 station->myseqno=rand(); /* the seqno this host will use */
517             while(station->myseqno<20 || station->myseqno>65500);
518 
519             station->mykeymod[0]=rand();
520             station->mykeymod[1]=rand();
521             station->mykeymod[2]=rand();
522             station->mykeymod[3]=rand();
523             station->stationseqno=0;                /* peer hasn't answered yet. */
524 
525 
526             /* If we don't have the station already in global list....*/
527             if(!FWsamStationExists(station,FWsamStationList))
528             {
529                 if(FWsamCheckIn(station))           /* ...and we can talk to the agent...  */
530                 {
531                     if((newlistp=(FWsamList *)malloc(sizeof(FWsamList)))==NULL)
532                         FatalError("ERROR => [Alert_FWsam](AlertFWsamInit) malloc failed for global newlistp!\n");
533 
534                     newlistp->station=station;
535                     newlistp->next=NULL;
536 
537                     if(!FWsamStationList)               /* ... add it to the global list/ */
538                         FWsamStationList=newlistp;
539                     else
540                     {
541                         listp=FWsamStationList;
542                         while(listp->next)
543                             listp=listp->next;
544                         listp->next=newlistp;
545                     }
546                 }
547                 else
548                 {
549                     TwoFishDestroy(station->stationfish); /* if not, we trash it. */
550                     free(station);
551                     station=NULL;
552                 }
553             }
554 #ifdef FWSAMDEBUG
555             else
556                 LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Host %s:%i already in global list, skipping CheckIn.\n", sfip_ntoa(&station->stationip),station->stationport);
557 #endif
558 
559             if(station)
560             {
561                 /* If we don't have the station already in local list....*/
562                 if(!FWsamStationExists(station,fwsamlist))
563                 {
564                     if((newlistp=(FWsamList *)malloc(sizeof(FWsamList)))==NULL)
565                         FatalError("ERROR => [Alert_FWsam](AlertFWsamInit) malloc failed for local newlistp!\n");
566 
567                     newlistp->station=station;
568                     newlistp->next=NULL;
569 
570                     if(!fwsamlist)              /* ... add it to the local list/ */
571                         fwsamlist=newlistp;
572                     else
573                     {
574                         listp=fwsamlist;
575                         while(listp->next)
576                             listp=listp->next;
577                         listp->next=newlistp;
578                     }
579                 }
580 
581 #ifdef FWSAMDEBUG
582                 else
583                     LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Host %s:%i already in local list, skipping.\n",sfip_ntoa(&station->stationip),station->stationport);
584 
585                 LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) #%i: Host %s [%s] port %i password %s\n",++hostcnt,stathost,sfip_ntoa(&station->stationip),station->stationport,station->stationkey);
586 #endif
587             }
588         }
589     }   /* next one */
590 
591 #ifdef FWSAMDEBUG
592     LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Linking fwsam alert function to call list...\n");
593 #endif
594 
595     /* Set the preprocessor function into the function list */
596     AddFuncToOutputList(AlertFWsam, OUTPUT_TYPE__LOG, fwsamlist);
597     AddFuncToCleanExitList(AlertFWsamCleanExitFunc, fwsamlist);
598     AddFuncToRestartList(AlertFWsamRestartFunc, fwsamlist);
599 }
600 
601 
602 /*  This routine reads in a str from a file, snips white-spaces
603  *  off the front and back, removes comments, and pretties the
604  *  string. Returns true or false if a line was read or not.
605 */
FWsamReadLine(char * buf,unsigned long bufsize,FILE * fp)606 int FWsamReadLine(char *buf,unsigned long bufsize,FILE *fp)
607 {   char *p;
608 
609     if(fgets(buf,bufsize-1,fp))
610     {
611         buf[bufsize-1]=0;
612 
613 #ifdef FWSAMDEBUG
614         LogMessage("DEBUG => [Alert_FWsam](AlertFWsamReadLine) Line: %s\n",buf);
615 #endif
616 
617         p=buf;
618         while(isspace(*p))
619           p++;
620         if(p>buf)
621 	;
622             strcpy(buf,p);
623         if(*buf)
624         {
625             p=buf+strlen(buf)-1;    /* remove leading and trailing spaces */
626             while(isspace(*p))
627                 *p-- =0;
628         }
629         p=buf;
630         if(*p=='#' || *p==';')
631             *p=0;
632         else
633             p++;
634         while(*p)                   /* remove inline comments (except escaped #'s and ;'s) */
635         {
636             if(*p=='#' || *p==';')
637             {
638                 if(*(p-1)=='\\')
639                     strcpy(p-1,p);
640                 else
641                     *p=0;
642             }
643             else
644                 p++;
645         }
646         return TRUE;
647     }
648     return FALSE;
649 }
650 
651 /*  This function checks if a given snortsam station is already in
652  *  a given list.
653 */
FWsamStationExists(FWsamStation * who,FWsamList * list)654 int FWsamStationExists(FWsamStation *who,FWsamList *list)
655 {
656     while(list)
657     {
658         if(list->station)
659         {
660             if( IP_EQUALITY(&who->stationip, &list->station->stationip) &&
661                 who->stationport==list->station->stationport )
662             return TRUE;
663         }
664         list=list->next;
665     }
666     return FALSE;
667 }
668 
669 
670 /* Parses the duration of the argument, recognizing minutes, hours, etc..
671 */
FWsamParseDuration(char * p)672 unsigned long FWsamParseDuration(char *p)
673 {   unsigned long dur=0,tdu;
674     char *tok,c1,c2;
675 
676     while(*p)
677     {
678         tok=p;
679         while(*p && isdigit(*p))
680             p++;
681         if(*p)
682         {
683             c1=tolower(*p);
684             *p=0;
685             p++;
686             if(*p && !isdigit(*p))
687             {
688                 c2=tolower(*p++);
689                 while(*p && !isdigit(*p))
690                     p++;
691             }
692             else
693                 c2=0;
694             tdu=atol(tok);
695             switch(c1)
696             {
697                 case 'm':
698                     if(c2=='o')             /* month */
699                         tdu*=(60*60*24*30); /* use 30 days */
700                     else
701                         tdu*=60;            /* minutes */
702                     break;
703                 case 's':
704                     break;                  /* seconds */
705                 case 'h':
706                     tdu*=(60*60);           /* hours */
707                     break;
708                 case 'd':
709                     tdu*=(60*60*24);        /* days */
710                     break;
711                 case 'w':
712                     tdu*=(60*60*24*7);      /* week */
713                     break;
714                 case 'y':
715                     tdu*=(60*60*24*365);    /* year */
716                     break;
717             }
718             dur+=tdu;
719         }
720         else
721             dur+=atol(tok);
722     }
723 
724     return dur;
725 }
726 
727 
728 /*  This routine parses an option line. It is called by FWsamParseLine,
729  *  which parses the sid-block.map file, and also by AlertFWsamOptionInit,
730  *  which is called by Snort when processing fwsam: options in rules.
731  *  It returns TRUE it there is a possible option problem, otherwise FALSE.
732 */
FWsamParseOption(FWsamOptions * optp,char * ap)733 int FWsamParseOption(FWsamOptions *optp,char *ap)
734 {
735     int possprob=FALSE;
736 
737     /* set defaults */
738 
739     optp->duration=300;                 /* default of 5 minute block */
740     optp->how=FWSAM_HOW_INOUT;          /* inbound and outbound block */
741     optp->who=FWSAM_WHO_SRC;            /* the source  */
742     optp->loglevel=FWSAM_LOG_LONGALERT; /* the log level default */
743     /* parse the fwsam keywords */
744 
745 #ifdef FWSAMDEBUG
746     LogMessage("DEBUG => [Alert_FWsam](AlertFWamOptionInit) Parse Options Args: %s\n",ap);
747 #endif
748 
749     if(*ap)     /* should be dst/src (the WHO) or duration */
750     {
751         if(isdigit(*ap))
752             optp->duration=FWsamParseDuration(ap);
753         else
754         {
755             switch(*ap)         /* yeah, we're lazy and check only the first character */
756             {
757                 case 'p':                                   /* permanent, perm */
758                 case 'f':                                   /* forever */
759                 case 'i':                                   /* infinite, inf */
760                     optp->duration=0;
761                     break;
762                 case 'd':                                   /* destination, dest, dst */
763                     optp->who=FWSAM_WHO_DST;
764                     break;
765                 case 's':                                   /* source, src */
766                     optp->who=FWSAM_WHO_SRC;
767                     break;
768                 default:
769                     possprob=TRUE;
770             }
771             while(*ap && *ap!=',' && *ap!='[')
772                 ap++;
773             if(*ap=='[')
774             {   ap++;       /* now we have the HOW */
775                 switch(*ap)
776                 {
777                     case 'i':                               /* in */
778                     case 's':                               /* source, src */
779                         optp->how=FWSAM_HOW_IN;
780                         break;
781                     case 'o':   ;                           /* out */
782                     case 'd':                               /* destination, dest, dst */
783                         optp->how=FWSAM_HOW_OUT;
784                         break;
785                     case 'b':   ;                           /* both */
786                     case 'e':                               /* either */
787                         optp->how=FWSAM_HOW_INOUT;
788                         break;
789                     case 't':   ;                           /* this */
790                     case 'c':                               /* connection, conn */
791                         optp->how=FWSAM_HOW_THIS;
792                         break;
793                     default:
794                         possprob=TRUE;
795                 }
796                 while(*ap && *ap!=',')
797                     ap++;
798             }
799             if(*ap==',')
800             {
801                 ap++;
802                 if(isdigit(*ap))  /* and figure out how long to block */
803                     optp->duration=FWsamParseDuration(ap);
804                 else if(*ap=='p' || *ap=='f' || *ap=='i')
805                     optp->duration=0;
806                 else
807                     possprob=TRUE;
808             }
809             else if(!*ap)
810                 possprob=TRUE;
811         }
812     }
813     else
814         possprob=TRUE;
815 
816     return possprob;
817 }
818 
819 
820 /*  This goes through the lines of sid-block.map and sets the
821  *  options for fwsam if the file is being used.
822 */
FWsamParseLine(FWsamOptions * optp,char * buf)823 void FWsamParseLine(FWsamOptions *optp,char *buf)
824 {
825     char *ap;
826 
827     ap=buf; /* start at the beginning of the argument */
828 
829     while(*ap)
830     {
831         if(isspace(*ap))        /* normalize spaces (tabs into space, etc) */
832             *ap=' ';
833         if(isupper(*ap))        /* and set to lower case */
834             *ap=tolower(*ap);
835         ap++;
836     }
837     while((ap=strrchr(buf,' '))!=NULL)  /* remove spaces */
838         strcpy(ap,ap+1);
839 
840     ap=buf;
841     if(*ap)
842     {
843         while(*ap && *ap!=':' && *ap!='|') ap++;
844         *ap++ =0;
845         while(*ap && (*ap==':' || *ap=='|')) ap++;
846 
847         optp->sid=(unsigned long)atol(buf);
848 
849         if(FWsamParseOption(optp,ap))
850             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);
851     }
852     else
853         optp->sid=0;
854 }
855 
856 
857 /* Generates a new encryption key for TwoFish based on seq numbers and a random that
858  * the SnortSam agents send on checkin (in protocol)
859 */
FWsamNewStationKey(FWsamStation * station,FWsamPacket * packet)860 void FWsamNewStationKey(FWsamStation *station,FWsamPacket *packet)
861 {
862     char newkey[TwoFish_KEY_LENGTH+2];
863     int i;
864 
865     newkey[0]=packet->snortseqno[0];        /* current snort seq # (which both know) */
866     newkey[1]=packet->snortseqno[1];
867     newkey[2]=packet->fwseqno[0];           /* current SnortSam seq # (which both know) */
868     newkey[3]=packet->fwseqno[1];
869     newkey[4]=packet->protocol[0];      /* the random SnortSam chose */
870     newkey[5]=packet->protocol[1];
871 
872     strncpy(newkey+6,station->stationkey,TwoFish_KEY_LENGTH-6); /* append old key */
873     newkey[TwoFish_KEY_LENGTH]=0;
874 
875     newkey[0]^=station->mykeymod[0];        /* modify key with key modifiers which were */
876     newkey[1]^=station->mykeymod[1];        /* exchanged during the check-in handshake. */
877     newkey[2]^=station->mykeymod[2];
878     newkey[3]^=station->mykeymod[3];
879     newkey[4]^=station->fwkeymod[0];
880     newkey[5]^=station->fwkeymod[1];
881     newkey[6]^=station->fwkeymod[2];
882     newkey[7]^=station->fwkeymod[3];
883 
884     for(i=0;i<=7;i++)
885         if(newkey[i]==0)
886             newkey[i]++;
887 
888     strcpy(station->stationkey,newkey);
889     TwoFishDestroy(station->stationfish);
890     station->stationfish=TwoFishInit(newkey);
891 }
892 
893 
894 #ifdef FWSAMDEBUG
895 /* This does nothing else than inet_ntoa, but it keeps 4 results in a static string
896  * unlike inet_ntoa which keeps only one. This is used for (s)printf's were two IP
897  * addresses are printed.
898 */
inettoa(unsigned long ip)899 char *inettoa(unsigned long ip)
900 {
901     struct in_addr ips;
902     static char addr[4][20];
903     static unsigned char toggle;
904 
905     ips.s_addr=ip;
906     toggle=(toggle+1)&3;
907     strncpy(addr[toggle],inet_ntoa(ips),18);
908     return addr[toggle];
909 }
910 #endif
911 
912 
913 /*  This routing will search the option list as defined
914  *  by the sid-block.map file and return a pointer
915  *  to the matching record.
916 */
FWsamGetOption(unsigned long sid)917 FWsamOptions *FWsamGetOption(unsigned long sid)
918 {
919     signed long i,step,diff,o,o2;
920 
921 #ifdef FWSAM_FANCYFETCH       /* Fancy-fetch jumps in decreasing n/2 steps and takes much less lookups */
922     o=o2= -1;
923     i=step=FWsamMaxOptions>>1;
924     while(i>=0 && i<FWsamMaxOptions && i!=o2)
925     {
926         diff=sid-FWsamOptionField[i].sid;
927         if(!diff)
928             return &(FWsamOptionField[i]);
929         if(step>1)
930             step=step>>1;
931         o2=o;
932         o=i;
933         if(diff>0)
934             i+=step;
935         else
936             i-=step;
937     }
938 #else                       /* This is just a sequential list lookup */
939     for(i=0;i<FWsamMaxOptions;i++)
940         if(FWsamOptionField[i].sid==sid)
941             return &(FWsamOptionField[i]);
942 #endif
943     return NULL;
944 }
945 
946 
947 /****************************************************************************
948  *
949  * Function: AlertFWsam(Packet *, char *)
950  *
951  * Purpose: Send the current alert to a remote module on a FW-1 mgmt station
952  *
953  * Arguments: p => pointer to the packet data struct
954  *            msg => the message to print in the alert
955  *
956  * Returns: void function
957  *
958  ***************************************************************************/
AlertFWsam(Packet * p,void * event,uint32_t event_type,void * arg)959 void AlertFWsam(Packet *p, void *event, uint32_t event_type, void *arg)
960 {
961     FWsamOptions *optp;
962     FWsamPacket sampacket;
963     FWsamStation *station=NULL;
964     FWsamList *fwsamlist;
965     int stationsocket;
966     int i,len,deletestation,stationtry=0;
967     char *encbuf,*decbuf;
968     static unsigned long lastbsip[FWSAM_REPET_BLOCKS];
969     static unsigned long lastbdip[FWSAM_REPET_BLOCKS];
970     static unsigned long lastbduration[FWSAM_REPET_BLOCKS];
971     static unsigned long lastbtime[FWSAM_REPET_BLOCKS];
972     static unsigned short lastbsp[FWSAM_REPET_BLOCKS];
973     static unsigned short lastbdp[FWSAM_REPET_BLOCKS];
974     static unsigned short lastbproto[FWSAM_REPET_BLOCKS];
975     static unsigned short lastbpointer;
976     static unsigned char lastbmode[FWSAM_REPET_BLOCKS];
977     static unsigned long btime=0;
978 
979     SigNode     *sn = NULL;
980     ClassType   *cn = NULL;
981 
982     /*
983     ** Remove Compiler warning.
984       ReferenceNode   *rn = NULL;
985     */
986 
987     if(event==NULL)
988     {
989 #ifdef FWSAMDEBUG
990         LogMessage("DEBUG => [Alert_FWsam] NULL event!\n");
991 #endif
992         return;
993     }
994 
995     if(p == NULL)
996     {
997 #ifdef FWSAMDEBUG
998         LogMessage("DEBUG => [Alert_FWsam] NULL packet!\n");
999 #endif
1000         return;
1001     }
1002 
1003     if(arg == NULL)
1004     {
1005 #ifdef FWSAMDEBUG
1006         LogMessage("DEBUG => [Alert_FWsam] NULL arg!\n");
1007 #endif
1008         return;
1009     }
1010 
1011     /* SnortSam does no IPv6 */
1012     if (!IS_IP4(p)) {
1013 #ifdef FWSAMDEBUG
1014         LogMessage("DEBUG => [Alert_FWsam] not acting on non-IP4 packet!\n");
1015 #endif
1016         return;
1017     }
1018 
1019     optp=NULL;
1020     sn = GetSigByGidSid(ntohl(((Unified2EventCommon *)event)->generator_id),
1021                         ntohl(((Unified2EventCommon *)event)->signature_id),
1022 			ntohl(((Unified2EventCommon *)event)->signature_revision));
1023 
1024     cn = ClassTypeLookupById(barnyard2_conf, ntohl(((Unified2EventCommon *)event)->classification_id));
1025 
1026     if(FWsamOptionField)            /* If using the file (field present), let's use that */
1027         optp=FWsamGetOption(ntohl(((Unified2EventCommon *)event)->signature_id));
1028 
1029     if(optp)    /* if options specified for this rule */
1030     {
1031         if(!btime)          /* if this is the first time this function is */
1032         {
1033             for(i=0;i<FWSAM_REPET_BLOCKS;i++)   /*  called, reset the time and protocol to 0. */
1034             {
1035                 lastbproto[i]=0;
1036                 lastbtime[i]=0;
1037             }
1038         }
1039 
1040         fwsamlist=(FWsamList *)arg;
1041 
1042 #ifdef FWSAMDEBUG
1043         LogMessage("DEBUG => [Alert_FWsam] Alert -> Msg=\"%s\"\n",sn->msg);
1044         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);
1045 #endif
1046 
1047         len=TRUE;
1048         btime=(unsigned long)time(NULL);    /* get current time */
1049         /* This is a cheap check to see if the blocking request matches any of the previous requests. */
1050         for(i=0; i<FWSAM_REPET_BLOCKS && len; i++)
1051         {
1052             if( ( ( optp->how==FWSAM_HOW_THIS ) ?   /* if blocking mode SERVICE, check for src and dst    */
1053 		  ( lastbsip[i]==(unsigned long)GET_SRC_IP(p) && lastbdip[i]==(unsigned long)GET_DST_IP(p) && lastbproto[i]==GET_IPH_PROTO(p) &&
1054 		    ( IP_HAS_PORTS(p) ? /* check port only of TCP or UDP */
1055 /*                  ((optp->who==FWSAM_WHO_SRC)?(lastbsp[i]==record->sp):(lastbdp[i]==record->dp)):TRUE) ): */
1056                         lastbdp[i]==p->dp : TRUE
1057                       )
1058                     ) :
1059                     (
1060                       ( optp->who==FWSAM_WHO_SRC) ?
1061 		      ( lastbsip[i]==(unsigned long)GET_SRC_IP(p) ) :
1062 		      ( lastbdip[i]==(unsigned long)GET_DST_IP(p) )
1063                     )
1064                  ) && /* otherwise if we block source, only compare source. Same for dest. */
1065                  lastbduration[i]==optp->duration &&
1066                  (lastbmode[i] & (FWSAM_HOW|FWSAM_WHO))==(optp->how|optp->who) &&
1067                  ( btime-lastbtime[i]<((optp->duration>FWSAM_REPET_TIME) ? FWSAM_REPET_TIME : optp->duration))
1068                )
1069             {
1070                 len=FALSE;      /* If so, we don't need to block again. */
1071             }
1072         }
1073 
1074         if(len)
1075         {
1076             if(++lastbpointer>=FWSAM_REPET_BLOCKS)      /* increase repetitive check pointer */
1077                 lastbpointer=0;
1078 
1079             lastbsip[lastbpointer]=(unsigned long)GET_SRC_IP(p);     /* and note packet details */
1080             lastbdip[lastbpointer]=(unsigned long)GET_DST_IP(p);
1081             lastbduration[lastbpointer]=optp->duration;
1082             lastbmode[lastbpointer]=optp->how|optp->who|optp->loglevel;
1083             lastbproto[lastbpointer]=GET_IPH_PROTO(p);
1084             if(IP_HAS_PORTS(p))
1085             {
1086                 lastbsp[lastbpointer]=p->sp;                   /* set ports if TCP or UDP */
1087                 lastbdp[lastbpointer]=p->dp;
1088             }
1089             lastbtime[lastbpointer]=btime;
1090 
1091 
1092             while(fwsamlist!=NULL)
1093             {
1094                 station=fwsamlist->station;
1095                 //if(station->stationip.s_addr)
1096                 if(station->stationip.ip32[0])
1097                 {
1098                     deletestation=FALSE;
1099                     stationtry++;               /* first try */
1100                     /* create a socket for the station */
1101                     stationsocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
1102                     if(stationsocket==INVALID_SOCKET)
1103                         FatalError("ERROR => [Alert_FWsam] Funky socket error (socket)!\n");
1104                     if(bind(stationsocket,(struct sockaddr *)&(station->localsocketaddr),sizeof(struct sockaddr)))
1105                         FatalError("ERROR => [Alert_FWsam] Could not bind socket!\n");
1106 
1107                     /* let's connect to the agent */
1108                     if(connect(stationsocket,(struct sockaddr *)&station->stationsocketaddr,sizeof(struct sockaddr)))
1109                     {
1110                         LogMessage("WARNING => [Alert_FWsam] Could not send block to host %s. Will try later.\n",sfip_ntoa(&station->stationip));
1111 #ifdef WIN32
1112                         closesocket(stationsocket);
1113 #else
1114                         close(stationsocket);
1115 #endif
1116                         stationtry=0;
1117                     }
1118                     else
1119                     {
1120 #ifdef FWSAMDEBUG
1121                         LogMessage("DEBUG => [Alert_FWsam] Connected to host %s.\n",sfip_ntoa(&station->stationip));
1122 #endif
1123                         /* now build the packet */
1124                         station->myseqno+=station->stationseqno; /* increase my seqno by adding agent seq no */
1125                         sampacket.endiancheck=1;                        /* This is an endian indicator for Snortsam */
1126                         sampacket.snortseqno[0]=(char)station->myseqno;
1127                         sampacket.snortseqno[1]=(char)(station->myseqno>>8);
1128                         sampacket.fwseqno[0]=(char)station->stationseqno;/* fill station seqno */
1129                         sampacket.fwseqno[1]=(char)(station->stationseqno>>8);
1130                         sampacket.status=FWSAM_STATUS_BLOCK;            /* set block mode */
1131                         sampacket.version=FWSAM_PACKETVERSION;          /* set packet version */
1132                         sampacket.duration[0]=(char)optp->duration;     /* set duration */
1133                         sampacket.duration[1]=(char)(optp->duration>>8);
1134                         sampacket.duration[2]=(char)(optp->duration>>16);
1135                         sampacket.duration[3]=(char)(optp->duration>>24);
1136                         sampacket.fwmode=optp->how|optp->who|optp->loglevel; /* set the mode */
1137                         sampacket.dstip[0]=(char)p->iph->ip_dst.s_addr; /* destination IP */
1138                         sampacket.dstip[1]=(char)(p->iph->ip_dst.s_addr>>8);
1139                         sampacket.dstip[2]=(char)(p->iph->ip_dst.s_addr>>16);
1140                         sampacket.dstip[3]=(char)(p->iph->ip_dst.s_addr>>24);
1141                         sampacket.srcip[0]=(char)p->iph->ip_src.s_addr; /* source IP */
1142                         sampacket.srcip[1]=(char)(p->iph->ip_src.s_addr>>8);
1143                         sampacket.srcip[2]=(char)(p->iph->ip_src.s_addr>>16);
1144                         sampacket.srcip[3]=(char)(p->iph->ip_src.s_addr>>24);
1145                         sampacket.protocol[0]=(char)p->iph->ip_proto;   /* protocol */
1146                         sampacket.protocol[1]=(char)(p->iph->ip_proto>>8);/* protocol */
1147 
1148                         if(IP_HAS_PORTS(p))
1149                         {   sampacket.srcport[0]=(char)p->sp;   /* set ports */
1150                             sampacket.srcport[1]=(char)(p->sp>>8);
1151                             sampacket.dstport[0]=(char)p->dp;
1152                             sampacket.dstport[1]=(char)(p->dp>>8);
1153                         }
1154                         else
1155                             sampacket.srcport[0]=sampacket.srcport[1]=sampacket.dstport[0]=sampacket.dstport[1]=0;
1156 
1157                         uint32_t sig_id = ntohl(((Unified2EventCommon *)event)->signature_id);
1158                         sampacket.sig_id[0]=(char)sig_id;        /* set signature ID */
1159                         sampacket.sig_id[1]=(char)(sig_id>>8);
1160                         sampacket.sig_id[2]=(char)(sig_id>>16);
1161                         sampacket.sig_id[3]=(char)(sig_id>>24);
1162 
1163 #ifdef FWSAMDEBUG
1164                         LogMessage("DEBUG => [Alert_FWsam] Sending BLOCK\n");
1165                         LogMessage("DEBUG => [Alert_FWsam] Snort SeqNo:  %x\n",station->myseqno);
1166                         LogMessage("DEBUG => [Alert_FWsam] Mgmt SeqNo :  %x\n",station->stationseqno);
1167                         LogMessage("DEBUG => [Alert_FWsam] Status     :  %i\n",FWSAM_STATUS_BLOCK);
1168                         LogMessage("DEBUG => [Alert_FWsam] Mode       :  %i\n",optp->how|optp->who|optp->loglevel);
1169                         LogMessage("DEBUG => [Alert_FWsam] Duration   :  %li\n",optp->duration);
1170                         LogMessage("DEBUG => [Alert_FWsam] Protocol   :  %i\n",GET_IPH_PROTO(p));
1171 #ifdef SUP_IP6
1172                         LogMessage("DEBUG => [Alert_FWsam] Src IP     :  %s\n",sfip_ntoa(GET_SRC_IP(p)));
1173                         LogMessage("DEBUG => [Alert_FWsam] Dest IP    :  %s\n",sfip_ntoa(GET_DST_IP(p)));
1174 #else
1175                         LogMessage("DEBUG => [Alert_FWsam] Src IP     :  %s\n",inet_ntoa(GET_SRC_ADDR(p)));
1176                         LogMessage("DEBUG => [Alert_FWsam] Dest IP    :  %s\n",inet_ntoa(GET_DST_ADDR(p)));
1177 #endif
1178                         LogMessage("DEBUG => [Alert_FWsam] Src Port   :  %i\n",p->sp);
1179                         LogMessage("DEBUG => [Alert_FWsam] Dest Port  :  %i\n",p->dp);
1180                         LogMessage("DEBUG => [Alert_FWsam] Sig_ID     :  %lu\n",ntohl(((Unified2EventCommon *)event)->signature_id));
1181 
1182 #endif
1183 
1184                         encbuf=TwoFishAlloc(sizeof(FWsamPacket),FALSE,FALSE,station->stationfish); /* get the encryption buffer */
1185                         len=TwoFishEncrypt((char *)&sampacket,&encbuf,sizeof(FWsamPacket),FALSE,station->stationfish); /* encrypt the packet with current key */
1186 
1187                         if(send(stationsocket,encbuf,len,0)!=len) /* weird...could not send */
1188                         {   LogMessage("WARNING => [Alert_FWsam] Could not send to host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
1189 #ifdef WIN32
1190                             closesocket(stationsocket);
1191 #else
1192                             close(stationsocket);
1193 #endif
1194                             stationtry=0;
1195                         }
1196                         else
1197                         {   i=FWSAM_NETWAIT;
1198 #ifdef WIN32
1199                             ioctlsocket(stationsocket,FIONBIO,&i);  /* set non blocking and wait for  */
1200 #else
1201                             ioctl(stationsocket,FIONBIO,&i);        /* set non blocking and wait for  */
1202 #endif
1203                             while(i-- >1)                           /* the response packet   */
1204                             {   waitms(10); /* wait for response (default maximum 3 secs */
1205                                 if(recv(stationsocket,encbuf,len,0)==len)
1206                                     i=0; /* if we received packet we set the counter to 0. */
1207                                          /* by the time we check with if, it's already dec'ed to -1 */
1208                             }
1209                             if(!i) /* id we timed out (i was one, then dec'ed)... */
1210                             {   LogMessage("WARNING => [Alert_FWsam] Did not receive response from host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
1211 #ifdef WIN32
1212                                 closesocket(stationsocket);
1213 #else
1214                                 close(stationsocket);
1215 #endif
1216                                 stationtry=0;
1217                             }
1218                             else /* got a packet */
1219                             {   decbuf=(char *)&sampacket; /* get the pointer to the packet struct */
1220                                 len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try to decrypt the packet with current key */
1221 
1222                                 if(len!=sizeof(FWsamPacket)) /* invalid decryption */
1223                                 {   strcpy(station->stationkey,station->initialkey); /* try the intial key */
1224                                     TwoFishDestroy(station->stationfish);
1225                                     station->stationfish=TwoFishInit(station->stationkey); /* re-initialize the TwoFish with the intial key */
1226                                     len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try again to decrypt */
1227                                     LogMessage("INFO => [Alert_FWsam] Had to use initial key!\n");
1228                                 }
1229                                 if(len==sizeof(FWsamPacket)) /* valid decryption */
1230                                 {   if(sampacket.version==FWSAM_PACKETVERSION)/* master speaks my language */
1231                                     {   if(sampacket.status==FWSAM_STATUS_OK || sampacket.status==FWSAM_STATUS_NEWKEY
1232                                         || sampacket.status==FWSAM_STATUS_RESYNC || sampacket.status==FWSAM_STATUS_HOLD)
1233                                         {   station->stationseqno=sampacket.fwseqno[0] | (sampacket.fwseqno[1]<<8); /* get stations seqno */
1234                                             station->lastcontact=(unsigned long)time(NULL); /* set the last contact time (not used yet) */
1235 #ifdef FWSAMDEBUG
1236                                     LogMessage("DEBUG => [Alert_FWsam] Received %s\n",sampacket.status==FWSAM_STATUS_OK?"OK":
1237                                                                            sampacket.status==FWSAM_STATUS_NEWKEY?"NEWKEY":
1238                                                                            sampacket.status==FWSAM_STATUS_RESYNC?"RESYNC":
1239                                                                            sampacket.status==FWSAM_STATUS_HOLD?"HOLD":"ERROR");
1240                                     LogMessage("DEBUG => [Alert_FWsam] Snort SeqNo:  %x\n",sampacket.snortseqno[0]|(sampacket.snortseqno[1]<<8));
1241                                     LogMessage("DEBUG => [Alert_FWsam] Mgmt SeqNo :  %x\n",station->stationseqno);
1242                                     LogMessage("DEBUG => [Alert_FWsam] Status     :  %i\n",sampacket.status);
1243                                     LogMessage("DEBUG => [Alert_FWsam] Version    :  %i\n",sampacket.version);
1244 #endif
1245                                             if(sampacket.status==FWSAM_STATUS_HOLD)
1246                                             {   i=FWSAM_NETHOLD;            /* Stay on hold for a maximum of 60 secs (default) */
1247                                                 while(i-- >1)                           /* the response packet   */
1248                                                 {   waitms(10); /* wait for response  */
1249                                                     if(recv(stationsocket,encbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,0)==sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE)
1250                                                       i=0; /* if we received packet we set the counter to 0. */
1251                                                 }
1252                                                 if(!i) /* id we timed out (i was one, then dec'ed)... */
1253                                                 {   LogMessage("WARNING => [Alert_FWsam] Did not receive response from host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
1254                                                     stationtry=0;
1255                                                     sampacket.status=FWSAM_STATUS_ERROR;
1256                                                 }
1257                                                 else /* got a packet */
1258                                                 {   decbuf=(char *)&sampacket; /* get the pointer to the packet struct */
1259                                                     len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try to decrypt the packet with current key */
1260 
1261                                                     if(len!=sizeof(FWsamPacket)) /* invalid decryption */
1262                                                     {   strcpy(station->stationkey,station->initialkey); /* try the intial key */
1263                                                         TwoFishDestroy(station->stationfish);
1264                                                         station->stationfish=TwoFishInit(station->stationkey); /* re-initialize the TwoFish with the intial key */
1265                                                         len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try again to decrypt */
1266                                                         LogMessage("INFO => [Alert_FWsam] Had to use initial key again!\n");
1267                                                     }
1268 #ifdef FWSAMDEBUG
1269                                     LogMessage("DEBUG => [Alert_FWsam] Received %s\n",sampacket.status==FWSAM_STATUS_OK?"OK":
1270                                                                            sampacket.status==FWSAM_STATUS_NEWKEY?"NEWKEY":
1271                                                                            sampacket.status==FWSAM_STATUS_RESYNC?"RESYNC":
1272                                                                            sampacket.status==FWSAM_STATUS_HOLD?"HOLD":"ERROR");
1273                                     LogMessage("DEBUG => [Alert_FWsam] Snort SeqNo:  %x\n",sampacket.snortseqno[0]|(sampacket.snortseqno[1]<<8));
1274                                     LogMessage("DEBUG => [Alert_FWsam] Mgmt SeqNo :  %x\n",station->stationseqno);
1275                                     LogMessage("DEBUG => [Alert_FWsam] Status     :  %i\n",sampacket.status);
1276                                     LogMessage("DEBUG => [Alert_FWsam] Version    :  %i\n",sampacket.version);
1277 #endif
1278                                                     if(len!=sizeof(FWsamPacket)) /* invalid decryption */
1279                                                     {   ErrorMessage("ERROR => [Alert_FWsam] Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1280                                                         deletestation=TRUE;
1281                                                         sampacket.status=FWSAM_STATUS_ERROR;
1282                                                     }
1283                                                     else if(sampacket.version!=FWSAM_PACKETVERSION) /* invalid protocol version */
1284                                                     {   ErrorMessage("ERROR => [Alert_FWsam] Protocol version error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1285                                                         deletestation=TRUE;
1286                                                         sampacket.status=FWSAM_STATUS_ERROR;
1287                                                     }
1288                                                     else if(sampacket.status!=FWSAM_STATUS_OK && sampacket.status!=FWSAM_STATUS_NEWKEY && sampacket.status!=FWSAM_STATUS_RESYNC)
1289                                                     {   ErrorMessage("ERROR => [Alert_FWsam] Funky handshake error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1290                                                         deletestation=TRUE;
1291                                                         sampacket.status=FWSAM_STATUS_ERROR;
1292                                                     }
1293                                                 }
1294                                             }
1295                                             if(sampacket.status==FWSAM_STATUS_RESYNC)  /* if station want's to resync... */
1296                                             {   strcpy(station->stationkey,station->initialkey); /* ...we use the intial key... */
1297                                                 memcpy(station->fwkeymod,sampacket.duration,4);  /* and note the random key modifier */
1298                                             }
1299                                             if(sampacket.status==FWSAM_STATUS_NEWKEY || sampacket.status==FWSAM_STATUS_RESYNC)
1300                                             {
1301                                                 FWsamNewStationKey(station,&sampacket); /* generate new TwoFish keys */
1302 #ifdef FWSAMDEBUG
1303                                                     LogMessage("DEBUG => [Alert_FWsam] Generated new encryption key...\n");
1304 #endif
1305                                             }
1306 #ifdef WIN32
1307                                             closesocket(stationsocket);
1308 #else
1309                                             close(stationsocket);
1310 #endif
1311                                             stationtry=0;
1312                                         }
1313                                         else if(sampacket.status==FWSAM_STATUS_ERROR) /* if SnortSam reports an error on second try, */
1314                                         {
1315 #ifdef WIN32
1316                                             closesocket(stationsocket);               /* something is messed up and ... */
1317 #else
1318                                             close(stationsocket);
1319 #endif
1320                                             if(stationtry>1)                          /* we ignore that station. */
1321                                             {   deletestation=TRUE;                   /* flag for deletion */
1322                                                 ErrorMessage("ERROR => [Alert_FWsam] Could not renegotiate key! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1323                                             }
1324                                             else                            /* if we get an error on the first try, */
1325                                             {   if(!FWsamCheckIn(station))  /* we first try to check in again. */
1326                                                 {   deletestation=TRUE;
1327                                                     ErrorMessage("ERROR => [Alert_FWsam] Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1328                                                 }
1329                                             }
1330                                         }
1331                                         else /* an unknown status means trouble... */
1332                                         {   ErrorMessage("ERROR => [Alert_FWsam] Funky handshake error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1333 #ifdef WIN32
1334                                             closesocket(stationsocket);
1335 #else
1336                                             close(stationsocket);
1337 #endif
1338                                             deletestation=TRUE;
1339                                         }
1340                                     }
1341                                     else   /* if the SnortSam agent uses a different packet version, we have no choice but to ignore it. */
1342                                     {   ErrorMessage("ERROR => [Alert_FWsam] Protocol version error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1343 #ifdef WIN32
1344                                         closesocket(stationsocket);
1345 #else
1346                                         close(stationsocket);
1347 #endif
1348                                         deletestation=TRUE;
1349                                     }
1350                                 }
1351                                 else /* if the intial key failed to decrypt as well, the keys are not configured the same, and we ignore that SnortSam station. */
1352                                 {   ErrorMessage("ERROR => [Alert_FWsam] Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1353 #ifdef WIN32
1354                                     closesocket(stationsocket);
1355 #else
1356                                     close(stationsocket);
1357 #endif
1358                                     deletestation=TRUE;
1359                                 }
1360                             }
1361                         }
1362                         free(encbuf); /* release of the TwoFishAlloc'ed encryption buffer */
1363                     }
1364                     if(stationtry==0 || deletestation)      /* if everything went real well, or real bad... */
1365                     {   if(deletestation){                  /* If it went bad, we remove the station from the list by marking the IP */
1366 //                          station->stationip.s_addr=0;
1367                             station->stationip.ip32[0]=0;
1368                                                 }
1369                         fwsamlist=fwsamlist->next;
1370                     }
1371                 }
1372                 else
1373                     fwsamlist=fwsamlist->next;
1374             }
1375         }
1376         else
1377         {
1378 #ifdef FWSAMDEBUG
1379             LogMessage("DEBUG => [Alert_FWsam] Skipping repetitive block.\n");
1380 #endif
1381         }
1382     }
1383 }
1384 
1385 /*  FWsamCheckOut will be called when Snort exists. It de-registeres this snort sensor
1386  *  from the list of sensor that the SnortSam agent keeps.
1387  */
FWsamCheckOut(FWsamStation * station)1388 void FWsamCheckOut(FWsamStation *station)
1389 {
1390     FWsamPacket sampacket;
1391     int stationsocket;
1392     int i,len;
1393     char *encbuf,*decbuf;
1394 
1395 
1396     stationsocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
1397     if(stationsocket==INVALID_SOCKET)
1398         FatalError("ERROR => [Alert_FWsam](FWsamCheckOut) Funky socket error (socket)!\n");
1399     if(bind(stationsocket,(struct sockaddr *)&(station->localsocketaddr),sizeof(struct sockaddr)))
1400         FatalError("ERROR => [Alert_FWsam](FWsamCheckOut) Could not bind socket!\n");
1401 
1402     /* let's connect to the agent */
1403     if(!connect(stationsocket,(struct sockaddr *)&station->stationsocketaddr,sizeof(struct sockaddr)))
1404     {
1405         LogMessage("INFO => [Alert_FWsam](FWsamCheckOut) Disconnecting from host %s.\n",sfip_ntoa(&station->stationip));
1406         /* now build the packet */
1407         station->myseqno+=station->stationseqno; /* increase my seqno */
1408         sampacket.endiancheck=1;
1409         sampacket.snortseqno[0]=(char)station->myseqno;
1410         sampacket.snortseqno[1]=(char)(station->myseqno>>8);
1411         sampacket.fwseqno[0]=(char)station->stationseqno; /* fill station seqno */
1412         sampacket.fwseqno[1]=(char)(station->stationseqno>>8);
1413         sampacket.status=FWSAM_STATUS_CHECKOUT;  /* checking out... */
1414         sampacket.version=FWSAM_PACKETVERSION;
1415 
1416 #ifdef FWSAMDEBUG
1417             LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Sending CHECKOUT\n");
1418             LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Snort SeqNo:  %x\n",station->myseqno);
1419             LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Mgmt SeqNo :  %x\n",station->stationseqno);
1420             LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Status     :  %i\n",sampacket.status);
1421 
1422 #endif
1423 
1424         encbuf=TwoFishAlloc(sizeof(FWsamPacket),FALSE,FALSE,station->stationfish); /* get encryption buffer */
1425         len=TwoFishEncrypt((char *)&sampacket,&encbuf,sizeof(FWsamPacket),FALSE,station->stationfish); /* encrypt packet with current key */
1426 
1427         if(send(stationsocket,encbuf,len,0)==len)
1428         {
1429             i=FWSAM_NETWAIT;
1430 #ifdef WIN32
1431             ioctlsocket(stationsocket,FIONBIO,&i);  /* set non blocking and wait for  */
1432 #else
1433             ioctl(stationsocket,FIONBIO,&i);        /* set non blocking and wait for  */
1434 #endif
1435             while(i-- >1)
1436             {
1437                 waitms(10);                 /* ...wait a maximum of 3 secs for response... */
1438                 if(recv(stationsocket,encbuf,len,0)==len) /* ... for the status packet */
1439                     i=0;
1440             }
1441 
1442             if(i) /* if we got the packet */
1443             {
1444                 decbuf=(char *)&sampacket;
1445                 len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish);
1446 
1447                 if(len!=sizeof(FWsamPacket)) /* invalid decryption */
1448                 {   strcpy(station->stationkey,station->initialkey); /* try initial key */
1449                     TwoFishDestroy(station->stationfish);            /* toss this fish */
1450                     station->stationfish=TwoFishInit(station->stationkey); /* re-initialze TwoFish with initial key */
1451                     len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* and try to decrypt again */
1452                     LogMessage("INFO => [Alert_FWsam](FWsamCheckOut) Had to use initial key!\n");
1453                 }
1454                 if(len==sizeof(FWsamPacket)) /* valid decryption */
1455                 {   if(sampacket.version!=FWSAM_PACKETVERSION) /* but don't really care since we are on the way out */
1456                         ErrorMessage("WARNING => [Alert_FWsam](FWsamCheckOut) Protocol version error! What the hell, we're quitting anyway! :)\n");
1457                 }
1458                 else
1459                     ErrorMessage("WARNING => [Alert_FWsam](FWsamCheckOut) Password mismatch! What the hell, we're quitting anyway! :)\n");
1460             }
1461         }
1462         free(encbuf); /* release TwoFishAlloc'ed buffer */
1463     }
1464     else
1465         LogMessage("WARNING => [Alert_FWsam] Could not connect to host %s for CheckOut. What the hell, we're quitting anyway! :)\n",sfip_ntoa(&station->stationip));
1466 #ifdef WIN32
1467     closesocket(stationsocket);
1468 #else
1469     close(stationsocket);
1470 #endif
1471 }
1472 
1473 
1474 
1475 /*   FWSamFree: Disconnects all FW-1 management stations,
1476  *   closes sockets, and frees the structures.
1477  */
FWsamFree(FWsamList * list)1478 void FWsamFree(FWsamList *list)
1479 {
1480     FWsamList *next;
1481 
1482     while(list) /* Free pointer list for rule type */
1483     {
1484         next=list->next;
1485         free(list);
1486         list=next;
1487     }
1488     list=FWsamStationList;
1489 
1490     while(list) /* Free global pointer list and stations */
1491     {
1492         next=list->next;
1493         if (list->station)
1494         {
1495             if(list->station->stationip.ip32[0])
1496             //if(list->station->stationip.s_addr)
1497                 FWsamCheckOut(list->station); /* Send a Check-Out to SnortSam, */
1498 
1499             TwoFishDestroy(list->station->stationfish); /* toss the fish, */
1500             free(list->station); /* free station, */
1501         }
1502         free(list); /* free pointer, */
1503         list=next; /* and move to next. */
1504     }
1505     FWsamStationList=NULL;
1506     if(FWsamOptionField)
1507         free(FWsamOptionField);
1508 }
1509 
AlertFWsamCleanExitFunc(int signal,void * arg)1510 void AlertFWsamCleanExitFunc(int signal, void *arg)
1511 {
1512     FWsamList *fwsamlist;
1513 
1514 #ifdef FWSAMDEBUG
1515     LogMessage("DEBUG => [Alert_FWsam](AlertFWsamCleanExitFunc) Exiting...\n");
1516 #endif
1517 
1518     fwsamlist=(FWsamList *)arg;
1519     FWsamFree(fwsamlist); /* Free all elements */
1520 }
1521 
AlertFWsamRestartFunc(int signal,void * arg)1522 void AlertFWsamRestartFunc(int signal, void *arg)
1523 {
1524     FWsamList *fwsamlist;
1525 
1526 #ifdef FWSAMDEBUG
1527     LogMessage("DEBUG => [Alert_FWsam](AlertFWsamRestartFunc) Restarting...\n");
1528 #endif
1529 
1530     fwsamlist=(FWsamList *)arg;
1531     FWsamFree(fwsamlist); /* Free all elements */
1532 }
1533 
1534 /*  This routine registers this Snort sensor with SnortSam.
1535  *  It will also change the encryption key based on some variables.
1536  */
FWsamCheckIn(FWsamStation * station)1537 int FWsamCheckIn(FWsamStation *station)
1538 {
1539     int i,len,stationok=TRUE;
1540     FWsamPacket sampacket;
1541     char *encbuf,*decbuf;
1542     int stationsocket;
1543 
1544 
1545     /* create a socket for the station */
1546     stationsocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
1547 
1548     if(stationsocket==INVALID_SOCKET)
1549         FatalError("ERROR => [Alert_FWsam](FWsamCheckIn) Funky socket error (socket)!\n");
1550     if(bind(stationsocket,(struct sockaddr *)&(station->localsocketaddr),sizeof(struct sockaddr)))
1551         FatalError("ERROR => [Alert_FWsam](FWsamCheckIn) Could not bind socket!\n");
1552 
1553     i=TRUE;
1554     /* let's connect to the agent */
1555     if(connect(stationsocket,(struct sockaddr *)&station->stationsocketaddr,sizeof(struct sockaddr)))
1556         LogMessage("WARNING => [Alert_FWsam](FWsamCheckIn) Could not connect to host %s. Will try later.\n",sfip_ntoa(&station->stationip));
1557     else
1558     {
1559         LogMessage("INFO => [Alert_FWsam](FWsamCheckIn) Connected to host %s.\n",sfip_ntoa(&station->stationip));
1560         /* now build the packet */
1561         sampacket.endiancheck=1;
1562         sampacket.snortseqno[0]=(char)station->myseqno; /* fill my sequence number number */
1563         sampacket.snortseqno[1]=(char)(station->myseqno>>8); /* fill my sequence number number */
1564         sampacket.status=FWSAM_STATUS_CHECKIN; /* let's check in */
1565         sampacket.version=FWSAM_PACKETVERSION; /* set the packet version */
1566         memcpy(sampacket.duration,station->mykeymod,4);  /* we'll send SnortSam our key modifier in the duration slot */
1567                                                /* (the checkin packet is just the plain initial key) */
1568 #ifdef FWSAMDEBUG
1569             LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Sending CheckIn\n");
1570             LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Snort SeqNo:  %x\n",station->myseqno);
1571             LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Mode       :  %i\n",sampacket.status);
1572             LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Version    :  %i\n",sampacket.version);
1573 #endif
1574         encbuf=TwoFishAlloc(sizeof(FWsamPacket),FALSE,FALSE,station->stationfish); /* get buffer for encryption */
1575         len=TwoFishEncrypt((char *)&sampacket,&encbuf,sizeof(FWsamPacket),FALSE,station->stationfish); /* encrypt with initial key */
1576         if(send(stationsocket,encbuf,len,0)!=len) /* weird...could not send */
1577             LogMessage("WARNING => [Alert_FWsam](FWsamCheckIn) Could not send to host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
1578         else
1579         {
1580             i=FWSAM_NETWAIT;
1581 #ifdef WIN32
1582             ioctlsocket(stationsocket,FIONBIO,&i);  /* set non blocking and wait for  */
1583 #else
1584             ioctl(stationsocket,FIONBIO,&i);        /* set non blocking and wait for  */
1585 #endif
1586             while(i-- >1)
1587             {
1588                 waitms(10); /* wait a maximum of 3 secs for response */
1589                 if(recv(stationsocket,encbuf,len,0)==len)
1590                     i=0;
1591             }
1592             if(!i) /* time up? */
1593                 LogMessage("WARNING => [Alert_FWsam](FWsamCheckIn) Did not receive response from host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
1594             else
1595             {
1596                 decbuf=(char *)&sampacket; /* got status packet */
1597                 len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try to decrypt with initial key */
1598                 if(len==sizeof(FWsamPacket)) /* valid decryption */
1599                 {
1600 #ifdef FWSAMDEBUG
1601                     LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Received %s\n",sampacket.status==FWSAM_STATUS_OK?"OK":
1602                                                                sampacket.status==FWSAM_STATUS_NEWKEY?"NEWKEY":
1603                                                                sampacket.status==FWSAM_STATUS_RESYNC?"RESYNC":
1604                                                                sampacket.status==FWSAM_STATUS_HOLD?"HOLD":"ERROR");
1605                     LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Snort SeqNo:  %x\n",sampacket.snortseqno[0]|(sampacket.snortseqno[1]<<8));
1606                     LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Mgmt SeqNo :  %x\n",sampacket.fwseqno[0]|(sampacket.fwseqno[1]<<8));
1607                     LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Status     :  %i\n",sampacket.status);
1608                     LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Version    :  %i\n",sampacket.version);
1609 #endif
1610                     if(sampacket.version==FWSAM_PACKETVERSION) /* master speaks my language */
1611                     {
1612                         if(sampacket.status==FWSAM_STATUS_OK || sampacket.status==FWSAM_STATUS_NEWKEY || sampacket.status==FWSAM_STATUS_RESYNC)
1613                         {
1614                             station->stationseqno=sampacket.fwseqno[0]|(sampacket.fwseqno[1]<<8); /* get stations seqno */
1615                             station->lastcontact=(unsigned long)time(NULL);
1616 
1617                             if(sampacket.status==FWSAM_STATUS_NEWKEY || sampacket.status==FWSAM_STATUS_RESYNC)  /* generate new keys */
1618                             {
1619                                 memcpy(station->fwkeymod,sampacket.duration,4); /* note the key modifier */
1620                                 FWsamNewStationKey(station,&sampacket); /* and generate new TwoFish keys (with key modifiers) */
1621 #ifdef FWSAMDEBUG
1622                 LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Generated new encryption key...\n");
1623 #endif
1624                             }
1625                         }
1626                         else /* weird, got a strange status back */
1627                         {
1628                             ErrorMessage("ERROR => [Alert_FWsam](FWsamCheckIn) Funky handshake error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1629                             stationok=FALSE;
1630                         }
1631                     }
1632                     else /* packet version does not match */
1633                     {
1634                         ErrorMessage("ERROR =>[Alert_FWsam](FWsamCheckIn) Protocol version error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1635                         stationok=FALSE;
1636                     }
1637                 }
1638                 else /* key does not match */
1639                 {
1640                     ErrorMessage("ERROR => [Alert_FWsam](FWsamCheckIn) Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
1641                     stationok=FALSE;
1642                 }
1643             }
1644         }
1645         free(encbuf); /* release TwoFishAlloc'ed buffer */
1646     }
1647 #ifdef WIN32
1648     closesocket(stationsocket);
1649 #else
1650     close(stationsocket);
1651 #endif
1652     return stationok;
1653 }
1654 #undef FWSAMDEBUG
1655 
1656