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