2f155bf84ee2e20903e28d135d7aba312d265710
[ossec-hids.git] / src / analysisd / fts.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 /* First time seen functions 
17  */
18
19
20 #include "fts.h"
21 #include "eventinfo.h"
22
23 int fts_minsize_for_str = 0;
24
25 OSList *fts_list = NULL;
26 OSHash *fts_store = NULL;
27
28 FILE *fp_list = NULL;
29 FILE *fp_ignore = NULL;
30
31
32 /** int FTS_Init()
33  * Starts the FTS module.
34  */
35 int FTS_Init()
36 {
37     int fts_list_size;
38     char _line[OS_FLSIZE + 1];
39
40     _line[OS_FLSIZE] = '\0';
41             
42     
43     fts_list = OSList_Create();
44     if(!fts_list)
45     {
46         merror(LIST_ERROR, ARGV0);
47         return(0);
48     }
49
50     /* Creating store data */
51     fts_store = OSHash_Create();
52     if(!fts_store)
53     {
54         merror(LIST_ERROR, ARGV0);
55         return(0);
56     }
57     if(!OSHash_setSize(fts_store, 2048))
58     {
59         merror(LIST_ERROR, ARGV0);
60         return(0);
61     }
62     
63
64     /* Getting default list size */
65     fts_list_size = getDefine_Int("analysisd",
66                                   "fts_list_size",
67                                   12,512);
68
69     /* Getting minimum string size */
70     fts_minsize_for_str = getDefine_Int("analysisd",
71                                         "fts_min_size_for_str",
72                                         6, 128);
73     
74     if(!OSList_SetMaxSize(fts_list, fts_list_size))
75     {
76         merror(LIST_SIZE_ERROR, ARGV0);
77         return(0);
78     }
79
80
81     /* creating fts list */
82     fp_list = fopen(FTS_QUEUE, "r+");
83     if(!fp_list)
84     {
85         /* Create the file if we cant open it */
86         fp_list = fopen(FTS_QUEUE, "w+");
87         if(fp_list)
88             fclose(fp_list);
89         
90         fp_list = fopen(FTS_QUEUE, "r+");
91         if(!fp_list)
92         {
93             merror(FOPEN_ERROR, ARGV0, FTS_QUEUE);
94             return(0);
95         }
96     }
97
98
99     /* Adding content from the files to memory */
100     fseek(fp_list, 0, SEEK_SET);
101     while(fgets(_line, OS_FLSIZE , fp_list) != NULL)
102     {
103         char *tmp_s;
104
105         /* Removing new lines */
106         tmp_s = strchr(_line, '\n');
107         if(tmp_s)
108         {
109             *tmp_s = '\0';
110         }
111
112
113         os_strdup(_line, tmp_s);
114         if(OSHash_Add(fts_store, tmp_s, tmp_s) <= 0)
115         {
116             free(tmp_s);
117             merror(LIST_ADD_ERROR, ARGV0);
118         }
119     }
120
121     
122     /* Creating ignore list */
123     fp_ignore = fopen(IG_QUEUE, "r+");
124     if(!fp_ignore)
125     {
126         /* Create the file if we cant open it */
127         fp_ignore = fopen(IG_QUEUE, "w+");
128         if(fp_ignore)
129             fclose(fp_ignore);
130         
131         fp_ignore = fopen(IG_QUEUE, "r+");
132         if(!fp_ignore)
133         {
134             merror(FOPEN_ERROR, ARGV0, IG_QUEUE);
135             return(0);
136         }
137     }
138
139     debug1("%s: DEBUG: FTSInit completed.", ARGV0);
140                                                             
141     return(1);
142 }
143
144 /* AddtoIGnore -- adds a pattern to be ignored.
145  */
146 void AddtoIGnore(Eventinfo *lf)
147 {
148     fseek(fp_ignore, 0, SEEK_END);    
149
150     #ifdef TESTRULE
151     return;
152     #endif
153     
154     /* Assigning the values to the FTS */
155     fprintf(fp_ignore, "%s %s %s %s %s %s %s %s\n",
156             (lf->decoder_info->name && (lf->generated_rule->ignore & FTS_NAME))?
157                         lf->decoder_info->name:"",
158             (lf->id && (lf->generated_rule->ignore & FTS_ID))?lf->id:"",
159             (lf->dstuser&&(lf->generated_rule->ignore & FTS_DSTUSER))?
160                         lf->dstuser:"",
161             (lf->srcip && (lf->generated_rule->ignore & FTS_SRCIP))?
162                         lf->srcip:"",
163             (lf->dstip && (lf->generated_rule->ignore & FTS_DSTIP))?
164                         lf->dstip:"",
165             (lf->data && (lf->generated_rule->ignore & FTS_DATA))?
166                         lf->data:"",            
167             (lf->systemname && (lf->generated_rule->ignore & FTS_SYSTEMNAME))?
168                         lf->systemname:"",            
169             (lf->generated_rule->ignore & FTS_LOCATION)?lf->location:"");
170
171     fflush(fp_ignore);
172
173     return;
174 }
175
176
177 /* IGnore v0.1
178  * Check if the event is to be ignored.
179  * Only after an event is matched (generated_rule must be set).
180  */
181 int IGnore(Eventinfo *lf)
182 {
183     char _line[OS_FLSIZE + 1];
184     char _fline[OS_FLSIZE +1];
185
186     _line[OS_FLSIZE] = '\0';
187
188
189     /* Assigning the values to the FTS */
190     snprintf(_line,OS_FLSIZE, "%s %s %s %s %s %s %s %s\n",
191             (lf->decoder_info->name && (lf->generated_rule->ckignore & FTS_NAME))?
192                             lf->decoder_info->name:"",
193             (lf->id && (lf->generated_rule->ckignore & FTS_ID))?lf->id:"",
194             (lf->dstuser && (lf->generated_rule->ckignore & FTS_DSTUSER))?
195                             lf->dstuser:"",
196             (lf->srcip && (lf->generated_rule->ckignore & FTS_SRCIP))?
197                             lf->srcip:"",
198             (lf->dstip && (lf->generated_rule->ckignore & FTS_DSTIP))?
199                             lf->dstip:"",
200             (lf->data && (lf->generated_rule->ignore & FTS_DATA))?
201                             lf->data:"",
202             (lf->systemname && (lf->generated_rule->ignore & FTS_SYSTEMNAME))?
203                             lf->systemname:"",                                
204             (lf->generated_rule->ckignore & FTS_LOCATION)?lf->location:"");
205
206     _fline[OS_FLSIZE] = '\0';
207
208
209     /** Checking if the ignore is present **/
210     /* Pointing to the beginning of the file */
211     fseek(fp_ignore, 0, SEEK_SET);
212     while(fgets(_fline, OS_FLSIZE , fp_ignore) != NULL)
213     {
214         if(strcmp(_fline, _line) != 0)
215             continue;
216
217         /* If we match, we can return 1 */
218         return(1);
219     }
220
221     return(0);
222 }
223
224
225 /* FTS v0.1
226  *  Check if the word "msg" is present on the "queue".
227  *  If it is not, write it there.
228  */ 
229 int FTS(Eventinfo *lf)
230 {
231     int number_of_matches = 0;
232
233     char _line[OS_FLSIZE + 1];
234     
235     char *line_for_list = NULL;
236
237     OSListNode *fts_node;
238
239     _line[OS_FLSIZE] = '\0';
240
241
242     /* Assigning the values to the FTS */
243     snprintf(_line, OS_FLSIZE, "%s %s %s %s %s %s %s %s %s",
244             lf->decoder_info->name,
245             (lf->id && (lf->decoder_info->fts & FTS_ID))?lf->id:"",
246             (lf->dstuser && (lf->decoder_info->fts & FTS_DSTUSER))?lf->dstuser:"",
247             (lf->srcuser && (lf->decoder_info->fts & FTS_SRCUSER))?lf->srcuser:"",
248             (lf->srcip && (lf->decoder_info->fts & FTS_SRCIP))?lf->srcip:"",
249             (lf->dstip && (lf->decoder_info->fts & FTS_DSTIP))?lf->dstip:"",
250             (lf->data && (lf->decoder_info->fts & FTS_DATA))?lf->data:"",
251             (lf->systemname && (lf->decoder_info->fts & FTS_SYSTEMNAME))?lf->systemname:"",
252             (lf->decoder_info->fts & FTS_LOCATION)?lf->location:"");
253
254
255     /** Checking if FTS is already present **/
256     if(OSHash_Get(fts_store, _line))
257     {
258         return(0);
259     }        
260
261     
262     /* Checking if from the last FTS events, we had
263      * at least 3 "similars" before. If yes, we just
264      * ignore it.
265      */
266     if(lf->decoder_info->type == IDS)
267     {
268         fts_node = OSList_GetLastNode(fts_list);
269         while(fts_node)
270         {
271             if(OS_StrHowClosedMatch((char *)fts_node->data, _line) > 
272                     fts_minsize_for_str)
273             {
274                 number_of_matches++;
275
276                 /* We go and add this new entry to the list */
277                 if(number_of_matches > 2)
278                 {
279                     _line[fts_minsize_for_str] = '\0';
280                     break;
281                 }
282             }
283
284             fts_node = OSList_GetPrevNode(fts_list);
285         }
286
287         os_strdup(_line, line_for_list);
288         OSList_AddData(fts_list, line_for_list);
289     }
290     
291     
292     /* Storing new entry */
293     if(line_for_list == NULL)
294     {
295         os_strdup(_line, line_for_list);
296     }
297
298     if(OSHash_Add(fts_store, line_for_list, line_for_list) <= 1)
299     {
300         return(0);
301     }
302
303     
304     #ifdef TESTRULE
305     return(1);
306     #endif
307     
308     
309     /* Saving to fts fp */      
310     fseek(fp_list, 0, SEEK_END);
311     fprintf(fp_list,"%s\n", _line);
312     fflush(fp_list);
313
314     return(1);
315 }
316
317
318 /* EOF */