Merge commit 'v2.5.1'
[ossec-hids.git] / src / analysisd / analysisd.c
index 25f8e18..8119c22 100755 (executable)
@@ -1,11 +1,11 @@
-/* @(#) $Id: analysisd.c,v 1.149 2009/11/20 16:11:46 dcid Exp $ */
+/* @(#) $Id$ */
 
-/* Copyright (C) 2009 Trend Micro Inc.
+/* Copyright (C) 2010 Trend Micro Inc.
  * All rights 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.
  *
  * License details at the LICENSE file included with OSSEC or 
@@ -41,6 +41,7 @@
 #include "config.h"
 #include "rules.h"
 #include "stats.h"
+
 #include "eventinfo.h"
 #include "analysisd.h"
 
@@ -73,6 +74,7 @@ int GlobalConf(char * cfgfile);
 
 /* For rules */
 void Rules_OP_CreateRules();
+void Lists_OP_CreateLists();
 int Rules_OP_ReadRules(char * cfgfile);
 int _setlevels(RuleNode *node, int nnode);
 int AddHash_Rule(RuleNode *node);
@@ -87,6 +89,7 @@ int FTS_Init();
 int FTS(Eventinfo *lf);
 int AddtoIGnore(Eventinfo *lf);
 int IGnore(Eventinfo *lf);
+int doDiff(RuleInfo *currently_rule, Eventinfo *lf);
 
 
 /* For decoders */
@@ -271,8 +274,7 @@ int main_analysisd(int argc, char **argv)
         OS_PicvizOpen(Config.picviz_socket);
         chown(Config.picviz_socket, uid, gid);
     }
-    
-    
+
     /* Setting the group */    
     if(Privsep_SetGroup(gid) < 0)
         ErrorExit(SETGID_ERROR,ARGV0,group);
@@ -286,54 +288,109 @@ int main_analysisd(int argc, char **argv)
     
     
 
-    /* Initializing the list */
-    OS_CreateOSDecoderList();
-        
-
-    /* Reading decoders */
-    if(!ReadDecodeXML(XML_DECODER))
+    /*
+     * 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. 
+     */
     {
-        ErrorExit(CONFIG_ERROR, ARGV0,  XML_DECODER);
-    }
+        {
+            /* Initializing the decoders list */
+            OS_CreateOSDecoderList();
 
-    /* Reading local ones. */
-    c = ReadDecodeXML(XML_LDECODER);
-    if(!c)
-    {
-        if((c != -2))
-            ErrorExit(CONFIG_ERROR, ARGV0,  XML_LDECODER);
-    }
-    else
-    {
-        if(!test_config)
-            verbose("%s: INFO: Reading local decoder file.", ARGV0);
-    }
-    SetDecodeXML();
+            if(!Config.decoders) 
+            { /* Legacy loading */
+                /* Reading decoders */
+                if(!ReadDecodeXML(XML_DECODER))
+                {
+                    ErrorExit(CONFIG_ERROR, ARGV0,  XML_DECODER);
+                }
 
-    
-    /* Creating the rules list */
-    Rules_OP_CreateRules();
+                /* Reading local ones. */
+                c = ReadDecodeXML(XML_LDECODER);
+                if(!c)
+                {
+                    if((c != -2))
+                        ErrorExit(CONFIG_ERROR, ARGV0,  XML_LDECODER);
+                }
+                else
+                {
+                    if(!test_config)
+                        verbose("%s: INFO: Reading local decoder file.", ARGV0);
+                }
+            }
+            else
+            { /* New loaded based on file speified in ossec.conf */
+                char **decodersfiles;
+                decodersfiles = Config.decoders;
+                while( decodersfiles && *decodersfiles)
+                {
+                    if(!test_config)
+                        verbose("%s: INFO: Reading decoder file %s.", ARGV0, *decodersfiles);
+                    if(!ReadDecodeXML(*decodersfiles))
+                        ErrorExit(CONFIG_ERROR, ARGV0, *decodersfiles);
+                    
+                    free(*decodersfiles);    
+                    decodersfiles++;    
+                }
+            }
 
-   
-    /* Reading the rules */
-    {
-        char **rulesfiles;
-        rulesfiles = Config.includes;
-        while(rulesfiles && *rulesfiles)
-        {
-            if(!test_config)
-                verbose("%s: INFO: Reading rules file: '%s'", ARGV0, *rulesfiles);
-            if(Rules_OP_ReadRules(*rulesfiles) < 0)
-                ErrorExit(RULES_ERROR, ARGV0, *rulesfiles);
-                
-            free(*rulesfiles);    
-            rulesfiles++;    
+            /* Load decoders */
+            SetDecodeXML();
         }
+        { /* Load Lists */
+            /* Initializing the lists of list struct */
+            Lists_OP_CreateLists(); 
+            /* Load each list into list struct */
+            {
+                char **listfiles;
+                listfiles = Config.lists;
+                while(listfiles && *listfiles)
+                {
+                    if(!test_config)
+                        verbose("%s: INFO: Reading loading the lists file: '%s'", ARGV0, *listfiles);
+                    if(Lists_OP_LoadList(*listfiles) < 0)
+                        ErrorExit(LISTS_ERROR, ARGV0, *listfiles);
+                    free(*listfiles);
+                    listfiles++;
+                }
+                free(Config.lists);
+                Config.lists = NULL;
+            }
+        }
+        { /* Load Rules */
+            /* Creating the rules list */
+            Rules_OP_CreateRules();
 
-        free(Config.includes);
-        Config.includes = NULL;
+            /* Reading the rules */
+            {
+                char **rulesfiles;
+                rulesfiles = Config.includes;
+                while(rulesfiles && *rulesfiles)
+                {
+                    if(!test_config)
+                        verbose("%s: INFO: Reading rules file: '%s'", ARGV0, *rulesfiles);
+                    if(Rules_OP_ReadRules(*rulesfiles) < 0)
+                        ErrorExit(RULES_ERROR, ARGV0, *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 
+             * search thought the list of lists for the correct file during rule evaluation.
+             */
+            OS_ListLoadRules();
+        }
     }
-    
+
     
     /* Fixing the levels/accuracy */
     {
@@ -1109,7 +1166,7 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
    
 
     #ifdef TESTRULE
-    if(full_output)
+    if(full_output && !alert_only)
     print_out("    Trying rule: %d - %s", currently_rule->sigid,
                                           currently_rule->comment);
     #endif
@@ -1123,7 +1180,6 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
     }
    
     
-    
     /* Checking program name */
     if(currently_rule->program_name)
     {
@@ -1149,6 +1205,9 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
                             strlen(lf->id),
                             currently_rule->id))
             return(NULL);
+        #ifdef CDBLOOKUP
+
+        #endif
     }
     
 
@@ -1192,6 +1251,9 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
         {
             return(NULL);
         }
+        #ifdef CDBLOOKUP
+
+        #endif
     }
 
 
@@ -1211,6 +1273,9 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
             {
                 return(NULL);
             }
+            #ifdef CDBLOOKUP
+
+            #endif
         }
 
         /* Checking for the dstip */
@@ -1225,6 +1290,9 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
             {
                 return(NULL);
             }
+            #ifdef CDBLOOKUP
+
+            #endif
         }
 
         if(currently_rule->srcport)
@@ -1240,6 +1308,9 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
             {
                 return(NULL);
             }
+            #ifdef CDBLOOKUP
+
+            #endif
         }
         if(currently_rule->dstport)
         {
@@ -1254,6 +1325,9 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
             {
                 return(NULL);
             }
+            #ifdef CDBLOOKUP
+
+            #endif
         }
     } /* END PACKET_INFO */
     
@@ -1289,6 +1363,9 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
                     return(NULL);
             }
             else
+            #ifdef CDBLOOKUP
+
+            #endif
             {
                 /* no user set */
                 return(NULL);
@@ -1361,9 +1438,18 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
                         currently_rule->status))
                 return(NULL);
         }
+
+
+        /* Do diff check. */
+        if(currently_rule->context_opts & SAME_DODIFF)
+        {
+            if(!doDiff(currently_rule, lf))
+            {
+                return(NULL);
+            }
+        }
     }
 
-                                                                    
     /* Checking for the FTS flag */
     if(currently_rule->alert_opts & DO_FTS)
     {
@@ -1385,6 +1471,98 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
         }
     }
 
+    /* List lookups */
+    if(currently_rule->lists != NULL)
+    {
+        ListRule *list_holder=currently_rule->lists;
+        while(list_holder)
+        {
+            switch(list_holder->field)
+            {
+                case RULE_SRCIP:
+                    if(!lf->srcip)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->srcip))
+                        return(NULL);
+                    break;
+                case RULE_SRCPORT:
+                    if(!lf->srcport)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->srcport))
+                        return(NULL);
+                    break;
+                case RULE_DSTIP:
+                    if(!lf->dstip)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->dstip))
+                        return(NULL);
+                    break;
+                case RULE_DSTPORT:
+                    if(!lf->dstport)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->dstport))
+                        return(NULL);
+                    break;
+                case RULE_USER:
+                    if(lf->srcuser)
+                    {
+                        if(!OS_DBSearch(list_holder,lf->srcuser))
+                            return(NULL);
+                    }
+                    else if(lf->dstuser)
+                    {
+                        if(!OS_DBSearch(list_holder,lf->dstuser))
+                            return(NULL);
+                    }
+                    else
+                    {
+                        return(NULL);
+                    }
+                    break;
+                case RULE_URL:
+                    if(!lf->url)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->url))
+                        return(NULL);
+                    break;
+                case RULE_ID:
+                    if(!lf->id)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->id))
+                        return(NULL);
+                    break;
+                case RULE_HOSTNAME:
+                    if(!lf->hostname)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->hostname))
+                        return(NULL);
+                    break;
+                case RULE_PROGRAM_NAME:
+                    if(!lf->program_name)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->program_name))
+                        return(NULL);
+                    break;
+                case RULE_STATUS:
+                    if(!lf->status)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->status))
+                        return(NULL);
+                    break;
+                case RULE_ACTION:
+                    if(!lf->action)
+                        return(NULL);
+                    if(!OS_DBSearch(list_holder,lf->action))
+                        return(NULL);
+                    break;
+                default:
+                    return(NULL);
+            }
+
+            list_holder = list_holder->next;
+        }
+    }
+
         
     /* If it is a context rule, search for it */
     if(currently_rule->context == 1)
@@ -1394,7 +1572,7 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
     }
 
     #ifdef TESTRULE
-    if(full_output)
+    if(full_output && !alert_only)
     print_out("       *Rule %d matched.", currently_rule->sigid);
     #endif
     
@@ -1406,7 +1584,7 @@ RuleInfo *OS_CheckIfRuleMatch(Eventinfo *lf, RuleNode *curr_node)
         RuleInfo *child_rule = NULL;
         
         #ifdef TESTRULE
-        if(full_output)
+        if(full_output && !alert_only)
         print_out("       *Trying child rules.");
         #endif
         
@@ -1539,3 +1717,4 @@ void DumpLogstats()
 
 
 /* EOF */
+