1 : <?php
2 :
3 : /**
4 : * PHPIDS
5 : *
6 : * Requirements: PHP5, SimpleXML
7 : *
8 : * Copyright (c) 2008 PHPIDS group (http://php-ids.org)
9 : *
10 : * PHPIDS is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation, version 3 of the License, or
13 : * (at your option) any later version.
14 : *
15 : * PHPIDS is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public License
21 : * along with PHPIDS. If not, see <http://www.gnu.org/licenses/>.
22 : *
23 : * PHP version 5.1.6+
24 : *
25 : * @category Security
26 : * @package PHPIDS
27 : * @author Mario Heiderich <mario.heiderich@gmail.com>
28 : * @author Christian Matthies <ch0012@gmail.com>
29 : * @author Lars Strojny <lars@strojny.net>
30 : * @license http://www.gnu.org/licenses/lgpl.html LGPL
31 : * @link http://php-ids.org/
32 : */
33 :
34 : /**
35 : * Filter Storage
36 : *
37 : * This class provides various default functions for gathering filter patterns
38 : * to be used later on by the detection mechanism. You might extend this class
39 : * to your requirements.
40 : *
41 : * @category Security
42 : * @package PHPIDS
43 : * @author Christian Matthies <ch0012@gmail.com>
44 : * @author Mario Heiderich <mario.heiderich@gmail.com>
45 : * @author Lars Strojny <lars@strojny.net>
46 : * @copyright 2007 The PHPIDS Group
47 : * @license http://www.gnu.org/licenses/lgpl.html LGPL
48 : * @version Release: $Id:Storage.php 517 2007-09-15 15:04:13Z mario $
49 : * @link http://php-ids.org/
50 : */
51 : class IDS_Filter_Storage
52 : {
53 :
54 : /**
55 : * Filter source file
56 : *
57 : * @var string
58 : */
59 : protected $source = null;
60 :
61 : /**
62 : * Holds caching settings
63 : *
64 : * @var array
65 : */
66 : protected $cacheSettings = null;
67 :
68 : /**
69 : * Cache container
70 : *
71 : * @var object IDS_Caching wrapper
72 : */
73 : protected $cache = null;
74 :
75 : /**
76 : * Filter container
77 : *
78 : * @var array
79 : */
80 : protected $filterSet = array();
81 :
82 : /**
83 : * Constructor
84 : *
85 : * Loads filters based on provided IDS_Init settings.
86 : *
87 : * @param object $init IDS_Init instance
88 : *
89 : * @throws Exception if unsupported filter type is given
90 : * @return void
91 : */
92 : public final function __construct(IDS_Init $init)
93 : {
94 42 : if ($init->config) {
95 :
96 42 : $caching = isset($init->config['Caching']['caching']) ?
97 42 : $init->config['Caching']['caching'] : 'none';
98 :
99 42 : $type = $init->config['General']['filter_type'];
100 42 : $this->source = $init->getBasePath()
101 42 : . $init->config['General']['filter_path'];
102 :
103 42 : if ($caching && $caching != 'none') {
104 42 : $this->cacheSettings = $init->config['Caching'];
105 42 : include_once 'IDS/Caching/Factory.php';
106 42 : $this->cache = IDS_Caching::factory($init, 'storage');
107 42 : }
108 :
109 : switch ($type) {
110 42 : case 'xml' :
111 41 : $this->getFilterFromXML();
112 41 : break;
113 1 : case 'json' :
114 1 : $this->getFilterFromJson();
115 1 : break;
116 0 : default :
117 0 : throw new Exception('Unsupported filter type.');
118 0 : }
119 42 : }
120 42 : }
121 :
122 : /**
123 : * Sets the filter array
124 : *
125 : * @param array $filterSet array containing multiple IDS_Filter instances
126 : *
127 : * @return object $this
128 : */
129 : public final function setFilterSet($filterSet)
130 : {
131 1 : foreach ($filterSet as $filter) {
132 1 : $this->addFilter($filter);
133 1 : }
134 :
135 1 : return $this;
136 : }
137 :
138 : /**
139 : * Returns registered filters
140 : *
141 : * @return array
142 : */
143 : public final function getFilterSet()
144 : {
145 35 : return $this->filterSet;
146 : }
147 :
148 : /**
149 : * Adds a filter
150 : *
151 : * @param object $filter IDS_Filter instance
152 : *
153 : * @return object $this
154 : */
155 : public final function addFilter(IDS_Filter $filter)
156 : {
157 42 : $this->filterSet[] = $filter;
158 42 : return $this;
159 : }
160 :
161 : /**
162 : * Checks if any filters are cached
163 : *
164 : * @return mixed $filters cached filters or false
165 : */
166 : private function _isCached()
167 : {
168 42 : $filters = false;
169 :
170 42 : if ($this->cacheSettings) {
171 :
172 42 : if ($this->cache) {
173 42 : $filters = $this->cache->getCache();
174 42 : }
175 42 : }
176 :
177 42 : return $filters;
178 : }
179 :
180 : /**
181 : * Loads filters from XML using SimpleXML
182 : *
183 : * This function parses the provided source file and stores the result.
184 : * If caching mode is enabled the result will be cached to increase
185 : * the performance.
186 : *
187 : * @throws Exception if problems with fetching the XML data occur
188 : * @return object $this
189 : */
190 : public function getFilterFromXML()
191 : {
192 :
193 41 : if (extension_loaded('SimpleXML')) {
194 :
195 : /*
196 : * See if filters are already available in the cache
197 : */
198 41 : $filters = $this->_isCached();
199 :
200 : /*
201 : * If they aren't, parse the source file
202 : */
203 41 : if (!$filters) {
204 1 : if (file_exists($this->source)) {
205 1 : if (LIBXML_VERSION >= 20621) {
206 1 : $filters = simplexml_load_file($this->source,
207 1 : null,
208 1 : LIBXML_COMPACT);
209 1 : } else {
210 0 : $filters = simplexml_load_file($this->source);
211 : }
212 1 : }
213 1 : }
214 :
215 : /*
216 : * In case we still don't have any filters loaded and exception
217 : * will be thrown
218 : */
219 41 : if (empty($filters)) {
220 0 : throw new Exception(
221 : 'XML data could not be loaded.' .
222 : ' Make sure you specified the correct path.'
223 0 : );
224 : }
225 :
226 : /*
227 : * Now the storage will be filled with IDS_Filter objects
228 : */
229 41 : $data = array();
230 41 : $nocache = $filters instanceof SimpleXMLElement;
231 41 : $filters = $nocache ? $filters->filter : $filters;
232 :
233 41 : include_once 'IDS/Filter.php';
234 :
235 41 : foreach ($filters as $filter) {
236 :
237 41 : $id = $nocache ? (string) $filter->id :
238 41 : $filter['id'];
239 41 : $rule = $nocache ? (string) $filter->rule :
240 41 : $filter['rule'];
241 41 : $impact = $nocache ? (string) $filter->impact :
242 41 : $filter['impact'];
243 41 : $tags = $nocache ? array_values((array) $filter->tags) :
244 41 : $filter['tags'];
245 41 : $description = $nocache ? (string) $filter->description :
246 41 : $filter['description'];
247 :
248 41 : $this->addFilter(new IDS_Filter($id,
249 41 : $rule,
250 41 : $description,
251 41 : (array) $tags[0],
252 41 : (int) $impact));
253 :
254 41 : $data[] = array(
255 41 : 'id' => $id,
256 41 : 'rule' => $rule,
257 41 : 'impact' => $impact,
258 41 : 'tags' => $tags,
259 : 'description' => $description
260 41 : );
261 41 : }
262 :
263 : /*
264 : * If caching is enabled, the fetched data will be cached
265 : */
266 41 : if ($this->cacheSettings) {
267 :
268 41 : $this->cache->setCache($data);
269 41 : }
270 :
271 41 : } else {
272 0 : throw new Exception(
273 : 'SimpleXML not loaded.'
274 0 : );
275 : }
276 :
277 41 : return $this;
278 : }
279 :
280 : /**
281 : * Loads filters from Json file using ext/Json
282 : *
283 : * This function parses the provided source file and stores the result.
284 : * If caching mode is enabled the result will be cached to increase
285 : * the performance.
286 : *
287 : * @throws Exception if problems with fetching the JSON data occur
288 : * @return object $this
289 : */
290 : public function getFilterFromJson()
291 : {
292 :
293 1 : if (extension_loaded('Json')) {
294 :
295 : /*
296 : * See if filters are already available in the cache
297 : */
298 1 : $filters = $this->_isCached();
299 :
300 : /*
301 : * If they aren't, parse the source file
302 : */
303 1 : if (!$filters) {
304 0 : if (file_exists($this->source)) {
305 0 : @set_magic_quotes_runtime(0);
306 0 : $content = file_get_contents($this->source);
307 0 : $filters = json_decode($content);
308 0 : } else {
309 0 : throw new Exception(
310 : 'JSON data could not be loaded.' .
311 : ' Make sure you specified the correct path.'
312 0 : );
313 : }
314 0 : }
315 :
316 1 : if (!$filters) {
317 0 : throw new Exception(
318 : 'JSON data could not be loaded.' .
319 : ' Make sure you specified the correct path.'
320 0 : );
321 : }
322 :
323 : /*
324 : * Now the storage will be filled with IDS_Filter objects
325 : */
326 1 : $data = array();
327 1 : $nocache = !is_array($filters);
328 1 : $filters = $nocache ? $filters->filters->filter : $filters;
329 :
330 1 : include_once 'IDS/Filter.php';
331 :
332 1 : foreach ($filters as $filter) {
333 :
334 1 : $id = $nocache ? (string) $filter->id :
335 1 : $filter['id'];
336 1 : $rule = $nocache ? (string) $filter->rule :
337 1 : $filter['rule'];
338 1 : $impact = $nocache ? (string) $filter->impact :
339 1 : $filter['impact'];
340 1 : $tags = $nocache ? array_values((array) $filter->tags) :
341 1 : $filter['tags'];
342 1 : $description = $nocache ? (string) $filter->description :
343 1 : $filter['description'];
344 :
345 1 : $this->addFilter(new IDS_Filter($id,
346 1 : $rule,
347 1 : $description,
348 1 : (array) $tags[0],
349 1 : (int) $impact));
350 :
351 1 : $data[] = array(
352 1 : 'id' => $id,
353 1 : 'rule' => $rule,
354 1 : 'impact' => $impact,
355 1 : 'tags' => $tags,
356 : 'description' => $description
357 1 : );
358 1 : }
359 :
360 : /*
361 : * If caching is enabled, the fetched data will be cached
362 : */
363 1 : if ($this->cacheSettings) {
364 1 : $this->cache->setCache($data);
365 1 : }
366 :
367 1 : } else {
368 0 : throw new Exception(
369 : 'ext/json not loaded.'
370 0 : );
371 : }
372 :
373 1 : return $this;
374 : }
375 : }
376 :
377 : /*
378 : * Local variables:
379 : * tab-width: 4
380 : * c-basic-offset: 4
381 : * End:
382 : */
|