Imported Upstream version 2.7
[ossec-hids.git] / src / analysisd / alerts / log.c
index 4095b61..95e1e63 100755 (executable)
@@ -1,11 +1,12 @@
-/* @(#) $Id$ */
+/* @(#) $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 2) 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
+ */
+unsigned long StrIP2Int(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 */
+        int len = strlen(ip);
+        if ((len < 7) || (len > 15)) return 0;
+
+        sscanf(ip, "%d.%d.%d.%d", &c1, &c2, &c3, &c4);
+        return((unsigned long)c4+c3*256+c2*256*256+c1*256*256*256);
+}
+
+
+/* GeoIPLookup */
+/* Use the GeoIP API to locate an IP address
+ */
+char *GeoIPLookup(char *ip)
+{
+       GeoIP   *gi;
+       GeoIPRecord     *gir;
+       char buffer[OS_SIZE_1024 +1];
+        unsigned long longip;
+
+       /* 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);
+                       return("Unknown");
+               }
+               gir = GeoIP_record_by_name_v6(gi, (const char *)ip);
+       }
+       else {
+               /* Use the IPv4 DB */
+                /* If we have a RFC1918 IP, do not perform a DB lookup (performance) */
+                longip = StrIP2Int(ip);
+                if (longip == 0 ) return("Unknown");
+                if ((longip & NETMASK_8)  == RFC1918_10 ||
+                    (longip & NETMASK_12) == RFC1918_172 ||
+                    (longip & NETMASK_16) == RFC1918_192) return("");
+
+               gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
+               if (gi == NULL) {
+                       merror(INVALID_GEOIP_DB, ARGV0, Config.geoip_db_path);
+                       return("Unknown");
+               }
+               gir = GeoIP_record_by_name(gi, (const char *)ip);
+       }
+       if (gir != NULL) {
+               sprintf(buffer,"%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(buffer);
+       }
+       GeoIP_delete(gi);
+       return("Unknown");
+}
+#endif /* GEOIP */
 
 /* Drop/allow patterns */
 OSMatch FWDROPpm;
@@ -25,13 +106,22 @@ OSMatch FWALLOWpm;
 
 
 /* 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,7 +133,7 @@ void OS_Store(Eventinfo *lf)
             lf->location,
             lf->full_log);
 
-    fflush(_eflog); 
+    fflush(_eflog);
     return;    
 }
 
@@ -51,10 +141,20 @@ void OS_Store(Eventinfo *lf)
 
 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) { strncpy(geoip_msg_src, GeoIPLookup(lf->srcip), OS_SIZE_1024); }
+       if (lf->dstip) { strncpy(geoip_msg_dst, GeoIPLookup(lf->dstip), OS_SIZE_1024); }
+    }
+#endif
     printf(
            "** 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 ":"",
@@ -69,8 +169,38 @@ void OS_LogOutput(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);
 
 
@@ -98,11 +228,21 @@ void OS_LogOutput(Eventinfo *lf)
 /* _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) { strncpy(geoip_msg_src, GeoIPLookup(lf->srcip), OS_SIZE_1024 ); }
+        if (lf->dstip) { strncpy(geoip_msg_dst, GeoIPLookup(lf->dstip), 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 ":"",
@@ -117,8 +257,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);
 
 
@@ -156,7 +326,7 @@ void OS_InitFwLog()
         ErrorExit(REGEX_COMPILE, ARGV0, FWALLOW,
                 FWALLOWpm.error);
     }
-                    
+
 }
 
 
@@ -167,7 +337,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);
     }
@@ -197,7 +368,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 */
@@ -205,9 +376,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))
@@ -225,7 +396,7 @@ int FW_Log(Eventinfo *lf)
                 os_free(lf->action);
                 os_strdup("UNKNOWN", lf->action);
             }
-            break;    
+            break;
     }
 
 
@@ -245,7 +416,7 @@ int FW_Log(Eventinfo *lf)
             lf->srcport,
             lf->dstip,
             lf->dstport);
-    
+
     fflush(_fflog);
 
     return(1);