dodan override za lintian
[ossec-hids.git] / src / analysisd / alerts / log.c
index 2686620..2acde59 100755 (executable)
@@ -1,11 +1,12 @@
-/* @(#) $Id: log.c,v 1.33 2009/11/20 15:38:28 dcid Exp $ */
+/* @(#) $Id: ./src/analysisd/alerts/log.c, 2012/03/30 dcid Exp $
+ */
 
 /* Copyright (C) 2009 Trend Micro Inc.
  * All right reserved.
  *
  * This program is a free software; you can redistribute it
  * and/or modify it under the terms of the GNU General Public
- * License (version 3) as published by the FSF - Free Software 
+ * License (version 2) as published by the FSF - Free Software
  * Foundation
  */
 
 #include "eventinfo.h"
 #include "config.h"
 
+#ifdef GEOIP
+/* GeoIP Stuff */
+#include "GeoIP.h"
+#include "GeoIPCity.h"
+
+#define RFC1918_10     (167772160 & 4278190080)        /* 10/8 */
+#define RFC1918_172    (2886729728 & 4293918720)       /* 172.17/12 */
+#define RFC1918_192    (3232235520 & 4294901760)       /* 192.168/16 */
+#define NETMASK_8      4278190080      /* 255.0.0.0    */
+#define NETMASK_12     4293918720      /* 255.240.0.0  */
+#define NETMASK_16     4294901760      /* 255.255.0.0  */
+
+static const char * _mk_NA( const char * p ){
+       return (p ? p : "N/A");
+}
+
+/* StrIP2Long */
+/* Convert an dot-quad IP address into long format
+ */
+static unsigned long StrIP2Int(const char *ip) {
+       unsigned int c1,c2,c3,c4;
+       /* IP address is not coming from user input -> We can trust it */
+       /* only minimal checking is performed */
+       size_t len = strlen(ip);
+       if ((len < 7) || (len > 15)) return (0);
+
+       sscanf(ip, "%u.%u.%u.%u", &c1, &c2, &c3, &c4);
+       return((unsigned long)c4+c3*256+c2*256*256+c1*256*256*256);
+}
+
+
+/* GeoIP_Lookup */
+/* Use the GeoIP API to locate an IP address
+ */
+static void GeoIP_Lookup(const char *ip, char *buffer, const size_t length)
+{
+       GeoIP   *gi;
+       GeoIPRecord     *gir;
+
+       /* Dumb way to detect an IPv6 address */
+       if (strchr(ip, ':')) {
+               /* Use the IPv6 DB */
+               gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
+               if (gi == NULL) {
+                       merror(INVALID_GEOIP_DB, ARGV0, Config.geoip6_db_path);
+                       snprintf(buffer, length, "Unknown (1)");
+                       return;
+               }
+               gir = GeoIP_record_by_name_v6(gi, ip);
+       }
+       else {
+               /* Use the IPv4 DB */
+               /* If we have a RFC1918 IP, do not perform a DB lookup (performance) */
+               unsigned long longip = StrIP2Int(ip);
+               if (longip == 0 ) {
+                       snprintf(buffer, length, "Unknown (2)");
+                       return;
+               }
+               if ((longip & NETMASK_8)  == RFC1918_10 ||
+               (longip & NETMASK_12) == RFC1918_172 ||
+               (longip & NETMASK_16) == RFC1918_192) {
+                       snprintf(buffer, length, "RFC1918 IP");
+                       return;
+               }
+
+               gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
+               if (gi == NULL) {
+                       merror(INVALID_GEOIP_DB, ARGV0, Config.geoip_db_path);
+                       snprintf(buffer, length, "Unknown (3)");
+                       return;
+               }
+               gir = GeoIP_record_by_name(gi, ip);
+       }
+       if (gir != NULL) {
+               snprintf(buffer,length,"%s,%s,%s",
+                               _mk_NA(gir->country_code),
+                               _mk_NA(GeoIP_region_name_by_code(gir->country_code, gir->region)),
+                               _mk_NA(gir->city)
+               );
+               GeoIP_delete(gi);
+               return;
+       }
+       GeoIP_delete(gi);
+       snprintf(buffer, length, "Unknown (4)");
+       return;
+}
+#endif /* GEOIP */
 
 /* Drop/allow patterns */
 OSMatch FWDROPpm;
 OSMatch FWALLOWpm;
 
+/*
+ * Allow custom alert output tokens.
+ */
 
+typedef enum e_custom_alert_tokens_id
+{
+  CUSTOM_ALERT_TOKEN_TIMESTAMP = 0,
+  CUSTOM_ALERT_TOKEN_FTELL,
+  CUSTOM_ALERT_TOKEN_RULE_ALERT_OPTIONS,
+  CUSTOM_ALERT_TOKEN_HOSTNAME,
+  CUSTOM_ALERT_TOKEN_LOCATION,
+  CUSTOM_ALERT_TOKEN_RULE_ID,
+  CUSTOM_ALERT_TOKEN_RULE_LEVEL,
+  CUSTOM_ALERT_TOKEN_RULE_COMMENT,
+  CUSTOM_ALERT_TOKEN_SRC_IP,
+  CUSTOM_ALERT_TOKEN_DST_USER,
+  CUSTOM_ALERT_TOKEN_FULL_LOG,
+  CUSTOM_ALERT_TOKEN_RULE_GROUP,
+  CUSTOM_ALERT_TOKEN_LAST
+} CustomAlertTokenID;
+
+char CustomAlertTokenName[CUSTOM_ALERT_TOKEN_LAST][15] =
+{
+{ "$TIMESTAMP" },
+{ "$FTELL" },
+{ "$RULEALERT" },
+{ "$HOSTNAME" },
+{ "$LOCATION" },
+{ "$RULEID" },
+{ "$RULELEVEL" },
+{ "$RULECOMMENT" },
+{ "$SRCIP" },
+{ "$DSTUSER" },
+{ "$FULLLOG" },
+{ "$RULEGROUP" },
+};
 /* OS_Store: v0.2, 2005/02/10 */
-/* Will store the events in a file 
+/* Will store the events in a file
  * The string must be null terminated and contain
  * any necessary new lines, tabs, etc.
  *
  */
 void OS_Store(Eventinfo *lf)
 {
+    if(strcmp(lf->location, "ossec-keepalive") == 0)
+    {
+        return;
+    }
+    if(strstr(lf->location, "->ossec-keepalive") != NULL)
+    {
+        return;
+    }
+
     fprintf(_eflog,
             "%d %s %02d %s %s%s%s %s\n",
             lf->year,
@@ -43,20 +175,116 @@ void OS_Store(Eventinfo *lf)
             lf->location,
             lf->full_log);
 
-    fflush(_eflog); 
-    return;    
+    fflush(_eflog);
+    return;
 }
 
 
+
+void OS_LogOutput(Eventinfo *lf)
+{
+#ifdef GEOIP
+    char geoip_msg_src[OS_SIZE_1024 +1];
+    char geoip_msg_dst[OS_SIZE_1024 +1];
+    geoip_msg_src[0] = '\0';
+    geoip_msg_dst[0] = '\0';
+    if (Config.loggeoip) {
+       if (lf->srcip) GeoIP_Lookup(lf->srcip, geoip_msg_src, OS_SIZE_1024);
+       if (lf->dstip) GeoIP_Lookup(lf->dstip, geoip_msg_dst, OS_SIZE_1024);
+    }
+#endif
+    printf(
+           "** Alert %d.%ld:%s - %s\n"
+            "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'"
+            "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n",
+            lf->time,
+            __crt_ftell,
+            lf->generated_rule->alert_opts & DO_MAILALERT?" mail ":"",
+            lf->generated_rule->group,
+            lf->year,
+            lf->mon,
+            lf->day,
+            lf->hour,
+            lf->hostname != lf->location?lf->hostname:"",
+            lf->hostname != lf->location?"->":"",
+            lf->location,
+            lf->generated_rule->sigid,
+            lf->generated_rule->level,
+            lf->generated_rule->comment,
+
+            lf->srcip == NULL?"":"\nSrc IP: ",
+            lf->srcip == NULL?"":lf->srcip,
+
+#ifdef GEOIP
+            (strlen(geoip_msg_src) == 0)?"":"\nSrc Location: ",
+            (strlen(geoip_msg_src) == 0)?"":geoip_msg_src,
+#else
+           "",
+            "",
+#endif
+
+            lf->srcport == NULL?"":"\nSrc Port: ",
+            lf->srcport == NULL?"":lf->srcport,
+
+            lf->dstip == NULL?"":"\nDst IP: ",
+            lf->dstip == NULL?"":lf->dstip,
+
+#ifdef GEOIP
+            (strlen(geoip_msg_dst) == 0)?"":"\nDst Location: ",
+            (strlen(geoip_msg_dst) == 0)?"":geoip_msg_dst,
+#else
+            "",
+            "",
+#endif
+
+            lf->dstport == NULL?"":"\nDst Port: ",
+            lf->dstport == NULL?"":lf->dstport,
+
+            lf->dstuser == NULL?"":"\nUser: ",
+            lf->dstuser == NULL?"":lf->dstuser,
+
+            lf->full_log);
+
+
+    /* Printing the last events if present */
+    if(lf->generated_rule->last_events)
+    {
+        char **lasts = lf->generated_rule->last_events;
+        while(*lasts)
+        {
+            printf("%.1256s\n",*lasts);
+            lasts++;
+        }
+        lf->generated_rule->last_events[0] = NULL;
+    }
+
+    printf("\n");
+
+    fflush(stdout);
+    return;
+}
+
+
+
 /* OS_Log: v0.3, 2006/03/04 */
 /* _writefile: v0.2, 2005/02/09 */
 void OS_Log(Eventinfo *lf)
 {
+#ifdef GEOIP
+    char geoip_msg_src[OS_SIZE_1024 +1];
+    char geoip_msg_dst[OS_SIZE_1024 +1];
+    geoip_msg_src[0] = '\0';
+    geoip_msg_dst[0] = '\0';
+    if (Config.loggeoip) {
+        if (lf->srcip) GeoIP_Lookup(lf->srcip, geoip_msg_src, OS_SIZE_1024 );
+        if (lf->dstip) GeoIP_Lookup(lf->dstip, geoip_msg_dst, OS_SIZE_1024 );
+    }
+#endif
     /* Writting to the alert log file */
     fprintf(_aflog,
             "** Alert %d.%ld:%s - %s\n"
-            "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'\n"
-            "Src IP: %s\nUser: %s\n%.1256s\n",
+            "%d %s %02d %s %s%s%s\nRule: %d (level %d) -> '%s'"
+            "%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n%.1256s\n",
             lf->time,
             __crt_ftell,
             lf->generated_rule->alert_opts & DO_MAILALERT?" mail ":"",
@@ -71,8 +299,38 @@ void OS_Log(Eventinfo *lf)
             lf->generated_rule->sigid,
             lf->generated_rule->level,
             lf->generated_rule->comment,
-            lf->srcip == NULL?"(none)":lf->srcip,
-            lf->dstuser == NULL?"(none)":lf->dstuser,
+
+            lf->srcip == NULL?"":"\nSrc IP: ",
+            lf->srcip == NULL?"":lf->srcip,
+
+#ifdef GEOIP
+            (strlen(geoip_msg_src) == 0)?"":"\nSrc Location: ",
+            (strlen(geoip_msg_src) == 0)?"":geoip_msg_src,
+#else
+            "",
+            "",
+#endif
+
+            lf->srcport == NULL?"":"\nSrc Port: ",
+            lf->srcport == NULL?"":lf->srcport,
+
+            lf->dstip == NULL?"":"\nDst IP: ",
+            lf->dstip == NULL?"":lf->dstip,
+
+#ifdef GEOIP
+            (strlen(geoip_msg_dst) == 0)?"":"\nDst Location: ",
+            (strlen(geoip_msg_dst) == 0)?"":geoip_msg_dst,
+#else
+            "",
+            "",
+#endif
+
+            lf->dstport == NULL?"":"\nDst Port: ",
+            lf->dstport == NULL?"":lf->dstport,
+
+            lf->dstuser == NULL?"":"\nUser: ",
+            lf->dstuser == NULL?"":lf->dstuser,
+
             lf->full_log);
 
 
@@ -91,10 +349,137 @@ void OS_Log(Eventinfo *lf)
     fprintf(_aflog,"\n");
 
     fflush(_aflog);
-    return;    
+    return;
 }
 
+/* OS_CustomLog: v0.1, 2012/10/10*/
+void OS_CustomLog(Eventinfo *lf,char* format)
+{
+  char *log;
+  char *tmp_log;
+  char tmp_buffer[1024];
+  //Replace all the tokens:
+  os_strdup(format,log);
+
+  snprintf(tmp_buffer, 1024, "%d", lf->time);
+  tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_TIMESTAMP], tmp_buffer);
+  if(log)
+  {
+    os_free(log);
+    log=NULL;
+  }
+  snprintf(tmp_buffer, 1024, "%ld", __crt_ftell);
+  log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_FTELL], tmp_buffer);
+  if (tmp_log)
+  {
+    os_free(tmp_log);
+    tmp_log=NULL;
+  }
+
+
+  snprintf(tmp_buffer, 1024, "%s", (lf->generated_rule->alert_opts & DO_MAILALERT)?"mail " : "");
+  tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_ALERT_OPTIONS], tmp_buffer);
+  if(log)
+  {
+    os_free(log);
+    log=NULL;
+  }
+
+
+  snprintf(tmp_buffer, 1024, "%s",lf->hostname?lf->hostname:"None");
+  log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_HOSTNAME], tmp_buffer);
+  if (tmp_log)
+  {
+    os_free(tmp_log);
+    tmp_log=NULL;
+  }
+
+  snprintf(tmp_buffer, 1024, "%s",lf->location?lf->location:"None");
+  tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_LOCATION], tmp_buffer);
+  if(log)
+  {
+    os_free(log);
+    log=NULL;
+  }
+
+
+  snprintf(tmp_buffer, 1024, "%d", lf->generated_rule->sigid);
+  log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_ID], tmp_buffer);
+  if (tmp_log)
+  {
+    os_free(tmp_log);
+    tmp_log=NULL;
+  }
+
+  snprintf(tmp_buffer, 1024, "%d", lf->generated_rule->level);
+  tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_LEVEL], tmp_buffer);
+  if(log)
+  {
+    os_free(log);
+    log=NULL;
+  }
+
+  snprintf(tmp_buffer, 1024, "%s",lf->srcip?lf->srcip:"None");
+  log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_SRC_IP], tmp_buffer);
+  if (tmp_log)
+  {
+    os_free(tmp_log);
+    tmp_log=NULL;
+  }
+
+  snprintf(tmp_buffer, 1024, "%s",lf->srcuser?lf->srcuser:"None");
 
+  tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_DST_USER], tmp_buffer);
+  if(log)
+  {
+    os_free(log);
+    log=NULL;
+  }
+  char * escaped_log;
+  escaped_log = escape_newlines(lf->full_log);
+
+  log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_FULL_LOG],escaped_log );
+  if (tmp_log)
+  {
+    os_free(tmp_log);
+    tmp_log=NULL;
+  }
+
+  if(escaped_log)
+  {
+    os_free(escaped_log);
+    escaped_log=NULL;
+  }
+
+  snprintf(tmp_buffer, 1024, "%s",lf->generated_rule->comment?lf->generated_rule->comment:"");
+  tmp_log = searchAndReplace(log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_COMMENT], tmp_buffer);
+  if(log)
+  {
+    os_free(log);
+    log=NULL;
+  }
+
+  snprintf(tmp_buffer, 1024, "%s",lf->generated_rule->group?lf->generated_rule->group:"");
+  log = searchAndReplace(tmp_log, CustomAlertTokenName[CUSTOM_ALERT_TOKEN_RULE_GROUP], tmp_buffer);
+  if (tmp_log)
+  {
+    os_free(tmp_log);
+    tmp_log=NULL;
+  }
+
+
+  fprintf(_aflog,"%s",log);
+  fprintf(_aflog,"\n");
+  fflush(_aflog);
+
+  if(log)
+  {
+    os_free(log);
+    log=NULL;
+  }
+
+  return;
+}
 
 void OS_InitFwLog()
 {
@@ -110,7 +495,7 @@ void OS_InitFwLog()
         ErrorExit(REGEX_COMPILE, ARGV0, FWALLOW,
                 FWALLOWpm.error);
     }
-                    
+
 }
 
 
@@ -121,7 +506,8 @@ int FW_Log(Eventinfo *lf)
      * action, there is no point in going
      * forward over here
      */
-    if(!lf->action || !lf->srcip)
+    if(!lf->action || !lf->srcip || !lf->dstip || !lf->srcport ||
+       !lf->dstport || !lf->protocol)
     {
         return(0);
     }
@@ -151,7 +537,7 @@ int FW_Log(Eventinfo *lf)
             os_free(lf->action);
             os_strdup("CLOSED", lf->action);
             break;
-        /* allow, accept, */    
+        /* allow, accept, */
         case 'a':
         case 'A':
         /* pass/permitted */
@@ -159,9 +545,9 @@ int FW_Log(Eventinfo *lf)
         case 'P':
         /* open */
         case 'o':
-        case 'O':    
+        case 'O':
             os_free(lf->action);
-            os_strdup("ALLOW", lf->action);        
+            os_strdup("ALLOW", lf->action);
             break;
         default:
             if(OSMatch_Execute(lf->action,strlen(lf->action),&FWDROPpm))
@@ -179,7 +565,7 @@ int FW_Log(Eventinfo *lf)
                 os_free(lf->action);
                 os_strdup("UNKNOWN", lf->action);
             }
-            break;    
+            break;
     }
 
 
@@ -199,7 +585,7 @@ int FW_Log(Eventinfo *lf)
             lf->srcport,
             lf->dstip,
             lf->dstport);
-    
+
     fflush(_fflog);
 
     return(1);