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