56c41a47a442da8731d95a923578c69037c526b0
[ossec-hids.git] / src / analysisd / decoders / plugins / sonicwall_decoder.c
1 /* @(#) $Id$ */
2
3 /* Copyright (C) 2009 Trend Micro Inc.
4  * All rights reserved.
5  *
6  * This program is a free software; you can redistribute it
7  * and/or modify it under the terms of the GNU General Public
8  * License (version 2) as published by the FSF - Free Software
9  * Foundation.
10  *
11  * License details at the LICENSE file included with OSSEC or 
12  * online at: http://www.ossec.net/en/licensing.html
13  */
14
15
16 #include "shared.h"
17 #include "eventinfo.h"
18
19
20 /* Regex to extract the priority and event id */
21 #define SONICWALL_REGID  "pri=(\\d) c=(\\d+) m=(\\d+) "
22
23 /* Regex to extract the srcip and dst ip */
24 #define SONICWALL_REGEX "src=(\\d+.\\d+.\\d+.\\d+):(\\d+):\\S+ " \
25                         "dst=(\\d+.\\d+.\\d+.\\d+):(\\d+):"
26
27 /* Regex for the web proxy messages */
28 #define SONICWALL_PROXY "result=(\\d+) dstname=(\\S+) arg=(\\S+)$"
29
30
31
32 /** Global variables -- not thread safe. If we ever multi thread
33  * analysisd, these will need to be changed.
34  */                        
35 OSRegex *__sonic_regex_prid = NULL;
36 OSRegex *__sonic_regex_sdip = NULL;
37 OSRegex *__sonic_regex_prox = NULL;
38
39
40
41 /* SonicWall decoder init */
42 void *SonicWall_Decoder_Init()
43 {
44     debug1("%s: Initializing SonicWall decoder..", ARGV0);
45
46
47     /* Allocating memory */
48     os_calloc(1, sizeof(OSRegex), __sonic_regex_sdip);
49     os_calloc(1, sizeof(OSRegex), __sonic_regex_prid);
50     os_calloc(1, sizeof(OSRegex), __sonic_regex_prox);
51
52     /* Compiling our regexes */
53     if(!OSRegex_Compile(SONICWALL_REGEX, __sonic_regex_sdip, OS_RETURN_SUBSTRING))
54     {
55         merror(REGEX_COMPILE, ARGV0, SONICWALL_REGEX, __sonic_regex_sdip->error);
56         return(0);
57     }
58     if(!OSRegex_Compile(SONICWALL_REGID, __sonic_regex_prid, OS_RETURN_SUBSTRING))
59     {
60         merror(REGEX_COMPILE, ARGV0, SONICWALL_REGID, __sonic_regex_prid->error);
61         return(0);
62     }
63     if(!OSRegex_Compile(SONICWALL_PROXY, __sonic_regex_prox, OS_RETURN_SUBSTRING))
64     {
65         merror(REGEX_COMPILE, ARGV0, SONICWALL_PROXY, __sonic_regex_prox->error);
66         return(0);
67     }
68
69     /* We must have the sub_strings to retrieve the nodes */
70     if(!__sonic_regex_sdip->sub_strings)
71     {
72         merror(REGEX_SUBS, ARGV0, SONICWALL_REGEX);
73         return(0);
74     }
75     if(!__sonic_regex_prid->sub_strings)
76     {
77         merror(REGEX_SUBS, ARGV0, SONICWALL_REGID);
78         return(0);
79     }
80     if(!__sonic_regex_prox->sub_strings)
81     {
82         merror(REGEX_SUBS, ARGV0, SONICWALL_PROXY);
83         return(0);
84     }
85
86     /* There is nothing else to do over here */
87     return(NULL);
88 }
89
90
91
92 /* SonicWall decoder 
93  * Will extract the id, severity, action, srcip, dstip, protocol,srcport,dstport
94  * severity will be extracted as status.
95  * Examples:
96  * Jan  3 13:45:36 192.168.5.1 id=firewall sn=000SERIAL time="2007-01-03 14:48:06" fw=1.1.1.1 pri=6 c=262144 m=98 msg="Connection Opened" n=23419 src=2.2.2.2:36701:WAN dst=1.1.1.1:50000:WAN proto=tcp/50000
97  * Jan  3 13:45:36 192.168.5.1 id=firewall sn=000SERIAL time="2007-01-03 14:48:07" fw=1.1.1.1 pri=1 c=32 m=30 msg="Administrator login denied due to bad credentials" n=7 src=2.2.2.2:36701:WAN dst=1.1.1.1:50000:WAN
98  */                             
99 void *SonicWall_Decoder_Exec(Eventinfo *lf)
100 {
101     int i = 0;
102     char category[8];
103     char *tmp_str = NULL;
104
105
106     /* Zeroing category */
107     category[0] = '\0';
108     lf->decoder_info->type = SYSLOG;
109     
110     
111     
112     /** We first run our regex to extract the severity, cat and id. **/
113     if(!(tmp_str = OSRegex_Execute(lf->log, __sonic_regex_prid)))
114     {
115         return(NULL);
116     }
117
118     /* Getting severity, id and category */
119     if(__sonic_regex_prid->sub_strings[0] &&
120        __sonic_regex_prid->sub_strings[1] &&
121        __sonic_regex_prid->sub_strings[2])
122     {
123         lf->status = __sonic_regex_prid->sub_strings[0];
124         lf->id = __sonic_regex_prid->sub_strings[2];
125
126
127         /* Getting category */
128         strncpy(category, __sonic_regex_prid->sub_strings[1], 7);
129
130
131         /* Clearing all substrings */
132         __sonic_regex_prid->sub_strings[0] = NULL;
133         __sonic_regex_prid->sub_strings[2] = NULL;
134         
135         free(__sonic_regex_prid->sub_strings[1]);
136         __sonic_regex_prid->sub_strings[1] = NULL;
137     }
138     else
139     {
140         i = 0;
141         while(__sonic_regex_prid->sub_strings[i])
142         {
143             free(__sonic_regex_prid->sub_strings[i]);
144             __sonic_regex_prid->sub_strings[i] = NULL;
145             i++;
146         }
147
148         return(NULL);
149     }
150
151
152
153
154     /** Getting ips and ports **/
155     if(!(tmp_str = OSRegex_Execute(tmp_str, __sonic_regex_sdip)))
156     {
157         return(NULL);
158     }
159     if(__sonic_regex_sdip->sub_strings[0] && 
160        __sonic_regex_sdip->sub_strings[1] && 
161        __sonic_regex_sdip->sub_strings[2] && 
162        __sonic_regex_sdip->sub_strings[3])
163     {
164         /* Setting all the values */
165         lf->srcip = __sonic_regex_sdip->sub_strings[0];
166         lf->srcport = __sonic_regex_sdip->sub_strings[1];
167         lf->dstip = __sonic_regex_sdip->sub_strings[2];
168         lf->dstport = __sonic_regex_sdip->sub_strings[3];
169
170
171         /* Clearing substrings */
172         __sonic_regex_sdip->sub_strings[0] = NULL;
173         __sonic_regex_sdip->sub_strings[1] = NULL;
174         __sonic_regex_sdip->sub_strings[2] = NULL;
175         __sonic_regex_sdip->sub_strings[3] = NULL;
176
177
178         /* Looking for protocol */
179         tmp_str = strchr(tmp_str, ' ');
180         if(tmp_str)
181         {
182             tmp_str++;
183             if(strncmp(tmp_str, "proto=", 6) == 0)
184             {
185                 char *proto = NULL;
186
187                 i = 0;
188                 tmp_str += 6;
189                 
190
191                 /* Allocating memory for the protocol */
192                 os_calloc(8, sizeof(char), proto);
193                 while(isValidChar(*tmp_str) && (*tmp_str != '/'))
194                 {
195                     proto[i] = *tmp_str;
196                     i++;
197                     tmp_str++;
198
199                     if(i >= 6)
200                     {
201                         break;
202                     }
203                 }
204
205                 /* Setting protocol to event info structure */
206                 lf->protocol = proto;
207             }
208         }
209     }
210     else
211     {
212         i = 0;
213         while(__sonic_regex_sdip->sub_strings[i])
214         {
215             free(__sonic_regex_sdip->sub_strings[i]);
216             __sonic_regex_sdip->sub_strings[i] = 0;
217             i++;
218         }
219
220         return(NULL);
221     }
222
223
224
225     
226     /** Setting the category/action based on the id. **/
227
228     /* IDS event */
229     if(strcmp(category, "32") == 0)
230     {
231         lf->decoder_info->type = IDS;
232     }
233     
234     /* Firewall connection opened */
235     else if((strcmp(lf->id, "98") == 0) ||
236             (strcmp(lf->id, "597") == 0) || 
237             (strcmp(lf->id, "598") == 0)) 
238     {
239         lf->decoder_info->type = FIREWALL;
240         os_strdup("pass", lf->action); 
241     }
242     
243     /* Firewall connection dropped */
244     else if((strcmp(lf->id, "38") == 0) ||
245             (strcmp(lf->id, "36") == 0) ||
246             (strcmp(lf->id, "173") == 0) ||
247             (strcmp(lf->id, "174") == 0) ||
248             (strcmp(lf->id, "37") == 0))
249     {
250         lf->decoder_info->type = FIREWALL;
251         os_strdup("drop", lf->action); 
252     }
253     
254     /* Firewall connection closed */
255     else if(strcmp(lf->id, "537") == 0)
256     {
257         lf->decoder_info->type = FIREWALL;
258         os_strdup("close", lf->action);
259     }
260     
261     /* Proxy msg */
262     else if(strcmp(lf->id, "97") == 0)
263     {
264         lf->decoder_info->type = SQUID;
265
266
267         /* Checking if tmp_str is valid */
268         if(!tmp_str)
269         {
270             return(NULL);
271         }
272         
273
274         /* We first run our regex to extract the severity and id. */
275         if(!OSRegex_Execute(tmp_str, __sonic_regex_prox))
276         {
277             return(NULL);
278         }
279
280
281         /* Getting HTTP responde code as id */
282         if(__sonic_regex_prox->sub_strings[0])
283         {
284             free(lf->id);
285             lf->id = __sonic_regex_prox->sub_strings[0];
286             __sonic_regex_prox->sub_strings[0] = NULL;
287         }
288         else
289         {
290             return(NULL);
291         }
292         
293
294         /* Getting HTTP page */
295         if(__sonic_regex_prox->sub_strings[1] && 
296            __sonic_regex_prox->sub_strings[2])
297         {
298             char *final_url;
299             int url_size = strlen(__sonic_regex_prox->sub_strings[1]) +
300                            strlen(__sonic_regex_prox->sub_strings[2]) + 2;
301             
302             os_calloc(url_size +1, sizeof(char), final_url);
303             snprintf(final_url, url_size, "%s%s", 
304                                 __sonic_regex_prox->sub_strings[1],
305                                 __sonic_regex_prox->sub_strings[2]);
306
307
308             /* Clearing the memory */
309             free(__sonic_regex_prox->sub_strings[1]);
310             free(__sonic_regex_prox->sub_strings[2]);
311             __sonic_regex_prox->sub_strings[1] = NULL;
312             __sonic_regex_prox->sub_strings[2] = NULL;
313
314
315             /* Setting the url */
316             lf->url = final_url;
317         }
318         else
319         {
320             merror("%s: Error getting regex - SonicWall." , ARGV0);
321         }
322
323         return(NULL);
324     }
325
326     
327     return(NULL);
328 }
329
330 /* END Decoder */