~ubuntu-branches/ubuntu/hardy/prewikka/hardy

« back to all changes in this revision

Viewing changes to prewikka/views/alertlisting.py

  • Committer: Bazaar Package Importer
  • Author(s): Pierre Chifflier
  • Date: 2007-04-11 14:41:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070411144109-2hh7zx3amwd27b4l
Tags: upstream-0.9.10
ImportĀ upstreamĀ versionĀ 0.9.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2004,2005,2006 PreludeIDS Technologies. All Rights Reserved.
 
2
# Author: Nicolas Delon <nicolas.delon@prelude-ids.com>
 
3
#
 
4
# This file is part of the Prewikka program.
 
5
#
 
6
# This program is free software; you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation; either version 2, or (at your option)
 
9
# 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; see the file COPYING.  If not, write to
 
18
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
 
 
20
import copy, re, urllib, time, prelude, preludedb, operator
 
21
from prewikka import view, User, utils
 
22
from prewikka.views.messagelisting import MessageListingParameters, MessageListing, ListedMessage
 
23
 
 
24
 
 
25
def cmp_severities(x, y):
 
26
    d = { None: 0, "info": 1, "low": 2, "medium": 3, "high": 4 }
 
27
    return d[y] - d[x]
 
28
 
 
29
 
 
30
def _normalizeName(name):
 
31
    return "".join([ i.capitalize() for i in name.split("_") ])
 
32
        
 
33
 
 
34
def _getEnumValue(class_id):
 
35
    i = 0
 
36
    nlist = [ ]
 
37
        
 
38
    while True:
 
39
        value = prelude.idmef_class_enum_to_string(class_id, i)
 
40
        i += 1
 
41
        if value == None:
 
42
            if i == 1:
 
43
                continue
 
44
                
 
45
            break
 
46
                
 
47
        nlist += [ value ]            
 
48
    
 
49
    return nlist
 
50
 
 
51
                
 
52
def _getPathList(class_id, path, add_index=None, depth=0):        
 
53
    plist = []
 
54
        
 
55
    if depth == 0:
 
56
        if not add_index:
 
57
            path = path.replace("(0)", "").replace("(-1)", "")
 
58
            
 
59
        tmp = path[path.rfind(".") + 1:]
 
60
        elen = tmp.find("(")
 
61
        if elen == -1:
 
62
            plist += [( _normalizeName(tmp), None, None) ]
 
63
        else:
 
64
            plist += [( _normalizeName(tmp[:elen]), None, None) ]
 
65
        depth += 1
 
66
    
 
67
    i = 0        
 
68
    child_list = []
 
69
 
 
70
    while True:
 
71
        name = prelude.idmef_class_get_child_name(class_id, i)
 
72
        if not name or (name == "file" and class_id == prelude.IDMEF_CLASS_ID_LINKAGE):
 
73
            break
 
74
         
 
75
        vtype = prelude.idmef_class_get_child_value_type(class_id, i)
 
76
        space = "\u00a0\u00a0" * depth
 
77
            
 
78
        if vtype == prelude.IDMEF_VALUE_TYPE_CLASS:
 
79
            if add_index and prelude.idmef_class_is_child_list(class_id, i):
 
80
                index = add_index
 
81
            else:
 
82
                index = ""
 
83
                
 
84
            child_list += [ (space + _normalizeName(name), None, None) ]
 
85
            child_list += _getPathList(prelude.idmef_class_get_child_class(class_id, i), path + "." + name + index, add_index, depth + 1)
 
86
        else:
 
87
            if vtype == prelude.IDMEF_VALUE_TYPE_ENUM:
 
88
                pval = _getEnumValue(prelude.idmef_class_get_child_class(class_id, i))
 
89
            else:
 
90
                pval = None
 
91
                   
 
92
            plist += [( space + name, path + "." + name, pval) ]
 
93
            
 
94
        i += 1
 
95
            
 
96
    return plist + child_list
 
97
 
 
98
 
 
99
def _getClassificationPath(add_empty=False, add_index=None):
 
100
    empty = [ ]
 
101
    if add_empty:
 
102
        empty += [("", "none", None)]   
 
103
    
 
104
    return empty + \
 
105
           [("messageid", "alert.messageid", None)] + \
 
106
           _getPathList(prelude.IDMEF_CLASS_ID_CLASSIFICATION, "alert.classification", add_index=add_index) + \
 
107
           _getPathList(prelude.IDMEF_CLASS_ID_ASSESSMENT, "alert.assessment", add_index=add_index) + \
 
108
           _getPathList(prelude.IDMEF_CLASS_ID_OVERFLOW_ALERT, "alert.overflow_alert", add_index=add_index) + \
 
109
           _getPathList(prelude.IDMEF_CLASS_ID_CORRELATION_ALERT, "alert.correlation_alert", add_index=add_index) + \
 
110
           _getPathList(prelude.IDMEF_CLASS_ID_TOOL_ALERT, "alert.tool_alert", add_index=add_index) + \
 
111
           _getPathList(prelude.IDMEF_CLASS_ID_ADDITIONAL_DATA, "alert.additional_data", add_index=add_index)
 
112
 
 
113
def _getSourcePath(add_empty=False, add_index=None):
 
114
    empty = [ ]
 
115
    if add_empty:
 
116
        empty += [("", "none", None)]   
 
117
    
 
118
    return empty + _getPathList(prelude.IDMEF_CLASS_ID_SOURCE, "alert.source(0)", add_index=add_index)
 
119
 
 
120
def _getTargetPath(add_empty=False, add_index=None):
 
121
    empty = [ ]
 
122
    if add_empty:
 
123
        empty += [("", "none", None)]   
 
124
    
 
125
    return empty + _getPathList(prelude.IDMEF_CLASS_ID_TARGET, "alert.target(0)", add_index=add_index)
 
126
 
 
127
def _getAnalyzerPath(add_empty=False, add_index=None):
 
128
    empty = [ ]
 
129
    if add_empty:
 
130
        empty += [("", "none", None)]   
 
131
    
 
132
    return empty + _getPathList(prelude.IDMEF_CLASS_ID_ANALYZER, "alert.analyzer(-1)", add_index=add_index)
 
133
 
 
134
 
 
135
CLASSIFICATION_FILTERS = _getClassificationPath()
 
136
CLASSIFICATION_AGGREGATIONS = _getClassificationPath(add_empty=True, add_index="(0)")
 
137
 
 
138
SOURCE_FILTERS = _getSourcePath()
 
139
SOURCE_AGGREGATIONS = _getSourcePath(add_empty=True, add_index="(0)")
 
140
 
 
141
TARGET_FILTERS = _getTargetPath()
 
142
TARGET_AGGREGATIONS = _getTargetPath(add_empty=True, add_index="(0)")
 
143
 
 
144
ANALYZER_FILTERS = _getAnalyzerPath()
 
145
ANALYZER_AGGREGATIONS = _getAnalyzerPath(add_empty=True, add_index="(0)")
 
146
 
 
147
 
 
148
 
 
149
class AlertListingParameters(MessageListingParameters):
 
150
    allow_extra_parameters = True
 
151
 
 
152
    def register(self):
 
153
        self.max_index = 0
 
154
        MessageListingParameters.register(self)
 
155
        self.optional("aggregated_source", list, [ "alert.source(0).node.address(0).address" ], save=True)
 
156
        self.optional("aggregated_target", list, [ "alert.target(0).node.address(0).address" ], save=True)
 
157
        self.optional("aggregated_classification", list, [ "none" ], save=True)
 
158
        self.optional("aggregated_analyzer", list, [ "none" ], save=True)
 
159
        self.optional("filter", str, save=True)
 
160
        self.optional("alert.classification.text", list, [ ], save=True)
 
161
        self.optional("alert.assessment.impact.severity", list, [ "info", "low", "medium", "high", "none" ], save=True)
 
162
        self.optional("alert.assessment.impact.completion", list, [ "succeeded", "failed", "none" ], save=True)
 
163
        self.optional("alert.assessment.impact.type", list, [ "other", "admin", "dos", "file", "recon", "user" ], save=True)
 
164
        self.optional("alert.type", list, ["alert.create_time", "alert.correlation_alert.name", "alert.overflow_alert.program", "alert.tool_alert.name"], save=True)
 
165
 
 
166
    def _checkOperator(self, operator):
 
167
        if operator[0] == "!":
 
168
            operator = operator[1:]
 
169
            
 
170
        if not operator in ("=", "<", ">", "<=", ">=", "~", "~*", "<>", "<>*"):
 
171
            raise view.InvalidParameterValueError("operator", operator)
 
172
    
 
173
    def _loadColumnParam(self, view_name, user, paramlist, column, do_save):
 
174
        ret = False
 
175
        sorted = [ ]
 
176
 
 
177
        for parameter, object in paramlist.items():
 
178
            idx = parameter.find(column + "_object_")
 
179
            if idx == -1:
 
180
                continue
 
181
 
 
182
            num = int(parameter.replace(column + "_object_", "", 1))
 
183
            if num >= self.max_index:
 
184
                self.max_index = num + 1
 
185
 
 
186
            ret = True
 
187
            operator = paramlist.get(column + "_operator_" + str(num), "=")
 
188
            self._checkOperator(operator)
 
189
 
 
190
            try:
 
191
                value = paramlist[column + "_value_" + str(num)]
 
192
            except KeyError:
 
193
                continue
 
194
 
 
195
            do_append = True
 
196
            for tmp in sorted:
 
197
                if tmp[1] == object and tmp[2] == operator and tmp[3] == value:
 
198
                    do_append = False
 
199
                    break
 
200
 
 
201
            if do_append:
 
202
                sorted.append((num, object, operator, value))
 
203
 
 
204
        sorted.sort()
 
205
        self[column] = [ (i[1], i[2], i[3]) for i in sorted ]
 
206
        
 
207
        
 
208
        if do_save:
 
209
            user.delConfigValueMatch(view_name, "%s_object_%%" % (column))
 
210
            user.delConfigValueMatch(view_name, "%s_operator_%%" % (column))
 
211
            user.delConfigValueMatch(view_name, "%s_value_%%" % (column))
 
212
 
 
213
            for num, obj, operator, value in sorted:
 
214
                user.setConfigValue(view_name, "%s_object_%d" % (column, num), obj)
 
215
                user.setConfigValue(view_name, "%s_operator_%d" % (column, num), operator)
 
216
                user.setConfigValue(view_name, "%s_value_%d" % (column, num), value)
 
217
 
 
218
        return ret
 
219
    
 
220
        
 
221
    def normalize(self, view_name, user):
 
222
        do_save = self.has_key("_save")
 
223
        do_load = MessageListingParameters.normalize(self, view_name, user)
 
224
 
 
225
        for severity in self["alert.assessment.impact.severity"]:
 
226
            if not severity in ("info", "low", "medium", "high", "none"):
 
227
                raise view.InvalidParameterValueError("alert.assessment.impact.severity", severity)
 
228
        
 
229
        for completion in self["alert.assessment.impact.completion"]:
 
230
            if not completion in ("succeeded", "failed", "none"):
 
231
                raise view.InvalidParameterValueError("alert.assessment.impact.completion", completion)
 
232
 
 
233
        for type in self["alert.assessment.impact.type"]:
 
234
            if not type in ("other", "admin", "dos", "file", "recon", "user"):
 
235
                raise view.InvalidParameterValueError("alert.assessment.impact.type", type)
 
236
 
 
237
        for type in self["alert.type"]:
 
238
            if not type in ("alert.create_time", "alert.correlation_alert.name", "alert.overflow_alert.program", "alert.tool_alert.name"):
 
239
                raise view.InvalidParameterValueError("alert.type", type)
 
240
                
 
241
        load_saved = True
 
242
        for column in "classification", "source", "target", "analyzer":
 
243
            ret = self._loadColumnParam(view_name, user, self, column, do_save)
 
244
            if ret:
 
245
                load_saved = False
 
246
        
 
247
        if load_saved and do_load and user.configuration.has_key(view_name):
 
248
            for column in "classification", "source", "target", "analyzer":
 
249
                self._loadColumnParam(view_name, user, user.configuration[view_name], column, do_save)
 
250
                    
 
251
        for category in "classification", "source", "target", "analyzer":
 
252
            i = 0
 
253
            for path in self["aggregated_%s" % category]:
 
254
                
 
255
                if self["aggregated_%s" % category].count(path) > 1:
 
256
                    self["aggregated_%s" % category].remove(path)
 
257
                    
 
258
                if path[0] == "!":
 
259
                    self["aggregated_%s" % category][i] = path[1:]
 
260
                
 
261
                i += 1
 
262
 
 
263
 
 
264
 
 
265
class SensorAlertListingParameters(AlertListingParameters):
 
266
    def register(self):
 
267
        AlertListingParameters.register(self)
 
268
        self.mandatory("analyzerid", long)
 
269
 
 
270
    def normalize(self, view_name, user):
 
271
        AlertListingParameters.normalize(self, view_name, user)
 
272
        self["analyzer"].insert(0, ("alert.analyzer.analyzerid", "=", str(self["analyzerid"])))
 
273
 
 
274
 
 
275
class CorrelationAlertListingParameters(AlertListingParameters):
 
276
    def register(self):
 
277
        AlertListingParameters.register(self)
 
278
        self.optional("aggregated_source", list, [ ], save=True)
 
279
        self.optional("aggregated_target", list, [ ], save=True)
 
280
        self.optional("alert.type", list, ["alert.correlation_alert.name"], save=True)
 
281
        
 
282
    def normalize(self, view_name, user):
 
283
        AlertListingParameters.normalize(self, view_name, user)
 
284
 
 
285
 
 
286
class ToolAlertListingParameters(AlertListingParameters):
 
287
    def register(self):
 
288
        AlertListingParameters.register(self)
 
289
        self.optional("aggregated_source", list, [ ], save=True)
 
290
        self.optional("aggregated_target", list, [ ], save=True)
 
291
        self.optional("alert.type", list, ["alert.tool_alert.name"], save=True)
 
292
        
 
293
    def normalize(self, view_name, user):
 
294
        AlertListingParameters.normalize(self, view_name, user)
 
295
 
 
296
 
 
297
class ListedAlert(ListedMessage):
 
298
    def __init__(self, *args, **kwargs):        
 
299
        apply(ListedMessage.__init__, (self, ) + args, kwargs)
 
300
        self.reset()
 
301
 
 
302
    def _getKnownValue(self, direction, key):
 
303
        return { "alert.%s.service.port" % direction: ("service", None),
 
304
                 "alert.%s.node.address.address" % direction: ("addresses", self._setMessageDirectionAddress),
 
305
                 "alert.%s.node.name" % direction: ("addresses", self._setMessageDirectionNodeName), 
 
306
                 }[key]
 
307
    
 
308
    def _initValue(self, dataset, name, value):
 
309
        dataset[name] = value
 
310
 
 
311
    def _initDirection(self, dataset):
 
312
        self._initValue(dataset, "protocol", { "value": None })
 
313
        self._initValue(dataset, "service", { "value": None })
 
314
        self._initValue(dataset, "addresses", [ ])
 
315
        self._initValue(dataset, "listed_values", [ ])
 
316
        self._initValue(dataset, "aggregated_hidden", 0)
 
317
        return dataset
 
318
    
 
319
    def _initDirectionIfNeeded(self, direction):
 
320
        if len(self[direction]) == 0:        
 
321
            self[direction].append(self._initDirection({ }))
 
322
                    
 
323
    def _setMainAndExtraValues(self, dataset, name, object_main, object_extra):
 
324
        if object_main != None:
 
325
            dataset[name] = { "value": object_main }
 
326
            dataset[name + "_extra"] = { "value": object_extra }
 
327
                
 
328
        else:
 
329
            dataset[name] = { "value": object_extra }
 
330
            dataset[name + "_extra"] = { "value": None }
 
331
 
 
332
    def _guessAddressCategory(self, address):
 
333
        if re.compile("\d\.\d\.\d\.\d").match(address):
 
334
            return "ipv4-addr"
 
335
            
 
336
        elif re.compile(".*@.*").match(address):
 
337
            return "e-mail"
 
338
        
 
339
        elif address.count(":") > 1:
 
340
            return "ipv6-addr"
 
341
 
 
342
        return None        
 
343
 
 
344
    def _setMessageDirectionAddress(self, dataset, direction, address, category=None):  
 
345
        if category == None:
 
346
            category = self._guessAddressCategory(address)
 
347
            
 
348
        hfield = self.createHostField("alert.%s.node.address.address" % direction, address, category=category, direction=direction)
 
349
        dataset["addresses"].append(hfield)
 
350
 
 
351
    def _setMessageDirectionNodeName(self, dataset, direction, name):
 
352
        dataset["addresses"].append(self.createHostField("alert.%s.node.name" % direction, name, direction=direction))
 
353
      
 
354
    def _setMessageDirectionOther(self, dataset, direction, path, value, extra_path=None, extra=None):
 
355
        if value == None:
 
356
           if extra == None:
 
357
                return
 
358
                
 
359
           value = extra
 
360
           path = extra_path
 
361
           extra = extra_path = None
 
362
                   
 
363
        l = path.split(".")
 
364
        l[-2] = l[-2].replace("(0)", "")
 
365
        
 
366
        if l[-2] != direction:
 
367
            name = _normalizeName(l[-2]) + " "
 
368
        else:
 
369
            name = ""
 
370
                
 
371
        name += l[-1]
 
372
        
 
373
        item = (name, self.createInlineFilteredField(path, value, direction), extra)
 
374
        if not item in dataset["listed_values"]:
 
375
            dataset["listed_values"].append(item)
 
376
       
 
377
        
 
378
    def _setMessageDirection(self, dataset, direction, obj):
 
379
        dataset["interface"] = { "value": obj["interface"] }
 
380
        
 
381
        for userid in obj["user.user_id"]:
 
382
            self._setMessageDirectionOther(dataset, direction, "alert.%s.user.user_id.name" % direction, userid["name"], 
 
383
                                                               "alert.%s.user.user_id.number" % direction, userid["number"])
 
384
                                                      
 
385
        name = obj["node.name"]
 
386
        if name != None:
 
387
            self._setMessageDirectionNodeName(dataset, direction, name)
 
388
            
 
389
        for addr in obj["node.address"]:
 
390
            self._setMessageDirectionAddress(dataset, direction, addr["address"], addr["category"])
 
391
        
 
392
        self._setMessageDirectionOther(dataset, direction, "alert.%s.process.name" % direction, obj["process.name"], 
 
393
                                                           "alert.%s.process.pid" % direction, extra=obj["process.pid"])        
 
394
 
 
395
        proto = None
 
396
        if obj["service.iana_protocol_name"]:
 
397
            proto = obj["service.iana_protocol_name"]
 
398
            
 
399
        elif obj["service.iana_protocol_number"]:
 
400
            num = obj["service.iana_protocol_number"]
 
401
            proto = utils.protocol_number_to_name(num)
 
402
 
 
403
        if not proto:
 
404
            proto = obj["service.protocol"]
 
405
       
 
406
        self._setMainAndExtraValues(dataset, "protocol", proto, None)
 
407
        self._setMainAndExtraValues(dataset, "service", obj["service.port"], None)
 
408
 
 
409
        dataset["files"] = []
 
410
 
 
411
    def _lookupDataset(self, dlist, dataset):
 
412
        for dset in dlist:
 
413
           if dset.items() == dataset.items():
 
414
                return dset
 
415
                
 
416
        return None
 
417
         
 
418
    def _setMessageSource(self, message):
 
419
        total = 0
 
420
        index = 0
 
421
        for source in message["alert.source"]:
 
422
            dataset = { }
 
423
            self._initDirection(dataset)
 
424
            self._setMessageDirection(dataset, "source", source)
 
425
            
 
426
            if not self._lookupDataset(self["source"], dataset):
 
427
                total += 1
 
428
                if self._source_index == self.env.max_aggregated_source:
 
429
                        continue
 
430
                        
 
431
                index += 1
 
432
                self._source_index += 1
 
433
                self["source"].append(dataset)
 
434
 
 
435
        self["aggregated_source_total"] += total
 
436
        self["aggregated_source_hidden"] += (total - index)
 
437
        
 
438
    def _setMessageTarget(self, message):     
 
439
        index = 0
 
440
        total = 0
 
441
        
 
442
        for target in message["alert.target"]:
 
443
            dataset = { }
 
444
            self._initDirection(dataset)
 
445
            self._setMessageDirection(dataset, "target", target)
 
446
                        
 
447
            flist = []
 
448
            for f in target["file"]:
 
449
                if f["path"] in flist:
 
450
                    continue
 
451
                
 
452
                flist.append(f["path"])
 
453
                self._setMessageDirectionOther(dataset, "target", "alert.target.file.path", f["path"]) 
 
454
        
 
455
            if not self._lookupDataset(self["target"], dataset):
 
456
                total += 1
 
457
                if self._target_index == self.env.max_aggregated_target:
 
458
                        continue
 
459
                        
 
460
                index += 1
 
461
                self._target_index += 1                        
 
462
                self["target"].append(dataset)
 
463
 
 
464
        self["aggregated_target_total"] += total
 
465
        self["aggregated_target_hidden"] += (total - index)
 
466
 
 
467
    def _setMessageClassificationReferences(self, dataset, message):
 
468
        dataset["classification_references"] = [ ]
 
469
        for ref in message["alert.classification.reference"]:
 
470
            fstr = ""
 
471
 
 
472
            origin = ref["origin"]
 
473
            if origin:
 
474
                fstr += origin
 
475
 
 
476
            name = ref["name"]
 
477
            if name:
 
478
                fstr += ":" + name
 
479
 
 
480
            urlstr = "https://www.prelude-ids.com/reference_details.php?origin=%s&name=%s" % (ref["origin"], ref["name"])
 
481
            if ref["origin"] in ("vendor-specific", "user-specific"):
 
482
                urlstr += "&url=" + ref["url"]
 
483
                
 
484
            dataset["classification_references"].append((urlstr, fstr))
 
485
 
 
486
    def _setMessageClassification(self, dataset, message):
 
487
        self._setMessageClassificationReferences(dataset, message)
 
488
        dataset["classification"] = self.createInlineFilteredField("alert.classification.text",
 
489
                                                                   message["alert.classification.text"])
 
490
    
 
491
    def _fetchInfoFromLinkedMessage(self, criteria, source, target):
 
492
        result = self.env.idmef_db.getAlertIdents(criteria)
 
493
        for ident in result:
 
494
            idmef = self.env.idmef_db.getAlert(ident)
 
495
            
 
496
            if not source:
 
497
                self._setMessageSource(idmef)
 
498
            
 
499
            if not target:
 
500
                self._setMessageTarget(idmef)
 
501
    
 
502
    
 
503
    def _setMessageAlertIdentInfo(self, message, alert, ident):        
 
504
        fetch_classification_info = fetch_source_info = fetch_target_info = True
 
505
 
 
506
        i = 0        
 
507
        params = { }
 
508
        criteria = [ ]
 
509
        source_analyzer = None
 
510
        
 
511
        for alertident in alert["alertident"]:
 
512
            i += 1
 
513
            
 
514
            # IDMEF draft 14 page 27
 
515
            # If the "analyzerid" is not provided, the alert is assumed to have come
 
516
            # from the same analyzer that is sending the Alert.
 
517
            
 
518
            analyzerid = alertident["analyzerid"]
 
519
            if not analyzerid:
 
520
                if source_analyzer:
 
521
                    analyzerid = source_analyzer
 
522
                else:
 
523
                    for a in message["analyzer"]:
 
524
                        if a["analyzerid"]:
 
525
                            source_analyzer = analyzerid = a["analyzerid"]
 
526
                            break
 
527
                
 
528
            params["analyzer_object_%d" % i] = "alert.analyzer.analyzerid"
 
529
            params["analyzer_value_%d" % i] = analyzerid
 
530
            params["classification_object_%d" % i] = "alert.messageid"
 
531
            params["classification_value_%d" % i] = alertident["alertident"]
 
532
 
 
533
            criteria.append("(alert.messageid = '%s' && alert.analyzer.analyzerid = '%s')" % (utils.escape_criteria(alertident["alertident"]), utils.escape_criteria(analyzerid)))
 
534
        
 
535
        source = message["alert.source"]
 
536
        target = message["alert.target"]
 
537
        if not source or not target:
 
538
            self._fetchInfoFromLinkedMessage(" || ".join(criteria), source, target)
 
539
            
 
540
        self["sub_alert_number"] = i
 
541
        self["sub_alert_name"] = alert["name"]
 
542
        self["sub_alert_link"] = self.createMessageLink(ident, "alert_summary")
 
543
                        
 
544
        tmp = self.parameters
 
545
        tmp -= [ "timeline_unit", "timeline_value", "offset",
 
546
                 "aggregated_classification", "aggregated_source",
 
547
                 "aggregated_target", "aggregated_analyzer", "alert.type", "alert.assessment.impact.severity",
 
548
                 "alert.assessment.impact.completion" ]
 
549
 
 
550
        tmp["aggregated_target"] = tmp["aggregated_source"] = \
 
551
        tmp["aggregated_classification"] = tmp["aggregated_analyzer"] = "none"
 
552
 
 
553
        params["timeline_unit"] = "unlimited"        
 
554
        self["sub_alert_display"] = utils.create_link("alert_listing", tmp + params)
 
555
    
 
556
    def _setClassificationInfos(self, dataset, message, ident):
 
557
        dataset["count"] = 1
 
558
        dataset["display"] = self.createMessageLink(ident, "alert_summary")
 
559
        dataset["severity"] = { "value": message["alert.assessment.impact.severity"] }
 
560
        dataset["completion"] = { "value": message["alert.assessment.impact.completion"] }
 
561
            
 
562
    def _setMessageTime(self, message):
 
563
        self["time"] = self.createTimeField(message["alert.create_time"], self.timezone)
 
564
        if (message["alert.analyzer_time"] != None and
 
565
            abs(int(message["alert.create_time"]) - int(message["alert.analyzer_time"])) > 60):
 
566
            self["analyzer_time"] = self.createTimeField(message["alert.analyzer_time"], self.timezone)
 
567
        else:
 
568
            self["analyzer_time"] = { "value": None }
 
569
 
 
570
    def addSensor(self, name, model, node_name):
 
571
        sensor = { }
 
572
        self["sensors"].append(sensor)
 
573
        
 
574
        if name:
 
575
            sensor["name"] = self.createInlineFilteredField("alert.analyzer.name", name, direction="analyzer")
 
576
   
 
577
        elif model:
 
578
            sensor["name"] = self.createInlineFilteredField("alert.analyzer.model", model, direction="analyzer")
 
579
        
 
580
        sensor["node_name"] = self.createInlineFilteredField("alert.analyzer.node.name", node_name, direction="analyzer")
 
581
 
 
582
    def setMessage(self, message, ident):
 
583
        self["infos"] = [ { } ]
 
584
        
 
585
        self.addSensor(message["alert.analyzer(-1).name"], message["alert.analyzer(-1).model"], message["alert.analyzer(-1).node.name"])
 
586
        self._setMessageTime(message)
 
587
                
 
588
        dataset = self["infos"][0]
 
589
        self._setClassificationInfos(dataset, message, ident)
 
590
        self._setMessageClassification(dataset, message)
 
591
 
 
592
        if message["alert.correlation_alert"]:        
 
593
            self["sub_alert_type"] = "Correlation Alert"
 
594
            self._setMessageAlertIdentInfo(message, message["alert.correlation_alert"], ident)
 
595
            
 
596
        elif message["alert.tool_alert"]:
 
597
            self["sub_alert_type"] = "Tool Alert"
 
598
            self._setMessageAlertIdentInfo(message, message["alert.tool_alert"], ident)
 
599
            
 
600
        if not self["source"]:
 
601
            self._setMessageSource(message)
 
602
            
 
603
        if not self["target"]:
 
604
            self._setMessageTarget(message)
 
605
            
 
606
    def setMessageDirectionGeneric(self, direction, object, value):
 
607
        self._initDirectionIfNeeded(direction)
 
608
        dataset = self[direction][-1]
 
609
            
 
610
        try:
 
611
            dset_name, function = self._getKnownValue(direction, object.replace("(0)", ""))
 
612
        except KeyError:
 
613
            return self._setMessageDirectionOther(dataset, direction, object, value)
 
614
                        
 
615
        if function:
 
616
            function(dataset, direction, value)
 
617
        else:
 
618
            if type(dataset[dset_name]) is list:
 
619
                dataset[dset_name].append({ "value": value })
 
620
            else:
 
621
                dataset[dset_name]["value"] = value
 
622
                        
 
623
    def reset(self):
 
624
        self["sensors"] = [ ]    
 
625
        self["source"] = [ ]
 
626
        self["target"] = [ ]
 
627
        self["sub_alert_name"] = None
 
628
        self["aggregated_source_total"] = 0
 
629
        self["aggregated_source_hidden"] = 0
 
630
        self["aggregated_source_expand"] = 0
 
631
        self["aggregated_target_total"] = 0
 
632
        self["aggregated_target_hidden"] = 0
 
633
        self["aggregated_target_expand"] = 0
 
634
        self._source_index = 0
 
635
        self._target_index = 0 
 
636
 
 
637
 
 
638
class ListedAggregatedAlert(ListedAlert):
 
639
    def __init__(self, *args, **kwargs):
 
640
        apply(ListedAlert.__init__, (self,) + args, kwargs)
 
641
        self["aggregated"] = True
 
642
        self["aggregated_classification_hidden"] = 0
 
643
        self["infos"] = [ ]
 
644
        self["source"] = [ ]
 
645
        self["target"] = [ ]
 
646
                    
 
647
    def setTime(self, time_min, time_max):
 
648
        self["time_min"] = self.createTimeField(time_min, self.parameters["timezone"])
 
649
        self["time_max"] = self.createTimeField(time_max, self.parameters["timezone"])
 
650
 
 
651
    def setCriteriaForDeletion(self, delete_criteria):
 
652
        self["delete"] = urllib.quote_plus(" && ".join(delete_criteria))
 
653
 
 
654
    def setInfos(self, count, classification, severity, completion):
 
655
        infos = {
 
656
            "classification_references": "",
 
657
            "count": count,
 
658
            "classification": self.createInlineFilteredField("alert.classification.text", classification),
 
659
            "severity": { "value": severity },
 
660
            "completion": { "value": completion }
 
661
            }
 
662
        
 
663
        self["infos"].append(infos)
 
664
 
 
665
        return infos
 
666
 
 
667
 
 
668
 
 
669
class AlertListing(MessageListing, view.View):
 
670
    view_name = "alert_listing"
 
671
    view_parameters = AlertListingParameters
 
672
    view_permissions = [ User.PERM_IDMEF_VIEW ]
 
673
    view_template = "AlertListing"
 
674
 
 
675
    root = "alert"
 
676
    summary_view = "alert_summary"
 
677
    details_view = "alert_details"
 
678
    listed_alert = ListedAlert
 
679
    listed_aggregated_alert = ListedAggregatedAlert
 
680
    alert_type_default = ["alert.create_time", "alert.correlation_alert.name", "alert.overflow_alert.program", "alert.tool_alert.name"]
 
681
    
 
682
    def init(self, env):
 
683
        self._max_aggregated_classifications = int(env.config.general.getOptionValue("max_aggregated_classifications", 10))
 
684
 
 
685
    def _getMessageIdents(self, criteria, limit=-1, offset=-1):
 
686
        return self.env.idmef_db.getAlertIdents(criteria, limit, offset)
 
687
 
 
688
    def _fetchMessage(self, ident):
 
689
        return self.env.idmef_db.getAlert(ident)
 
690
 
 
691
    def _setMessage(self, message, ident):
 
692
        msg = self.listed_alert(self.view_name, self.env, self.parameters)
 
693
        msg.setMessage(message, ident)
 
694
        msg["aggregated"] = False
 
695
        msg["delete"] = ident
 
696
        
 
697
        return msg
 
698
    
 
699
    def _getFilters(self, storage, login):
 
700
        return storage.getAlertFilters(login)
 
701
 
 
702
    def _getFilter(self, storage, login, name):
 
703
        return storage.getAlertFilter(login, name)
 
704
 
 
705
    def _deleteMessage(self, ident):
 
706
        self.env.idmef_db.deleteAlert(ident)
 
707
 
 
708
    def _lists_have_same_content(self, l1, l2):
 
709
        l1 = copy.copy(l1)
 
710
        l2 = copy.copy(l2)
 
711
        l1.sort()
 
712
        l2.sort()
 
713
 
 
714
        return l1 == l2
 
715
 
 
716
    def _applyOptionalEnumFilter(self, criteria, column, object, values):        
 
717
        if ( self.parameters.has_key(object) and not self._lists_have_same_content(self.parameters[object], values) ):
 
718
            new = [ ]
 
719
            for value in values:
 
720
                if value in self.parameters[object]:
 
721
                    if value == "none":
 
722
                        new.append("!%s" % (object))
 
723
                    else:
 
724
                        new.append("%s = '%s'" % (object, utils.escape_criteria(value)))
 
725
            
 
726
            criteria.append("(" + " || ".join(new) + ")")
 
727
            self.dataset[object] = self.parameters[object]
 
728
            self.dataset[column + "_filtered"] = True
 
729
        else:
 
730
            self.dataset[object] = values
 
731
    
 
732
    def _applyAlertTypeFilters(self, criteria):
 
733
        if "alert.create_time" in self.parameters["alert.type"]:
 
734
            have_base = True
 
735
        else:
 
736
            have_base = False
 
737
            
 
738
        new = [ ]
 
739
        
 
740
        for param in ["alert.correlation_alert.name", "alert.overflow_alert.program", "alert.tool_alert.name"]:
 
741
            if not have_base:
 
742
                if param in self.parameters["alert.type"]:
 
743
                    new.append("%s" % param)
 
744
            else:
 
745
                if not param in self.parameters["alert.type"]:
 
746
                    new.append("!%s" % param)
 
747
 
 
748
        self.dataset["alert.type"] = self.parameters["alert.type"]
 
749
        
 
750
        if len(new) == 0:
 
751
            return 
 
752
       
 
753
        if not have_base:
 
754
            criteria.append("(" + " || ".join(new) + ")")
 
755
        else:
 
756
            criteria.append("(" + " && ".join(new) + ")")
 
757
         
 
758
        if not self._lists_have_same_content(self.parameters["alert.type"], self.alert_type_default):   
 
759
            self.dataset["classification_filtered"] = True    
 
760
           
 
761
    def _applyClassificationFilters(self, criteria):
 
762
        self._applyAlertTypeFilters(criteria)
 
763
        
 
764
        self._applyOptionalEnumFilter(criteria, "classification", "alert.assessment.impact.severity",
 
765
                                      ["info", "low", "medium", "high", "none"])
 
766
        self._applyOptionalEnumFilter(criteria, "classification", "alert.assessment.impact.completion",
 
767
                                      ["failed", "succeeded", "none"])
 
768
        self._applyOptionalEnumFilter(criteria, "classification", "alert.assessment.impact.type",  
 
769
                                      ["other", "admin", "dos", "file", "recon", "user"])  
 
770
    
 
771
                            
 
772
    def _applyCheckboxFilters(self, criteria, type):
 
773
        def get_string((object, operator, value)):
 
774
            return "%s %s '%s'" % (object, operator, utils.escape_criteria(value))
 
775
                 
 
776
        if self.parameters[type]:
 
777
 
 
778
            # If one object is specified more than one time, and since this object
 
779
            # can not have two different value, we want to apply an OR operator.
 
780
            #
 
781
            # We apply an AND operator between the different objects.
 
782
            
 
783
            merge = { }
 
784
            for obj in self.parameters[type]:
 
785
                if merge.has_key(obj[0]):
 
786
                    merge[obj[0]] += [ obj ]
 
787
                else:
 
788
                    merge[obj[0]] =  [ obj ]
 
789
 
 
790
            newcrit = ""
 
791
            for key in iter(merge):
 
792
                if len(newcrit) > 0:
 
793
                    newcrit += " && "
 
794
 
 
795
                newcrit += "(" + " || ".join(map(get_string, merge[key])) + ")"
 
796
 
 
797
            if newcrit:
 
798
                criteria.append(newcrit)
 
799
            
 
800
            self.dataset[type] = [ (path.replace("(0)", "").replace("(-1)", ""), operator, value) for path, operator, value in self.parameters[type] ]
 
801
            self.dataset["%s_filtered" % type] = True
 
802
        else:
 
803
            self.dataset[type] = [ ("", "", "") ]
 
804
            self.dataset["%s_filtered" % type] = False
 
805
        
 
806
    def _applyFilters(self, criteria):
 
807
        self._applyCheckboxFilters(criteria, "classification")
 
808
        self._applyClassificationFilters(criteria)
 
809
        
 
810
        self._applyCheckboxFilters(criteria, "source")
 
811
        self._applyCheckboxFilters(criteria, "target")
 
812
        self._applyCheckboxFilters(criteria, "analyzer")
 
813
 
 
814
            
 
815
    def _getMissingAggregatedInfos(self, message, path_value_hash, parameters, criteria2, aggregated_count):
 
816
        selection = [ ]
 
817
        index = 0
 
818
        selection_list = [ ]
 
819
        
 
820
        for path in ("alert.classification.text", "alert.analyzer(-1).node.name",
 
821
                     "alert.analyzer(-1).name", "alert.analyzer(-1).model", "alert.assessment.impact.severity",
 
822
                     "alert.assessment.impact.completion"):
 
823
                    
 
824
            if not path_value_hash.has_key(path):
 
825
                selection_list += [ (path, index) ]
 
826
                index += 1
 
827
                            
 
828
        selection = [ "%s/group_by" % i[0] for i in selection_list ]
 
829
           
 
830
        alert_list = self.env.idmef_db.getValues( selection + ["max(alert.messageid)", "count(alert.messageid)" ], criteria2)
 
831
        alertsraw = { }
 
832
        nodesraw = { }
 
833
        
 
834
        for values in alert_list:
 
835
            for path, index in selection_list:
 
836
                path_value_hash[path] = values[index]
 
837
            
 
838
            max_messageid = values[-2]
 
839
            alert_count = values[-1]
 
840
            
 
841
            classification = path_value_hash["alert.classification.text"]
 
842
            analyzer_name = path_value_hash["alert.analyzer(-1).name"]
 
843
            analyzer_model = path_value_hash["alert.analyzer(-1).model"]
 
844
            analyzer_node_name = path_value_hash["alert.analyzer(-1).node.name"]
 
845
            severity = path_value_hash["alert.assessment.impact.severity"]
 
846
            completion = path_value_hash["alert.assessment.impact.completion"]
 
847
            
 
848
            alertkey = (classification or "") + "-" + (severity or "") + "-" + (completion or "")
 
849
            
 
850
            if alertsraw.has_key(alertkey):
 
851
               alertsraw[alertkey][-2] += alert_count
 
852
            else:
 
853
               alertsraw[alertkey] = ( [classification, severity, completion, alert_count, max_messageid] )
 
854
               
 
855
            nodekey = (analyzer_name or analyzer_model or "") + "-" + (analyzer_node_name or "")
 
856
            if not nodesraw.has_key(nodekey):
 
857
               message.addSensor(analyzer_name, analyzer_model, analyzer_node_name)
 
858
               nodesraw[nodekey] = True
 
859
                   
 
860
        res = alertsraw.values()
 
861
        res.sort(lambda x, y: cmp_severities(x[1], y[1]))
 
862
 
 
863
        result_count = 0
 
864
        
 
865
        for classification, severity, completion, count, messageid in res:
 
866
            if result_count >= self._max_aggregated_classifications:
 
867
                continue
 
868
                
 
869
            result_count += 1
 
870
 
 
871
            message["aggregated_classifications_hidden"] -= count
 
872
            infos = message.setInfos(count, classification, severity, completion)
 
873
                    
 
874
            if count == 1:
 
875
                ident = self.env.idmef_db.getAlertIdents("alert.messageid = '%s'" % utils.escape_criteria(messageid))[0]
 
876
                if aggregated_count == 1:                            
 
877
                    message.reset()
 
878
                    message.setMessage(self._fetchMessage(ident), ident)
 
879
                else:                                
 
880
                    infos["display"] = message.createMessageLink(ident, "alert_summary")
 
881
            else:
 
882
                entry_param = {}
 
883
                        
 
884
                if classification:
 
885
                    entry_param["classification_object_%d" % self.parameters.max_index] = "alert.classification.text"
 
886
                    entry_param["classification_operator_%d" % self.parameters.max_index] = "="
 
887
                    entry_param["classification_value_%d" % self.parameters.max_index] = utils.escape_criteria(classification)
 
888
 
 
889
                entry_param["alert.assessment.impact.severity"] = severity or "none"
 
890
                entry_param["alert.assessment.impact.completion"] = completion or "none"
 
891
                                                
 
892
                entry_param["aggregated_target"] = \
 
893
                entry_param["aggregated_source"] = \
 
894
                entry_param["aggregated_analyzer"] = \
 
895
                entry_param["aggregated_classification"] = "none"
 
896
                        
 
897
                infos["display"] = utils.create_link(self.view_name, self.parameters -
 
898
                                                     [ "offset", "aggregated_classification",
 
899
                                                       "aggregated_source", "aggregated_target", "aggregated_analyzer" ] +
 
900
                                                     parameters + entry_param)
 
901
                                                         
 
902
                                                                           
 
903
    def _getPathValueType(self, path):
 
904
        p = prelude.idmef_path_new(path)
 
905
        t = prelude.idmef_path_get_value_type(p, -1)
 
906
        prelude.idmef_path_destroy(p)
 
907
        return t
 
908
        
 
909
    def _setAggregatedMessagesNoValues(self, criteria, ag_s, ag_t, ag_c, ag_a):
 
910
        ag_list = ag_s + ag_t + ag_c + ag_a
 
911
        
 
912
        ##
 
913
        selection = [ "%s/group_by" % path for path in ag_list ] + \
 
914
                    [ "count(alert.create_time)", "max(alert.create_time)/order_desc" ]
 
915
 
 
916
        results = self.env.idmef_db.getValues(selection, criteria)
 
917
        total_results = len(results)
 
918
        
 
919
        for values in results[self.parameters["offset"]:self.parameters["offset"]+self.parameters["limit"]]:
 
920
            start = 0
 
921
            aggregated_source_values = []
 
922
            aggregated_target_values = []
 
923
            aggregated_classification_values = []
 
924
            aggregated_analyzer_values = []
 
925
            
 
926
            if len(ag_s) > 0:
 
927
                start = len(ag_s)
 
928
                aggregated_source_values = values[:len(ag_s)]
 
929
 
 
930
            if len(ag_t) > 0:
 
931
                last = start + len(ag_t)
 
932
                aggregated_target_values = values[start:last]
 
933
                start = last
 
934
 
 
935
            if len(ag_c) > 0:
 
936
                last = start + len(ag_c)
 
937
                if values[start:last]:
 
938
                    aggregated_classification_values = values[start:last]
 
939
                start = last
 
940
 
 
941
            if len(ag_a) > 0:
 
942
                last = start + len(ag_a)
 
943
                if values[start:last]:
 
944
                    aggregated_analyzer_values = values[start:last]
 
945
                start = last
 
946
                
 
947
 
 
948
            aggregated_count = values[start]
 
949
            time_min = values[start + 1]
 
950
            
 
951
            criteria2 = criteria[:]
 
952
            delete_criteria = [ ]
 
953
            message = self.listed_aggregated_alert(self.view_name, self.env, self.parameters)
 
954
                   
 
955
            valueshash = {}
 
956
            for path, value in zip(ag_list, values[:start]):
 
957
                valueshash[path] = value
 
958
                
 
959
                if path.find("source") != -1:
 
960
                    direction = "source"
 
961
                elif path.find("target") != -1:
 
962
                    direction = "target"
 
963
                else:
 
964
                    direction = None
 
965
                    
 
966
                if value == None:
 
967
                    if self._getPathValueType(path) != prelude.IDMEF_VALUE_TYPE_STRING:
 
968
                        criterion = "! %s" % (path)
 
969
                    else:
 
970
                        criterion = "(! %s || %s == '')" % (path, path)
 
971
                else:
 
972
                    criterion = "%s == '%s'" % (path, utils.escape_criteria(str(value)))
 
973
                    if direction != None:
 
974
                        message.setMessageDirectionGeneric(direction, path, value)
 
975
                       
 
976
                criteria2.append(criterion)
 
977
                delete_criteria.append(criterion)
 
978
 
 
979
            time_min = self.env.idmef_db.getValues(["alert.create_time/order_asc"], criteria2, limit=1)[0][0]
 
980
            time_max = self.env.idmef_db.getValues(["alert.create_time/order_desc"], criteria2, limit=1)[0][0]
 
981
          
 
982
            parameters = self._createAggregationParameters(aggregated_classification_values,
 
983
                                                           aggregated_source_values, aggregated_target_values, aggregated_analyzer_values)
 
984
 
 
985
            message["aggregated_classifications_total"] = aggregated_count
 
986
            message["aggregated_classifications_hidden"] = aggregated_count
 
987
            message["aggregated_classifications_hidden_expand"] = utils.create_link(self.view_name,
 
988
                                                                                    self.parameters -
 
989
                                                                                    [ "offset",
 
990
                                                                                      "aggregated_source",
 
991
                                                                                      "aggregated_target",
 
992
                                                                                      "aggregated_analyzer" ]
 
993
                                                                                    + parameters +
 
994
                                                                                    { "aggregated_classification":
 
995
                                                                                      "alert.classification.text" } )
 
996
                                                                                      
 
997
            self._getMissingAggregatedInfos(message, valueshash, parameters, criteria2, aggregated_count)      
 
998
 
 
999
            delete_criteria.append("alert.create_time >= '%s'" % time_min.toYMDHMS())
 
1000
            delete_criteria.append("alert.create_time <= '%s'" % time_max.toYMDHMS())
 
1001
            
 
1002
            self.dataset["messages"].append(message)
 
1003
            message.setTime(time_min, time_max)
 
1004
            message.setCriteriaForDeletion(delete_criteria)
 
1005
            
 
1006
        return total_results
 
1007
    
 
1008
 
 
1009
    def _createAggregationParameters(self, aggregated_classification_values, aggregated_source_values, aggregated_target_values, aggregated_analyzer_values):
 
1010
        parameters = { }
 
1011
                
 
1012
        for values, column in ((aggregated_classification_values, "classification"),
 
1013
                               (aggregated_source_values, "source"),
 
1014
                               (aggregated_target_values, "target"),
 
1015
                               (aggregated_analyzer_values, "analyzer")):
 
1016
            i = self.parameters.max_index
 
1017
            for path, value in zip(self.parameters["aggregated_%s" % column], values):
 
1018
                if value == None:
 
1019
                    continue
 
1020
            
 
1021
                parameters["%s_object_%d" % (column, i)] = path.replace("(0)", "").replace("(-1)", "")
 
1022
                parameters["%s_operator_%d" % (column, i)] = "="
 
1023
                parameters["%s_value_%d" % (column, i)] = value
 
1024
                i += 1
 
1025
                        
 
1026
        
 
1027
        return parameters
 
1028
    
 
1029
    def _setMessages(self, criteria):
 
1030
        self.dataset["messages"] = [ ]
 
1031
        self.dataset["aggregated_source"] = self.parameters["aggregated_source"]
 
1032
        self.dataset["aggregated_target"] = self.parameters["aggregated_target"]
 
1033
        self.dataset["aggregated_classification"] = self.parameters["aggregated_classification"]
 
1034
        self.dataset["aggregated_analyzer"] = self.parameters["aggregated_analyzer"]
 
1035
        
 
1036
        ag_s = self.parameters["aggregated_source"][:]
 
1037
        ag_t = self.parameters["aggregated_target"][:]
 
1038
        ag_c = self.parameters["aggregated_classification"][:]
 
1039
        ag_a = self.parameters["aggregated_analyzer"][:]
 
1040
        
 
1041
        for l in ag_s, ag_t, ag_c, ag_a:
 
1042
            while "none" in l:
 
1043
                l.remove("none")
 
1044
 
 
1045
        if len(ag_s + ag_t + ag_c + ag_a) > 0:
 
1046
            return self._setAggregatedMessagesNoValues(criteria, ag_s, ag_t, ag_c, ag_a)
 
1047
       
 
1048
        results = self.env.idmef_db.getAlertIdents(criteria)
 
1049
 
 
1050
        for ident in results[self.parameters["offset"] : self.parameters["offset"] + self.parameters["limit"]]:
 
1051
            message = self.env.idmef_db.getAlert(ident)
 
1052
            dataset = self._setMessage(message, ident)
 
1053
            self.dataset["messages"].append(dataset)
 
1054
 
 
1055
        return len(results)
 
1056
        
 
1057
    def _setDatasetConstants(self):
 
1058
        self.dataset["classification_filters"] = CLASSIFICATION_FILTERS
 
1059
        self.dataset["classification_aggregations"] = CLASSIFICATION_AGGREGATIONS
 
1060
        self.dataset["source_filters"] = SOURCE_FILTERS
 
1061
        self.dataset["source_aggregations"] = SOURCE_AGGREGATIONS
 
1062
        self.dataset["target_filters"] = TARGET_FILTERS
 
1063
        self.dataset["target_aggregations"] = TARGET_AGGREGATIONS
 
1064
        self.dataset["analyzer_filters"] = ANALYZER_FILTERS
 
1065
        self.dataset["analyzer_aggregations"] = ANALYZER_AGGREGATIONS
 
1066
 
 
1067
    def render(self):
 
1068
        self._deleteMessages()
 
1069
        self._setDatasetConstants()
 
1070
        
 
1071
        self.dataset["filters"] = self.env.db.getAlertFilterNames(self.user.login)
 
1072
        self.dataset["current_filter"] = self.parameters.get("filter", "")
 
1073
        
 
1074
        criteria = [ ]
 
1075
        
 
1076
        if self.parameters.has_key("filter"):
 
1077
            filter = self.env.db.getAlertFilter(self.user.login, self.parameters["filter"])
 
1078
            if filter:
 
1079
                criteria.append("(%s)" % str(filter))
 
1080
 
 
1081
        start = end = None
 
1082
        if self.parameters.has_key("timeline_unit") and self.parameters["timeline_unit"] != "unlimited":
 
1083
            start, end = self._getTimelineRange()
 
1084
            criteria.append("alert.create_time >= '%s' && alert.create_time < '%s'" % (str(start), str(end)))
 
1085
        
 
1086
        self._applyFilters(criteria)
 
1087
        self._adjustCriteria(criteria)
 
1088
 
 
1089
        self._setTimeline(start, end)
 
1090
        self._setNavPrev(self.parameters["offset"])
 
1091
 
 
1092
        self._setHiddenParameters()
 
1093
 
 
1094
        self.dataset["messages"] = [ ]
 
1095
        total = self._setMessages(criteria)
 
1096
 
 
1097
        self.dataset["nav.from"] = self.parameters["offset"] + 1
 
1098
        self.dataset["nav.to"] = self.parameters["offset"] + len(self.dataset["messages"])
 
1099
        self.dataset["limit"] = self.parameters["limit"]
 
1100
        self.dataset["total"] = total
 
1101
        self.dataset["correlation_alert_view"] = False
 
1102
 
 
1103
        self._setNavNext(self.parameters["offset"], total)
 
1104
        self._setTimezone()
 
1105
 
 
1106
 
 
1107
class ListedSensorAlert(ListedAlert):
 
1108
    view_name = "sensor_alert_listing"
 
1109
 
 
1110
 
 
1111
 
 
1112
class ListedSensorAggregatedAlert(ListedAggregatedAlert):
 
1113
    view_name = "sensor_alert_listing"
 
1114
 
 
1115
 
 
1116
class CorrelationAlertListing(AlertListing, view.View):
 
1117
    view_name = "correlation_alert_listing"
 
1118
    view_parameters = CorrelationAlertListingParameters
 
1119
    alert_type_default = [ "alert.correlation_alert.name" ]
 
1120
    
 
1121
 
 
1122
class ToolAlertListing(AlertListing, view.View):
 
1123
    view_name = "tool_alert_listing"
 
1124
    view_parameters = ToolAlertListingParameters
 
1125
    alert_type_default = [ "alert.tool_alert.name" ]
 
1126
        
 
1127
 
 
1128
 
 
1129
class SensorAlertListing(AlertListing, view.View):
 
1130
    view_name = "sensor_alert_listing"
 
1131
    view_parameters = SensorAlertListingParameters
 
1132
    view_permissions = [ User.PERM_IDMEF_VIEW ]
 
1133
    view_template = "SensorAlertListing"
 
1134
 
 
1135
    listed_alert = ListedSensorAlert
 
1136
    listed_aggregated_alert = ListedSensorAggregatedAlert
 
1137
 
 
1138
    def _setHiddenParameters(self):
 
1139
        AlertListing._setHiddenParameters(self)
 
1140
        self.dataset["hidden_parameters"].append(("analyzerid", self.parameters["analyzerid"]))
 
1141
 
 
1142
    def render(self):
 
1143
        AlertListing.render(self)
 
1144
        self.dataset["analyzer_infos"] = self.env.idmef_db.getAnalyzer(self.parameters["analyzerid"])