def __init__(self, config): """ XMPP agent class. """ log.info("Starting agent...") self.config = config log.info("Setting up certificate") self.public_key = None try: if Crypto.version_info[:2] >= (2, 2): _public_key = self._read_pub_key() if _public_key: key = PublicKey.RSA.importKey(_public_key) self.public_key = key.publickey() except: pass if not self.public_key: log.warn('PyCrypto not available or version is < 2.2: Please upgrade: http://www.pycrypto.org/') log.info("Loading commands...") self.command_runner = CommandRunner(config['Plugins']) log.debug("Loading XMPP...") observers = [ ('/iq', self.__onIq), ] Client.__init__(self, self.config['XMPP'], observers, resource='ecm_agent-%d' % AGENT_VERSION_PROTOCOL )
def _processCommand(self, message): log.debug('Process Command') if self.public_key: if not self._verify_message(message): log.critical('[RSA CHECK: Failed] Command from %s has bad signature (Ignored)' % message.from_) result = (_E_UNVERIFIED_COMMAND, '', 'Bad signature', 0) self._onCallFinished(result, message) return else: # No public key, RSA functions are not available on this system log.warn('[RSA CHECK: No available] WARNING: Running unverified Command from %s' % message.from_) flush_callback = self._Flush message.command_replaced = message.command.replace('.', '_') d = self.command_runner.run_command(message.command_replaced, message.command_args, flush_callback, message) if d: d.addCallbacks(self._onCallFinished, self._onCallFailed, callbackKeywords={'message': message}, errbackKeywords={'message': message}, ) return d else: log.info("Command Ignored: Unknown command: %s" % message.command) result = (_E_RUNNING_COMMAND, '', "Unknown command: %s" % message.command, 0) self._onCallFinished(result, message) return
def _onPossibleErrorIq(self, elem): sender = elem['from'] for el in elem.elements(): if el.name == 'error' and el['code'] == '404': log.warn('Received a 404 code from the server, setting the target user as offline') if sender in self._online_contacts: self._online_contacts.remove(sender) else: log.debug('Received a 404 from %s which not (anymore?) in the online contacts list.')
def __onIq(self, msg): """ A new IQ message has been received and we should process it. """ log.debug('__onIq') log.debug("q Message received: \n%s" % msg.toXml()) log.debug("Message type: %s" % msg['type']) if self.keepalive.running: log.debug("Stop keepalived") self.keepalive.stop() log.debug("Starting keepalived") self.keepalive.start(KEEPALIVED_TIMEOUT, now=False) self.timestamp = time() message = IqMessage(msg) recv_command = message.command.replace('.', '_') if recv_command in self.running_commands: if self.timestamp > self.running_commands[recv_command]: del self.running_commands[recv_command] self.num_running_commands -= 1 log.debug("Deleted %s from running_commands dict as should have been completed" % (recv_command)) if recv_command not in self.running_commands: log.debug('recieved new command: %s with message: %s' % (message.command, message)) if hasattr(message, 'command') and hasattr(message, 'from_'): log.debug('online contacts: %s' % self._online_contacts) if message.from_ not in self._online_contacts: log.warn('IQ sender not in roster (%s), dropping message' % message.from_) else: self.running_commands[recv_command] = self.timestamp + int(message.command_args['timeout']) self.num_running_commands += 1 log.debug("Running commands: names: %s numbers: %i" % (self.running_commands, self.num_running_commands)) self._processCommand(message) else: log.debug("already running given command %s" %recv_command) result = (_E_RUNNING_COMMAND, '', 'another command is running', 0) self._send(result, message) del msg del message
def __onIq(self, msg): """ A new IQ message has been received and we should process it. """ log.debug('__onIq') mem_clean('__onIq [start]') self.running_commands += 1 log.debug("q Message received: \n%s" % msg.toXml()) log.debug("Message type: %s" % msg['type']) if msg['type'] == 'set': message = IqMessage(msg) if hasattr(message, 'command') and hasattr(message, 'from_'): log.debug('online contacts: %s' % self._online_contacts) if message.from_ not in self._online_contacts: log.warn('IQ sender not in roster (%s), dropping message' % message.from_) else: self._processCommand(message) else: log.warn('Unknown ecm_message received: Full XML:\n%s' % (msg.toXml())) del message else: log.warn('Unknown IQ type received: Full XML:\n%s' % (msg.toXml())) del msg mem_clean('__onIq [end]')
def __onIq(self, msg): """ A new IQ message has been received and we should process it. """ log.debug('__onIq') message_type = msg['type'] log.debug("q Message received: \n%s" % msg.toXml()) log.debug("Message type: %s" % message_type) if message_type == 'set': #Parse and check message format message = IqMessage(msg) if hasattr(message, 'command') and hasattr(message, 'from_'): log.debug('online contacts: %s' % self._online_contacts) if message.from_ not in self._online_contacts: log.warn('IQ sender not in roster (%s), dropping message' % message.from_) else: self._processCommand(message) else: log.warn('Unknown ecm_message received: "%s" Full XML:\n%s' % (message_type, msg.toXml())) else: log.warn('Unknown IQ type received: "%s" Full XML:\n%s' % (message_type, msg.toXml()))
def _onErrorRunning(self, failure): log.warn('Command failed to execute: %s' % failure) return 255, '', ''