source: trunk/src/sh_filter.c@ 512

Last change on this file since 512 was 232, checked in by katerina, 15 years ago

Add some missing files

File size: 6.5 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 2009 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include "config_xor.h"
22
23#include <string.h>
24#ifdef HAVE_REGEX_H
25#include <regex.h>
26#endif
27
28#include "samhain.h"
29#include "sh_utils.h"
30#include "sh_mem.h"
31#include "sh_filter.h"
32
33#undef FIL__
34#define FIL__ _("sh_filter.c")
35
36
37void sh_filter_free (sh_filter_type * filter)
38{
39 int i;
40
41 if (filter)
42 {
43 for (i = 0; i < filter->for_c; ++i) {
44#ifdef HAVE_REGEX_H
45 if (filter->for_v[i])
46 regfree(filter->for_v[i]);
47#else
48 if (filter->for_v[i])
49 SH_FREE(filter->for_v[i]);
50#endif
51 filter->for_v[i] = NULL;
52 }
53 filter->for_c = 0;
54
55 for (i = 0; i < filter->fand_c; ++i) {
56#ifdef HAVE_REGEX_H
57 if (filter->fand_v[i])
58 regfree(filter->fand_v[i]);
59#else
60 if (filter->fand_v[i])
61 SH_FREE(filter->fand_v[i]);
62#endif
63 filter->fand_v[i] = NULL;
64 }
65 filter->fand_c = 0;
66
67 for (i = 0; i < filter->fnot_c; ++i) {
68#ifdef HAVE_REGEX_H
69 if (filter->fnot_v[i])
70 regfree(filter->fnot_v[i]);
71#else
72 if (filter->fnot_v[i])
73 SH_FREE(filter->fnot_v[i]);
74#endif
75 filter->fnot_v[i] = NULL;
76 }
77 filter->fnot_c = 0;
78 }
79}
80
81
82int sh_filter_add (const char * str, sh_filter_type * filter, int type)
83{
84 int i = 0;
85 int flag = 0;
86 size_t s;
87
88 char * dupp;
89 char * p;
90 char * end;
91 int * ntok;
92 void ** stok;
93
94 SL_ENTER(_("sh_filter_filteradd"));
95
96 if (NULL == str || NULL == filter)
97 {
98 SL_RETURN((-1), _("sh_filter_filteradd"));
99 }
100
101 if (type == SH_FILT_OR) {
102 ntok = &(filter->for_c);
103 stok = filter->for_v;
104 }
105 else if (type == SH_FILT_AND) {
106 ntok = &(filter->fand_c);
107 stok = filter->fand_v;
108 }
109 else if (type == SH_FILT_NOT) {
110 ntok = &(filter->fnot_c);
111 stok = filter->fnot_v;
112 }
113 else {
114 SL_RETURN((-1), _("sh_filter_filteradd"));
115 }
116
117 i = *ntok;
118 if (i == SH_FILT_NUM) {
119 SL_RETURN((-1), _("sh_filter_filteradd"));
120 }
121
122 dupp = sh_util_strdup(str);
123 p = dupp;
124
125 do
126 {
127 while (*p == ',' || *p == ' ' || *p == '\t')
128 ++p;
129 if (*p == '\0')
130 break;
131
132 end = p; ++end;
133 if (*end == '\0')
134 break;
135
136 if (*p == '\'')
137 {
138 ++p; end = p; if (*end != '\'') ++end;
139 if (*p == '\0' || *end == '\0')
140 break;
141 while (*end != '\0' && *end != '\'')
142 ++end;
143 }
144 else if (*p == '"')
145 {
146 ++p; end = p; if (*end != '"') ++end;
147 if (*p == '\0' || *end == '\0')
148 break;
149 while (*end != '\0' && *end != '"')
150 ++end;
151 }
152 else
153 {
154 while (*end != '\0' && *end != ',' && *end != ' ' && *end != '\t')
155 ++end;
156 }
157 if (*end == '\0')
158 flag = 1;
159 else
160 *end = '\0';
161
162 s = strlen(p);
163 if (s > 0)
164 {
165 ++s;
166#ifdef HAVE_REGEX_H
167 if (stok[i] != NULL)
168 regfree((regex_t *) stok[i]);
169 {
170 int status;
171
172 stok[i] = SH_ALLOC(sizeof(regex_t));
173
174 status = regcomp((regex_t *) stok[i], p,
175 REG_NOSUB|REG_EXTENDED);
176 if (status != 0)
177 {
178 char * errbuf = SH_ALLOC(BUFSIZ);
179 (void) regerror(status, (regex_t *) stok[i],
180 errbuf, BUFSIZ);
181 errbuf[BUFSIZ-1] = '\0';
182 sh_error_handle ((-1), FIL__, __LINE__, status, MSG_E_REGEX,
183 errbuf, p);
184 SH_FREE(errbuf);
185 }
186 }
187#else
188 if (stok[i] != NULL)
189 SH_FREE(stok[i]);
190
191 stok[i] = SH_ALLOC(s);
192 (void) sl_strlcpy((char *) stok[i], p, s);
193#endif
194 ++i;
195 }
196
197 p = end; ++p;
198
199 if (i == SH_FILT_NUM)
200 break;
201 }
202 while (p != NULL && *p != '\0' && flag == 0);
203
204 *ntok = i;
205 SH_FREE(dupp);
206
207 SL_RETURN (0, _("sh_filter_filteradd"));
208}
209
210#ifdef HAVE_REGEX_H
211static int sh_filter_cmp(const char * message, void * pattern)
212{
213 int result;
214
215 result = regexec((regex_t *)pattern, message, 0, NULL, 0);
216
217 if (result != 0)
218 return -1;
219
220 /* Successful match. */
221 return 0;
222}
223#else
224static int sh_filter_cmp(const char * message, void * pattern)
225{
226 if (NULL == sl_strstr(message, (char *)pattern))
227 return -1;
228
229 /* Successful match. */
230 return 0;
231}
232#endif
233
234/*
235 * -- Check filters. Returns 0 if message passes.
236 */
237int sh_filter_filter (const char * message, sh_filter_type * filter)
238{
239 int i;
240
241 SL_ENTER(_("sh_filter_filter"));
242
243 if (filter)
244 {
245
246 /* Presence of any of these keywords prevents execution.
247 */
248 if (filter->fnot_c > 0)
249 {
250 for (i = 0; i < filter->fnot_c; ++i)
251 {
252 if (0 == sh_filter_cmp(message, filter->fnot_v[i]))
253 {
254 SL_RETURN ((-1), _("sh_filter_filter"));
255 }
256 }
257 }
258
259 /* Presence of all of these keywords is required for execution.
260 */
261 if (filter->fand_c > 0)
262 {
263 for (i = 0; i < filter->fand_c; ++i)
264 {
265 if (0 != sh_filter_cmp(message, filter->fand_v[i]))
266 {
267 SL_RETURN ((-1), _("sh_filter_filter"));
268 }
269 }
270 }
271
272 /* Presence of at least one of these keywords is required for execution.
273 */
274 if (filter->for_c > 0)
275 {
276 for (i = 0; i < filter->for_c; ++i)
277 {
278 if (0 == sh_filter_cmp(message, filter->for_v[i]))
279 {
280 goto isok;
281 }
282 }
283 SL_RETURN ((-1), _("sh_filter_filter"));
284 }
285 }
286
287 isok:
288 SL_RETURN ((0), _("sh_filter_filter"));
289}
290
291sh_filter_type * sh_filter_alloc(void)
292{
293 sh_filter_type * filter = SH_ALLOC(sizeof(sh_filter_type));
294
295 memset(filter, '\0', sizeof(sh_filter_type));
296 filter->for_c = 0;
297 filter->fand_c = 0;
298 filter->fnot_c = 0;
299 return filter;
300}
Note: See TracBrowser for help on using the repository browser.