Merge commit 'v2.5.1'
[ossec-hids.git] / src / analysisd / lists_list.c
diff --git a/src/analysisd/lists_list.c b/src/analysisd/lists_list.c
new file mode 100644 (file)
index 0000000..1078e55
--- /dev/null
@@ -0,0 +1,319 @@
+/* @(#) $Id$ */
+
+/* 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
+ * Foundation
+ */
+
+#include "shared.h"
+#include "rules.h"
+#include "cdb/cdb.h"
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+/* Global */
+ListNode *global_listnode;
+ListRule *global_listrule;
+
+/* 
+ */
+ListNode *_OS_AddList(ListNode *new_listnode);
+
+
+/* Create the ListRule */
+void OS_CreateListsList()
+{
+    global_listnode = NULL;
+    global_listrule = NULL;
+
+    return;
+}
+
+/* Get first listnode  */
+ListNode *OS_GetFirstList()
+{
+    ListNode *listnode_pt = global_listnode;
+    
+    return(listnode_pt);    
+}
+
+ListRule *OS_GetFirstListRule()
+{
+    ListRule *listrule_pt = global_listrule; 
+    return listrule_pt; 
+}
+
+void OS_ListLoadRules()
+{
+    ListRule *lrule = global_listrule;
+    while(lrule != NULL)
+    {
+        if(!lrule->loaded)
+        {
+            lrule->db = OS_FindList(lrule->filename);
+            lrule->loaded=1;
+        }
+        lrule = lrule->next;
+    }
+}
+
+ListRule *_OS_AddListRule(ListRule *new_listrule)
+{
+    
+    if(global_listrule == NULL)
+    {
+        global_listrule = new_listrule;
+    } 
+    else 
+    {
+        ListRule *last_list_rule = global_listrule;
+        while(last_list_rule->next != NULL)
+        {
+            last_list_rule = last_list_rule->next; 
+        }
+        last_list_rule->next = new_listrule; 
+    }
+    return(global_listrule);
+}
+
+
+
+/* Add a list in the chain */
+ListNode *_OS_AddList(ListNode *new_listnode)
+{
+    if(global_listnode == NULL)
+    {
+        /* First list */
+        global_listnode = new_listnode;
+    }
+    else
+    {
+        /* Adding new list to the end */
+        ListNode *last_list_node = global_listnode;
+
+        while(last_list_node->next != NULL)
+        {
+            last_list_node = last_list_node->next;
+        }
+        last_list_node->next = new_listnode;
+        
+    }
+    return(global_listnode);
+}
+
+/* External AddList */
+int OS_AddList(ListNode *new_listnode)
+{
+    _OS_AddList(new_listnode);
+    return(0);
+}
+
+ListNode *_OS_FindList(ListNode *_listnode, char *listname)
+{
+    ListNode *last_list_node = OS_GetFirstList();
+    if (last_list_node != NULL) {
+        do
+        {
+            if (strcmp(last_list_node->txt_filename, listname) == 0 ||
+                strcmp(last_list_node->cdb_filename, listname) == 0) 
+            {
+                /* Found first match returning */
+                return(last_list_node);
+            }
+            last_list_node = last_list_node->next;
+        } while (last_list_node != NULL);
+    }
+    return(NULL);
+}
+    
+ListNode *OS_FindList(char *listname)
+{
+    ListNode *matched = NULL;
+    matched = _OS_FindList(global_listnode, listname);
+    return matched;
+}
+
+ListRule *OS_AddListRule(ListRule *first_rule_list, 
+                         int lookup_type, 
+                         int field, 
+                         char *listname,
+                         OSMatch *matcher)
+{
+    ListRule *new_rulelist_pt = NULL;
+    new_rulelist_pt = (ListRule *)calloc(1,sizeof(ListRule));
+    new_rulelist_pt->field = field;
+    new_rulelist_pt->next = NULL;
+    new_rulelist_pt->matcher = matcher;
+    new_rulelist_pt->lookup_type = lookup_type; 
+    new_rulelist_pt->filename = listname;
+    if((new_rulelist_pt->db = OS_FindList(listname)) == NULL)
+        new_rulelist_pt->loaded = 0;
+    else
+        new_rulelist_pt->loaded = 1;
+    if(first_rule_list == NULL)
+    {
+        debug1("Adding First rulelist item: filename: %s field: %d lookup_type: %d",
+               new_rulelist_pt->filename,
+               new_rulelist_pt->field,
+               new_rulelist_pt->lookup_type);
+       first_rule_list = new_rulelist_pt;
+    }
+    else
+    {
+       while(first_rule_list->next)
+       {
+               first_rule_list = first_rule_list->next;
+        }
+        debug1("Adding rulelist item: filename: %s field: %d lookup_type: %d",
+               new_rulelist_pt->filename,
+               new_rulelist_pt->field,
+               new_rulelist_pt->lookup_type);
+        first_rule_list->next = new_rulelist_pt;
+    }
+    return first_rule_list;
+}
+
+int _OS_CDBOpen(ListNode *lnode)
+{
+    int fd;
+    if (lnode->loaded != 1)
+    {
+        if((fd = open(lnode->cdb_filename, O_RDONLY)) == -1)
+        {
+            merror(OPEN_ERROR, ARGV0, lnode->cdb_filename, strerror (errno));
+            return -1;
+        }
+        cdb_init(&lnode->cdb, fd);
+        lnode->loaded = 1;
+    }
+    return 0;
+}
+
+int OS_DBSearchKeyValue(ListRule *lrule, char *key)
+{
+    int result=-1;
+    char *val;
+    unsigned vlen, vpos;
+    if (lrule->db!= NULL)
+    {
+        if(_OS_CDBOpen(lrule->db) == -1) return 0;
+        if(cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
+            vpos = cdb_datapos(&lrule->db->cdb);
+            vlen = cdb_datalen(&lrule->db->cdb);
+            val = malloc(vlen);
+            cdb_read(&lrule->db->cdb, val, vlen, vpos);
+            result = OSMatch_Execute(val, vlen, lrule->matcher);
+            free(val);
+            return result; 
+        } else {
+            return 0;
+        }
+    } 
+    return 0;
+}
+
+
+
+int OS_DBSeachKey(ListRule *lrule, char *key)
+{
+    if (lrule->db != NULL)
+    {
+        if(_OS_CDBOpen(lrule->db) == -1) return -1;
+        if( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) return 1;
+    } 
+    return 0;
+}
+
+int OS_DBSeachKeyAddress(ListRule *lrule, char *key)
+{
+    //char _ip[128];
+    //_ip[127] = "\0";
+    if (lrule->db != NULL)
+    {
+        if(_OS_CDBOpen(lrule->db) == -1) return -1;
+        //snprintf(_ip,128,"%s",key);
+        //XXX Breka apart string on the . boundtrys a loop over to longest match. 
+
+        if( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
+            return 1;
+        }
+        else 
+        {
+            char *tmpkey;
+            os_strdup(key, tmpkey);
+            while(strlen(tmpkey) > 0)
+            {
+                if(tmpkey[strlen(tmpkey) - 1] == '.')
+                {
+                    if( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) {
+                        free(tmpkey);
+                        return 1;
+                    } 
+                }
+                tmpkey[strlen(tmpkey) - 1] = '\0';
+            }
+            free(tmpkey);
+        }
+    } 
+    return 0;
+}
+
+int OS_DBSearch(ListRule *lrule, char *key)
+{
+    //XXX - god damn hack!!! Jeremy Rossi 
+    if (lrule->loaded == 0)
+    {
+        lrule->db = OS_FindList(lrule->filename);
+        lrule->loaded = 1;
+    }
+    switch(lrule->lookup_type)
+    {
+        case LR_STRING_MATCH:
+            //debug1("LR_STRING_MATCH");
+            if(OS_DBSeachKey(lrule, key) == 1)
+                return 1;
+            else 
+                return 0;
+            break;
+        case LR_STRING_NOT_MATCH:
+            //debug1("LR_STRING_NOT_MATCH");
+            if(OS_DBSeachKey(lrule, key) == 1)
+                return 0;
+            else
+                return 1;
+            break;
+        case LR_STRING_MATCH_VALUE:
+            //debug1("LR_STRING_MATCH_VALUE");
+            // XXX TODO
+            return 0;
+            break;
+        case LR_ADDRESS_MATCH:
+            //debug1("LR_ADDRESS_MATCH");
+            return OS_DBSeachKeyAddress(lrule, key);
+            break;
+        case LR_ADDRESS_NOT_MATCH:
+            //debug1("LR_ADDRESS_NOT_MATCH");
+            if(OS_DBSeachKeyAddress(lrule, key) == 0)
+                return 1;
+            else
+                return 0;
+            break;
+        case LR_ADDRESS_MATCH_VALUE: 
+            //debug1("LR_ADDRESS_MATCH_VALUE");
+            // XXX TODO 
+            return 0; 
+            break;
+        default:
+            debug1("lists_list.c::OS_DBSearch should never hit default");
+            return 0;
+    }
+    return 0;
+}
+