izmjene licence
[ossec-hids.git] / src / logcollector / logcollector.c
index f14f007..9dbaa2b 100755 (executable)
@@ -1,11 +1,12 @@
-/* @(#) $Id: logcollector.c,v 1.59 2009/11/03 21:07:32 dcid Exp $ */
+/* @(#) $Id: ./src/logcollector/logcollector.c, 2012/03/28 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
  */
 
@@ -20,6 +21,22 @@ int _cday = 0;
 int update_fname(int i);
 
 
+char *rand_keepalive_str(char *dst, int size)
+{
+    static const char text[] = "abcdefghijklmnopqrstuvwxyz"
+                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                               "0123456789"
+                               "!@#$%^&*()_+-=;'[],./?";
+    int i, len = rand() % (size - 10);
+    strncpy(dst, "--MARK--: ", 12);
+    for ( i = 10; i < len; ++i )
+    {
+        dst[i] = text[rand() % (sizeof text - 1)];
+    }
+    dst[i] = '\0';
+    return dst;
+}
+
 /** void LogCollectorStart() v0.4
  * Handle file management.
  */
@@ -28,18 +45,22 @@ void LogCollectorStart()
     int i = 0, r = 0;
     int max_file = 0;
     int f_check = 0;
-    
+    int curr_time = 0;
+    char keepalive[1024];
+
+
+
     /* To check for inode changes */
     struct stat tmp_stat;
-    
-                
+
+
     #ifndef WIN32
-    
+
     int int_error = 0;
     struct timeval fp_timeout;
-    
+
     #else
-    
+
     /* Checking if we are on vista. */
     checkVista();
 
@@ -49,12 +70,12 @@ void LogCollectorStart()
     {
         win_read_vista_sec();
     }
-    
+
     #endif
 
     debug1("%s: DEBUG: Entering LogCollectorStart().", ARGV0);
-    
-    
+
+
     /* Initializing each file and structure */
     for(i = 0;;i++)
     {
@@ -67,7 +88,7 @@ void LogCollectorStart()
         {
             if(logff[r].file && strcmp(logff[i].file, logff[r].file) == 0)
             {
-                merror("%s: WARN: Duplicated log file given: '%s'.", 
+                merror("%s: WARN: Duplicated log file given: '%s'.",
                        ARGV0, logff[i].file);
                 logff[i].file = NULL;
                 logff[i].command = NULL;
@@ -81,42 +102,88 @@ void LogCollectorStart()
         {
             /* do nothing, duplicated entry. */
         }
-       
+
         else if(strcmp(logff[i].logformat,"eventlog") == 0)
         {
             #ifdef WIN32
-            
+
             verbose(READING_EVTLOG, ARGV0, logff[i].file);
             win_startel(logff[i].file);
-            
+
             #endif
             logff[i].file = NULL;
             logff[i].command = NULL;
             logff[i].fp = NULL;
         }
+        
+        else if(strcmp(logff[i].logformat, "eventchannel") == 0)
+        {
+                       #ifdef WIN32
+                       
+                       #ifdef EVENTCHANNEL_SUPPORT
+                       verbose(READING_EVTLOG, ARGV0, logff[i].file);
+                       win_start_event_channel(logff[i].file, logff[i].future, logff[i].query);
+                       #else
+                       merror("%s: WARN: eventchannel not available on this version of OSSEC", ARGV0);
+                       #endif
+                       
+                       #endif
+                       
+                       logff[i].file = NULL;
+                       logff[i].command = NULL;
+            logff[i].fp = NULL;
+        }
 
         else if(strcmp(logff[i].logformat, "command") == 0)
         {
             logff[i].file = NULL;
             logff[i].fp = NULL;
+            logff[i].size = 0;
 
             if(logff[i].command)
             {
                 logff[i].read = (void *)read_command;
+
+                verbose("%s: INFO: Monitoring output of command(%d): %s", ARGV0, logff[i].ign, logff[i].command);
+
+                if(!logff[i].alias)
+                {
+                    os_strdup(logff[i].command, logff[i].alias);
+                }
             }
             else
             {
-                merror("%s: ERROR: Missing command argument. Ignoring it.", 
+                merror("%s: ERROR: Missing command argument. Ignoring it.",
                        ARGV0);
             }
         }
-        
+        else if(strcmp(logff[i].logformat, "full_command") == 0)
+        {
+            logff[i].file = NULL;
+            logff[i].fp = NULL;
+            logff[i].size = 0;
+            if(logff[i].command)
+            {
+                logff[i].read = (void *)read_fullcommand;
+
+                verbose("%s: INFO: Monitoring full output of command(%d): %s", ARGV0, logff[i].ign, logff[i].command);
+
+                if(!logff[i].alias)
+                    os_strdup(logff[i].command, logff[i].alias);
+            }
+            else
+            {
+                merror("%s: ERROR: Missing command argument. Ignoring it.",
+                       ARGV0);
+            }
+        }
+
         else
         {
             logff[i].command = NULL;
 
 
-            /* Initializing the files */    
+            /* Initializing the files */
             if(logff[i].ffile)
             {
                 /* Day must be zero for all files to be initialized */
@@ -129,20 +196,26 @@ void LogCollectorStart()
                 {
                     ErrorExit(PARSE_ERROR, ARGV0, logff[i].ffile);
                 }
-                    
+
             }
             else
             {
                 handle_file(i, 1, 1);
             }
-            
+
             verbose(READING_FILE, ARGV0, logff[i].file);
-            
+
             /* Getting the log type */
             if(strcmp("snort-full", logff[i].logformat) == 0)
             {
                 logff[i].read = (void *)read_snortfull;
             }
+            #ifndef WIN32
+            if(strcmp("ossecalert", logff[i].logformat) == 0)
+            {
+                logff[i].read = (void *)read_ossecalert;
+            }
+            #endif
             else if(strcmp("nmapg", logff[i].logformat) == 0)
             {
                 logff[i].read = (void *)read_nmapg;
@@ -173,6 +246,10 @@ void LogCollectorStart()
                 }
                 logff[i].read = (void *)read_djbmultilog;
             }
+            else if(logff[i].logformat[0] >= '0' && logff[i].logformat[0] <= '9')
+            {
+                logff[i].read = (void *)read_multiline;
+            }
             else
             {
                 logff[i].read = (void *)read_syslog;
@@ -189,12 +266,25 @@ void LogCollectorStart()
             }
             #endif
         }
+
+        if(logff[i].alias)
+        {
+            int ii = 0;
+            while(logff[i].alias[ii] != '\0')
+            {
+                if(logff[i].alias[ii] == ':')
+                {
+                    logff[i].alias[ii] = '\\';
+                }
+                ii++;
+            }
+        }
     }
 
 
     /* Start up message */
     verbose(STARTUP_MSG, ARGV0, (int)getpid());
-        
+
     max_file = i -1;
 
 
@@ -203,8 +293,8 @@ void LogCollectorStart()
     {
         max_file = 0;
     }
-    
-    
+
+
     /* Daemon loop */
     while(1)
     {
@@ -212,7 +302,7 @@ void LogCollectorStart()
         fp_timeout.tv_sec = loop_timeout;
         fp_timeout.tv_usec = 0;
 
-        /* Waiting for the select timeout */ 
+        /* Waiting for the select timeout */
         if ((r = select(0, NULL, NULL, NULL, &fp_timeout)) < 0)
         {
             merror(SELECT_ERROR, ARGV0);
@@ -225,27 +315,32 @@ void LogCollectorStart()
             continue;
         }
         #else
-        
+
         /* Windows don't like select that way */
         sleep(loop_timeout + 2);
 
-        
+
         /* Check for messages in the event viewer */
         win_readel();
         #endif
-        
+
         f_check++;
 
-        
+
         /* Checking which file is available */
         for(i = 0; i <= max_file; i++)
         {
             if(!logff[i].fp)
             {
                 /* Run the command. */
-                if((f_check == VCHECK_FILES) && logff[i].command)
+                if(logff[i].command && (f_check %2))
                 {
-                    logff[i].read(i, &r, 0);
+                    curr_time = time(0);
+                    if((curr_time - logff[i].size) >= logff[i].ign)
+                    {
+                        logff[i].size = curr_time;
+                        logff[i].read(i, &r, 0);
+                    }
                 }
                 continue;
             }
@@ -319,7 +414,7 @@ void LogCollectorStart()
                         logff[i].ign++;
                         continue;
                     }
-                    
+
                     #ifdef WIN32
                     logff[i].read(i, &r, 1);
                     #endif
@@ -331,17 +426,19 @@ void LogCollectorStart()
             }
         }
 
-        
+
         /* Only check bellow if check > VCHECK_FILES */
         if(f_check <= VCHECK_FILES)
             continue;
 
-            
+
         /* Send keep alive message */
-        SendMSG(logr_queue, "--MARK--", "ossec-keepalive", LOCALFILE_MQ);
+
+        rand_keepalive_str(keepalive, 700);
+        SendMSG(logr_queue, keepalive, "ossec-keepalive", LOCALFILE_MQ);
 
 
-        /* Zeroing f_check */    
+        /* Zeroing f_check */
         f_check = 0;
 
 
@@ -351,8 +448,8 @@ void LogCollectorStart()
             /* These are the windows logs or ignored files */
             if(!logff[i].file)
                 continue;
-            
-            
+
+
             /* Files with date -- check for day change */
             if(logff[i].ffile)
             {
@@ -377,8 +474,8 @@ void LogCollectorStart()
                     continue;
                 }
             }
-            
-            
+
+
             /* Check for file change -- if the file is open already */
             if(logff[i].fp)
             {
@@ -387,7 +484,7 @@ void LogCollectorStart()
                 {
                     fclose(logff[i].fp);
                     logff[i].fp = NULL;
-                    
+
                     merror(FILE_ERROR, ARGV0, logff[i].file);
                 }
 
@@ -427,21 +524,21 @@ void LogCollectorStart()
                     snprintf(msg_alert, 512, "ossec: File rotated (inode "
                                              "changed): '%s'.",
                                              logff[i].file);
-                     
+
                     /* Send message about log rotated  */
-                    SendMSG(logr_queue, msg_alert, 
+                    SendMSG(logr_queue, msg_alert,
                             "ossec-logcollector", LOCALFILE_MQ);
-                            
+
                     debug1("%s: DEBUG: File inode changed. %s",
                             ARGV0, logff[i].file);
-                    
+
                     fclose(logff[i].fp);
 
                     #ifdef WIN32
                     CloseHandle(logff[i].h);
                     CloseHandle(h1);
                     #endif
-                    
+
                     logff[i].fp = NULL;
                     handle_file(i, 0, 1);
                     continue;
@@ -457,11 +554,11 @@ void LogCollectorStart()
                     snprintf(msg_alert, 512, "ossec: File size reduced "
                                              "(inode remained): '%s'.",
                                              logff[i].file);
-                     
+
                     /* Send message about log rotated  */
-                    SendMSG(logr_queue, msg_alert, 
+                    SendMSG(logr_queue, msg_alert,
                             "ossec-logcollector", LOCALFILE_MQ);
-                            
+
                     debug1("%s: DEBUG: File size reduced. %s",
                             ARGV0, logff[i].file);
 
@@ -477,7 +574,7 @@ void LogCollectorStart()
                     CloseHandle(logff[i].h);
                     CloseHandle(h1);
                     #endif
-                    
+
                     logff[i].fp = NULL;
                     handle_file(i, 1, 1);
                 }
@@ -488,9 +585,9 @@ void LogCollectorStart()
                 }
                 #endif
             }
-            
-            
-            /* Too many errors for the file */ 
+
+
+            /* Too many errors for the file */
             if(logff[i].ign > open_file_attempts)
             {
                 /* 999 Maximum ignore */
@@ -498,7 +595,7 @@ void LogCollectorStart()
                 {
                     continue;
                 }
-                
+
                 merror(LOGC_FILE_ERROR, ARGV0, logff[i].file);
                 if(logff[i].fp)
                 {
@@ -507,7 +604,7 @@ void LogCollectorStart()
                     CloseHandle(logff[i].h);
                     #endif
                 }
-                    
+
                 logff[i].fp = NULL;
 
 
@@ -524,9 +621,9 @@ void LogCollectorStart()
                 logff[i].ign = 999;
                 continue;
             }
-           
-           
-            /* File not opened */ 
+
+
+            /* File not opened */
             if(!logff[i].fp)
             {
                 if(logff[i].ign >= 999)
@@ -552,13 +649,13 @@ int update_fname(int i)
 {
     struct tm *p;
     time_t __ctime = time(0);
-    
+
     char lfile[OS_FLSIZE + 1];
     size_t ret;
 
 
     p = localtime(&__ctime);
-    
+
 
     /* Handle file */
     if(p->tm_mday == _cday)
@@ -573,17 +670,17 @@ int update_fname(int i)
     {
         ErrorExit(PARSE_ERROR, ARGV0, logff[i].ffile);
     }
-    
-    
+
+
     /* Update the file name */
     if(strcmp(lfile, logff[i].file) != 0)
     {
         os_free(logff[i].file);
 
-        os_strdup(lfile, logff[i].file);    
+        os_strdup(lfile, logff[i].file);
 
         verbose(VAR_LOG_MON, ARGV0, logff[i].file);
-        
+
         /* Setting cday to zero because other files may need
          * to be changed.
          */
@@ -601,7 +698,7 @@ int handle_file(int i, int do_fseek, int do_log)
 {
     int fd;
     struct stat stat_fd;
-    
+
     /* We must be able to open the file, fseek and get the
      * time of change from it.
      */
@@ -624,10 +721,10 @@ int handle_file(int i, int do_fseek, int do_log)
         logff[i].fp = NULL;
         return(-1);
     }
-    
+
     logff[i].fd = stat_fd.st_ino;
     logff[i].size =  stat_fd.st_size;
-    
+
 
     #else
     BY_HANDLE_FILE_INFORMATION lpFileInformation;
@@ -692,7 +789,7 @@ int handle_file(int i, int do_fseek, int do_log)
         }
         #endif
     }
-    
+
 
     /* Setting ignore to zero */
     logff[i].ign = 0;
@@ -700,4 +797,37 @@ int handle_file(int i, int do_fseek, int do_log)
 }
 
 
+#ifdef WIN32
+
+/* Remove newlines and replace tabs in the argument fields with spaces */
+void win_format_event_string(char *string)
+{
+    if (string == NULL) {
+        return;
+    }
+
+    while (*string != '\0') {
+        if (*string == '\n' || *string == '\r' || *string == ':') {
+            if (*string == '\n' || *string == '\r') {
+                *string = ' ';
+            }
+
+            string++;
+
+            while (*string == '\t') {
+                *string = ' ';
+                string++;
+            }
+
+            continue;
+        }
+
+        string++;
+    }
+}
+
+#endif /* WIN32 */
+
+
+
 /* EOF */