Package ioids :: Module messagewrapper
[hide private]
[frames] | no frames]

Source Code for Module ioids.messagewrapper

  1  """ 
  2  Handles all concerns for wrapping and parsing xml data. 
  3   
  4  Inter-Organisational Intrusion Detection System (IOIDS) 
  5   
  6  @author: Michael Pilgermann 
  7  @contact: mailto:mpilgerm@glam.ac.uk 
  8  @license: GPL (General Public License) 
  9  """ 
 10   
 11  import xml.dom 
 12  from xml.dom import Node 
 13  import xml.dom.ext.reader.Sax2 
 14  from StringIO import StringIO 
 15  import xml.dom.ext 
 16   
 17  from xmldb_infos import DATATYPES 
 18   
 19  import soapsytools.messagewrapper 
 20   
 21  # "singleton" 
 22  _genericWrapper = None 
23 -def getGenericWrapper():
24 """ 25 Singleton implementation. 26 27 @return: The instance for the generic wrapper class 28 @rtype: L{soapsytools.messagewrapper.GenericWrapper} 29 """ 30 soapsytools.messagewrapper.getGenericWrapper()
31 32 33 # "singleton" 34 _xmlDBWrapper = None
35 -def getXMLDBWrapper():
36 """ 37 Singleton implementation. 38 39 @return: The instance for the generic wrapper class 40 @rtype: L{GenericWrapper} 41 """ 42 global _xmlDBWrapper 43 if not _xmlDBWrapper: 44 _xmlDBWrapper = IoidsXMLDBWrapper() 45 return _xmlDBWrapper
46
47 -class IoidsXMLDBWrapper(soapsytools.messagewrapper.XMLDBWrapper):
48 """ 49 Wrapper / Parser for XML database queries / replies. 50 """
51 - def __init__(self):
52 """ 53 Yet empty constructor. 54 """ 55 from config import DB_DATA_TYPE 56 soapsytools.messagewrapper.XMLDBWrapper.__init__(self, DB_DATA_TYPE)
57 58 59 # "singleton" 60 _ioidsMessageWrapper = None
61 -def getIoidsMessageWrapper():
62 """ 63 Singleton implementation. 64 65 @return: The instance for the ioids message wrapper class 66 @rtype: L{IoidsMessageWrapper} 67 """ 68 global _ioidsMessageWrapper 69 if not _ioidsMessageWrapper : 70 _ioidsMessageWrapper = IoidsMessageWrapper() 71 return _ioidsMessageWrapper
72
73 -class IoidsMessageWrapper(soapsytools.messagewrapper.EventMessageWrapper):
74 """ 75 Wrapper for messages to be exchanged between IOIDS nodes. 76 """ 77
78 - def __init__(self):
79 """ 80 Yet empty constructor. 81 """ 82 pass
83
84 - def _assembleIoidsEventSubMessage(self, ioidsEvent, parentNode, doc):
85 """ 86 Assemble the tree underneath a IOIDS event (no relations). 87 """ 88 # the following (commented) code was made for incorperating IDMEF as message standard 89 # for the base - event information 90 # it has been decided, however, to use another (db alligned) message format ... 91 ## elementIoidsEvent = doc.createElement('ioidsevent') 92 ## parentNode.appendChild(elementIoidsEvent) 93 94 ## sender = None 95 ## source = None 96 ## event = None 97 ## classification = None 98 ## classificationCode = None 99 ## for rel in ioidsEvent[2]: 100 ## if rel[0] == 'ioids_sender': 101 ## sender = self._getValueInTree(rel, ['ioids_peer', 'peer_memberid']) 102 ## if rel[0] == 'ioids_source': 103 ## source = self._getValueInTree(rel, ['ioids_peer', 'peer_memberid']) 104 ## if rel[0] == 'ioids_classification': 105 ## classification = rel[1]['classification_name'] 106 ## classification_code = rel[1]['classification_code'] 107 ## if rel[0] == 'event': 108 ## event = rel 109 ## 110 ## if sender: 111 ## elementSender = doc.createElement('sender') 112 ## elementIoidsEvent.appendChild(elementSender) 113 ## senderText = doc.createTextNode(sender) 114 ## elementSender.appendChild(senderText) 115 ## 116 ## if source: 117 ## elementSource = doc.createElement('source') 118 ## elementIoidsEvent.appendChild(elementSource) 119 ## sourceText = doc.createTextNode(source) 120 ## elementSource.appendChild(sourceText) 121 ## 122 ## if classification and classification_code: 123 ## elementClassification = doc.createElement('classification') 124 ## elementIoidsEvent.appendChild(elementClassification) 125 ## elementClassification.setAttribute('code', classification_code) 126 ## classificationText = doc.createTextNode(classification) 127 ## elementClassification.appendChild(classificationText) 128 ## 129 ## if event: 130 ## self._assemblePlainEvent(event, elementIoidsEvent, doc) 131 ## 132 ## elementCommunity = doc.createElement('community') 133 ## elementIoidsEvent.appendChild(elementCommunity) 134 ## communityText = doc.createTextNode(ioidsEvent[1]['community_id']) 135 ## elementCommunity.appendChild(communityText) 136 137 # all we need to do now, is wrapping the ioids event into the corrosponding XML structure 138 self._wrapAnyItemToDom(ioidsEvent, parentNode, doc)
139 140
141 - def _assembleAdditionalDataForIdmefFromEvent(self, event, parentNode, doc):
142 elementAddData = doc.createElement('AdditionalData') 143 elementAddData.setAttribute('type', 'xml') 144 elementAddData.setAttribute('meaning', 'ioids remaining information') 145 146 elementReporter = doc.createElement('ioids:Reporter') 147 reporter = self._getRelationInTree(event, ['reporter']) 148 try: 149 elementReporter.setAttribute('ioids:name', reporter[1]['rprt_name']) 150 except KeyError, msg: 151 pass 152 self._assembleNode(self._getRelationInTree(reporter, ['agent']), elementReporter, doc) 153 154 elementAddData.appendChild(elementReporter) 155 156 parentNode.appendChild(elementAddData)
157
158 - def _assembleExtension(self, extension, parentNode, doc):
159 elementExtension = doc.createElement('extension') 160 elementExtension.setAttribute('type', extension[1]['extension_name']) 161 parentNode.appendChild(elementExtension) 162 getExtensionWrapperHandler().getFullExtensionMessage(extension[1]['extension_name'], extension[2][0], elementExtension, doc)
163
164 - def _assembleRelatedEvent(self, relation, parentNode, doc):
165 event = self._getRelationInTree(relation, ['event']) 166 rel_type = self._getValueInTree(relation, ['ioids_relation_type', 'ioids_relation_type_name']) 167 extension = self._getRelationInTree(relation, ['extension']) 168 elementRelation = doc.createElement('relation') 169 elementRelation.setAttribute('type', rel_type) 170 parentNode.appendChild(elementRelation) 171 self._assemblePlainEvent(event, elementRelation, doc) 172 self._assembleExtension(extension, elementRelation, doc)
173
174 - def assembleIoidsMessage(self, ioidsEvent, relatedEvents = [], doc = None, parentNode = None):
175 """ 176 Assembled the XML message for the given ioids event. 177 178 @param ioidsEvent: Information of the IOIDS event in list / dict format (name, attrbutes, relations) 179 @type ioidsEvent: C{List} of [C{String}, C{Dict}, C{List}] 180 @param relatedEvents: Information about related events for the given IOIDS event. Each relation as couple (type / pure event / extension information) 181 @type relatedEvents: C{List} of Couples 182 """ 183 if parentNode: 184 elementRoot = doc.createElement('ioids') 185 parentNode.appendChild(elementRoot) 186 else: 187 impl = xml.dom.getDOMImplementation() 188 doc = impl.createDocument(None, 'ioids', None) 189 elementRoot = doc.documentElement 190 191 self._assembleIoidsEventSubMessage(ioidsEvent, elementRoot, doc) 192 193 elementRelations = doc.createElement('relations') 194 elementRoot.appendChild(elementRelations) 195 196 for rel in relatedEvents: 197 self._assembleRelatedEvent(rel, elementRelations, doc) 198 199 if not parentNode: 200 return self._toXml(doc)
201
202 - def _unwrapSomething(self, domNode):
203 dict = {} 204 relations = [] 205 attDict = domNode._get_attributes() 206 for key in attDict.keys(): 207 dict[key[1]] = domNode.getAttribute(key) 208 for child in domNode.childNodes: 209 if child.nodeType == Node.ELEMENT_NODE: 210 relations.append(self._unwrapSomething(child)) 211 return [domNode.nodeName, dict, relations]
212
213 - def unwrapFullIoidsEventMessage(self, data, domNode = None):
214 from errorhandling import IoidsFormatException 215 216 if not domNode: 217 try: 218 root = xml.dom.ext.reader.Sax2.FromXml(data) 219 except Exception, msg: 220 ## print "!!!!!!!!! Internal message format error - XML message:\n****************\n%s\n**************\n" %(data) 221 raise IoidsFormatException("XML Format string error: %s" %(msg)) 222 node = root.childNodes[1] 223 else: 224 node = domNode 225 if node.nodeName != 'ioids': 226 raise IoidsFormatException('This is not a ioids message.') 227 228 ioidsEvent = None 229 relations = [] 230 for child1 in node.childNodes: 231 if child1.nodeType == Node.ELEMENT_NODE: 232 if child1.nodeName == 'ioids_event': 233 ioidsEvent = self._unwrapSomething(child1) 234 elif child1.nodeName == 'relations': 235 for child2 in child1.childNodes: 236 if child2.nodeType == Node.ELEMENT_NODE: 237 if child2.nodeName == 'relation': 238 rel = self._unwrapSomething(child2) 239 relations.append(rel) 240 else: 241 raise IoidsFormatException('Unknown tag at this location inside IOIDS message: %s' %(child2.nodeName)) 242 else: 243 raise IoidsFormatException('Unknown tag at this location inside IOIDS message: %s' %(child1.nodeName)) 244 245 return ioidsEvent, relations
246 247
248 - def wrapKnowledgeRequestMessage(self, conditions):
249 impl = xml.dom.getDOMImplementation() 250 doc = impl.createDocument(None, 'knowledge-request', None) 251 elementRoot = doc.documentElement 252 253 elementConditions = doc.createElement('conditions') 254 elementRoot.appendChild(elementConditions) 255 256 for condition in conditions: 257 attributeName = condition[0] 258 operatorKey = condition[1] 259 value = condition[2] 260 261 elementCondition = doc.createElement('condition') 262 elementCondition.setAttribute('attribute', attributeName) 263 elementCondition.setAttribute('operator', operatorKey) 264 valueText = doc.createTextNode(value) 265 elementCondition.appendChild(valueText) 266 267 elementConditions.appendChild(elementCondition) 268 return self._toXml(doc)
269
270 - def parseKnowledgeRequestMessage(self, xmlString):
271 """ 272 @return: Conditions in List / List format 273 @rtype: C{List} of C{List} 274 """ 275 from errorhandling import IoidsFormatException 276 try: 277 root = xml.dom.ext.reader.Sax2.FromXml(xmlString) 278 except Exception, msg: 279 raise IoidsFormatException("XML Format string error: %s" %(msg)) 280 node = root.childNodes[1] 281 if node.nodeName != 'knowledge-request': 282 raise IoidsFormatException('This is not a ioids knowledge request message.') 283 284 conditions = [] 285 for child1 in node.childNodes: 286 if child1.nodeType == Node.ELEMENT_NODE: 287 if child1.nodeName == 'conditions': 288 for child2 in child1.childNodes: 289 if child2.nodeType == Node.ELEMENT_NODE: 290 if child2.nodeName == 'condition': 291 attributeName = child2.getAttribute('attribute') 292 operator = child2.getAttribute('operator') 293 for child3 in child2.childNodes: 294 if child3.nodeType == Node.TEXT_NODE: 295 value = child3.nodeValue 296 conditions.append([attributeName, operator, value]) 297 else: 298 raise IoidsFormatException('Unknown tag at this location inside knowledge request message: %s' %(child2.nodeName)) 299 else: 300 raise IoidsFormatException('Unknown tag at this location inside knowledge request message: %s' %(child1.nodeName)) 301 return conditions
302
303 - def wrapKnowledgeReplyMessage(self, fullIoidsEvents):
304 """ 305 @param fullIoidsEvents: List of IOIDS events to include in the reply (full events including relations - optionally) - each entry as a couple (ioidsEvent, relationsList) 306 @type fullIoidsEvents: C{List} of C{Couples} 307 """ 308 impl = xml.dom.getDOMImplementation() 309 doc = impl.createDocument(None, 'knowledge-reply', None) 310 elementRoot = doc.documentElement 311 312 elementResults = doc.createElement('results') 313 elementResults.setAttribute('count', str(len(fullIoidsEvents))) 314 elementRoot.appendChild(elementResults) 315 316 for fullEvent, relations in fullIoidsEvents: 317 elementResult = doc.createElement('result') 318 self.assembleIoidsMessage(fullEvent, relations, doc, elementResult) 319 elementResults.appendChild(elementResult) 320 321 return self._toXml(doc)
322
323 - def parseKnowledgeReplyMessage(self, xmlString):
324 """ 325 @return: List of full IOIDS events - couples in form (ioidsEvent | relationList) 326 @rtype: C{List} of C{Couples} 327 """ 328 from errorhandling import IoidsFormatException 329 try: 330 root = xml.dom.ext.reader.Sax2.FromXml(xmlString) 331 except Exception, msg: 332 raise IoidsFormatException("XML Format string error: %s" %(msg)) 333 node = root.childNodes[1] 334 if node.nodeName != 'knowledge-reply': 335 raise IoidsFormatException('This is not a ioids knowledge reply message.') 336 337 fullIoidsEvents = [] 338 for child1 in node.childNodes: 339 if child1.nodeType == Node.ELEMENT_NODE: 340 if child1.nodeName == 'results': 341 for child2 in child1.childNodes: 342 if child2.nodeType == Node.ELEMENT_NODE: 343 if child2.nodeName == 'result': 344 for child3 in child2.childNodes: 345 if child3.nodeType == Node.ELEMENT_NODE: 346 if child3.nodeName == 'ioids': 347 oneEvent, relations = self.unwrapFullIoidsEventMessage(None, child3) 348 fullIoidsEvents.append((oneEvent, relations)) 349 return fullIoidsEvents
350 351 352 # "singleton" 353 _extensionWrapperHandler = None
354 -def getExtensionWrapperHandler():
355 """ 356 Singleton implementation. 357 """ 358 global _extensionWrapperHandler 359 if not _extensionWrapperHandler: 360 _extensionWrapperHandler = ExtensionWrapperHandler() 361 return _extensionWrapperHandler
362
363 -class ExtensionWrapperHandler:
364 """ 365 Connects to the appropriate extension implementation to get the data wrapped. 366 """ 367
368 - def __init__(self):
369 """ 370 Yet empty constructor. 371 """ 372 from config import SOAPSY_EXTENSIONS 373 self._extensions = SOAPSY_EXTENSIONS
374
375 - def getFullExtensionMessage(self, extensionName, extensionData, parentNode, doc):
376 if not self._extensions.has_key(extensionName): 377 return None 378 379 ext_mw = self._extensions[extensionName]['messagewrapper'] 380 return ext_mw().getFullExtensionMessage(extensionData, parentNode, doc)
381