1 /* Copyright (C) 2009 Trend Micro Inc.
2 * All right 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 "shared.h"
11 #include "log.h"
12 #include "alerts.h"
13 #include "getloglocation.h"
14 #include "rules.h"
15 #include "eventinfo.h"
16 #include "config.h"
17
18
19 /* Drop/allow patterns */
20 static OSMatch FWDROPpm;
21 static OSMatch FWALLOWpm;
22
23 /* Allow custom alert output tokens */
24 typedef enum e_custom_alert_tokens_id {
25 CUSTOM_ALERT_TOKEN_TIMESTAMP = 0,
26 CUSTOM_ALERT_TOKEN_FTELL,
27 CUSTOM_ALERT_TOKEN_RULE_ALERT_OPTIONS,
28 CUSTOM_ALERT_TOKEN_HOSTNAME,
29 CUSTOM_ALERT_TOKEN_LOCATION,
30 CUSTOM_ALERT_TOKEN_RULE_ID,
31 CUSTOM_ALERT_TOKEN_RULE_LEVEL,
32 CUSTOM_ALERT_TOKEN_RULE_COMMENT,
33 CUSTOM_ALERT_TOKEN_SRC_IP,
34 CUSTOM_ALERT_TOKEN_DST_USER,
35 CUSTOM_ALERT_TOKEN_FULL_LOG,
36 CUSTOM_ALERT_TOKEN_RULE_GROUP,
37 CUSTOM_ALERT_TOKEN_LAST
38 } CustomAlertTokenID;
39
40 static const char CustomAlertTokenName[CUSTOM_ALERT_TOKEN_LAST][15] = {
41 { "$TIMESTAMP" },
42 { "$FTELL" },
43 { "$RULEALERT" },
44 { "$HOSTNAME" },
45 { "$LOCATION" },
46 { "$RULEID" },
47 { "$RULELEVEL" },
48 { "$RULECOMMENT" },
49 { "$SRCIP" },
50 { "$DSTUSER" },
51 { "$FULLLOG" },
52 { "$RULEGROUP" },
53 };
54
55 /* Store the events in a file
56 * The string must be null terminated and contain
57 * any necessary new lines, tabs, etc.
58 */
OS_Store(const Eventinfo * lf)59 void OS_Store(const Eventinfo *lf)
60 {
61 if (strcmp(lf->location, "ossec-keepalive") == 0) {
62 return;
63 }
64 if (strstr(lf->location, "->ossec-keepalive") != NULL) {
65 return;
66 }
67
68 fprintf(_eflog,
69 "%d %s %02d %s %s%s%s %s\n",
70 lf->year,
71 lf->mon,
72 lf->day,
73 lf->hour,
74 lf->hostname != lf->location ? lf->hostname : "",
75 lf->hostname != lf->location ? "->" : "",
76 lf->location,
77 lf->full_log);
78
79 fflush(_eflog);
80 return;
81 }
82
OS_LogOutput(Eventinfo * lf)83 void OS_LogOutput(Eventinfo *lf)
84 {
85 #ifdef LIBGEOIP_ENABLED
86 if (Config.geoipdb_file) {
87 if (lf->srcip && !lf->srcgeoip) {
88 lf->srcgeoip = GetGeoInfobyIP(lf->srcip);
89 }
90 if (lf->dstip && !lf->dstgeoip) {
91 lf->dstgeoip = GetGeoInfobyIP(lf->dstip);
92 }
93 }
94 #endif
95
96 printf(
97 "** Alert %ld.%ld:%s - %s\n"
98 "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'"
99 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n",
100 (long int)lf->time,
101 __crt_ftell,
102 lf->generated_rule->alert_opts & DO_MAILALERT ? " mail " : "",
103 lf->generated_rule->group,
104 lf->year,
105 lf->mon,
106 lf->day,
107 lf->hour,
108 lf->hostname != lf->location ? lf->hostname : "",
109 lf->hostname != lf->location ? "->" : "",
110 lf->location,
111 lf->generated_rule->sigid,
112 lf->generated_rule->level,
113 lf->generated_rule->comment,
114
115 lf->srcip == NULL ? "" : "\nSrc IP: ",
116 lf->srcip == NULL ? "" : lf->srcip,
117
118 #ifdef LIBGEOIP_ENABLED
119 lf->srcgeoip == NULL ? "" : "\nSrc Location: ",
120 lf->srcgeoip == NULL ? "" : lf->srcgeoip,
121 #else
122 "",
123 "",
124 #endif
125
126
127
128 lf->srcport == NULL ? "" : "\nSrc Port: ",
129 lf->srcport == NULL ? "" : lf->srcport,
130
131 lf->dstip == NULL ? "" : "\nDst IP: ",
132 lf->dstip == NULL ? "" : lf->dstip,
133
134 #ifdef LIBGEOIP_ENABLED
135 lf->dstgeoip == NULL ? "" : "\nDst Location: ",
136 lf->dstgeoip == NULL ? "" : lf->dstgeoip,
137 #else
138 "",
139 "",
140 #endif
141
142
143
144 lf->dstport == NULL ? "" : "\nDst Port: ",
145 lf->dstport == NULL ? "" : lf->dstport,
146
147 lf->dstuser == NULL ? "" : "\nUser: ",
148 lf->dstuser == NULL ? "" : lf->dstuser,
149
150 lf->full_log);
151
152 /* Print the last events if present */
153 if (lf->generated_rule->last_events) {
154 char **lasts = lf->generated_rule->last_events;
155 while (*lasts) {
156 printf("%.1256s\n", *lasts);
157 lasts++;
158 }
159 lf->generated_rule->last_events[0] = NULL;
160 }
161
162 printf("\n");
163
164 fflush(stdout);
165 return;
166 }
167
OS_Log(Eventinfo * lf)168 void OS_Log(Eventinfo *lf)
169 {
170 #ifdef LIBGEOIP_ENABLED
171 if (Config.geoipdb_file) {
172 if (lf->srcip && !lf->srcgeoip) {
173 lf->srcgeoip = GetGeoInfobyIP(lf->srcip);
174 }
175 if (lf->dstip && !lf->dstgeoip) {
176 lf->dstgeoip = GetGeoInfobyIP(lf->dstip);
177 }
178 }
179 #endif
180
181 /* Writing to the alert log file */
182 fprintf(_aflog,
183 "** Alert %ld.%ld:%s - %s\n"
184 "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'"
185 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n",
186 (long int)lf->time,
187 __crt_ftell,
188 lf->generated_rule->alert_opts & DO_MAILALERT ? " mail " : "",
189 lf->generated_rule->group,
190 lf->year,
191 lf->mon,
192 lf->day,
193 lf->hour,
194 lf->hostname != lf->location ? lf->hostname : "",
195 lf->hostname != lf->location ? "->" : "",
196 lf->location,
197 lf->generated_rule->sigid,
198 lf->generated_rule->level,
199 lf->generated_rule->comment,
200
201 lf->srcip == NULL ? "" : "\nSrc IP: ",
202 lf->srcip == NULL ? "" : lf->srcip,
203
204 #ifdef LIBGEOIP_ENABLED
205 lf->srcgeoip == NULL ? "" : "\nSrc Location: ",
206 lf->srcgeoip == NULL ? "" : lf->srcgeoip,
207 #else
208 "",
209 "",
210 #endif
211
212
213 lf->srcport == NULL ? "" : "\nSrc Port: ",
214 lf->srcport == NULL ? "" : lf->srcport,
215
216 lf->dstip == NULL ? "" : "\nDst IP: ",
217 lf->dstip == NULL ? "" : lf->dstip,
218
219 #ifdef LIBGEOIP_ENABLED
220 lf->dstgeoip == NULL ? "" : "\nDst Location: ",
221 lf->dstgeoip == NULL ? "" : lf->dstgeoip,
222 #else
223 "",
224 "",
225 #endif
226
227
228
229 lf->dstport == NULL ? "" : "\nDst Port: ",
230 lf->dstport == NULL ? "" : lf->dstport,
231
232 lf->dstuser == NULL ? "" : "\nUser: ",
233 lf->dstuser == NULL ? "" : lf->dstuser,
234
235 lf->full_log);
236
237 /* Print the last events if present */
238 if (lf->generated_rule->last_events) {
239 char **lasts = lf->generated_rule->last_events;
240 while (*lasts) {
241 fprintf(_aflog, "%.1256s\n", *lasts);
242 lasts++;
243 }
244 lf->generated_rule->last_events[0] = NULL;
245 }
246
247 fprintf(_aflog, "\n");
248 fflush(_aflog);
249
250 return;
251 }
252
OS_CustomLog(const Eventinfo * lf,const char * format)253 void OS_CustomLog(const Eventinfo *lf, const char *format)
254 {
255 char *log;
256 char *tmp_log;
257 char tmp_buffer[1024];
258
259 /* Replace all the tokens */
260 os_strdup(format, log);
261
262 snprintf(tmp_buffer, 1024, "%ld", (long int)lf->time);
263 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_TIMESTAMP], tmp_buffer);
264 if (log) {
265 os_free(log);
266 log = NULL;
267 }
268 snprintf(tmp_buffer, 1024, "%ld", __crt_ftell);
269 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_FTELL], tmp_buffer);
270 if (tmp_log) {
271 os_free(tmp_log);
272 tmp_log = NULL;
273 }
274
275 snprintf(tmp_buffer, 1024, "%s", (lf->generated_rule->alert_opts & DO_MAILALERT) ? "mail " : "");
276 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_ALERT_OPTIONS], tmp_buffer);
277 if (log) {
278 os_free(log);
279 log = NULL;
280 }
281
282 snprintf(tmp_buffer, 1024, "%s", lf->hostname ? lf->hostname : "None");
283 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_HOSTNAME], tmp_buffer);
284 if (tmp_log) {
285 os_free(tmp_log);
286 tmp_log = NULL;
287 }
288
289 snprintf(tmp_buffer, 1024, "%s", lf->location ? lf->location : "None");
290 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_LOCATION], tmp_buffer);
291 if (log) {
292 os_free(log);
293 log = NULL;
294 }
295
296 snprintf(tmp_buffer, 1024, "%d", lf->generated_rule->sigid);
297 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_ID], tmp_buffer);
298 if (tmp_log) {
299 os_free(tmp_log);
300 tmp_log = NULL;
301 }
302
303 snprintf(tmp_buffer, 1024, "%d", lf->generated_rule->level);
304 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_LEVEL], tmp_buffer);
305 if (log) {
306 os_free(log);
307 log = NULL;
308 }
309
310 snprintf(tmp_buffer, 1024, "%s", lf->srcip ? lf->srcip : "None");
311 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_SRC_IP], tmp_buffer);
312 if (tmp_log) {
313 os_free(tmp_log);
314 tmp_log = NULL;
315 }
316
317 snprintf(tmp_buffer, 1024, "%s", lf->dstuser ? lf->dstuser : "None");
318
319 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_DST_USER], tmp_buffer);
320 if (log) {
321 os_free(log);
322 log = NULL;
323 }
324 char *escaped_log;
325 escaped_log = escape_newlines(lf->full_log);
326
327 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_FULL_LOG], escaped_log );
328 if (tmp_log) {
329 os_free(tmp_log);
330 tmp_log = NULL;
331 }
332
333 if (escaped_log) {
334 os_free(escaped_log);
335 escaped_log = NULL;
336 }
337
338 snprintf(tmp_buffer, 1024, "%s", lf->generated_rule->comment ? lf->generated_rule->comment : "");
339 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_COMMENT], tmp_buffer);
340 if (log) {
341 os_free(log);
342 log = NULL;
343 }
344
345 snprintf(tmp_buffer, 1024, "%s", lf->generated_rule->group ? lf->generated_rule->group : "");
346 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_GROUP], tmp_buffer);
347 if (tmp_log) {
348 os_free(tmp_log);
349 tmp_log = NULL;
350 }
351
352 fprintf(_aflog, "%s", log);
353 fprintf(_aflog, "\n");
354 fflush(_aflog);
355
356 if (log) {
357 os_free(log);
358 log = NULL;
359 }
360
361 return;
362 }
363
OS_InitFwLog()364 void OS_InitFwLog()
365 {
366 /* Initialize fw log regexes */
367 if (!OSMatch_Compile(FWDROP, &FWDROPpm, 0)) {
368 ErrorExit(REGEX_COMPILE, ARGV0, FWDROP,
369 FWDROPpm.error);
370 }
371
372 if (!OSMatch_Compile(FWALLOW, &FWALLOWpm, 0)) {
373 ErrorExit(REGEX_COMPILE, ARGV0, FWALLOW,
374 FWALLOWpm.error);
375 }
376 }
377
FW_Log(Eventinfo * lf)378 int FW_Log(Eventinfo *lf)
379 {
380 /* If we don't have the srcip or the
381 * action, there is no point in going
382 * forward over here
383 */
384 if (!lf->action || !lf->srcip || !lf->dstip || !lf->srcport ||
385 !lf->dstport || !lf->protocol) {
386 return (0);
387 }
388
389 /* Set the actions */
390 switch (*lf->action) {
391 /* discard, drop, deny, */
392 case 'd':
393 case 'D':
394 /* reject, */
395 case 'r':
396 case 'R':
397 /* block */
398 case 'b':
399 case 'B':
400 os_free(lf->action);
401 os_strdup("DROP", lf->action);
402 break;
403 /* Closed */
404 case 'c':
405 case 'C':
406 /* Teardown */
407 case 't':
408 case 'T':
409 os_free(lf->action);
410 os_strdup("CLOSED", lf->action);
411 break;
412 /* allow, accept, */
413 case 'a':
414 case 'A':
415 /* pass/permitted */
416 case 'p':
417 case 'P':
418 /* open */
419 case 'o':
420 case 'O':
421 os_free(lf->action);
422 os_strdup("ALLOW", lf->action);
423 break;
424 default:
425 if (OSMatch_Execute(lf->action, strlen(lf->action), &FWDROPpm)) {
426 os_free(lf->action);
427 os_strdup("DROP", lf->action);
428 }
429 if (OSMatch_Execute(lf->action, strlen(lf->action), &FWALLOWpm)) {
430 os_free(lf->action);
431 os_strdup("ALLOW", lf->action);
432 } else {
433 os_free(lf->action);
434 os_strdup("UNKNOWN", lf->action);
435 }
436 break;
437 }
438
439 /* Log to file */
440 fprintf(_fflog,
441 "%d %s %02d %s %s%s%s %s %s %s:%s->%s:%s\n",
442 lf->year,
443 lf->mon,
444 lf->day,
445 lf->hour,
446 lf->hostname != lf->location ? lf->hostname : "",
447 lf->hostname != lf->location ? "->" : "",
448 lf->location,
449 lf->action,
450 lf->protocol,
451 lf->srcip,
452 lf->srcport,
453 lf->dstip,
454 lf->dstport);
455
456 fflush(_fflog);
457
458 return (1);
459 }
460
461