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