novi upstream verzije 2.8.3
[ossec-hids.git] / src / analysisd / alerts / log.c
index 95e1e63..2acde59 100755 (executable)
 #define NETMASK_16     4294901760      /* 255.255.0.0  */
 
 static const char * _mk_NA( const char * p ){
-       return p ? p : "N/A";
+       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);
+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);
 }
 
 
-/* GeoIPLookup */
+/* GeoIP_Lookup */
 /* Use the GeoIP API to locate an IP address
  */
-char *GeoIPLookup(char *ip)
+static void GeoIP_Lookup(const char *ip, char *buffer, const size_t length)
 {
        GeoIP   *gi;
        GeoIPRecord     *gir;
-       char buffer[OS_SIZE_1024 +1];
-        unsigned long longip;
 
        /* Dumb way to detect an IPv6 address */
        if (strchr(ip, ':')) {
@@ -66,37 +64,46 @@ char *GeoIPLookup(char *ip)
                gi = GeoIP_open(Config.geoip_db_path, GEOIP_INDEX_CACHE);
                if (gi == NULL) {
                        merror(INVALID_GEOIP_DB, ARGV0, Config.geoip6_db_path);
-                       return("Unknown");
+                       snprintf(buffer, length, "Unknown (1)");
+                       return;
                }
-               gir = GeoIP_record_by_name_v6(gi, (const char *)ip);
+               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) */
-                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("");
+               /* 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);
-                       return("Unknown");
+                       snprintf(buffer, length, "Unknown (3)");
+                       return;
                }
-               gir = GeoIP_record_by_name(gi, (const char *)ip);
+               gir = GeoIP_record_by_name(gi, ip);
        }
        if (gir != NULL) {
-               sprintf(buffer,"%s,%s,%s",
+               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(buffer);
+               return;
        }
        GeoIP_delete(gi);
-       return("Unknown");
+       snprintf(buffer, length, "Unknown (4)");
+       return;
 }
 #endif /* GEOIP */
 
@@ -104,7 +111,42 @@ char *GeoIPLookup(char *ip)
 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
  * The string must be null terminated and contain
@@ -134,7 +176,7 @@ void OS_Store(Eventinfo *lf)
             lf->full_log);
 
     fflush(_eflog);
-    return;    
+    return;
 }
 
 
@@ -147,8 +189,8 @@ void OS_LogOutput(Eventinfo *lf)
     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); }
+       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(
@@ -219,7 +261,7 @@ void OS_LogOutput(Eventinfo *lf)
     printf("\n");
 
     fflush(stdout);
-    return;    
+    return;
 }
 
 
@@ -234,8 +276,8 @@ void OS_Log(Eventinfo *lf)
     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 ); }
+        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 */
@@ -307,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()
 {