Imported Upstream version 2.7
[ossec-hids.git] / src / analysisd / testrule.c
index c36d8ec..d2f5b25 100755 (executable)
@@ -1,4 +1,5 @@
-/* @(#) $Id$ */
+/* @(#) $Id: ./src/analysisd/testrule.c, 2012/07/23 dcid Exp $
+ */
 
 /* Copyright (C) 2009 Trend Micro Inc.
  * All rights reserved.
@@ -8,7 +9,7 @@
  * License (version 2) as published by the FSF - Free Software
  * Foundation.
  *
- * License details at the LICENSE file included with OSSEC or 
+ * License details at the LICENSE file included with OSSEC or
  * online at: http://www.ossec.net/en/licensing.html
  */
 
@@ -16,7 +17,7 @@
 /* Part of the OSSEC
  * Available at http://www.ossec.net
  */
-  
+
 
 /* ossec-analysisd.
  * Responsible for correlation and log decoding.
@@ -92,6 +93,28 @@ int ReadDecodeXML(char *file);
 int SetDecodeXML();
 
 
+void logtest_help(const char *prog)
+{
+    print_out(" ");
+    print_out("%s %s - %s (%s)", __name, __version, __author, __contact);
+    print_out("%s", __site);
+    print_out(" ");
+    print_out("  %s: -[Vatfdh] [-U ut_str] [-u user] [-g group] [-c config] [-D dir]", prog);
+    print_out("    -V          Version and license message");
+    print_out("    -a          Alerts output");
+    print_out("    -t          Test configuration");
+    print_out("    -v          Verbose (full) output/rule debugging");
+    print_out("    -d          Execute in debug mode");
+    print_out("    -h          This help message");
+    print_out("    -U <rule:alert:decoder>   Unit test. Refer to contrib/ossec-testing/runtests.py");
+    print_out("    -u <user>   Run as 'user'");
+    print_out("    -g <group>  Run as 'group'");
+    print_out("    -c <config> Read the 'config' file");
+    print_out("    -D <dir>    Chroot to 'dir'");
+    print_out(" ");
+    exit(1);
+}
+
 
 
 /** int main(int argc, char **argv)
@@ -100,7 +123,7 @@ int main(int argc, char **argv)
 {
     int t_config = 0;
     int c = 0, m_queue = 0;
-    char *ut_str = NULL; 
+    char *ut_str = NULL;
 
     char *dir = DEFAULTDIR;
     char *user = USER;
@@ -120,7 +143,7 @@ int main(int argc, char **argv)
     active_responses = NULL;
     memset(prev_month, '\0', 4);
 
-    while((c = getopt(argc, argv, "VatfdhU:u:g:D:c:")) != -1){
+    while((c = getopt(argc, argv, "VatvdhU:u:g:D:c:")) != -1){
         switch(c){
            case 'V':
                print_version();
@@ -129,7 +152,7 @@ int main(int argc, char **argv)
                 t_config = 1;
                 break;
             case 'h':
-                help(ARGV0);
+                logtest_help(ARGV0);
                 break;
             case 'd':
                 nowDebug();
@@ -153,6 +176,7 @@ int main(int argc, char **argv)
                 if(!optarg)
                     ErrorExit("%s: -D needs an argument",ARGV0);
                 dir = optarg;
+                break;
             case 'c':
                 if(!optarg)
                     ErrorExit("%s: -c needs an argument",ARGV0);
@@ -160,12 +184,12 @@ int main(int argc, char **argv)
                 break;
             case 'a':
                 alert_only = 1;
-                break;    
-            case 'f':
-                full_output = 1;    
+                break;
+            case 'v':
+                full_output = 1;
                 break;
             default:
-                help(ARGV0);
+                logtest_help(ARGV0);
                 break;
         }
 
@@ -181,14 +205,14 @@ int main(int argc, char **argv)
     }
 
     debug1(READ_CONFIG, ARGV0);
-        
 
-    
+
+
     /* Getting servers hostname */
     memset(__shost, '\0', 512);
     if(gethostname(__shost, 512 -1) != 0)
     {
-        strncpy(__shost, OSSEC_SERVER, 512 -1);    
+        strncpy(__shost, OSSEC_SERVER, 512 -1);
     }
     else
     {
@@ -199,7 +223,7 @@ int main(int argc, char **argv)
         if(_ltmp)
             *_ltmp = '\0';
     }
-    
+
 
 
     if(chdir(dir) != 0)
@@ -207,18 +231,18 @@ int main(int argc, char **argv)
 
 
     /*
-     * Anonymous Section: Load rules, decoders, and lists 
+     * Anonymous Section: Load rules, decoders, and lists
      *
      * As lists require two pass loading of rules that make use of list lookups
-     * are created with blank database structs, and need to be filled in after 
-     * completion of all rules and lists. 
+     * are created with blank database structs, and need to be filled in after
+     * completion of all rules and lists.
      */
     {
         { /* Lad decders */
             /* Initializing the decoders list */
             OS_CreateOSDecoderList();
 
-            if(!Config.decoders) 
+            if(!Config.decoders)
             { /* Legacy loading */
                 /* Reading decoders */
                 if(!ReadDecodeXML("etc/decoder.xml"))
@@ -248,9 +272,9 @@ int main(int argc, char **argv)
                     verbose("%s: INFO: Reading decoder file %s.", ARGV0, *decodersfiles);
                     if(!ReadDecodeXML(*decodersfiles))
                         ErrorExit(CONFIG_ERROR, ARGV0, *decodersfiles);
-                    
-                    free(*decodersfiles);    
-                    decodersfiles++;    
+
+                    free(*decodersfiles);
+                    decodersfiles++;
                 }
             }
 
@@ -259,14 +283,14 @@ int main(int argc, char **argv)
         }
         { /* Load Lists */
             /* Initializing the lists of list struct */
-            Lists_OP_CreateLists(); 
+            Lists_OP_CreateLists();
             /* Load each list into list struct */
             {
                 char **listfiles;
                 listfiles = Config.lists;
                 while(listfiles && *listfiles)
                 {
-                    verbose("%s: INFO: Reading loading the lists file: '%s'", ARGV0, *listfiles);
+                    verbose("%s: INFO: Reading the lists file: '%s'", ARGV0, *listfiles);
                     if(Lists_OP_LoadList(*listfiles) < 0)
                         ErrorExit(LISTS_ERROR, ARGV0, *listfiles);
                     free(*listfiles);
@@ -289,31 +313,31 @@ int main(int argc, char **argv)
                     debug1("%s: INFO: Reading rules file: '%s'", ARGV0, *rulesfiles);
                     if(Rules_OP_ReadRules(*rulesfiles) < 0)
                         ErrorExit(RULES_ERROR, ARGV0, *rulesfiles);
-                        
-                    free(*rulesfiles);    
-                    rulesfiles++;    
+
+                    free(*rulesfiles);
+                    rulesfiles++;
                 }
 
                 free(Config.includes);
                 Config.includes = NULL;
             }
-            
+
             /* Find all rules with that require list lookups and attache the
-             * the correct list struct to the rule.  This keeps rules from having to 
+             * the correct list struct to the rule.  This keeps rules from having to
              * search thought the list of lists for the correct file during rule evaluation.
              */
             OS_ListLoadRules();
         }
     }
 
-    
+
     /* Fixing the levels/accuracy */
     {
         int total_rules;
         RuleNode *tmp_node = OS_GetFirstRule();
 
         total_rules = _setlevels(tmp_node, 0);
-        debug1("%s: INFO: Total rules enabled: '%d'", ARGV0, total_rules);    
+        debug1("%s: INFO: Total rules enabled: '%d'", ARGV0, total_rules);
     }
 
 
@@ -334,7 +358,7 @@ int main(int argc, char **argv)
         exit(0);
     }
 
-    
+
     /* Start up message */
     verbose(STARTUP_MSG, ARGV0, getpid());
 
@@ -344,7 +368,7 @@ int main(int argc, char **argv)
 
 
     exit(0);
-    
+
 }
 
 
@@ -360,12 +384,12 @@ void OS_ReadMSG(int m_queue, char *ut_str)
     int exit_code = 0;
     char *ut_alertlevel = NULL;
     char *ut_rulelevel = NULL;
-    char *ut_decoder_name = NULL; 
+    char *ut_decoder_name = NULL;
 
     if(ut_str)
     {
         /* XXX Break apart string */
-        ut_rulelevel = ut_str; 
+        ut_rulelevel = ut_str;
         ut_alertlevel =  strchr(ut_rulelevel, ':');
         if(!ut_alertlevel)
         {
@@ -375,7 +399,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
         else
         {
             *ut_alertlevel = '\0';
-            ut_alertlevel++; 
+            ut_alertlevel++;
         }
         ut_decoder_name = strchr(ut_alertlevel, ':');
         if(!ut_decoder_name)
@@ -407,7 +431,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
     {
         ErrorExit(FTS_LIST_ERROR, ARGV0);
     }
-                                
+
 
     __crt_ftell = 1;
 
@@ -418,17 +442,17 @@ void OS_ReadMSG(int m_queue, char *ut_str)
 
     /* Doing some cleanup */
     memset(msg, '\0', OS_MAXSTR +1);
-    
+
 
     if(!alert_only)
     print_out("%s: Type one log per line.\n", ARGV0);
-    
-    
+
+
     /* Daemon loop */
     while(1)
     {
         lf = (Eventinfo *)calloc(1,sizeof(Eventinfo));
-        
+
         /* This shouldn't happen .. */
         if(lf == NULL)
         {
@@ -438,9 +462,9 @@ void OS_ReadMSG(int m_queue, char *ut_str)
 
         /* Fixing the msg. */
         snprintf(msg, 15, "1:stdin:");
-        
-    
-        
+
+
+
         /* Receive message from queue */
         if(fgets(msg +8, OS_MAXSTR, stdin))
         {
@@ -460,10 +484,10 @@ void OS_ReadMSG(int m_queue, char *ut_str)
             {
                 continue;
             }
-            
-            
+
+
             if(!alert_only)print_out("\n");
-            
+
 
             /* Default values for the log info */
             Zero_Eventinfo(lf);
@@ -492,17 +516,17 @@ void OS_ReadMSG(int m_queue, char *ut_str)
 
             /* Decoding event. */
             DecodeEvent(lf);
-            
+
 
             /* Looping all the rules */
             rulenode_pt = OS_GetFirstRule();
-            if(!rulenode_pt) 
+            if(!rulenode_pt)
             {
                 ErrorExit("%s: Rules in an inconsistent state. Exiting.",
                         ARGV0);
             }
 
-            
+
             #ifdef TESTRULE
             if(full_output && !alert_only)
                 print_out("\n**Rule debugging:");
@@ -521,9 +545,9 @@ void OS_ReadMSG(int m_queue, char *ut_str)
                     /* We go ahead in here and process the alert. */
                     currently_rule = lf->generated_rule;
                 }
-                                                                                                                                                                                            
+
                 /* The categories must match */
-                else if(rulenode_pt->ruleinfo->category != 
+                else if(rulenode_pt->ruleinfo->category !=
                         lf->decoder_info->type)
                 {
                     continue;
@@ -531,7 +555,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
 
 
                 /* Checking each rule. */
-                else if((currently_rule = OS_CheckIfRuleMatch(lf, rulenode_pt)) 
+                else if((currently_rule = OS_CheckIfRuleMatch(lf, rulenode_pt))
                         == NULL)
                 {
                     continue;
@@ -545,13 +569,13 @@ void OS_ReadMSG(int m_queue, char *ut_str)
                   print_out("       Rule id: '%d'", currently_rule->sigid);
                   print_out("       Level: '%d'", currently_rule->level);
                   print_out("       Description: '%s'",currently_rule->comment);
-                  for (last_info_detail = currently_rule->info_details; last_info_detail != NULL; last_info_detail = last_info_detail->next) 
+                  for (last_info_detail = currently_rule->info_details; last_info_detail != NULL; last_info_detail = last_info_detail->next)
                   {
                       print_out("       Info - %s: '%s'", ruleinfodetail_text[last_info_detail->type], last_info_detail->data);
                   }
                 }
                 #endif
-                                            
+
 
 
                 /* Ignore level 0 */
@@ -561,7 +585,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
                 }
 
 
-                /* Checking ignore time */ 
+                /* Checking ignore time */
                 if(currently_rule->ignore_time)
                 {
                     if(currently_rule->time_ignored == 0)
@@ -572,7 +596,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
                      * is less than the time it should be ignored,
                      * leave (do not alert again).
                      */
-                    else if((lf->time - currently_rule->time_ignored) 
+                    else if((lf->time - currently_rule->time_ignored)
                             < currently_rule->ignore_time)
                     {
                         break;
@@ -586,7 +610,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
                 /* Pointer to the rule that generated it */
                 lf->generated_rule = currently_rule;
 
-                
+
                 /* Checking if we should ignore it */
                 if(currently_rule->ckignore && IGnore(lf))
                 {
@@ -594,7 +618,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
                     lf->generated_rule = NULL;
                     break;
                 }
-                
+
                 /* Checking if we need to add to ignore list */
                 if(currently_rule->ignore)
                 {
@@ -626,19 +650,19 @@ void OS_ReadMSG(int m_queue, char *ut_str)
                     }
                     else
                     {
-                        lf->sid_node_to_delete = 
+                        lf->sid_node_to_delete =
                             currently_rule->sid_prev_matched->last_node;
                     }
                 }
                 /* Group list */
                 else if(currently_rule->group_prev_matched)
                 {
-                    i = 0;  
-                    
+                    i = 0;
+
                     while(i < currently_rule->group_prev_matched_sz)
                     {
                         if(!OSList_AddData(
-                                currently_rule->group_prev_matched[i], 
+                                currently_rule->group_prev_matched[i],
                                 lf))
                         {
                            merror("%s: Unable to add data to grp list.",ARGV0);
@@ -646,7 +670,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
                         i++;
                     }
                 }
-                
+
                 OS_AddEvent(lf);
 
                 break;
@@ -659,7 +683,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
                 char holder[1024];
                 holder[1] = '\0';
                 exit_code = 3;
-                if(strcasecmp(ut_decoder_name, lf->decoder_info->name) == 0)
+                if(lf->decoder_info->name != NULL && strcasecmp(ut_decoder_name, lf->decoder_info->name) == 0)
                 {
                     exit_code--;
                     snprintf(holder, 1023, "%d", currently_rule->sigid);
@@ -678,7 +702,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
 
 
             /* Only clear the memory if the eventinfo was not
-             * added to the stateful memory 
+             * added to the stateful memory
              * -- message is free inside clean event --
              */
             if(lf->generated_rule == NULL)
@@ -687,7 +711,7 @@ void OS_ReadMSG(int m_queue, char *ut_str)
         }
         else
         {
-            exit(exit_code);   
+            exit(exit_code);
         }
     }
     exit(exit_code);