Imported Upstream version 2.7
[ossec-hids.git] / src / analysisd / lists_list.c
1 /* @(#) $Id: ./src/analysisd/lists_list.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All right reserved.
6  *
7  * This program is a free software; you can redistribute it
8  * and/or modify it under the terms of the GNU General Public
9  * License (version 3) as published by the FSF - Free Software
10  * Foundation
11  */
12
13
14 #include "shared.h"
15 #include "rules.h"
16 #include "cdb/cdb.h"
17 #include <fcntl.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <errno.h>
21
22 /* Global */
23 ListNode *global_listnode;
24 ListRule *global_listrule;
25
26 /*
27  */
28 ListNode *_OS_AddList(ListNode *new_listnode);
29
30
31 /* Create the ListRule */
32 void OS_CreateListsList()
33 {
34     global_listnode = NULL;
35     global_listrule = NULL;
36
37     return;
38 }
39
40 /* Get first listnode  */
41 ListNode *OS_GetFirstList()
42 {
43     ListNode *listnode_pt = global_listnode;
44
45     return(listnode_pt);
46 }
47
48 ListRule *OS_GetFirstListRule()
49 {
50     ListRule *listrule_pt = global_listrule;
51     return listrule_pt;
52 }
53
54 void OS_ListLoadRules()
55 {
56     ListRule *lrule = global_listrule;
57     while(lrule != NULL)
58     {
59         if(!lrule->loaded)
60         {
61             lrule->db = OS_FindList(lrule->filename);
62             lrule->loaded=1;
63         }
64         lrule = lrule->next;
65     }
66 }
67
68 ListRule *_OS_AddListRule(ListRule *new_listrule)
69 {
70
71     if(global_listrule == NULL)
72     {
73         global_listrule = new_listrule;
74     }
75     else
76     {
77         ListRule *last_list_rule = global_listrule;
78         while(last_list_rule->next != NULL)
79         {
80             last_list_rule = last_list_rule->next;
81         }
82         last_list_rule->next = new_listrule;
83     }
84     return(global_listrule);
85 }
86
87
88
89 /* Add a list in the chain */
90 ListNode *_OS_AddList(ListNode *new_listnode)
91 {
92     if(global_listnode == NULL)
93     {
94         /* First list */
95         global_listnode = new_listnode;
96     }
97     else
98     {
99         /* Adding new list to the end */
100         ListNode *last_list_node = global_listnode;
101
102         while(last_list_node->next != NULL)
103         {
104             last_list_node = last_list_node->next;
105         }
106         last_list_node->next = new_listnode;
107
108     }
109     return(global_listnode);
110 }
111
112 /* External AddList */
113 int OS_AddList(ListNode *new_listnode)
114 {
115     _OS_AddList(new_listnode);
116     return(0);
117 }
118
119 ListNode *_OS_FindList(ListNode *_listnode, char *listname)
120 {
121     ListNode *last_list_node = OS_GetFirstList();
122     if (last_list_node != NULL) {
123         do
124         {
125             if (strcmp(last_list_node->txt_filename, listname) == 0 ||
126                 strcmp(last_list_node->cdb_filename, listname) == 0)
127             {
128                 /* Found first match returning */
129                 return(last_list_node);
130             }
131             last_list_node = last_list_node->next;
132         } while (last_list_node != NULL);
133     }
134     return(NULL);
135 }
136
137 ListNode *OS_FindList(char *listname)
138 {
139     ListNode *matched = NULL;
140     matched = _OS_FindList(global_listnode, listname);
141     return matched;
142 }
143
144 ListRule *OS_AddListRule(ListRule *first_rule_list,
145                          int lookup_type,
146                          int field,
147                          char *listname,
148                          OSMatch *matcher)
149 {
150     ListRule *new_rulelist_pt = NULL;
151     new_rulelist_pt = (ListRule *)calloc(1,sizeof(ListRule));
152     new_rulelist_pt->field = field;
153     new_rulelist_pt->next = NULL;
154     new_rulelist_pt->matcher = matcher;
155     new_rulelist_pt->lookup_type = lookup_type;
156     new_rulelist_pt->filename = listname;
157     if((new_rulelist_pt->db = OS_FindList(listname)) == NULL)
158         new_rulelist_pt->loaded = 0;
159     else
160         new_rulelist_pt->loaded = 1;
161     if(first_rule_list == NULL)
162     {
163         debug1("Adding First rulelist item: filename: %s field: %d lookup_type: %d",
164                new_rulelist_pt->filename,
165                new_rulelist_pt->field,
166                new_rulelist_pt->lookup_type);
167         first_rule_list = new_rulelist_pt;
168     }
169     else
170     {
171         while(first_rule_list->next)
172         {
173                 first_rule_list = first_rule_list->next;
174         }
175         debug1("Adding rulelist item: filename: %s field: %d lookup_type: %d",
176                new_rulelist_pt->filename,
177                new_rulelist_pt->field,
178                new_rulelist_pt->lookup_type);
179         first_rule_list->next = new_rulelist_pt;
180     }
181     return first_rule_list;
182 }
183
184 int _OS_CDBOpen(ListNode *lnode)
185 {
186     int fd;
187     if (lnode->loaded != 1)
188     {
189         if((fd = open(lnode->cdb_filename, O_RDONLY)) == -1)
190         {
191             merror(OPEN_ERROR, ARGV0, lnode->cdb_filename, strerror (errno));
192             return -1;
193         }
194         cdb_init(&lnode->cdb, fd);
195         lnode->loaded = 1;
196     }
197     return 0;
198 }
199
200 int OS_DBSearchKeyValue(ListRule *lrule, char *key)
201 {
202     int result=-1;
203     char *val;
204     unsigned vlen, vpos;
205     if (lrule->db!= NULL)
206     {
207         if(_OS_CDBOpen(lrule->db) == -1) return 0;
208         if(cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
209             vpos = cdb_datapos(&lrule->db->cdb);
210             vlen = cdb_datalen(&lrule->db->cdb);
211             val = malloc(vlen);
212             cdb_read(&lrule->db->cdb, val, vlen, vpos);
213             result = OSMatch_Execute(val, vlen, lrule->matcher);
214             free(val);
215             return result;
216         } else {
217             return 0;
218         }
219     }
220     return 0;
221 }
222
223
224
225 int OS_DBSeachKey(ListRule *lrule, char *key)
226 {
227     if (lrule->db != NULL)
228     {
229         if(_OS_CDBOpen(lrule->db) == -1) return -1;
230         if( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) return 1;
231     }
232     return 0;
233 }
234
235 int OS_DBSeachKeyAddress(ListRule *lrule, char *key)
236 {
237     //char _ip[128];
238     //_ip[127] = "\0";
239     if (lrule->db != NULL)
240     {
241         if(_OS_CDBOpen(lrule->db) == -1) return -1;
242         //snprintf(_ip,128,"%s",key);
243         //XXX Breka apart string on the . boundtrys a loop over to longest match.
244
245         if( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
246             return 1;
247         }
248         else
249         {
250             char *tmpkey;
251             os_strdup(key, tmpkey);
252             while(strlen(tmpkey) > 0)
253             {
254                 if(tmpkey[strlen(tmpkey) - 1] == '.')
255                 {
256                     if( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) {
257                         free(tmpkey);
258                         return 1;
259                     }
260                 }
261                 tmpkey[strlen(tmpkey) - 1] = '\0';
262             }
263             free(tmpkey);
264         }
265     }
266     return 0;
267 }
268
269 int OS_DBSearch(ListRule *lrule, char *key)
270 {
271     //XXX - god damn hack!!! Jeremy Rossi
272     if (lrule->loaded == 0)
273     {
274         lrule->db = OS_FindList(lrule->filename);
275         lrule->loaded = 1;
276     }
277     switch(lrule->lookup_type)
278     {
279         case LR_STRING_MATCH:
280             //debug1("LR_STRING_MATCH");
281             if(OS_DBSeachKey(lrule, key) == 1)
282                 return 1;
283             else
284                 return 0;
285             break;
286         case LR_STRING_NOT_MATCH:
287             //debug1("LR_STRING_NOT_MATCH");
288             if(OS_DBSeachKey(lrule, key) == 1)
289                 return 0;
290             else
291                 return 1;
292             break;
293         case LR_STRING_MATCH_VALUE:
294             //debug1("LR_STRING_MATCH_VALUE");
295             // XXX TODO
296             return 0;
297             break;
298         case LR_ADDRESS_MATCH:
299             //debug1("LR_ADDRESS_MATCH");
300             return OS_DBSeachKeyAddress(lrule, key);
301             break;
302         case LR_ADDRESS_NOT_MATCH:
303             //debug1("LR_ADDRESS_NOT_MATCH");
304             if(OS_DBSeachKeyAddress(lrule, key) == 0)
305                 return 1;
306             else
307                 return 0;
308             break;
309         case LR_ADDRESS_MATCH_VALUE:
310             //debug1("LR_ADDRESS_MATCH_VALUE");
311             // XXX TODO
312             return 0;
313             break;
314         default:
315             debug1("lists_list.c::OS_DBSearch should never hit default");
316             return 0;
317     }
318     return 0;
319 }
320