def shutdown(self): """ Shut down the backend process. """ self._isAlive = 0 from g4dslogging import getDefaultLogger, ROUTING_TABLE_UPDATED getDefaultLogger().newMessage(ROUTING_TABLE_UPDATED, 'Routing Table updater is shutdown')
def startup(self): """ Starts up G4DS. Regarding to the settings in the configuration files the connections are established and the database is loaded. """ from maintainlib import _printAction, _finishActionLine, SUCESS_POS, SUCESS_NEG, SUCESS_SKIP from errorhandling import G4dsException print "\n" + "*" * 90 _printAction(0, "Starting up G4DS",1) _printAction(1, "Loading Configuration", 1) self.loadConfigurations() # initialise with their private keys from the personal credential manager ## _finishActionLine() _printAction(1, "Start G4DS logging") from g4dslogging import getDefaultLogger try: getDefaultLogger() _finishActionLine() except G4dsException, msg: _finishActionLine(SUCESS_NEG) _printAction(2, str(msg)) _finishActionLine(SUCESS_NEG)
def updateNow(self, timeout = 60): """ Performs the actual updating process. """ from g4dsconfigurationcontroller import getRoutingController from communitymanager import getMemberManager, getCommunityManager peerList = {} # the dict here is a bit chicky - but the simpliest way to avoid duplicates # get the ids of connected gateways and download their routing tables for communityid in getMemberManager().getLocalMember().getCommunityIds(): comm = getCommunityManager().getCommunity(communityid) for gw in comm.getSourceGateways(): if gw.getMemberId() != getMemberManager().getLocalMember().getId(): peerList[gw.getMemberId()] = None peerList = peerList.keys() for peerId in peerList: routesRemote = getRoutingController().downloadRoutingTable(peerId, timeout = timeout) from routingtablemanager import getRoutingTableManager import thread thread.start_new_thread(getRoutingTableManager().applyRoutingTableFromNode, (peerId, routesRemote)) from g4dslogging import getDefaultLogger, ROUTING_TABLE_UPDATED getDefaultLogger().newMessage(ROUTING_TABLE_UPDATED, 'Routing table updated')
def dispatch(self, message, incomingmessageid): """ Unwrappes the message and tries to deliver directly, or if not possible through another routing hop. """ ## print "\tRouting Dispatcher: Received something to pass on." from g4dslogging import getDefaultLogger, COMMUNICATION_INCOMING_MSG_DETAILS getDefaultLogger().newMessage(COMMUNICATION_INCOMING_MSG_DETAILS, '-- Control Msg - SS: Routing Engine') from messagewrapper import getControlMessageWrapper action, sucess, args, unwrapped = getControlMessageWrapper().unwrapSSRoutingMessage(message) destination = args['destination'] protocol = args['protocol'] community = args['community'] from authorisationcontroller import getAuthorisationController from messagehandler import getMessageContextController sourceCommunity = getMessageContextController().getValue(incomingmessageid, 'communityid') ## # let's check, whether the sender of this message is allowed to route into the community ## if not getAuthorisationController().validate(getMessageContextController().getValue(incomingmessageid, 'senderid'), ## sourceCommunity, 'g4ds.routing.route'): ## return from communitymanager import getMemberManager # check first, whether we are the final receipient if getMemberManager().getLocalMember().getId() == destination: # great stuff - pass it to the global dispatcher from messagehandler import getGlobalDispatcher getGlobalDispatcher().dispatch(protocol, unwrapped) else: args = {} args['destination'] = destination args['protocol'] = protocol args['community'] = community from messagewrapper import getControlMessageWrapper wrapped, doc, element = getControlMessageWrapper().wrapSSRoutingMessage('1', args = args, data = unwrapped) from g4dsconfigurationcontroller import getOutgoingControlMessagesHandler, CONTROL_ROUTER # check, whether we can reach the dest community directly try: getMemberManager().getLocalMember().getCommunityIds().index(community) # great to know; but are we allowed this action? if not getAuthorisationController().validate(getMemberManager().getLocalMember().getId(), community, 'g4ds.routing.route'): raise ValueError('I am in the dest community; but I am not allowed to route into it. Let us try to find somebody else.') # unfortunately, we can only check the dest tc with the access control - let's check for scr / dest combination additionally for gw in getMemberManager().getLocalMember().getGateways(): if gw.getSourceCommunityId() == sourceCommunity and gw.getDestinationCommunityId() == community: getOutgoingControlMessagesHandler().sendMessage(destination, CONTROL_ROUTER, "Routing message", wrapped, communityid = community) raise ValueError('I am in the dest community; but I am not allowed to route into it. Let us try to find somebody else.') except ValueError, msg: # ok - looks like we can only pass it on to the next hop gateway_member_id, peercommunity, hops = getRoutingTableManager().getNexthopForCommunity(community) # are we allowed this action then? if not getAuthorisationController().validate(getMemberManager().getLocalMember().getId(), peercommunity, 'g4ds.routing.route'): return # ah, fair enough - is it also allowed for the combination src TC / dst TC? for gw in getMemberManager().getLocalMember().getGateways(): if gw.getSourceCommunityId() == sourceCommunity and gw.getDestinationCommunityId() == peercommunity: getOutgoingControlMessagesHandler().sendMessage(gateway_member_id, CONTROL_ROUTER, "Routing message", wrapped, communityid = peercommunity)
def flushTable(self): """ Flushes the routing table - the table will be totally empty afterwards. """ self._routingtable = {} if self._dbconnected: self._rtm_db.emptyRoutingTable() from g4dslogging import getDefaultLogger, ROUTING_TABLE_UPDATED_MANUALLY getDefaultLogger().newMessage(ROUTING_TABLE_UPDATED_MANUALLY, 'Routing table flushed')
def dispatch(self, protocol, message, inbackground = 1): """ Receives the raw messages from the protocol implementations and passes them somewhere depending on the type. Message is passed to the L{messagewrapper.MessageWrapper.unwrapG4dsMessage} function for removing the g4ds-"header" and gain the actual information. Afterwards, in case of an encrypted message it is passed to the private function L{_handleDecryptionAndValidation} which will thereupon unwrap and decrypt the message. Then, the message is passed and it is identified, whether there is a service or a control message contained. Depending on this, the content is either passed to the L{g4dsconfigurationcontroller.ControlMessageDispatcher.dispatch} or to the L{serviceintegrator.ServiceIntegrator.dispatch}. @param protocol: Protocol as identified for the incoming message @type protocol: C{String} @param message: String representation of the XML message @type message: C{String} """ if inbackground: import thread thread.start_new_thread(self.dispatch,(protocol, message, 0)) return from errorhandling import G4dsException try: from g4dslogging import getDefaultLogger, COMMUNICATION_INCOMING_MSG, COMMUNICATION_INCOMING_MSG_DETAILS getDefaultLogger().newMessage(COMMUNICATION_INCOMING_MSG, 'New incoming message') firstmessage = message message, rootnode = getMessageWrapper().unwrapG4dsMessage(message) message, senderidDec, communityid = self._handleDecryptionAndValidation(message, protocol) message, mid, senderid, refid = getMessageWrapper().unwrapG4dsPlain(message) getDefaultLogger().newMessage(COMMUNICATION_INCOMING_MSG_DETAILS, '-- MSG ID %s | SENDER %s' %(mid, senderid)) getDefaultLogger().newMessage(COMMUNICATION_INCOMING_MSG_DETAILS, '-- Size of msg (brutto | netto): %d | %d Bytes' %(len(firstmessage), len(message))) getMessageContextController().addMessage(mid) getMessageContextController().addValue(mid, 'refid', refid) getMessageContextController().addValue(mid, 'senderid', senderid) getMessageContextController().addValue(mid, 'communityid', communityid) root = xml.dom.ext.reader.Sax2.FromXml(message) childnode = root.childNodes[1] if childnode.nodeType == Node.ELEMENT_NODE: stio = StringIO() xml.dom.ext.PrettyPrint(childnode, stio) xmlSubTreeString = stio.getvalue() stio.close() if childnode.nodeName == xmlconfig.g4ds_control_node: id, name, data = getMessageWrapper().unwrapControlMessage(xmlSubTreeString) getControlMessageDispatcher().dispatch(childnode, id, name, data, mid) if childnode.nodeName == xmlconfig.g4ds_service_node: id, name, data = getMessageWrapper().unwrapServiceMessage(xmlSubTreeString) getServiceIntegrator().dispatch(id, name, data, mid) except G4dsException, msg: from g4dslogging import getDefaultLogger, COMMUNICATION_INCOMING_ERROR getDefaultLogger().newMessage(COMMUNICATION_INCOMING_ERROR, msg)
def __init__(self): """ Initialises the background process. """ self._isAlive = 1 from config import ENABLE_ROUTING from g4dslogging import getDefaultLogger, ROUTING_TABLE_UPDATED import thread if ENABLE_ROUTING: thread.start_new_thread(self.runForEver, ()) getDefaultLogger().newMessage(ROUTING_TABLE_UPDATED, 'Routing Table updater intialised') else: getDefaultLogger().newMessage(ROUTING_TABLE_UPDATED, 'Routing Table updater disabled in config file.') from errorhandling import G4dsRuntimeException raise G4dsRuntimeException('Dynamic routing is disabled in config file.')
def recalculateRoutingTable(self): """ Creates routing entries from the scratch by processing gateway information. The values for directly reachable communities are applied. Furthermore, communities, which may be reached through one community only (1 hop) are put into as well. The rest should be sorted out be the dynamic routing faciliites. """ numberOfEntries = 0 tmpList = [] # we have to maintain this list with new entries; just in case # the routing table was not flushed beforehand # first process directly reachable communities - cost = 1 from communitymanager import getMemberManager, getCommunityManager for communityid in getMemberManager().getLocalMember().getCommunityIds(): # everybody can route into its own community ...that's just important to pass it on to any gw within the community entry = RoutingTableEntry(None, communityid, communityid, getMemberManager().getLocalMember().getId(), communityid, 1) getRoutingTableManager().addEntry(entry) numberOfEntries += 1 tmpList.append(entry) # get all the gateways of the directly connected communities for communityid in getMemberManager().getLocalMember().getCommunityIds(): comm = getCommunityManager().getCommunity(communityid) for gw in comm.getSourceGateways(): # if it's myself, I can reach it directly (cost 1) if gw.getMemberId() == getMemberManager().getLocalMember().getId(): entry = RoutingTableEntry(None, communityid, gw.getDestinationCommunityId(), gw.getMemberId(), communityid, 1) getRoutingTableManager().addEntry(entry) numberOfEntries += 1 tmpList.append(entry) # now get all the entries with cost 2 # what do we do: We check the available entries with cost 1 and have a look, which (source) gateways are # available for them (for their destination gateway) for item in tmpList: srcTC = item.getDestinationTC() # the destination tc of the hop 1 entry will be the src tc of the hop 2 entry comm = getCommunityManager().getCommunity(srcTC) for gw in comm.getSourceGateways(): entry = RoutingTableEntry(None, item.getSourceTC(), gw.getDestinationCommunityId(), gw.getMemberId(), srcTC, 2) getRoutingTableManager().addEntry(entry) numberOfEntries += 1 from g4dslogging import getDefaultLogger, ROUTING_TABLE_UPDATED_MANUALLY getDefaultLogger().newMessage(ROUTING_TABLE_UPDATED_MANUALLY, 'Routing table recalculated - added %d entries.' %(numberOfEntries)) return numberOfEntries
def _assembleRoutingMessage(self, message, endpoint): final_destination = endpoint.getMemberId() community = endpoint.getCommunityId() from communicationmanager import getProtocolManager protocolname = getProtocolManager().getProtocol(endpoint.getProtocolId()).getName() gateway_member_id, peercommunity, hops = getRoutingTableManager().getNexthopForCommunity(endpoint.getCommunityId()) args = {} args['destination'] = final_destination args['protocol'] = protocolname args['community'] = community from messagewrapper import getControlMessageWrapper wrapped, tmp, tmp1 = getControlMessageWrapper().wrapSSRoutingMessage('1', args = args, data = message) from g4dslogging import getDefaultLogger, COMMUNICATION_OUTGOING_MSG_DETAILS getDefaultLogger().newMessage(COMMUNICATION_OUTGOING_MSG_DETAILS, '-- Routing details: Gateway (%s | %s)' %(gateway_member_id, peercommunity)) getDefaultLogger().newMessage(COMMUNICATION_OUTGOING_MSG_DETAILS, '-- Size of Data %d chars' %(len(message))) from g4dsconfigurationcontroller import getOutgoingControlMessagesHandler, CONTROL_ROUTER getOutgoingControlMessagesHandler().sendMessage(gateway_member_id, CONTROL_ROUTER, "Routing message", wrapped, communityid = peercommunity)
def _logEntry(self, actor, target, action, reaction, reportPolicyError = 0): """ Reports this access control access to the logging facilities. """ from g4dslogging import getDefaultLogger, PERMISSION_MESSAGE_PASSED, PERMISSION_MESSAGE_DROPPED, PERMISSION_POLICY_ERROR if reportPolicyError: getDefaultLogger().newMessage(PERMISSION_POLICY_ERROR, 'Access Control Policy error - rules are not covering all actions. Check your rulesets. Apply default reaction from config module for now.') global REACTION_DICT if REACTION_DICT[reaction]: getDefaultLogger().newMessage(PERMISSION_MESSAGE_PASSED, 'Access Control - message passed: %s -> %s (A: %s)' %(actor, target, action)) else: getDefaultLogger().newMessage(PERMISSION_MESSAGE_DROPPED, 'Access Control - access violation: %s -> %s (A: %s)' %(actor, target, action))
def _handleDecryptionAndValidation(self, message, protocolname): """ Helper function for supporting the decryption of the message. The passed message is passed to the L{messagewrapper.MessageWrapper.unwrapForDecryption} for removing the encryption "header" and gaining the name of the algorithm and the cipher text. Afterwards, the function decrypt in the securitycontroller is invoked and the result is returned. @return: Result of the L{securitycontroller.SecurityController.decrypt} @rtype: C{String} """ alg, data = getMessageWrapper().unwrapForDecryption(message) data = getSecurityController().decrypt(data, alg) algName, memberid, communityid, data, signature = getMessageWrapper().unwrapForValidation(data) from communicationmanager import getEndpointManager from errorhandling import G4dsDependencyException, G4dsCommunicationException from g4dslogging import getDefaultLogger, COMMUNICATION_INCOMING_NO_ENDPOINT from securitymanager import getCredentialManager, getAlgorithmManager try: endpoint = getEndpointManager().findEndpoint(memberid, communityid, protocolname, algName) credential = getCredentialManager().getCredential(endpoint.getCredentialId()) if not credential: getDefaultLogger().newMessage(COMMUNICATION_INCOMING_NO_ENDPOINT, 'No credential found for the sender of the incoming message - validation aborted.') raise G4dsCommunicationException('No credential found for the sender of the incoming message - validation aborted.') key = credential.getKey() if not getSecurityController().validate(data, signature, key, algName): raise G4dsCommunicationException('Signature not valid for this message.') return data, memberid, communityid except G4dsDependencyException, msg: getDefaultLogger().newMessage(COMMUNICATION_INCOMING_NO_ENDPOINT, 'Src Enpoint Detemination: %s - attempt key determination' %(msg)) # we have to carry on here - if the message is routed; the end-to-end message integrity must still be ensured; however - both members are not in the # same community; hence - the receiver might not know about the endpoints of the sender; however, for this approach it's compulsary, that the public # key is known creds = getCredentialManager().getCredentialsForMember(memberid) for cred in creds: # well, problem here - the sender might have several keys of the same algorithm - no chance to get around checking them all here if getAlgorithmManager().getAlgorithm(cred.getAlgorithmId()).getName() == algName: key = cred.getKey() if getSecurityController().validate(data, signature, key, algName): return data, memberid, communityid # ohoh - looks like this message is not valied :( getDefaultLogger().newMessage(COMMUNICATION_INCOMING_NO_ENDPOINT, 'Src Enpoint Detemination: manual key search not sucessful.') raise G4dsCommunicationException('Signature not valid for the incoming message.')
def sendMessage(self, message, endpoint): """ Tries to deliver a message directly, if impossible via wrapping into routing message. All messages should be passed here and not be sent from anywhere else. The routing engine looks, whether the given endpoint may be reached directly from the local node. If this is possible, the message is sent off directly. If, however, this is not possible, the message is wrapped into a routing message and gateways are tried to identify for passing the message through the topology. """ # check, whether I am in the community of the given endpoint, if not - we need to attempt to route this message tc = endpoint.getCommunityId() from communitymanager import getMemberManager local = getMemberManager().getLocalMember() ## try: ## local.getCommunityIds().index(tc) from communicationmanager import getProtocolManager, getEndpointManager if len(getEndpointManager().getEndpointsForMember(local.getId(), tc)): from g4dslogging import getDefaultLogger, COMMUNICATION_OUTGOING_MSG, COMMUNICATION_OUTGOING_MSG_DETAILS getDefaultLogger().newMessage(COMMUNICATION_OUTGOING_MSG, 'New outgoing message - direct delivery (%s | %s)' %(endpoint.getMemberId(), tc)) getDefaultLogger().newMessage(COMMUNICATION_OUTGOING_MSG_DETAILS, '-- Endpoint %s' %(str(endpoint))) getDefaultLogger().newMessage(COMMUNICATION_OUTGOING_MSG_DETAILS, '-- Size of Data %d chars' %(len(message))) protocol = getProtocolManager().getProtocol(endpoint.getProtocolId()) from protocolcontroller import getProtocolController protocol = getProtocolController().getOpenProtocol(protocol.getName()) from socket import error from errorhandling import G4dsCommunicationException try: protocol.sendMessage(endpoint.getAddress(), message) except error, msg: raise G4dsCommunicationException('Sending Message: %s' %(msg))
protocol = getProtocolManager().getProtocol(endpoint.getProtocolId()) from protocolcontroller import getProtocolController protocol = getProtocolController().getOpenProtocol(protocol.getName()) from socket import error from errorhandling import G4dsCommunicationException try: protocol.sendMessage(endpoint.getAddress(), message) except error, msg: raise G4dsCommunicationException('Sending Message: %s' %(msg)) ## except ValueError, msg: else: # ok, not in there - let's route then from g4dslogging import getDefaultLogger, COMMUNICATION_OUTGOING_MSG_ROUTED getDefaultLogger().newMessage(COMMUNICATION_OUTGOING_MSG_ROUTED, 'New outgoing message - routed (%s | %s)' %(endpoint.getMemberId(), tc)) self._assembleRoutingMessage(message, endpoint) def _assembleRoutingMessage(self, message, endpoint): final_destination = endpoint.getMemberId() community = endpoint.getCommunityId() from communicationmanager import getProtocolManager protocolname = getProtocolManager().getProtocol(endpoint.getProtocolId()).getName() gateway_member_id, peercommunity, hops = getRoutingTableManager().getNexthopForCommunity(endpoint.getCommunityId()) args = {} args['destination'] = final_destination args['protocol'] = protocolname args['community'] = community from messagewrapper import getControlMessageWrapper
def testLogging(): from g4dslogging import getDefaultLogger getDefaultLogger()
except G4dsRuntimeException, msg: _finishActionLine(SUCESS_SKIP) _printAction(1, "Shutting down Listeners") from protocolcontroller import getProtocolController import socket try: getProtocolController().shutdownAllListeners() _finishActionLine() except socket.error, msg: _finishActionLine(SUCESS_NEG) _printAction(2, str(msg)) _finishActionLine(SUCESS_NEG) _printAction (1,"Shutting down Logging") from g4dslogging import getDefaultLogger getDefaultLogger().closedown() _finishActionLine() _printAction(0, "Shutdown complete") _finishActionLine() print "*" * 90 + "\n" ## ######################################## ## ## Interaction with G4ds ## def registerClient(self, serviceid, clientcallback): """ A new client has connected through C/S facilities. Let's go and register it with the service integrator. """