Example #1
0
    def test_attributes(self):
        def run(self):
            stop(self)

        self.assertIsInstance(self.a_net.stethoscope_sock, socket.socket)
        self.assertIsInstance(self.a_net.ironhouse, Ironhouse)
        self.assertIsInstance(self.a_net.node, Node)
        self.assertEqual(self.a_net.node.public_key, self.a['curve_key'])
        self.assertEqual(self.b_net.node.public_key, self.b['curve_key'])
        self.assertEqual(self.a_net.node.id, digest(self.a['vk']))
        self.assertEqual(self.b_net.node.id, digest(self.b['vk']))

        t = Timer(0.01, run, [self])
        t.start()
        self.loop.run_forever()
Example #2
0
    async def secure_server(self):
        log.info('Listening to secure connections at {}'.format(
            self.auth_port))
        try:
            while True:
                received_vk, received_ip = await self.sec_sock.recv_multipart()
                received_vk = received_vk.decode()
                received_ip = received_ip.decode()

                log.debug(
                    '{} got secure request {} from user claiming to be "{}"'.
                    format(os.getenv('HOST_IP', '127.0.0.1'), received_vk,
                           received_ip))

                if self.auth_validate(received_vk) == True:
                    public_key = self.vk2pk(received_vk)
                    self.add_public_key(public_key)
                    self.authorized_nodes[digest(received_vk)] = received_ip
                    self.pk2vk[public_key] = received_vk
                    log.debug('{} sending secure reply: {}'.format(
                        os.getenv('HOST_IP', '127.0.0.1'), self.vk))
                    log.debug('{}\'s New Authorized list: {}'.format(
                        os.getenv('HOST_IP', '127.0.0.1'),
                        list(self.authorized_nodes.values())))
                    self.sec_sock.send(self.vk.encode())
                else:
                    log.warning('Unauthorized user {}({})'.format(
                        received_ip, received_vk))
        finally:
            self.cleanup()
Example #3
0
 def setUp(self):
     self.loop = asyncio.new_event_loop()
     asyncio.set_event_loop(self.loop)
     self.a = genkeys(
         '06391888e37a48cef1ded85a375490df4f9b2c74f7723e88c954a055f3d2685a')
     self.b = genkeys(
         '91f7021a9e8c65ca873747ae24de08e0a7acf58159a8aa6548910fe152dab3d8')
     self.evil = genkeys(
         'c5cb6d3ac7d644df8c72b613d57e4c47df6107989e584863b86bde47df704464')
     self.off = genkeys(
         '8ddaf072b9108444e189773e2ddcb4cbd2a76bbf3db448e55d0bfc131409a197')
     self.a_net = Network(sk=self.a['sk'],
                          network_port=13321,
                          keyname='a',
                          wipe_certs=True,
                          loop=self.loop,
                          daemon=DaemonMock())
     self.b_net = Network(sk=self.b['sk'],
                          network_port=14321,
                          keyname='b',
                          wipe_certs=True,
                          loop=self.loop,
                          daemon=DaemonMock())
     self.evil_net = Network(sk=self.evil['sk'],
                             network_port=15321,
                             keyname='evil',
                             wipe_certs=True,
                             loop=self.loop,
                             daemon=DaemonMock())
     self.off_node = Node(digest(self.off['vk']),
                          ip='127.0.0.1',
                          port=16321,
                          public_key=self.off['curve_key'])
Example #4
0
 def __init__(self, ksize=20, alpha=3, node_id=None, discovery_mode='neighborhood', loop=None, max_peers=64, network_port=None, public_ip=None, event_sock=None, *args, **kwargs):
     """
     Create a server instance.  This will start listening on the given port.
     Args:
         ksize (int): The k parameter from the paper
         alpha (int): The ALPHA parameter from the paper
         node_id: The id for this node on the network.
     """
     self.loop = loop if loop else asyncio.get_event_loop()
     asyncio.set_event_loop(self.loop)
     self.vkcache = {}
     self.ksize = ksize
     self.alpha = alpha
     self.transport = None
     self.protocol = None
     self.refresh_loop = None
     self.save_state_loop = None
     self.event_sock = event_sock
     self.max_peers = max_peers
     self.network_port = network_port
     self.heartbeat_port = self.network_port+HEARTBEAT_PORT_OFFSET
     self.ironhouse = Ironhouse(auth_port=self.network_port+AUTH_PORT_OFFSET, *args, **kwargs)
     self.node = Node(
         node_id=digest(self.ironhouse.vk),
         public_key=self.ironhouse.public_key,
         ip=public_ip or os.getenv('HOST_IP', '127.0.0.1'),
         port=self.network_port
     )
     self.setup_stethoscope()
     self.ironhouse.setup_secure_server()
     self.listen()
     self.saveStateRegularly('state.tmp')
Example #5
0
    async def _lookup_ip(self, cmd, url, vk, *args, **kwargs):
        ip, node = None, None
        try:
            node, cached = await self.dht.network.lookup_ip(vk)
            # NOTE while secure, this is a more loose connection policy
            self.log.fatal('{} resolves for {}'.format(os.getenv('HOST_IP'),
                                                       node))
            if node and not cached:
                ip = node.ip if type(node) == Node else node.split(':')[0]
                public_key = self.dht.network.ironhouse.vk2pk(vk)
                authorization = await self.dht.network.ironhouse.authenticate(
                    public_key, ip)
                self.log.fatal('{} -> {} is {}'.format(os.getenv('HOST_IP'),
                                                       node, authorization))
                if authorization != 'authorized':
                    node = None
                else:
                    n = Node(node_id=digest(vk),
                             public_key=public_key,
                             ip=ip,
                             port=self.dht.network.network_port)
                    self.dht.network.protocol.router.addContact(n)
                    self.dht.network.connect_to_neighbor(n)

                self.log.fatal([
                    item[0]
                    for item in self.dht.network.bootstrappableNeighbors()
                ])
        except Exception as e:
            delim_line = '!' * 64
            err_msg = '\n\n' + delim_line + '\n' + delim_line
            err_msg += '\n ERROR CAUGHT IN LOOKUP FUNCTION {}\ncalled \w args={}\nand kwargs={}\n'\
                        .format(args, kwargs)
            err_msg += '\nError Message: '
            err_msg += '\n\n{}'.format(traceback.format_exc())
            err_msg += '\n' + delim_line + '\n' + delim_line
            self.log.error(err_msg)

        if node is None:

            kwargs = cmd.kwargs
            callback = ReactorCommand.create_callback(
                callback=StateInput.LOOKUP_FAILED, **kwargs)
            self.log.debug(
                "Sending callback failure to mainthread {}".format(callback))
            self.socket.send(callback.serialize())
            # TODO -- send callback to SM saying hey i couldnt lookup this vk

            return

        # Send interpolated command back through pipeline
        ip = node.ip if type(node) == Node else node
        new_url = IPUtils.interpolate_url(url, ip)
        kwargs = cmd.kwargs
        kwargs['url'] = new_url
        new_cmd = ReactorCommand.create_cmd(envelope=cmd.envelope, **kwargs)

        self._execute_cmd(new_cmd)
Example #6
0
    async def lookup_ip(self, node_key):
        node_id = digest(node_key)
        cache_node = self.lookup_ip_in_cache(node_id)
        if cache_node: return cache_node, True
        if node_id == self.node.id: return self.node

        nearest = self.protocol.router.findNeighbors(self.node)
        spider = NodeSpiderCrawl(self.protocol, self.node, nearest, self.ksize, self.alpha)

        log.debug("Starting lookup for node_key {}".format(node_key))
        res_node = await spider.find(node_id=node_id)

        if type(res_node) == list: res_node = None
        log.debug('VK {} resolves to {}'.format(node_key, res_node))
        if res_node != None:
            self.vkcache[node_id] = res_node
            pk = self.ironhouse.vk2pk(node_key)
        return res_node, False
Example #7
0
    def welcomeIfNewNode(self, node):
        """
        Given a new node, send it all the keys/values it should be storing,
        then add it to the routing table.

        @param node: A new node that just joined (or that we just found out
        about).

        Process:
        For each key in storage, get k closest nodes.  If newnode is closer
        than the furtherst in that list, and the node for this network
        is closer than the closest in that list, then store the key/value
        on the new node (per section 2.5 of the paper)
        """
        if not node:
            log.warning('This node is not welcomed.')
            return

        if not self.router.isNewNode(node):
            log.debug(
                "Skipping node {} that already exists in routing table".format(
                    node))
            return

        log.info("never seen %s before, adding to router", node)
        for key, value in self.storage.items():
            keynode = Node(digest(key))
            neighbors = self.router.findNeighbors(keynode)
            if len(neighbors) > 0:
                last = neighbors[-1].distanceTo(keynode)
                newNodeClose = node.distanceTo(keynode) < last
                first = neighbors[0].distanceTo(keynode)
                thisNodeClosest = self.sourceNode.distanceTo(keynode) < first
            if len(neighbors) == 0 or (newNodeClose and thisNodeClosest):
                asyncio.ensure_future(self.callStore(node, key, value))

        self.router.addContact(node)
        self.network.connect_to_neighbor(node)