1 /* Copyright (C) 2009 Trend Micro Inc.
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 3) as published by the FSF - Free Software
19 static ListNode *global_listnode;
20 static ListRule *global_listrule;
23 /* Create the ListRule */
24 void OS_CreateListsList()
26 global_listnode = NULL;
27 global_listrule = NULL;
32 /* Get first listnode */
33 ListNode *OS_GetFirstList()
35 ListNode *listnode_pt = global_listnode;
40 void OS_ListLoadRules()
42 ListRule *lrule = global_listrule;
43 while (lrule != NULL) {
45 lrule->db = OS_FindList(lrule->filename);
52 /* External AddList */
53 int OS_AddList(ListNode *new_listnode)
55 if (global_listnode == NULL) {
57 global_listnode = new_listnode;
59 /* Add new list to the end */
60 ListNode *last_list_node = global_listnode;
62 while (last_list_node->next != NULL) {
63 last_list_node = last_list_node->next;
65 last_list_node->next = new_listnode;
71 ListNode *OS_FindList(const char *listname)
73 ListNode *last_list_node = OS_GetFirstList();
74 if (last_list_node != NULL) {
76 if (strcmp(last_list_node->txt_filename, listname) == 0 ||
77 strcmp(last_list_node->cdb_filename, listname) == 0) {
78 /* Found first match returning */
79 return (last_list_node);
81 last_list_node = last_list_node->next;
82 } while (last_list_node != NULL);
87 ListRule *OS_AddListRule(ListRule *first_rule_list,
93 ListRule *new_rulelist_pt = NULL;
94 new_rulelist_pt = (ListRule *)calloc(1, sizeof(ListRule));
95 if (!new_rulelist_pt) {
99 new_rulelist_pt->field = field;
100 new_rulelist_pt->next = NULL;
101 new_rulelist_pt->matcher = matcher;
102 new_rulelist_pt->lookup_type = lookup_type;
103 new_rulelist_pt->filename = listname;
104 if ((new_rulelist_pt->db = OS_FindList(listname)) == NULL) {
105 new_rulelist_pt->loaded = 0;
107 new_rulelist_pt->loaded = 1;
109 if (first_rule_list == NULL) {
110 debug1("Adding First rulelist item: filename: %s field: %d lookup_type: %d",
111 new_rulelist_pt->filename,
112 new_rulelist_pt->field,
113 new_rulelist_pt->lookup_type);
114 first_rule_list = new_rulelist_pt;
116 while (first_rule_list->next) {
117 first_rule_list = first_rule_list->next;
119 debug1("Adding rulelist item: filename: %s field: %d lookup_type: %d",
120 new_rulelist_pt->filename,
121 new_rulelist_pt->field,
122 new_rulelist_pt->lookup_type);
123 first_rule_list->next = new_rulelist_pt;
125 return first_rule_list;
128 static int _OS_CDBOpen(ListNode *lnode)
131 if (lnode->loaded != 1) {
132 if ((fd = open(lnode->cdb_filename, O_RDONLY)) == -1) {
133 merror(OPEN_ERROR, ARGV0, lnode->cdb_filename, errno, strerror (errno));
136 cdb_init(&lnode->cdb, fd);
142 static int OS_DBSearchKeyValue(ListRule *lrule, char *key)
147 if (lrule->db != NULL) {
148 if (_OS_CDBOpen(lrule->db) == -1) {
151 if (cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
152 vpos = cdb_datapos(&lrule->db->cdb);
153 vlen = cdb_datalen(&lrule->db->cdb);
154 val = (char *) calloc(vlen + 1, sizeof(char));
156 merror("%s: malloc failed: %s", ARGV0, strerror(errno));
159 cdb_read(&lrule->db->cdb, val, vlen, vpos);
160 result = OSMatch_Execute(val, vlen, lrule->matcher);
170 static int OS_DBSeachKey(ListRule *lrule, char *key)
172 if (lrule->db != NULL) {
173 if (_OS_CDBOpen(lrule->db) == -1) {
176 if ( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
183 static int OS_DBSeachKeyAddress(ListRule *lrule, char *key)
185 if (lrule->db != NULL) {
186 if (_OS_CDBOpen(lrule->db) == -1) {
190 if ( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
194 os_strdup(key, tmpkey);
195 while (strlen(tmpkey) > 0) {
196 if (tmpkey[strlen(tmpkey) - 1] == '.') {
197 if ( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) {
202 tmpkey[strlen(tmpkey) - 1] = '\0';
210 static int OS_DBSearchKeyAddressValue(ListRule *lrule, char *key)
215 if (lrule->db != NULL) {
216 if (_OS_CDBOpen(lrule->db) == -1) {
220 /* First lookup for a single IP address */
221 if (cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
222 vpos = cdb_datapos(&lrule->db->cdb);
223 vlen = cdb_datalen(&lrule->db->cdb);
224 val = (char *) malloc(vlen);
226 merror("%s: malloc failed", ARGV0);
229 cdb_read(&lrule->db->cdb, val, vlen, vpos);
230 result = OSMatch_Execute(val, vlen, lrule->matcher);
234 /* IP address not found, look for matching subnets */
236 os_strdup(key, tmpkey);
237 while (strlen(tmpkey) > 0) {
238 if (tmpkey[strlen(tmpkey) - 1] == '.') {
239 if ( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) {
240 vpos = cdb_datapos(&lrule->db->cdb);
241 vlen = cdb_datalen(&lrule->db->cdb);
242 val = (char *) malloc(vlen);
243 cdb_read(&lrule->db->cdb, val, vlen, vpos);
244 result = OSMatch_Execute(val, vlen, lrule->matcher);
250 tmpkey[strlen(tmpkey) - 1] = '\0';
259 int OS_DBSearch(ListRule *lrule, char *key)
261 //XXX - god damn hack!!! Jeremy Rossi
262 if (lrule->loaded == 0) {
263 lrule->db = OS_FindList(lrule->filename);
266 switch (lrule->lookup_type) {
267 case LR_STRING_MATCH:
268 //debug1("LR_STRING_MATCH");
269 if (OS_DBSeachKey(lrule, key) == 1) {
273 case LR_STRING_NOT_MATCH:
274 //debug1("LR_STRING_NOT_MATCH");
275 if (OS_DBSeachKey(lrule, key) == 1) {
279 case LR_STRING_MATCH_VALUE:
280 //debug1("LR_STRING_MATCH_VALUE");
281 if (OS_DBSearchKeyValue(lrule, key) == 1) {
285 case LR_ADDRESS_MATCH:
286 //debug1("LR_ADDRESS_MATCH");
287 return OS_DBSeachKeyAddress(lrule, key);
288 case LR_ADDRESS_NOT_MATCH:
289 //debug1("LR_ADDRESS_NOT_MATCH");
290 if (OS_DBSeachKeyAddress(lrule, key) == 0) {
294 case LR_ADDRESS_MATCH_VALUE:
295 //debug1("LR_ADDRESS_MATCH_VALUE");
296 if (OS_DBSearchKeyAddressValue(lrule, key) == 0) {
301 debug1("lists_list.c::OS_DBSearch should never hit default");