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