Imported Upstream version 2.5.1
[ossec-hids.git] / src / analysisd / decoders / decoders_list.c
1 /* @(#) $Id$ */
2
3 /* Copyright (C) 2009 Trend Micro Inc.
4  * All rights 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 2) as published by the FSF - Free Software
9  * Foundation.
10  *
11  * License details at the LICENSE file included with OSSEC or 
12  * online at: http://www.ossec.net/en/licensing.html
13  */
14
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include "headers/debug_op.h"
21 #include "decoder.h"
22
23 #include "error_messages/error_messages.h"
24
25
26 /* We have two internal lists. One with the program_name
27  * and one without. This is going to improve greatly the
28  * performance of our decoder matching.
29  */
30 OSDecoderNode *osdecodernode_forpname;
31 OSDecoderNode *osdecodernode_nopname;
32
33
34 /* Create the Event List */
35 void OS_CreateOSDecoderList()
36 {
37     osdecodernode_forpname = NULL;
38     osdecodernode_nopname = NULL;
39
40     return;
41 }
42
43
44 /* Get first osdecoder */
45 OSDecoderNode *OS_GetFirstOSDecoder(char *p_name)
46 {
47     /* If program name is set, we return the forpname list.
48      */
49     if(p_name)
50     {
51         return(osdecodernode_forpname);
52     }
53     
54     return(osdecodernode_nopname);
55 }
56
57
58 /* Add a osdecoder to the list */
59 OSDecoderNode *_OS_AddOSDecoder(OSDecoderNode *s_node, OSDecoderInfo *pi)
60 {
61     OSDecoderNode *tmp_node = s_node;
62     int rm_f = 0;
63     
64     if(tmp_node)
65     {
66         OSDecoderNode *new_node;
67         
68         new_node = (OSDecoderNode *)calloc(1,sizeof(OSDecoderNode));
69         if(new_node == NULL)
70         {
71             merror(MEM_ERROR,ARGV0);
72             return(NULL);
73         }
74
75         /* Going to the last node */
76         do
77         {
78             /* Checking for common names */
79             if((strcmp(tmp_node->osdecoder->name,pi->name) == 0) &&
80                (pi->parent != NULL))
81             {
82                 if((tmp_node->osdecoder->prematch ||
83                     tmp_node->osdecoder->regex) && pi->regex_offset)
84                 {
85                     rm_f = 1;                    
86                 }
87                 
88                 /* Multi-regexes patterns cannot have prematch */
89                 if(pi->prematch)
90                 {
91                     merror(PDUP_INV, ARGV0,pi->name);
92                     return(NULL);
93                 }
94
95                 /* Multi-regex patterns cannot have fts set */
96                 if(pi->fts)
97                 {
98                     merror(PDUPFTS_INV, ARGV0,pi->name);
99                     return(NULL);
100                 }
101
102                 if(tmp_node->osdecoder->regex && pi->regex)
103                 {
104                     tmp_node->osdecoder->get_next = 1;
105                 }
106                 else
107                 {
108                     merror(DUP_INV, ARGV0,pi->name);
109                     return(NULL);
110                 }
111             }
112             
113         }while(tmp_node->next && (tmp_node = tmp_node->next));
114         
115         
116         /* Must have a prematch set */
117         if(!rm_f && (pi->regex_offset & AFTER_PREVREGEX))
118         {
119             merror(INV_OFFSET, ARGV0, pi->name);
120             return(NULL);
121         }
122         
123         tmp_node->next = new_node;
124         
125         new_node->next = NULL;
126         new_node->osdecoder = pi; 
127         new_node->child = NULL;
128     }
129     
130     else
131     {
132         /* Must not have a previous regex set */
133         if(pi->regex_offset & AFTER_PREVREGEX)
134         {
135             merror(INV_OFFSET, ARGV0, pi->name);
136             return(NULL);
137         }
138
139         tmp_node = (OSDecoderNode *)calloc(1, sizeof(OSDecoderNode));
140
141         if(tmp_node == NULL)
142         {
143             ErrorExit(MEM_ERROR,ARGV0);
144         }
145
146         tmp_node->child = NULL;
147         tmp_node->next = NULL;
148         tmp_node->osdecoder = pi;
149
150         s_node = tmp_node;
151     }
152
153     return (s_node);
154 }
155
156
157 int OS_AddOSDecoder(OSDecoderInfo *pi)
158 {
159     int added = 0;
160     OSDecoderNode *osdecodernode;
161
162
163     /* We can actually have two lists. One with program
164      * name and the other without.
165      */
166     if(pi->program_name)     
167     {
168         osdecodernode = osdecodernode_forpname;
169     }
170     else
171     {
172         osdecodernode = osdecodernode_nopname;
173     }
174
175     
176     /* Search for parent on both lists */
177     if(pi->parent)
178     {
179         OSDecoderNode *tmp_node = osdecodernode_forpname;
180
181         /* List with p_name */
182         while(tmp_node)
183         {
184             if(strcmp(tmp_node->osdecoder->name, pi->parent) == 0)
185             {
186                 tmp_node->child = _OS_AddOSDecoder(tmp_node->child, pi);
187                 if(!tmp_node->child)
188                 {
189                     merror(DEC_PLUGIN_ERR, ARGV0);
190                     return(0);
191                 }
192                 added = 1;
193             }
194             tmp_node = tmp_node->next;
195         }
196         
197
198         /* List without p name */
199         tmp_node = osdecodernode_nopname;
200         while(tmp_node)
201         {
202             if(strcmp(tmp_node->osdecoder->name, pi->parent) == 0)
203             {
204                 tmp_node->child = _OS_AddOSDecoder(tmp_node->child, pi);
205                 if(!tmp_node->child)
206                 {
207                     merror(DEC_PLUGIN_ERR, ARGV0);
208                     return(0);
209                 }
210                 added = 1;
211             }
212             tmp_node = tmp_node->next;
213         }
214
215
216         /* OSDecoder was added correctly */
217         if(added == 1)
218         {
219             return(1);
220         }
221         
222         merror(PPLUGIN_INV, ARGV0, pi->parent);
223         return(0); 
224     }
225     else
226     {
227         osdecodernode = _OS_AddOSDecoder(osdecodernode, pi);
228         if(!osdecodernode)
229         {
230             merror(DEC_PLUGIN_ERR, ARGV0);
231             return(0);
232         }
233
234         /* Updating global decoders pointers */
235         if(pi->program_name)
236         {
237             osdecodernode_forpname = osdecodernode;
238         }
239         else
240         {
241             osdecodernode_nopname = osdecodernode;
242         }
243     }
244     return(1);
245 }
246
247 /* EOF */