def func(node, *args):
            msgID = sha1(str(random.getrandbits(255))).digest()

            m = Message()
            m.messageID = msgID
            m.sender.MergeFrom(self.sourceNode.getProto())
            m.command = Command.Value(name.upper())
            m.protoVer = PROTOCOL_VERSION
            for arg in args:
                m.arguments.append(str(arg))
            m.testnet = self.multiplexer.testnet
            data = m.SerializeToString()

            address = (node.ip, node.port)
            relay_addr = None
            if node.nat_type == SYMMETRIC or \
                    (node.nat_type == RESTRICTED and self.sourceNode.nat_type == SYMMETRIC):
                relay_addr = node.relay_node

            d = defer.Deferred()
            if m.command != HOLE_PUNCH:
                timeout = reactor.callLater(self._waitTimeout, self.timeout, node)
                self._outstanding[msgID] = [d, address, timeout]
                self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID)))

            self.multiplexer.send_message(data, address, relay_addr)

            if self.multiplexer[address].state != State.CONNECTED and \
                            node.nat_type == RESTRICTED and \
                            self.sourceNode.nat_type != SYMMETRIC:
                self.hole_punch(Node(digest("null"), node.relay_node[0], node.relay_node[1], nat_type=FULL_CONE),
                                address[0], address[1], "True")
                self.log.debug("sending hole punch message to %s" % address[0] + ":" + str(address[1]))

            return d
    def receive_message(self, datagram, connection):
        m = Message()
        try:
            m.ParseFromString(datagram)
            sender = node.Node(m.sender.guid, m.sender.ip, m.sender.port, m.sender.signedPublicKey, m.sender.vendor)
        except Exception:
            # If message isn't formatted property then ignore
            self.log.warning("Received unknown message from %s, ignoring" % str(connection.dest_addr))
            return False

        # Check that the GUID is valid. If not, ignore
        if self.router.isNewNode(sender):
            try:
                pubkey = m.sender.signedPublicKey[len(m.sender.signedPublicKey) - 32:]
                verify_key = nacl.signing.VerifyKey(pubkey)
                verify_key.verify(m.sender.signedPublicKey)
                h = nacl.hash.sha512(m.sender.signedPublicKey)
                pow_hash = h[64:128]
                if int(pow_hash[:6], 16) >= 50 or hexlify(m.sender.guid) != h[:40]:
                    raise Exception('Invalid GUID')

            except Exception:
                self.log.warning("Received message from sender with invalid GUID, ignoring")
                return False

        if m.sender.vendor:
            VendorStore().save_vendor(m.sender.guid, m.sender.ip, m.sender.port, m.sender.signedPublicKey)

        msgID = m.messageID
        data = tuple(m.arguments)
        if msgID in self._outstanding:
            self._acceptResponse(msgID, data, sender)
        else:
            self._acceptRequest(msgID, str(Command.Name(m.command)).lower(), data, sender, connection)
Exemple #3
0
        def func(address, *args):
            msgID = sha1(str(random.getrandbits(255))).digest()
            d = defer.Deferred()
            if name != "hole_punch":
                seed = SEED_NODE_TESTNET if self.multiplexer.testnet else SEED_NODE
                if address in self.multiplexer and self.multiplexer[address].state == State.CONNECTED:
                    timeout = timeout = reactor.callLater(self._waitTimeout, self.timeout, address)
                else:
                    timeout = reactor.callLater(self._waitTimeout, self.hole_punch, seed,
                                                address[0], address[1], "True", msgID)
                self._outstanding[msgID] = [d, address, timeout]
                self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID)))
            elif args[3] in self._outstanding:
                prev_msgID = args[3]
                args = args[:3]
                deferred, addr, hp = self._outstanding[prev_msgID]  # pylint: disable=W0612
                timeout = reactor.callLater(3, self.timeout, addr)
                self._outstanding[prev_msgID] = [deferred, addr, timeout]
                self.log.debug("sending hole punch message to %s" % args[0] + ":" + str(args[1]))

            m = Message()
            m.messageID = msgID
            m.sender.MergeFrom(self.sourceNode.getProto())
            m.command = Command.Value(name.upper())
            m.protoVer = PROTOCOL_VERSION
            for arg in args:
                m.arguments.append(str(arg))
            m.testnet = self.multiplexer.testnet
            data = m.SerializeToString()

            self.multiplexer.send_message(data, address)
            return d
Exemple #4
0
 def receive_message(self, datagram):
     if len(datagram) < 166:
         self.log.warning(
             "received datagram too small from %s, ignoring" %
             self.addr)
         return False
     try:
         m = Message()
         m.ParseFromString(datagram)
         self.node = Node(
             m.sender.guid, m.sender.nodeAddress.ip,
             m.sender.nodeAddress.port, m.sender.publicKey,
             None if not m.sender.HasField("relayAddress") else
             (m.sender.relayAddress.ip, m.sender.relayAddress.port),
             m.sender.natType, m.sender.vendor)
         self.remote_node_version = m.protoVer
         if self.time_last_message == 0:
             h = nacl.hash.sha512(m.sender.publicKey)
             pow_hash = h[40:]
             if int(pow_hash[:6],
                    16) >= 50 or m.sender.guid.encode("hex") != h[:40]:
                 raise Exception('Invalid GUID')
         for processor in self.processors:
             if m.command in processor or m.command == NOT_FOUND:
                 processor.receive_message(m, self.node,
                                           self.connection,
                                           self.ban_score)
         if m.command != PING:
             self.time_last_message = time.time()
     except Exception:
         # If message isn't formatted property then ignore
         self.log.warning(
             "received an invalid message from %s, ignoring" %
             self.addr)
         return False
 def receive_message(self, datagram):
     if len(datagram) < 166:
         self.log.warning("received datagram too small from %s, ignoring" % self.addr)
         return False
     m = Message()
     try:
         m.ParseFromString(datagram)
         self.node = Node(m.sender.guid,
                          m.sender.nodeAddress.ip,
                          m.sender.nodeAddress.port,
                          m.sender.publicKey,
                          None if not m.sender.HasField("relayAddress") else
                          (m.sender.relayAddress.ip, m.sender.relayAddress.port),
                          m.sender.natType,
                          m.sender.vendor)
         pubkey = m.sender.publicKey
         verify_key = nacl.signing.VerifyKey(pubkey)
         signature = m.signature
         m.ClearField("signature")
         verify_key.verify(m.SerializeToString(), signature)
         h = nacl.hash.sha512(m.sender.publicKey)
         pow_hash = h[40:]
         if int(pow_hash[:6], 16) >= 50 or m.sender.guid.encode("hex") != h[:40]:
             raise Exception('Invalid GUID')
     except Exception:
         # If message isn't formatted property then ignore
         self.log.warning("received an invalid message from %s, ignoring" % self.addr)
         return False
     for processor in self.processors:
         if m.command in processor or m.command == NOT_FOUND:
             processor.receive_message(m, self.node, self.connection, self.ban_score)
 def _sendResponse(self, response, funcname, msgID, sender, connection):
     if self.noisy:
         self.log.debug("Sending response for msg id %s to %s" % (b64encode(msgID), sender))
     m = Message()
     m.messageID = msgID
     m.sender.MergeFrom(self.proto)
     m.command = Command.Value(funcname.upper())
     for arg in response:
         m.arguments.append(str(arg))
     data = m.SerializeToString()
     connection.send_message(data)
Exemple #7
0
 def func(address, *args):
     msgID = sha1(str(random.getrandbits(255))).digest()
     m = Message()
     m.messageID = msgID
     m.sender.MergeFrom(self.proto)
     m.command = Command.Value(name.upper())
     for arg in args:
         m.arguments.append(arg)
     data = m.SerializeToString()
     if self.noisy:
         self.log.msg("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID)))
     self.multiplexer.send_message(data, address)
     d = defer.Deferred()
     timeout = reactor.callLater(self._waitTimeout, self._timeout, msgID)
     self._outstanding[msgID] = (d, timeout)
     return d
Exemple #8
0
 def func(address, *args):
     msgID = sha1(str(random.getrandbits(255))).digest()
     m = Message()
     m.messageID = msgID
     m.sender.MergeFrom(self.proto)
     m.command = Command.Value(name.upper())
     m.protoVer = PROTOCOL_VERSION
     for arg in args:
         m.arguments.append(str(arg))
     m.testnet = self.multiplexer.testnet
     data = m.SerializeToString()
     d = defer.Deferred()
     self._outstanding[msgID] = [d, address]
     self.multiplexer.send_message(data, address)
     self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID)))
     return d
 def receive_message(self, datagram):
     if len(datagram) < 166:
         self.log.warning(
             "received datagram too small from %s, ignoring" %
             str(self.connection.dest_addr))
         return False
     m = Message()
     try:
         m.ParseFromString(datagram)
         for processor in self.processors:
             if m.command in processor:
                 processor.receive_message(datagram, self.connection)
     except Exception:
         # If message isn't formatted property then ignore
         self.log.warning("Received unknown message from %s, ignoring" %
                          str(self.connection.dest_addr))
         return False
 def func(address, *args):
     msgID = sha1(str(random.getrandbits(255))).digest()
     m = Message()
     m.messageID = msgID
     m.sender.MergeFrom(self.proto)
     m.command = Command.Value(name.upper())
     for arg in args:
         m.arguments.append(str(arg))
     data = m.SerializeToString()
     if self.noisy:
         self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID)))
     self.multiplexer.send_message(data, address)
     if name is not "hole_punch":
         d = defer.Deferred()
         timeout = reactor.callLater(self._waitTimeout, self._timeout, msgID, address)
         self._outstanding[msgID] = [d, timeout]
         return d
 def _sendResponse(self, response, funcname, msgID, sender, connection):
     self.log.debug("sending response for msg id %s to %s" % (b64encode(msgID), sender))
     m = Message()
     m.messageID = msgID
     m.sender.MergeFrom(self.sourceNode.getProto())
     m.protoVer = PROTOCOL_VERSION
     m.testnet = self.multiplexer.testnet
     if response is None:
         m.command = NOT_FOUND
     else:
         m.command = Command.Value(funcname.upper())
         if not isinstance(response, list):
             response = [response]
         for arg in response:
             m.arguments.append(str(arg))
     m.signature = self.signing_key.sign(m.SerializeToString())[:64]
     connection.send_message(m.SerializeToString())
Exemple #12
0
 def func(address, *args):
     msgID = sha1(str(random.getrandbits(255))).digest()
     m = Message()
     m.messageID = msgID
     m.sender.MergeFrom(self.sourceNode.getProto())
     m.command = Command.Value(name.upper())
     m.protoVer = PROTOCOL_VERSION
     for arg in args:
         m.arguments.append(str(arg))
     m.testnet = self.multiplexer.testnet
     data = m.SerializeToString()
     d = defer.Deferred()
     if name != "hole_punch":
         seed = SEED_NODE_TESTNET if self.multiplexer.testnet else SEED_NODE
         hole_punch = reactor.callLater(3, self.hole_punch, seed,
                                        address[0], address[1], "True")
         if address in self.multiplexer:
             hole_punch.cancel()
         self._outstanding[msgID] = [d, address, hole_punch]
         self.log.debug("calling remote function %s on %s (msgid %s)" %
                        (name, address, b64encode(msgID)))
     else:
         self.log.debug("sending hole punch message to %s" % args[0] +
                        ":" + str(args[1]))
     self.multiplexer.send_message(data, address)
     return d
        def func(node, *args):
            msgID = sha1(str(random.getrandbits(255))).digest()

            m = Message()
            m.messageID = msgID
            m.sender.MergeFrom(self.sourceNode.getProto())
            m.command = Command.Value(name.upper())
            m.protoVer = PROTOCOL_VERSION
            for arg in args:
                m.arguments.append(str(arg))
            m.testnet = self.multiplexer.testnet
            data = m.SerializeToString()

            address = (node.ip, node.port)
            relay_addr = None
            if node.nat_type == SYMMETRIC or \
                    (node.nat_type == RESTRICTED and self.sourceNode.nat_type == SYMMETRIC):
                relay_addr = node.relay_node

            d = defer.Deferred()
            if m.command != HOLE_PUNCH:
                timeout = reactor.callLater(self._waitTimeout, self.timeout, node)
                self._outstanding[msgID] = [d, address, timeout]
                self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID)))

            self.multiplexer.send_message(data, address, relay_addr)

            if self.multiplexer[address].state != State.CONNECTED and \
                            node.nat_type == RESTRICTED and \
                            self.sourceNode.nat_type != SYMMETRIC:
                self.hole_punch(Node(digest("null"), node.relay_node[0], node.relay_node[1], nat_type=FULL_CONE),
                                address[0], address[1], "True")
                self.log.debug("sending hole punch message to %s" % address[0] + ":" + str(address[1]))

            return d
Exemple #14
0
 def receive_message(self, datagram):
     if len(datagram) < 166:
         self.log.warning(
             "received datagram too small from %s, ignoring" %
             self.addr)
         return False
     m = Message()
     try:
         m.ParseFromString(datagram)
         self.node = Node(m.sender.guid, m.sender.ip, m.sender.port,
                          m.sender.signedPublicKey, m.sender.vendor)
         for processor in self.processors:
             if m.command in processor or m.command == NOT_FOUND:
                 processor.receive_message(datagram, self.connection)
     except Exception:
         # If message isn't formatted property then ignore
         self.log.warning("received unknown message from %s, ignoring" %
                          self.addr)
         return False
Exemple #15
0
 def func(address, *args):
     msgID = sha1(str(random.getrandbits(255))).digest()
     m = Message()
     m.messageID = msgID
     m.sender.MergeFrom(self.sourceNode.getProto())
     m.command = Command.Value(name.upper())
     m.protoVer = PROTOCOL_VERSION
     for arg in args:
         m.arguments.append(str(arg))
     m.testnet = self.multiplexer.testnet
     data = m.SerializeToString()
     d = defer.Deferred()
     if name != "hole_punch":
         seed = SEED_NODE_TESTNET if self.multiplexer.testnet else SEED_NODE
         hole_punch = reactor.callLater(3, self.hole_punch, seed, address[0], address[1], "True")
         if address in self.multiplexer:
             hole_punch.cancel()
         self._outstanding[msgID] = [d, address, hole_punch]
         self.log.debug("calling remote function %s on %s (msgid %s)" % (name, address, b64encode(msgID)))
     else:
         self.log.debug("sending hole punch message to %s" % args[0] + ":" + str(args[1]))
     self.multiplexer.send_message(data, address)
     return d
Exemple #16
0
 def _sendResponse(self, response, funcname, msgID, sender, connection):
     self.log.debug("sending response for msg id %s to %s" % (b64encode(msgID), sender))
     m = Message()
     m.messageID = msgID
     m.sender.MergeFrom(self.sourceNode.getProto())
     m.protoVer = PROTOCOL_VERSION
     m.testnet = self.multiplexer.testnet
     if response is None:
         m.command = NOT_FOUND
     else:
         m.command = Command.Value(funcname.upper())
         if not isinstance(response, list):
             response = [response]
         for arg in response:
             m.arguments.append(str(arg))
     m.signature = self.signing_key.sign(m.SerializeToString())[:64]
     connection.send_message(m.SerializeToString())
Exemple #17
0
 def _sendResponse(self, response, funcname, msgID, sender, connection):
     self.log.debug("sending response for msg id %s to %s" % (b64encode(msgID), sender))
     m = Message()
     m.messageID = msgID
     m.sender.MergeFrom(self.proto)
     m.protoVer = PROTOCOL_VERSION
     m.testnet = self.multiplexer.testnet
     if response is None:
         m.command = NOT_FOUND
     else:
         m.command = Command.Value(funcname.upper())
         for arg in response:
             m.arguments.append(str(arg))
     data = m.SerializeToString()
     connection.send_message(data)
Exemple #18
0
    def receive_message(self, datagram, connection, ban_score):
        m = Message()
        try:
            m.ParseFromString(datagram)
            sender = node.Node(m.sender.guid, m.sender.ip, m.sender.port,
                               m.sender.signedPublicKey, m.sender.vendor)
        except Exception:
            # If message isn't formatted property then ignore
            self.log.warning("received unknown message from %s, ignoring" %
                             str(connection.dest_addr))
            return False

        if m.testnet != self.multiplexer.testnet:
            self.log.warning(
                "received message from %s with incorrect network parameters." %
                str(connection.dest_addr))
            connection.shutdown()
            return False

        if m.protoVer < PROTOCOL_VERSION:
            self.log.warning(
                "received message from %s with incompatible protocol version."
                % str(connection.dest_addr))
            connection.shutdown()
            return False

        # Check that the GUID is valid. If not, ignore
        if self.router.isNewNode(sender):
            try:
                pubkey = m.sender.signedPublicKey[len(m.sender.signedPublicKey
                                                      ) - 32:]
                verify_key = nacl.signing.VerifyKey(pubkey)
                verify_key.verify(m.sender.signedPublicKey)
                h = nacl.hash.sha512(m.sender.signedPublicKey)
                pow_hash = h[64:128]
                if int(pow_hash[:6], 16) >= 50 or hexlify(
                        m.sender.guid) != h[:40]:
                    raise Exception('Invalid GUID')

            except Exception:
                self.log.warning(
                    "received message from sender with invalid GUID, ignoring")
                connection.shutdown()
                return False

        if m.sender.vendor:
            self.db.VendorStore().save_vendor(m.sender.guid.encode("hex"),
                                              m.sender.ip, m.sender.port,
                                              m.sender.signedPublicKey)

        msgID = m.messageID
        if m.command == NOT_FOUND:
            data = None
        else:
            data = tuple(m.arguments)
        if msgID in self._outstanding:
            self._acceptResponse(msgID, data, sender)
        elif m.command != NOT_FOUND:
            ban_score.process_message(m)
            self._acceptRequest(msgID,
                                str(Command.Name(m.command)).lower(), data,
                                sender, connection)