def receive(self): """Recieve message from the user and package for upstream consumption ### Description Wait for a connection and read a message. """ identifier = hash(self) # Purely for API consistency. self.connection, address = self.socket.accept() # pylint: disable=W0612 message = "" messages = self.connection.makefile("r") while True: piece = messages.readline().strip() if not len(piece): # Blank line separates messages ... break message += piece messages.close() logger.info("Got message, %s, from the user.", message) return identifier, helpers.translate(message)
def receive(self): # pylint: disable=R0912 """Recieve message from hypervisor and package for upstream consumption ### Description Wait for the watch to return some data and then pass that data to the caller. """ message = None while message is None: path, message = self._queue.get(timeout = sys.maxint) logger.debug("Current message at path, %s: %s", path, message) identifier = path.replace(self._receive_prefix + "/", "") logger.info("Received identifier, %s", identifier) logger.info("Translating message: %s", message) logger.info("Type of message: %s", type(message)) if type(message) is str: message = helpers.translate(message) if "function" in message: if message["function"] == "resetnetwork": msg = [] # TODO Is this check necessary or should we just go for the # TODO data? macs = set([ mac.replace(":", "") for mac in helpers.macs() if int(mac.replace(":", ""), 16) ]) # pylint: disable=C0301 logger.debug("MAC Addresses: %s", macs) # TODO Is there a better way than a busy wait? # MAC Addresses are upper in next gen but lower in first gen # Why do things like this happen? entries = set() while set([ entry.lower() for entry in entries ]) < set([ mac.lower() for mac in macs ]): # Required since we can't assume anything about the entries coming back ... pylint: disable=C0301 transaction = self.xs.transaction_start() entries = set(self.xs.ls(transaction, self._network_prefix)) self.xs.transaction_end(transaction) logger.debug("Entries: %s", entries) for entry in entries: transaction = self.xs.transaction_start() msg.append(self.xs.read(transaction, self._network_prefix + "/" + entry)) # pylint: disable=C0301 self.xs.transaction_end(transaction) logger.debug("Message: %s", message) for item in msg: tmp = helpers.translate(item) logger.debug("Adding in items: %s", tmp) if "ips" in tmp: if "ips" not in message: message["ips"] = {} message["ips"].update(tmp.pop("ips")) if "routes" in tmp: if "routes" not in message: message["routes"] = {} message["routes"].update(tmp.pop("routes")) message.update(tmp) logger.debug("Message: %s", message) msg = None transaction = self.xs.transaction_start() if self.xs.ls(transaction, self._hostname_prefix) is not None: msg = self.xs.read(transaction, self._hostname_prefix) self.xs.transaction_end(transaction) logger.debug("Found the hostname: %s", msg) if msg is not None: message["hostname"] = msg elif message["function"] == "injectfile": message["function"] = "file" elif message["function"] == "agentupdate": message["function"] = "update" elif message["function"] == "keyinit": crypto.generate_keys(message["arguments"]) logger.debug("Type of the key: %s", type(crypto.PUBLIC_KEY)) self.send(identifier, str(crypto.PUBLIC_KEY), "D0") return self.receive() # Hoping it's not keyinit's all the way down ... # pylint: disable=C0301 elif message["function"] == "version": logger.info("Faking the version passed back ...") self.send(identifier, "0.0.1.36") # Apparently it's a protocol version ... return self.receive() elif message["function"] == "password": if crypto.AES_KEYS is not None: logger.info("Decrypting password") message["password"] = crypto.decrypt(message["arguments"]) logger.debug("Password: encrypted => %s; decrypted => %s", message["arguments"], message["password"]) # pylint: disable=C0301 crypto.AES_KEYS = None else: self._queue.put((path, message)) return self.receive() # Potential for busy loop with itself if no keyinit ever comes ... # pylint: disable=C0301 logger.debug("Passing back identifier, %s, message, %s", identifier, message) # pylint: disable=C0301 return identifier, message