1 /* $Id: ssp_wgrd.c,v 2.7 2009/11/08 22:35:58 fknobbe Exp $
2  *
3  *
4  * Copyright (c) 2003-2008 Thomas Maier <thomas.maier@arcos.de>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  *
29  * ssp_wgrd.c
30  *
31  * Purpose:
32  *
33  * This SnortSam plugin is for Watchguard firewalls,
34  *
35  * To use this plugin you will have to get a piece of software from
36  * watchguard called fbidsmate, which is a commandline tool which we
37  * use to initiate the block, since the communication to the firebox
38  * is proprietary and watchguard do not want to let us know how it
39  * works.
40  *
41  * SnortSam can not expire the blocks since the fbidsmate of Watchguard
42  * has no unblock functionality. The duration of the block can be defined
43  * in the Policy Manager of the watchguard firebox under
44  * Setup/Blocked Sites/Duration for Auto-Blocked Sites.
45  *
46  */
47 
48 
49 #ifndef		__SSP_WGRD_C__
50 #define		__SSP_WGRD_C__
51 
52 
53 #include "snortsam.h"
54 #include "ssp_wgrd.h"
55 
56 
57 #include <sys/types.h>
58 #include <stdio.h>
59 #include <string.h>
60 #include <time.h>
61 #ifdef WIN32
62 #include <winsock.h>
63 #else
64 #include <netinet/in.h>
65 #include <arpa/inet.h>
66 #endif
67 
68 /* This routine parses the wgrd statements in the config file.
69 */
WGRDParse(char * val,char * file,unsigned long line,DATALIST * plugindatalist)70 void WGRDParse(char *val,char *file,unsigned long line,DATALIST *plugindatalist) {
71   WGRDDATA *wgrdp=NULL;
72   char *p2, msg[STRBUFSIZE+2];
73   struct in_addr nsip;
74 #ifdef FWSAMDEBUG
75   printf("Debug: [wgrd] Plugin Parsing...\n");
76 #endif
77   if(*val) {
78     char *cmd;
79     p2=val;
80     while(*p2 && !myisspace(*p2))   /* parse command */
81       p2++;
82     if(*p2)
83       *p2++ =0;
84     cmd=val;
85     val=p2;
86     while(*val && myisspace(*val))          /* skip spaces */
87       val++;
88     p2=val;
89     while(*p2 && !myisspace(*p2))
90       p2++;
91     if(*p2)
92       *p2++ =0;
93     nsip.s_addr=getip(val);
94     if(nsip.s_addr) {                 /* If we have a valid IP address */
95       wgrdp=safemalloc(sizeof(WGRDDATA),"WGRDParse","wgrdp");	/* create new watchguard */
96       plugindatalist->data=wgrdp;
97       wgrdp->ip_addr.s_addr=nsip.s_addr;
98       safecopy(wgrdp->command,cmd);     /* save command */
99       wgrdp->passphrase[0]=0;
100       wgrdp->passphrasefile[0]=0;
101       val=p2;
102       while(*val && myisspace(*val))          /* skip spaces */
103         val++;
104       if(*val) {
105         p2=val;
106         while(*p2 && !myisspace(*p2))   /* parse passphrase */
107           p2++;
108         if(*p2)
109           *p2++ =0;
110         safecopy(wgrdp->passphrase,val);     /* save passphrase */
111         if(*p2) {                                      /* if we have a pass file */
112           val=p2;
113           while(*val && myisspace(*val))          /* skip spaces */
114             val++;
115           if(*val) {
116             p2=val;
117             while(*p2 && !myisspace(*p2))   /* parse it */
118               p2++;
119             if(*p2)
120               *p2++ =0;
121             safecopy(wgrdp->passphrasefile,val);     /* save passwordfile */
122             wgrdp->passphrase[0]=0;		  /* erase passphrase */
123           }
124         }
125       }
126       if(!wgrdp->passphrase[0] && !wgrdp->passphrasefile[0] ) {
127         snprintf(msg,sizeof(msg)-1,"Error: [%s: %lu] Watchguard defined without login possibility!",file,line);
128         logmessage(1,msg,"wgrd",0);
129         free(wgrdp);
130         plugindatalist->data=NULL;
131 #ifdef FWSAMDEBUG
132       } else {
133         printf("Debug: [wgrd] Adding Watchguard: CMD \"%s\", IP \"%s\", PP \"%s\", PPF \"%s\"\n", wgrdp->command ,inettoa( wgrdp->ip_addr.s_addr),wgrdp->passphrase,wgrdp->passphrasefile);
134 #endif
135       }
136     } else {
137       snprintf(msg,sizeof(msg)-1,"Error: [%s: %lu] Invalid Watchguard parameter '%s' ignored.",file,line,val);
138       logmessage(1,msg,"wgrd",0);
139     }
140   } else {
141     snprintf(msg,sizeof(msg)-1,"Error: [%s: %lu] Empty Watchguard parameter.",file,line);
142     logmessage(1,msg,"wgrd",0);
143   }
144 }
145 
146 
147 /* This routine initiates the block.
148  */
WGRDBlock(BLOCKINFO * bd,void * data,unsigned long qp)149 void WGRDBlock(BLOCKINFO *bd,void *data,unsigned long qp)
150 {
151   char wgrdcmd[255], msg[STRBUFSIZE+2];
152   char *wgexecp = "fbidsmate";
153   WGRDDATA *wgrdp = (WGRDDATA *)data;
154 #ifdef FWSAMDEBUG
155 #ifdef WIN32
156   unsigned long threadid=GetCurrentThreadId();
157 #else
158   pthread_t threadid=pthread_self();
159 #endif
160 #endif
161   if(!wgrdp) return;
162   if(wgrdp->command)
163     wgexecp=wgrdp->command;
164 #ifdef FWSAMDEBUG
165 	printf("Debug: [wgrd][%lx] Plugin Blocking...\n",(unsigned long)threadid);
166 #endif
167   if(bd->block) {
168     snprintf(msg,sizeof(msg)-1,"Info: Blocking ip %s", inettoa(bd->blockip));
169     logmessage(1,msg,"wgrd",0);
170     /* Assemble command 2 possibilities with passphrase or with passphrasefile */
171     if ( *(wgrdp->passphrase) ) {
172       if (snprintf(wgrdcmd,sizeof(wgrdcmd)-1, "%s %s %s add_hostile %s", wgexecp, inettoa( wgrdp->ip_addr.s_addr), wgrdp->passphrase, inettoa(bd->blockip)) >= 255) {
173         snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", wgrdcmd);
174         logmessage(1,msg,"wgrd",0);
175         return;
176       }
177     } else {
178       if (snprintf(wgrdcmd,sizeof(wgrdcmd)-1, "%s %s -f %s add_hostile %s", wgexecp, inettoa( wgrdp->ip_addr.s_addr), wgrdp->passphrasefile, inettoa(bd->blockip)) >= 255) {
179         snprintf(msg,sizeof(msg)-1,"Error: Command %s is too long", wgrdcmd);
180         logmessage(1,msg,"wgrd",0);
181         return;
182       }
183     }
184   } else {
185     snprintf(msg,sizeof(msg)-1,"Info: UnBlocking ip %s not supported", inettoa(bd->blockip));
186     logmessage(3,msg,"wgrd",0);
187   }
188 #ifdef FWSAMDEBUG
189   printf("Debug: [wgrd][%lx] command %s\n", (unsigned long)threadid, wgrdcmd);
190 #endif
191   /* Run the command */
192   if (system(wgrdcmd) != 0) {
193     snprintf(msg,sizeof(msg)-1,"Error: Command %s Failed", wgrdcmd);
194     logmessage(1,msg,"wgrd",0);
195   } else {
196     snprintf(msg,sizeof(msg)-1,"Info: Command %s Executed Successfully", wgrdcmd);
197     logmessage(3,msg,"wgrd",0);
198   }
199   return;
200 }
201 
202 #endif /* __SSP_WGRD_C__ */
203