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