Imported Upstream version 2.7
[ossec-hids.git] / src / analysisd / decoders / syscheck.c
index b8c4a89..8618813 100755 (executable)
@@ -1,11 +1,12 @@
-/* @(#) $Id: syscheck.c,v 1.53 2009/11/04 18:45:38 dcid Exp $ */
+/* @(#) $Id: ./src/analysisd/decoders/syscheck.c, 2012/02/07 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
  */
 
@@ -44,7 +45,7 @@ typedef struct __sdb
     int id3;
     int idn;
     int idd;
-    
+
 
     /* Syscheck rule */
     OSDecoderInfo  *syscheck_dec;
@@ -52,7 +53,7 @@ typedef struct __sdb
 
     /* File search variables */
     fpos_t init_pos;
-    
+
 }_sdb; /* syscheck db information */
 
 
@@ -69,7 +70,7 @@ void SyscheckInit()
     int i = 0;
 
     sdb.db_err = 0;
-    
+
     for(;i <= MAX_AGENTS;i++)
     {
         sdb.agent_ips[i] = NULL;
@@ -80,7 +81,7 @@ void SyscheckInit()
     /* Clearing db memory */
     memset(sdb.buf, '\0', OS_MAXSTR +1);
     memset(sdb.comment, '\0', OS_MAXSTR +1);
-    
+
     memset(sdb.size, '\0', OS_FLSIZE +1);
     memset(sdb.perm, '\0', OS_FLSIZE +1);
     memset(sdb.owner, '\0', OS_FLSIZE +1);
@@ -95,13 +96,13 @@ void SyscheckInit()
     sdb.syscheck_dec->name = SYSCHECK_MOD;
     sdb.syscheck_dec->type = OSSEC_RL;
     sdb.syscheck_dec->fts = 0;
-    
+
     sdb.id1 = getDecoderfromlist(SYSCHECK_MOD);
     sdb.id2 = getDecoderfromlist(SYSCHECK_MOD2);
     sdb.id3 = getDecoderfromlist(SYSCHECK_MOD3);
     sdb.idn = getDecoderfromlist(SYSCHECK_NEW);
     sdb.idd = getDecoderfromlist(SYSCHECK_DEL);
-    
+
     debug1("%s: SyscheckInit completed.", ARGV0);
     return;
 }
@@ -115,7 +116,7 @@ void SyscheckInit()
 void __setcompleted(char *agent)
 {
     FILE *fp;
-    
+
     /* Getting agent file */
     snprintf(sdb.buf, OS_FLSIZE , "%s/.%s.cpt", SYSCHECK_DIR, agent);
 
@@ -153,7 +154,7 @@ void DB_SetCompleted(Eventinfo *lf)
     int i = 0;
 
     /* Finding file pointer */
-    while(sdb.agent_ips[i] != NULL)
+    while(sdb.agent_ips[i] != NULL &&  i < MAX_AGENTS)
     {
         if(strcmp(sdb.agent_ips[i], lf->location) == 0)
         {
@@ -162,7 +163,7 @@ void DB_SetCompleted(Eventinfo *lf)
             {
                 return;
             }
-            
+
             __setcompleted(lf->location);
 
 
@@ -184,7 +185,7 @@ FILE *DB_File(char *agent, int *agent_id)
     int i = 0;
 
     /* Finding file pointer */
-    while(sdb.agent_ips[i] != NULL)
+    while(sdb.agent_ips[i] != NULL  &&  i < MAX_AGENTS)
     {
         if(strcmp(sdb.agent_ips[i], agent) == 0)
         {
@@ -193,18 +194,24 @@ FILE *DB_File(char *agent, int *agent_id)
             *agent_id = i;
             return(sdb.agent_fps[i]);
         }
-        
-        i++;    
+
+        i++;
     }
 
     /* If here, our agent wasn't found */
+    if (i == MAX_AGENTS)
+    {
+        merror("%s: Unable to open integrity file. Increase MAX_AGENTS.",ARGV0);
+        return(NULL);
+    }
+
     os_strdup(agent, sdb.agent_ips[i]);
 
 
     /* Getting agent file */
     snprintf(sdb.buf, OS_FLSIZE , "%s/%s", SYSCHECK_DIR,agent);
-    
-        
+
+
     /* r+ to read and write. Do not truncate */
     sdb.agent_fps[i] = fopen(sdb.buf,"r+");
     if(!sdb.agent_fps[i])
@@ -217,8 +224,8 @@ FILE *DB_File(char *agent, int *agent_id)
             sdb.agent_fps[i] = fopen(sdb.buf, "r+");
         }
     }
-        
-    /* Checking again */    
+
+    /* Checking again */
     if(!sdb.agent_fps[i])
     {
         merror("%s: Unable to open '%s'",ARGV0, sdb.buf);
@@ -232,12 +239,12 @@ FILE *DB_File(char *agent, int *agent_id)
     /* Returning the opened pointer (the beginning of it) */
     fseek(sdb.agent_fps[i],0, SEEK_SET);
     *agent_id = i;
-    
-    
+
+
     /* Getting if the agent was completed */
     if(__iscompleted(agent))
     {
-        sdb.agent_cp[i][0] = '1';    
+        sdb.agent_cp[i][0] = '1';
     }
 
     return(sdb.agent_fps[i]);
@@ -252,10 +259,10 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
     int p = 0;
     int sn_size;
     int agent_id;
-    
+
     char *saved_sum;
     char *saved_name;
-    
+
     FILE *fp;
 
 
@@ -265,6 +272,7 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
     {
         merror("%s: Error handling integrity database.",ARGV0);
         sdb.db_err++; /* Increment db error */
+        lf->data = NULL;
         return(0);
     }
 
@@ -277,8 +285,8 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
         merror("%s: Error handling integrity database (fgetpos).",ARGV0);
         return(0);
     }
-    
-    
+
+
     /* Looping the file */
     while(fgets(sdb.buf, OS_MAXSTR, fp) != NULL)
     {
@@ -290,7 +298,7 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
         }
 
 
-        /* Getting name */    
+        /* Getting name */
         saved_name = strchr(sdb.buf, ' ');
         if(saved_name == NULL)
         {
@@ -300,8 +308,8 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
         }
         *saved_name = '\0';
         saved_name++;
-        
-        
+
+
         /* New format - with a timestamp */
         if(*saved_name == '!')
         {
@@ -330,7 +338,7 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
             fgetpos(fp, &sdb.init_pos);
             continue;
         }
-        
+
 
         saved_sum = sdb.buf;
 
@@ -341,7 +349,10 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
 
         /* checksum match, we can just return and keep going */
         if(strcmp(saved_sum, c_sum) == 0)
+        {
+            lf->data = NULL;
             return(0);
+        }
 
 
         /* If we reached here, the checksum of the file has changed */
@@ -351,10 +362,10 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
             if(saved_sum[-2] == '!')
             {
                 p++;
-                if(saved_sum[-1] == '!')    
+                if(saved_sum[-1] == '!')
                     p++;
                 else if(saved_sum[-1] == '?')
-                    p+=2;    
+                    p+=2;
             }
         }
 
@@ -381,6 +392,7 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
                 break;
 
                 default:
+                lf->data = NULL;
                 return(0);
                 break;
             }
@@ -413,7 +425,7 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
                     "File '%.756s' was deleted. Unable to retrieve "
                     "checksum.", f_name);
         }
-        
+
         /* If file was re-added, do not compare changes */
         else if(saved_sum[0] == '-' && saved_sum[1] == '1')
         {
@@ -422,10 +434,10 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
                      "File '%.756s' was re-added.", f_name);
         }
 
-        else    
+        else
         {
             int oldperm = 0, newperm = 0;
-            
+
             /* Providing more info about the file change */
             char *oldsize = NULL, *newsize = NULL;
             char *olduid = NULL, *newuid = NULL;
@@ -519,6 +531,11 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
                 snprintf(sdb.size, OS_FLSIZE,
                         "Size changed from '%s' to '%s'\n",
                         oldsize, newsize);
+
+                #ifdef PRELUDE
+                os_strdup(oldsize, lf->size_before);
+                os_strdup(newsize, lf->size_after);
+                #endif
             }
 
             /* Permission message */
@@ -528,21 +545,22 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
             }
             else if(oldperm > 0 && newperm > 0)
             {
+
                 snprintf(sdb.perm, OS_FLSIZE, "Permissions changed from "
                         "'%c%c%c%c%c%c%c%c%c' "
                         "to '%c%c%c%c%c%c%c%c%c'\n",
                         (oldperm & S_IRUSR)? 'r' : '-',
                         (oldperm & S_IWUSR)? 'w' : '-',
-                        
+
                         (oldperm & S_ISUID)? 's' :
                         (oldperm & S_IXUSR)? 'x' : '-',
-                        
+
                         (oldperm & S_IRGRP)? 'r' : '-',
                         (oldperm & S_IWGRP)? 'w' : '-',
 
                         (oldperm & S_ISGID)? 's' :
                         (oldperm & S_IXGRP)? 'x' : '-',
-                        
+
                         (oldperm & S_IROTH)? 'r' : '-',
                         (oldperm & S_IWOTH)? 'w' : '-',
 
@@ -557,10 +575,10 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
                         (newperm & S_ISUID)? 's' :
                         (newperm & S_IXUSR)? 'x' : '-',
 
-                        
+
                         (newperm & S_IRGRP)? 'r' : '-',
                         (newperm & S_IWGRP)? 'w' : '-',
-                        
+
                         (newperm & S_ISGID)? 's' :
                         (newperm & S_IXGRP)? 'x' : '-',
 
@@ -569,6 +587,11 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
 
                         (newperm & S_ISVTX)? 't' :
                         (newperm & S_IXOTH)? 'x' : '-');
+
+                #ifdef PRELUDE
+                lf->perm_before = oldperm;
+                lf->perm_after = newperm;
+                #endif
             }
 
             /* Ownership message */
@@ -581,7 +604,13 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
                 snprintf(sdb.owner, OS_FLSIZE, "Ownership was '%s', "
                         "now it is '%s'\n",
                         olduid, newuid);
-            }    
+
+
+                #ifdef PRELUDE
+                os_strdup(olduid, lf->owner_before);
+                os_strdup(newuid, lf->owner_after);
+                #endif
+            }
 
             /* group ownership message */
             if(!newgid || !oldgid || strcmp(newgid, oldgid) == 0)
@@ -593,6 +622,10 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
                 snprintf(sdb.gowner, OS_FLSIZE,"Group ownership was '%s', "
                         "now it is '%s'\n",
                         oldgid, newgid);
+                #ifdef PRELUDE
+                os_strdup(oldgid, lf->gowner_before);
+                os_strdup(newgid, lf->gowner_after);
+                #endif
             }
 
             /* md5 message */
@@ -605,6 +638,10 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
                 snprintf(sdb.md5, OS_FLSIZE, "Old md5sum was: '%s'\n"
                         "New md5sum is : '%s'\n",
                         oldmd5, newmd5);
+                #ifdef PRELUDE
+                os_strdup(oldmd5, lf->md5_before);
+                os_strdup(newmd5, lf->md5_after);
+                #endif
             }
 
             /* sha1 */
@@ -617,25 +654,36 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
                 snprintf(sdb.sha1, OS_FLSIZE, "Old sha1sum was: '%s'\n"
                         "New sha1sum is : '%s'\n",
                         oldsha1, newsha1);
+                #ifdef PRELUDE
+                os_strdup(oldsha1, lf->sha1_before);
+                os_strdup(newsha1, lf->sha1_after);
+                #endif
             }
+            #ifdef PRELUDE
+            os_strdup(f_name, lf->filename);
+            #endif
 
 
-            /* Provide information about the file */    
-            snprintf(sdb.comment, 512, "Integrity checksum changed for: "
+            /* Provide information about the file */
+            snprintf(sdb.comment, OS_MAXSTR, "Integrity checksum changed for: "
                     "'%.756s'\n"
                     "%s"
                     "%s"
                     "%s"
                     "%s"
                     "%s"
-                    "%s",
-                    f_name, 
+                    "%s"
+                    "%s%s",
+                    f_name,
                     sdb.size,
                     sdb.perm,
                     sdb.owner,
                     sdb.gowner,
                     sdb.md5,
-                    sdb.sha1);
+                    sdb.sha1,
+                    lf->data == NULL?"":"What changed:\n",
+                    lf->data == NULL?"":lf->data
+                    );
         }
 
 
@@ -643,22 +691,24 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
         free(lf->full_log);
         os_strdup(sdb.comment, lf->full_log);
         lf->log = lf->full_log;
+        lf->data = NULL;
+
 
-        
         /* Setting decoder */
         lf->decoder_info = sdb.syscheck_dec;
-                        
 
-        return(1); 
+
+        return(1);
 
     } /* continuiing... */
 
 
     /* If we reach here, this file is not present on our database */
     fseek(fp, 0, SEEK_END);
-    
+
     fprintf(fp,"+++%s !%d %s\n", c_sum, lf->time, f_name);
 
+    fflush(fp);
 
     /* Alert if configured to notify on new files */
     if((Config.syscheck_alert_new == 1) && (DB_IsCompleted(agent_id)))
@@ -669,7 +719,7 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
         snprintf(sdb.comment, OS_MAXSTR,
                               "New file '%.756s' "
                               "added to the file system.", f_name);
-        
+
 
         /* Creating a new log message */
         free(lf->full_log);
@@ -679,10 +729,12 @@ int DB_Search(char *f_name, char *c_sum, Eventinfo *lf)
 
         /* Setting decoder */
         lf->decoder_info = sdb.syscheck_dec;
+        lf->data = NULL;
 
         return(1);
     }
 
+    lf->data = NULL;
     return(0);
 }
 
@@ -695,10 +747,10 @@ int DecodeSyscheck(Eventinfo *lf)
 {
     char *c_sum;
     char *f_name;
-   
-   
+
+
     /* Every syscheck message must be in the following format:
-     * checksum filename     
+     * checksum filename
      */
     f_name = strchr(lf->log, ' ');
     if(f_name == NULL)
@@ -711,38 +763,53 @@ int DecodeSyscheck(Eventinfo *lf)
             DB_SetCompleted(lf);
             return(0);
         }
-         
+
         merror(SK_INV_MSG, ARGV0);
         return(0);
     }
-    
-    
+
+
     /* Zeroing to get the check sum */
     *f_name = '\0';
     f_name++;
 
 
+    /* Getting diff. */
+    lf->data = strchr(f_name, '\n');
+    if(lf->data)
+    {
+        *lf->data = '\0';
+        lf->data++;
+    }
+    else
+    {
+        lf->data = NULL;
+    }
+
+
+
     /* Checking if file is supposed to be ignored */
     if(Config.syscheck_ignore)
     {
         char **ff_ig = Config.syscheck_ignore;
-        
+
         while(*ff_ig)
         {
             if(strncasecmp(*ff_ig, f_name, strlen(*ff_ig)) == 0)
             {
+                lf->data = NULL;
                 return(0);
             }
-            
+
             ff_ig++;
         }
     }
-    
-    
+
+
     /* Checksum is at the beginning of the log */
     c_sum = lf->log;
-    
-    
+
+
     /* Searching for file changes */
     return(DB_Search(f_name, c_sum, lf));
 }