new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / analysisd / decoders / plugins / sonicwall_decoder.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All rights reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation.
8  */
9
10 #include "../plugin_decoders.h"
11
12 #include "shared.h"
13 #include "eventinfo.h"
14
15 /* Regex to extract the priority and event id */
16 #define SONICWALL_REGID  "pri=(\\d) c=(\\d+) m=(\\d+) "
17
18 /* Regex to extract the srcip and dst ip */
19 #define SONICWALL_REGEX "src=(\\d+.\\d+.\\d+.\\d+):(\\d+):\\S+ " \
20                         "dst=(\\d+.\\d+.\\d+.\\d+):(\\d+):"
21
22 /* Regex for the web proxy messages */
23 #define SONICWALL_PROXY "result=(\\d+) dstname=(\\S+) arg=(\\S+)$"
24
25 /* Global variables -- not thread safe. If we ever multi thread
26  * analysisd, these will need to be changed.
27  */
28 static OSRegex *__sonic_regex_prid = NULL;
29 static OSRegex *__sonic_regex_sdip = NULL;
30 static OSRegex *__sonic_regex_prox = NULL;
31
32
33 void *SonicWall_Decoder_Init()
34 {
35     debug1("%s: Initializing SonicWall decoder..", ARGV0);
36
37     /* Allocate memory */
38     os_calloc(1, sizeof(OSRegex), __sonic_regex_sdip);
39     os_calloc(1, sizeof(OSRegex), __sonic_regex_prid);
40     os_calloc(1, sizeof(OSRegex), __sonic_regex_prox);
41
42     /* Compile our regexes */
43     if (!OSRegex_Compile(SONICWALL_REGEX, __sonic_regex_sdip, OS_RETURN_SUBSTRING)) {
44         merror(REGEX_COMPILE, ARGV0, SONICWALL_REGEX, __sonic_regex_sdip->error);
45         return (0);
46     }
47     if (!OSRegex_Compile(SONICWALL_REGID, __sonic_regex_prid, OS_RETURN_SUBSTRING)) {
48         merror(REGEX_COMPILE, ARGV0, SONICWALL_REGID, __sonic_regex_prid->error);
49         return (0);
50     }
51     if (!OSRegex_Compile(SONICWALL_PROXY, __sonic_regex_prox, OS_RETURN_SUBSTRING)) {
52         merror(REGEX_COMPILE, ARGV0, SONICWALL_PROXY, __sonic_regex_prox->error);
53         return (0);
54     }
55
56     /* We must have the sub_strings to retrieve the nodes */
57     if (!__sonic_regex_sdip->sub_strings) {
58         merror(REGEX_SUBS, ARGV0, SONICWALL_REGEX);
59         return (0);
60     }
61     if (!__sonic_regex_prid->sub_strings) {
62         merror(REGEX_SUBS, ARGV0, SONICWALL_REGID);
63         return (0);
64     }
65     if (!__sonic_regex_prox->sub_strings) {
66         merror(REGEX_SUBS, ARGV0, SONICWALL_PROXY);
67         return (0);
68     }
69
70     /* There is nothing else to do over here */
71     return (NULL);
72 }
73
74 /* SonicWall decoder
75  * Will extract the id, severity, action, srcip, dstip, protocol,srcport,dstport
76  * severity will be extracted as status.
77  * Examples:
78  * 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
79  * 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
80  */
81 void *SonicWall_Decoder_Exec(Eventinfo *lf)
82 {
83     int i = 0;
84     char category[8];
85     const char *tmp_str = NULL;
86
87     /* Zero category */
88     category[0] = '\0';
89     lf->decoder_info->type = SYSLOG;
90
91     /* First run regex to extract the severity, cat and id */
92     if (!(tmp_str = OSRegex_Execute(lf->log, __sonic_regex_prid))) {
93         return (NULL);
94     }
95
96     /* Get severity, id and category */
97     if (__sonic_regex_prid->sub_strings[0] &&
98             __sonic_regex_prid->sub_strings[1] &&
99             __sonic_regex_prid->sub_strings[2]) {
100         lf->status = __sonic_regex_prid->sub_strings[0];
101         lf->id = __sonic_regex_prid->sub_strings[2];
102
103         /* Get category */
104         strncpy(category, __sonic_regex_prid->sub_strings[1], 7);
105
106         /* Clear all substrings */
107         __sonic_regex_prid->sub_strings[0] = NULL;
108         __sonic_regex_prid->sub_strings[2] = NULL;
109
110         free(__sonic_regex_prid->sub_strings[1]);
111         __sonic_regex_prid->sub_strings[1] = NULL;
112     } else {
113         i = 0;
114         while (__sonic_regex_prid->sub_strings[i]) {
115             free(__sonic_regex_prid->sub_strings[i]);
116             __sonic_regex_prid->sub_strings[i] = NULL;
117             i++;
118         }
119
120         return (NULL);
121     }
122
123     /* Get ips and ports */
124     if (!(tmp_str = OSRegex_Execute(tmp_str, __sonic_regex_sdip))) {
125         return (NULL);
126     }
127     if (__sonic_regex_sdip->sub_strings[0] &&
128             __sonic_regex_sdip->sub_strings[1] &&
129             __sonic_regex_sdip->sub_strings[2] &&
130             __sonic_regex_sdip->sub_strings[3]) {
131         /* Set all the values */
132         lf->srcip = __sonic_regex_sdip->sub_strings[0];
133         lf->srcport = __sonic_regex_sdip->sub_strings[1];
134         lf->dstip = __sonic_regex_sdip->sub_strings[2];
135         lf->dstport = __sonic_regex_sdip->sub_strings[3];
136
137         /* Clear substrings */
138         __sonic_regex_sdip->sub_strings[0] = NULL;
139         __sonic_regex_sdip->sub_strings[1] = NULL;
140         __sonic_regex_sdip->sub_strings[2] = NULL;
141         __sonic_regex_sdip->sub_strings[3] = NULL;
142
143         /* Look for protocol */
144         tmp_str = strchr(tmp_str, ' ');
145         if (tmp_str) {
146             tmp_str++;
147             if (strncmp(tmp_str, "proto=", 6) == 0) {
148                 char *proto = NULL;
149
150                 i = 0;
151                 tmp_str += 6;
152
153                 /* Allocate memory for the protocol */
154                 os_calloc(8, sizeof(char), proto);
155                 while (isValidChar(*tmp_str) && (*tmp_str != '/')) {
156                     proto[i] = *tmp_str;
157                     i++;
158                     tmp_str++;
159
160                     if (i >= 6) {
161                         break;
162                     }
163                 }
164
165                 /* Set protocol to event info structure */
166                 lf->protocol = proto;
167             }
168         }
169     } else {
170         i = 0;
171         while (__sonic_regex_sdip->sub_strings[i]) {
172             free(__sonic_regex_sdip->sub_strings[i]);
173             __sonic_regex_sdip->sub_strings[i] = 0;
174             i++;
175         }
176
177         return (NULL);
178     }
179
180     /* Set the category/action based on the id */
181
182     /* IDS event */
183     if (strcmp(category, "32") == 0) {
184         lf->decoder_info->type = IDS;
185     }
186
187     /* Firewall connection opened */
188     else if ((strcmp(lf->id, "98") == 0) ||
189              (strcmp(lf->id, "597") == 0) ||
190              (strcmp(lf->id, "598") == 0)) {
191         lf->decoder_info->type = FIREWALL;
192         os_strdup("pass", lf->action);
193     }
194
195     /* Firewall connection dropped */
196     else if ((strcmp(lf->id, "38") == 0) ||
197              (strcmp(lf->id, "36") == 0) ||
198              (strcmp(lf->id, "173") == 0) ||
199              (strcmp(lf->id, "174") == 0) ||
200              (strcmp(lf->id, "37") == 0)) {
201         lf->decoder_info->type = FIREWALL;
202         os_strdup("drop", lf->action);
203     }
204
205     /* Firewall connection closed */
206     else if (strcmp(lf->id, "537") == 0) {
207         lf->decoder_info->type = FIREWALL;
208         os_strdup("close", lf->action);
209     }
210
211     /* Proxy msg */
212     else if (strcmp(lf->id, "97") == 0) {
213         lf->decoder_info->type = SQUID;
214
215         /* Check if tmp_str is valid */
216         if (!tmp_str) {
217             return (NULL);
218         }
219
220         /* First run regex to extract the severity and id */
221         if (!OSRegex_Execute(tmp_str, __sonic_regex_prox)) {
222             return (NULL);
223         }
224
225         /* Get HTTP responde code as id */
226         if (__sonic_regex_prox->sub_strings[0]) {
227             free(lf->id);
228             lf->id = __sonic_regex_prox->sub_strings[0];
229             __sonic_regex_prox->sub_strings[0] = NULL;
230         } else {
231             return (NULL);
232         }
233
234         /* Get HTTP page */
235         if (__sonic_regex_prox->sub_strings[1] &&
236                 __sonic_regex_prox->sub_strings[2]) {
237             char *final_url;
238             size_t url_size = strlen(__sonic_regex_prox->sub_strings[1]) +
239                            strlen(__sonic_regex_prox->sub_strings[2]) + 2;
240
241             os_calloc(url_size + 1, sizeof(char), final_url);
242             snprintf(final_url, url_size, "%s%s",
243                      __sonic_regex_prox->sub_strings[1],
244                      __sonic_regex_prox->sub_strings[2]);
245
246
247             /* Clear memory */
248             free(__sonic_regex_prox->sub_strings[1]);
249             free(__sonic_regex_prox->sub_strings[2]);
250             __sonic_regex_prox->sub_strings[1] = NULL;
251             __sonic_regex_prox->sub_strings[2] = NULL;
252
253             /* Set the URL */
254             lf->url = final_url;
255         } else {
256             merror("%s: Error getting regex - SonicWall." , ARGV0);
257         }
258
259         return (NULL);
260     }
261
262     return (NULL);
263 }
264