Пример #1
0
 def test_get_difficulty(self):
     difficulty = 8
     ek = self._create_keysauth(difficulty)
     # first 8 bits of digest must be 0
     assert sha2(ek.public_key).to_bytes(256, 'big')[0] == 0
     assert KeysAuth.get_difficulty(ek.key_id) >= difficulty
     assert KeysAuth.is_pubkey_difficult(ek.public_key, difficulty)
     assert KeysAuth.is_pubkey_difficult(ek.key_id, difficulty)
Пример #2
0
    def test_react_to_hello(self):

        conn = MagicMock()
        conf = MagicMock()
        conf.opt_peer_num = 10

        node = Node(node_name='node', key='ffffffff')
        keys_auth = KeysAuth(self.path)
        keys_auth.key = node.key
        keys_auth.key_id = node.key

        peer_session = PeerSession(conn)
        peer_session.p2p_service = P2PService(node, conf, keys_auth, False)
        peer_session.p2p_service.metadata_manager = MagicMock()
        peer_session.send = MagicMock()
        peer_session.disconnect = MagicMock()
        peer_session._solve_challenge = MagicMock()

        def create_verify(value):
            def verify(*args):
                return value

            return verify

        key_id = 'deadbeef'
        peer_info = MagicMock()
        peer_info.key = key_id
        msg = MessageHello(port=1,
                           node_name='node2',
                           client_key_id=key_id,
                           node_info=peer_info,
                           proto_id=-1)

        peer_session.verify = create_verify(False)
        peer_session._react_to_hello(msg)
        peer_session.disconnect.assert_called_with(PeerSession.DCRUnverified)

        peer_session.verify = create_verify(True)
        peer_session._react_to_hello(msg)
        peer_session.disconnect.assert_called_with(
            PeerSession.DCRProtocolVersion)

        msg.proto_id = P2P_PROTOCOL_ID

        peer_session._react_to_hello(msg)
        assert key_id in peer_session.p2p_service.peers
        assert peer_session.p2p_service.peers[key_id]

        peer_session.p2p_service.peers[key_id] = MagicMock()
        conn.opened = True
        peer_session.key_id = None

        peer_session._react_to_hello(msg)
        peer_session.disconnect.assert_called_with(
            PeerSession.DCRDuplicatePeers)
Пример #3
0
    def _react_to_hello(self, msg):
        if self.verified:
            logger.error("Received unexpected Hello message, ignoring")
            return

        # Check if sender is a seed/bootstrap node
        port = getattr(msg, 'port', None)
        if (self.address, port) in self.p2p_service.seeds:
            compare_version(getattr(msg, 'client_ver', None))

        if not self.conn.opened:
            return

        proto_id = getattr(msg, 'proto_id', None)
        if proto_id != variables.PROTOCOL_CONST.ID:
            logger.info(
                "P2P protocol version mismatch %r vs %r (local)"
                " for node %r:%r", proto_id, variables.PROTOCOL_CONST.ID,
                self.address, self.port)
            self.disconnect(message.base.Disconnect.REASON.ProtocolVersion)
            return

        self.node_info = Node.from_dict(msg.node_info)

        if not KeysAuth.is_pubkey_difficult(self.node_info.key,
                                            self.p2p_service.key_difficulty):
            logger.info(
                "Key from %r (%s:%d) is not difficult enough (%d < %d).",
                self.node_info.node_name, self.address, self.port,
                KeysAuth.get_difficulty(self.node_info.key),
                self.p2p_service.key_difficulty)
            self.disconnect(message.base.Disconnect.REASON.KeyNotDifficult)
            return

        self.node_name = msg.node_name
        self.client_ver = msg.client_ver
        self.listen_port = msg.port
        self.key_id = msg.client_key_id
        self.metadata = msg.metadata

        solve_challenge = msg.solve_challenge
        challenge = msg.challenge
        difficulty = msg.difficulty

        if not self.__should_init_handshake():
            self.__send_hello()

        if solve_challenge:
            self._solve_challenge(challenge, difficulty)
        else:
            self.send(message.base.RandVal(rand_val=msg.rand_val))
Пример #4
0
    def test_react_to_stop_gossip(self):
        conn = MagicMock()
        conf = MagicMock()
        conf.opt_peer_num = 10

        node = Node(node_name='node', key='ffffffff')
        keys_auth = KeysAuth(self.path)
        keys_auth.key = node.key
        keys_auth.key_id = node.key

        peer_session = PeerSession(conn)
        peer_session.p2p_service = P2PService(node, conf, keys_auth, False)
        peer_session.key_id = "NEW KEY_ID"
        peer_session._react_to_stop_gossip(MessageStopGossip())
Пример #5
0
def create_client(datadir):
    # executed in a subprocess
    from golem.network.stun import pystun
    pystun.get_ip_info = override_ip_info

    from golem.client import Client
    app_config = AppConfig.load_config(datadir)
    config_desc = ClientConfigDescriptor()
    config_desc.init_from_app_config(app_config)
    config_desc.key_difficulty = 0
    config_desc.use_upnp = False

    from golem.core.keysauth import KeysAuth
    with mock.patch.dict('ethereum.keys.PBKDF2_CONSTANTS', {'c': 1}):
        keys_auth = KeysAuth(
            datadir=datadir,
            private_key_name=faker.Faker().pystr(),
            password='******',
            difficulty=config_desc.key_difficulty,
        )

    database = Database(
        db, fields=DB_FIELDS, models=DB_MODELS, db_dir=datadir)

    ets = _make_mock_ets()
    return Client(datadir=datadir,
                  app_config=app_config,
                  config_desc=config_desc,
                  keys_auth=keys_auth,
                  database=database,
                  transaction_system=ets,
                  use_monitor=False,
                  connect_to_known_hosts=False,
                  use_docker_manager=False)
Пример #6
0
    def test_add_task_header(self, *_):
        keys_auth_2 = KeysAuth(
            os.path.join(self.path, "2"),
            'priv_key',
            'password',
        )

        ts = self.ts

        task_header = get_example_task_header(keys_auth_2.public_key)

        with self.assertRaises(Exception) as raised:
            ts.add_task_header(task_header)
            self.assertEqual(raised.exception.message, "Invalid signature")
            self.assertEqual(len(ts.get_others_tasks_headers()), 0)

        task_header["signature"] = keys_auth_2.sign(
            TaskHeader.dict_to_binary(task_header))

        self.assertTrue(ts.add_task_header(task_header))
        self.assertEqual(len(ts.get_others_tasks_headers()), 1)

        task_header = get_example_task_header(keys_auth_2.public_key)
        task_id2 = task_header["fixed_header"]["task_id"]
        task_header["signature"] = keys_auth_2.sign(
            TaskHeader.dict_to_binary(task_header))

        self.assertTrue(ts.add_task_header(task_header))
        self.assertEqual(len(ts.get_others_tasks_headers()), 2)

        self.assertTrue(ts.add_task_header(task_header))
        self.assertEqual(len(ts.get_others_tasks_headers()), 2)

        new_header = dict(task_header)
        new_header["fixed_header"]["task_owner"]["pub_port"] = 9999
        new_header["signature"] = keys_auth_2.sign(
            TaskHeader.dict_to_binary(new_header))

        # An attempt to update fixed header should *not* succeed
        self.assertFalse(ts.add_task_header(new_header))
        self.assertEqual(len(ts.get_others_tasks_headers()), 2)
        saved_task = next(th for th in ts.get_others_tasks_headers()
                          if th["fixed_header"]["task_id"] == task_id2)
        self.assertEqual(saved_task["signature"], task_header["signature"])
Пример #7
0
 def setUp(self):
     super().setUp()
     self.keys_auth = KeysAuth(self.path, 'priv_key', 'password')
     self.service = P2PService(
         node=None,
         config_desc=ClientConfigDescriptor(),
         keys_auth=self.keys_auth,
         connect_to_known_hosts=False,
     )
     self.service.seeds = set()
Пример #8
0
 def setUp(self):
     super(TestP2PService, self).setUp()
     random.seed()
     # Mock saving keys as it takes long to compute and isn't needed here
     KeysAuth._save_private_key = mock.Mock()
     self.keys_auth = KeysAuth(self.path, 'priv_key', 'password')
     self.service = P2PService(None,
                               ClientConfigDescriptor(),
                               self.keys_auth,
                               connect_to_known_hosts=False)
Пример #9
0
    def test_save_keys(self):
        # given
        keys_dir = KeysAuth._get_or_create_keys_dir(self.path)
        assert os.listdir(keys_dir) == []  # empty dir
        key_name = 'priv'

        # when
        self._create_keysauth(key_name=key_name)

        # then
        self.assertCountEqual(os.listdir(keys_dir), [key_name])
Пример #10
0
    def _gen_data_for_test_react_to_remove_task(self):
        keys_auth = KeysAuth(self.path, 'priv_key', 'password')
        previous_ka = self.peer_session.p2p_service.keys_auth
        self.peer_session.p2p_service.keys_auth = keys_auth

        # Unknown task owner
        client = MagicMock()
        client.datadir = self.path
        with patch('golem.network.concent.handlers_library.HandlersLibrary'
                   '.register_handler',):
            task_server = task_server_factory.TaskServer(client=client,)
        self.peer_session.p2p_service.task_server = task_server
        peer_mock = MagicMock()
        self.peer_session.p2p_service.peers["ABC"] = peer_mock

        task_id = "test_{}".format(uuid.uuid4())
        msg = message.p2p.RemoveTask(task_id=task_id)
        msg.serialize(sign_as=keys_auth._private_key)
        assert keys_auth.verify(msg.sig, msg.get_short_hash(), keys_auth.key_id)
        return msg, task_id, previous_ka
Пример #11
0
 def _create_keysauth(self,
                      difficulty=0,
                      key_name=None,
                      password='') -> KeysAuth:
     if key_name is None:
         key_name = str(random())
     return KeysAuth(
         datadir=self.path,
         private_key_name=key_name,
         password=password,
         difficulty=difficulty,
     )
Пример #12
0
    def test_react_to_hello(self):
        conn = MagicMock()

        node = Node(node_name='node', key='ffffffff')
        keys_auth = KeysAuth(self.path)
        keys_auth.key = node.key
        keys_auth.key_id = node.key

        ts = TaskSession(conn)
        ts.task_server = Mock()
        ts.disconnect = Mock()
        ts.send = Mock()

        def create_verify(value):
            def verify(*args):
                return value

            return verify

        key_id = 'deadbeef'
        peer_info = MagicMock()
        peer_info.key = key_id
        msg = MessageHello(port=1,
                           node_name='node2',
                           client_key_id=key_id,
                           node_info=peer_info,
                           proto_id=-1)

        ts.verify = create_verify(False)
        ts._react_to_hello(msg)
        ts.disconnect.assert_called_with(TaskSession.DCRUnverified)

        ts.verify = create_verify(True)
        ts._react_to_hello(msg)
        ts.disconnect.assert_called_with(TaskSession.DCRProtocolVersion)

        msg.proto_id = TASK_PROTOCOL_ID

        ts._react_to_hello(msg)
        assert ts.send.called
Пример #13
0
    def test_exception_difficulty(self):
        # given
        lower_difficulty = 0
        req_difficulty = 7
        priv_key = str(random())[2:]
        assert lower_difficulty < req_difficulty  # just in case

        keys_dir = KeysAuth._get_or_create_keys_dir(self.path)
        # create key that has difficulty lower than req_difficulty
        while True:
            ka = self._create_keysauth(lower_difficulty, priv_key)
            if not ka.is_difficult(req_difficulty):
                break
            shutil.rmtree(keys_dir)  # to enable keys regeneration

        assert KeysAuth.get_difficulty(ka.key_id) >= lower_difficulty
        assert KeysAuth.get_difficulty(ka.key_id) < req_difficulty

        # then
        with self.assertRaisesRegex(Exception,
                                    "Loaded key is not difficult enough"):
            self._create_keysauth(difficulty=req_difficulty, key_name=priv_key)
Пример #14
0
    def test_send_results(self, trust, *_):
        ccd = ClientConfigDescriptor()
        ccd.min_price = 11
        keys_auth = KeysAuth(self.path, 'priv_key', '')
        task_header = get_example_task_header(keys_auth.public_key)
        n = Node.from_dict(task_header["fixed_header"]['task_owner'])

        ts = self.ts
        ts._is_address_accessible = Mock(return_value=True)
        ts.verify_header_sig = lambda x: True
        ts.client.get_suggested_addr.return_value = "10.10.10.10"
        ts.client.get_requesting_trust.return_value = ts.max_trust

        fd, result_file = tempfile.mkstemp()
        os.close(fd)
        results = {"data": [result_file]}
        task_header = get_example_task_header(keys_auth.public_key)
        task_id = task_header["fixed_header"]["task_id"]
        assert ts.add_task_header(task_header)
        assert ts.request_task()
        subtask_id = idgenerator.generate_new_id_from_id(task_id)
        subtask_id2 = idgenerator.generate_new_id_from_id(task_id)
        self.assertTrue(ts.send_results(subtask_id, task_id, results))
        self.assertTrue(ts.send_results(subtask_id2, task_id, results))
        wtr = ts.results_to_send[subtask_id]
        self.assertIsInstance(wtr, WaitingTaskResult)
        self.assertEqual(wtr.subtask_id, subtask_id)
        self.assertEqual(wtr.result, [result_file])
        self.assertEqual(wtr.last_sending_trial, 0)
        self.assertEqual(wtr.delay_time, 0)
        self.assertEqual(wtr.owner, n)
        self.assertEqual(wtr.already_sending, False)

        self.assertIsNotNone(ts.task_keeper.task_headers.get(task_id))

        ctd = ComputeTaskDef()
        ctd['task_id'] = task_id
        ctd['subtask_id'] = subtask_id
        ttc = msg_factories.tasks.TaskToComputeFactory(price=1)
        ttc.compute_task_def = ctd
        ts.task_manager.comp_task_keeper.receive_subtask(ttc)

        prev_call_count = trust.PAYMENT.increase.call_count
        ts.increase_trust_payment("xyz")
        self.assertGreater(trust.PAYMENT.increase.call_count, prev_call_count)
        prev_call_count = trust.PAYMENT.decrease.call_count
        ts.decrease_trust_payment("xyz")
        self.assertGreater(trust.PAYMENT.decrease.call_count, prev_call_count)

        os.remove(result_file)
Пример #15
0
    def test_request_task_concent_required(self, *_):
        self.ts.client.concent_service.enabled = True
        self.ts.task_archiver = Mock()
        keys_auth = KeysAuth(self.path, 'prv_key', '')
        task_dict = get_example_task_header(keys_auth.public_key)
        task_dict['fixed_header']['concent_enabled'] = False
        self.ts.add_task_header(task_dict)

        self.assertIsNone(self.ts.request_task())
        self.ts.task_archiver.add_support_status.assert_called_once_with(
            task_dict['fixed_header']['task_id'],
            SupportStatus(
                False,
                {UnsupportReason.CONCENT_REQUIRED: True},
            ),
        )
Пример #16
0
 def setUp(self):
     super().setUp()
     random.seed()
     self.peer_session = PeerSession(MagicMock())
     node = p2p_factories.Node()
     keys_auth = KeysAuth(self.path, 'priv_key', 'password')
     self.peer_session.conn.server = \
         self.peer_session.p2p_service = P2PService(
             node=node,
             config_desc=clientconfigdescriptor.ClientConfigDescriptor(),
             keys_auth=keys_auth,
             connect_to_known_hosts=False,
         )
     client = MagicMock()
     client.datadir = self.path
     with patch(
             'golem.network.concent.handlers_library.HandlersLibrary'
             '.register_handler',):
         self.peer_session.p2p_service.task_server = \
             task_server_factory.TaskServer(client=client)
Пример #17
0
    def set_password(self, password: str) -> bool:
        logger.info("Got password")

        try:
            self._keys_auth = KeysAuth(
                datadir=self._datadir,
                private_key_name=PRIVATE_KEY,
                password=password,
                difficulty=self._config_desc.key_difficulty,
            )
            # When Golem is ready to use different Ethereum account for
            # payments and identity this should be called only when
            # idendity was not just created above for the first time.
            self._ets.backwards_compatibility_privkey(
                self._keys_auth._private_key,  # noqa pylint: disable=protected-access
                password,
            )
            self._ets.set_password(password)
        except WrongPassword:
            logger.info("Password incorrect")
            return False
        return True
Пример #18
0
def key_gen(d: int):
    return KeysAuth._generate_keys(difficulty=d)
Пример #19
0
 def key_exists(self) -> bool:
     return KeysAuth.key_exists(self._datadir, PRIVATE_KEY)
Пример #20
0
    def test_request(self, tar, *_):
        ccd = ClientConfigDescriptor()
        ccd.min_price = 10
        n = NodeFactory()
        ts = TaskServer(
            node=n,
            config_desc=ccd,
            client=self.client,
            use_docker_manager=False,
            task_archiver=tar,
        )
        ts.verify_header_sig = lambda x: True
        self.ts = ts
        ts._is_address_accessible = Mock(return_value=True)
        ts.client.get_suggested_addr.return_value = "10.10.10.10"
        ts.client.get_suggested_conn_reverse.return_value = False
        ts.client.get_requesting_trust.return_value = 0.3
        self.assertIsInstance(ts, TaskServer)
        self.assertIsNone(ts.request_task())

        keys_auth = KeysAuth(self.path, 'prv_key', '')
        task_header = get_example_task_header(keys_auth.public_key)
        task_id = task_header["fixed_header"]["task_id"]
        ts.add_task_header(task_header)
        self.assertEqual(ts.request_task(), task_id)
        assert ts.remove_task_header(task_id)

        task_header = get_example_task_header(keys_auth.public_key)
        task_header["fixed_header"]["task_owner"]["pub_port"] = 0
        task_id2 = task_header["fixed_header"]["task_id"]
        self.assertTrue(ts.add_task_header(task_header))
        self.assertIsNotNone(ts.task_keeper.task_headers[task_id2])
        # FIXME FIx this test
        # self.assertIsNone(ts.request_task())
        # self.assertIsNone(ts.task_keeper.task_headers.get(task_id2))
        # assert not ts.remove_task_header(task_id2)
        # FIXME remove me
        ts.remove_task_header(task_id2)

        # Task can be rejected for 3 reasons at this stage; in all cases
        # the task should be reported TaskArchiver listed as unsupported:
        # 1. Requestor's trust level is too low
        tar.reset_mock()
        ts.config_desc.requesting_trust = 0.5
        task_header = get_example_task_header(keys_auth.public_key)
        task_id3 = task_header["fixed_header"]["task_id"]
        ts.add_task_header(task_header)
        self.assertIsNone(ts.request_task())
        tar.add_support_status.assert_called_with(
            task_id3,
            SupportStatus(False, {UnsupportReason.REQUESTOR_TRUST: 0.3}))
        assert ts.remove_task_header(task_id3)

        # 2. Task's max price is too low
        tar.reset_mock()
        ts.config_desc.requesting_trust = 0.0
        task_header = get_example_task_header(keys_auth.public_key)
        task_id4 = task_header["fixed_header"]["task_id"]
        task_header["fixed_header"]["max_price"] = 1
        ts.add_task_header(task_header)
        self.assertIsNone(ts.request_task())
        tar.add_support_status.assert_called_with(
            task_id4, SupportStatus(False, {UnsupportReason.MAX_PRICE: 1}))
        assert ts.remove_task_header(task_id4)

        # 3. Requestor is on a black list.
        tar.reset_mock()
        ts.acl.disallow(keys_auth.key_id)
        task_header = get_example_task_header(keys_auth.public_key)
        task_id5 = task_header["fixed_header"]["task_id"]
        ts.add_task_header(task_header)
        self.assertIsNone(ts.request_task())
        tar.add_support_status.assert_called_with(
            task_id5,
            SupportStatus(False,
                          {UnsupportReason.DENY_LIST: keys_auth.key_id}))
        assert ts.remove_task_header(task_id5)
Пример #21
0
 def test_difficulty(self):
     difficulty = 5
     ek = self._create_keysauth(difficulty)
     assert difficulty <= ek.difficulty
     assert ek.difficulty == KeysAuth.get_difficulty(ek.key_id)