1 /* @(#) $Id: ./src/analysisd/alerts/log.c, 2012/03/30 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
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
17 #include "getloglocation.h"
19 #include "eventinfo.h"
25 #include "GeoIPCity.h"
27 #define RFC1918_10 (167772160 & 4278190080) /* 10/8 */
28 #define RFC1918_172 (2886729728 & 4293918720) /* 172.17/12 */
29 #define RFC1918_192 (3232235520 & 4294901760) /* 192.168/16 */
30 #define NETMASK_8 4278190080 /* 255.0.0.0 */
31 #define NETMASK_12 4293918720 /* 255.240.0.0 */
32 #define NETMASK_16 4294901760 /* 255.255.0.0 */
34 static const char * _mk_NA( const char * p ){
35 return (p ? p : "N/A");
39 /* Convert an dot-quad IP address into long format
41 static unsigned long StrIP2Int(const char *ip) {
42 unsigned int c1,c2,c3,c4;
43 /* IP address is not coming from user input -> We can trust it */
44 /* only minimal checking is performed */
45 size_t len = strlen(ip);
46 if ((len < 7) || (len > 15)) return (0);
48 sscanf(ip, "%u.%u.%u.%u", &c1, &c2, &c3, &c4);
49 return((unsigned long)c4+c3*256+c2*256*256+c1*256*256*256);
54 /* Use the GeoIP API to locate an IP address
56 static void GeoIP_Lookup(const char *ip, char *buffer, const size_t length)
61 /* Dumb way to detect an IPv6 address */
62 if (strchr(ip, ':')) {
64 gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
66 merror(INVALID_GEOIP_DB, ARGV0, Config.geoip6_db_path);
67 snprintf(buffer, length, "Unknown (1)");
70 gir = GeoIP_record_by_name_v6(gi, ip);
74 /* If we have a RFC1918 IP, do not perform a DB lookup (performance) */
75 unsigned long longip = StrIP2Int(ip);
77 snprintf(buffer, length, "Unknown (2)");
80 if ((longip & NETMASK_8) == RFC1918_10 ||
81 (longip & NETMASK_12) == RFC1918_172 ||
82 (longip & NETMASK_16) == RFC1918_192) {
83 snprintf(buffer, length, "RFC1918 IP");
87 gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
89 merror(INVALID_GEOIP_DB, ARGV0, Config.geoip_db_path);
90 snprintf(buffer, length, "Unknown (3)");
93 gir = GeoIP_record_by_name(gi, ip);
96 snprintf(buffer,length,"%s,%s,%s",
97 _mk_NA(gir->country_code),
98 _mk_NA(GeoIP_region_name_by_code(gir->country_code, gir->region)),
105 snprintf(buffer, length, "Unknown (4)");
110 /* Drop/allow patterns */
115 * Allow custom alert output tokens.
118 typedef enum e_custom_alert_tokens_id
120 CUSTOM_ALERT_TOKEN_TIMESTAMP = 0,
121 CUSTOM_ALERT_TOKEN_FTELL,
122 CUSTOM_ALERT_TOKEN_RULE_ALERT_OPTIONS,
123 CUSTOM_ALERT_TOKEN_HOSTNAME,
124 CUSTOM_ALERT_TOKEN_LOCATION,
125 CUSTOM_ALERT_TOKEN_RULE_ID,
126 CUSTOM_ALERT_TOKEN_RULE_LEVEL,
127 CUSTOM_ALERT_TOKEN_RULE_COMMENT,
128 CUSTOM_ALERT_TOKEN_SRC_IP,
129 CUSTOM_ALERT_TOKEN_DST_USER,
130 CUSTOM_ALERT_TOKEN_FULL_LOG,
131 CUSTOM_ALERT_TOKEN_RULE_GROUP,
132 CUSTOM_ALERT_TOKEN_LAST
133 } CustomAlertTokenID;
135 char CustomAlertTokenName[CUSTOM_ALERT_TOKEN_LAST][15] =
150 /* OS_Store: v0.2, 2005/02/10 */
151 /* Will store the events in a file
152 * The string must be null terminated and contain
153 * any necessary new lines, tabs, etc.
156 void OS_Store(Eventinfo *lf)
158 if(strcmp(lf->location, "ossec-keepalive") == 0)
162 if(strstr(lf->location, "->ossec-keepalive") != NULL)
168 "%d %s %02d %s %s%s%s %s\n",
173 lf->hostname != lf->location?lf->hostname:"",
174 lf->hostname != lf->location?"->":"",
184 void OS_LogOutput(Eventinfo *lf)
187 char geoip_msg_src[OS_SIZE_1024 +1];
188 char geoip_msg_dst[OS_SIZE_1024 +1];
189 geoip_msg_src[0] = '\0';
190 geoip_msg_dst[0] = '\0';
191 if (Config.loggeoip) {
192 if (lf->srcip) GeoIP_Lookup(lf->srcip, geoip_msg_src, OS_SIZE_1024);
193 if (lf->dstip) GeoIP_Lookup(lf->dstip, geoip_msg_dst, OS_SIZE_1024);
197 "** Alert %d.%ld:%s - %s\n"
198 "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'"
199 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n",
202 lf->generated_rule->alert_opts & DO_MAILALERT?" mail ":"",
203 lf->generated_rule->group,
208 lf->hostname != lf->location?lf->hostname:"",
209 lf->hostname != lf->location?"->":"",
211 lf->generated_rule->sigid,
212 lf->generated_rule->level,
213 lf->generated_rule->comment,
215 lf->srcip == NULL?"":"\nSrc IP: ",
216 lf->srcip == NULL?"":lf->srcip,
219 (strlen(geoip_msg_src) == 0)?"":"\nSrc Location: ",
220 (strlen(geoip_msg_src) == 0)?"":geoip_msg_src,
226 lf->srcport == NULL?"":"\nSrc Port: ",
227 lf->srcport == NULL?"":lf->srcport,
229 lf->dstip == NULL?"":"\nDst IP: ",
230 lf->dstip == NULL?"":lf->dstip,
233 (strlen(geoip_msg_dst) == 0)?"":"\nDst Location: ",
234 (strlen(geoip_msg_dst) == 0)?"":geoip_msg_dst,
240 lf->dstport == NULL?"":"\nDst Port: ",
241 lf->dstport == NULL?"":lf->dstport,
243 lf->dstuser == NULL?"":"\nUser: ",
244 lf->dstuser == NULL?"":lf->dstuser,
249 /* Printing the last events if present */
250 if(lf->generated_rule->last_events)
252 char **lasts = lf->generated_rule->last_events;
255 printf("%.1256s\n",*lasts);
258 lf->generated_rule->last_events[0] = NULL;
269 /* OS_Log: v0.3, 2006/03/04 */
270 /* _writefile: v0.2, 2005/02/09 */
271 void OS_Log(Eventinfo *lf)
274 char geoip_msg_src[OS_SIZE_1024 +1];
275 char geoip_msg_dst[OS_SIZE_1024 +1];
276 geoip_msg_src[0] = '\0';
277 geoip_msg_dst[0] = '\0';
278 if (Config.loggeoip) {
279 if (lf->srcip) GeoIP_Lookup(lf->srcip, geoip_msg_src, OS_SIZE_1024 );
280 if (lf->dstip) GeoIP_Lookup(lf->dstip, geoip_msg_dst, OS_SIZE_1024 );
283 /* Writting to the alert log file */
285 "** Alert %d.%ld:%s - %s\n"
286 "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'"
287 "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n",
290 lf->generated_rule->alert_opts & DO_MAILALERT?" mail ":"",
291 lf->generated_rule->group,
296 lf->hostname != lf->location?lf->hostname:"",
297 lf->hostname != lf->location?"->":"",
299 lf->generated_rule->sigid,
300 lf->generated_rule->level,
301 lf->generated_rule->comment,
303 lf->srcip == NULL?"":"\nSrc IP: ",
304 lf->srcip == NULL?"":lf->srcip,
307 (strlen(geoip_msg_src) == 0)?"":"\nSrc Location: ",
308 (strlen(geoip_msg_src) == 0)?"":geoip_msg_src,
314 lf->srcport == NULL?"":"\nSrc Port: ",
315 lf->srcport == NULL?"":lf->srcport,
317 lf->dstip == NULL?"":"\nDst IP: ",
318 lf->dstip == NULL?"":lf->dstip,
321 (strlen(geoip_msg_dst) == 0)?"":"\nDst Location: ",
322 (strlen(geoip_msg_dst) == 0)?"":geoip_msg_dst,
328 lf->dstport == NULL?"":"\nDst Port: ",
329 lf->dstport == NULL?"":lf->dstport,
331 lf->dstuser == NULL?"":"\nUser: ",
332 lf->dstuser == NULL?"":lf->dstuser,
337 /* Printing the last events if present */
338 if(lf->generated_rule->last_events)
340 char **lasts = lf->generated_rule->last_events;
343 fprintf(_aflog,"%.1256s\n",*lasts);
346 lf->generated_rule->last_events[0] = NULL;
349 fprintf(_aflog,"\n");
355 /* OS_CustomLog: v0.1, 2012/10/10*/
356 void OS_CustomLog(Eventinfo *lf,char* format)
360 char tmp_buffer[1024];
361 //Replace all the tokens:
362 os_strdup(format,log);
364 snprintf(tmp_buffer, 1024, "%d", lf->time);
365 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_TIMESTAMP], tmp_buffer);
371 snprintf(tmp_buffer, 1024, "%ld", __crt_ftell);
372 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_FTELL], tmp_buffer);
380 snprintf(tmp_buffer, 1024, "%s", (lf->generated_rule->alert_opts & DO_MAILALERT)?"mail " : "");
381 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_ALERT_OPTIONS], tmp_buffer);
389 snprintf(tmp_buffer, 1024, "%s",lf->hostname?lf->hostname:"None");
390 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_HOSTNAME], tmp_buffer);
397 snprintf(tmp_buffer, 1024, "%s",lf->location?lf->location:"None");
398 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_LOCATION], tmp_buffer);
406 snprintf(tmp_buffer, 1024, "%d", lf->generated_rule->sigid);
407 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_ID], tmp_buffer);
414 snprintf(tmp_buffer, 1024, "%d", lf->generated_rule->level);
415 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_LEVEL], tmp_buffer);
422 snprintf(tmp_buffer, 1024, "%s",lf->srcip?lf->srcip:"None");
423 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_SRC_IP], tmp_buffer);
430 snprintf(tmp_buffer, 1024, "%s",lf->srcuser?lf->srcuser:"None");
432 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_DST_USER], tmp_buffer);
439 escaped_log = escape_newlines(lf->full_log);
441 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_FULL_LOG],escaped_log );
450 os_free(escaped_log);
454 snprintf(tmp_buffer, 1024, "%s",lf->generated_rule->comment?lf->generated_rule->comment:"");
455 tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_COMMENT], tmp_buffer);
462 snprintf(tmp_buffer, 1024, "%s",lf->generated_rule->group?lf->generated_rule->group:"");
463 log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_GROUP], tmp_buffer);
471 fprintf(_aflog,"%s",log);
472 fprintf(_aflog,"\n");
486 /* Initializing fw log regexes */
487 if(!OSMatch_Compile(FWDROP, &FWDROPpm, 0))
489 ErrorExit(REGEX_COMPILE, ARGV0, FWDROP,
493 if(!OSMatch_Compile(FWALLOW, &FWALLOWpm, 0))
495 ErrorExit(REGEX_COMPILE, ARGV0, FWALLOW,
502 /* FW_Log: v0.1, 2005/12/30 */
503 int FW_Log(Eventinfo *lf)
505 /* If we don't have the srcip or the
506 * action, there is no point in going
509 if(!lf->action || !lf->srcip || !lf->dstip || !lf->srcport ||
510 !lf->dstport || !lf->protocol)
516 /* Setting the actions */
519 /* discard, drop, deny, */
529 os_strdup("DROP", lf->action);
538 os_strdup("CLOSED", lf->action);
550 os_strdup("ALLOW", lf->action);
553 if(OSMatch_Execute(lf->action,strlen(lf->action),&FWDROPpm))
556 os_strdup("DROP", lf->action);
558 if(OSMatch_Execute(lf->action,strlen(lf->action),&FWALLOWpm))
561 os_strdup("ALLOW", lf->action);
566 os_strdup("UNKNOWN", lf->action);
574 "%d %s %02d %s %s%s%s %s %s %s:%s->%s:%s\n",
579 lf->hostname != lf->location?lf->hostname:"",
580 lf->hostname != lf->location?"->":"",