Beispiel #1
0
    async def test_timelord(self, timelord):
        timelord_api, timelord_server = timelord

        # timelord should not accept incoming connections
        pub_crt = timelord_server._private_key_path.parent / "p2p.crt"
        pub_key = timelord_server._private_key_path.parent / "p2p.key"
        generate_ca_signed_cert(
            timelord_server.chia_ca_crt_path.read_bytes(),
            timelord_server.chia_ca_key_path.read_bytes(),
            pub_crt,
            pub_key,
        )
        ssl_context = ssl_context_for_client(timelord_server.chia_ca_crt_path,
                                             timelord_server.chia_ca_key_path,
                                             pub_crt, pub_key)
        connected = await establish_connection(timelord_server, 12312,
                                               ssl_context)
        assert connected is False

        # Not even signed by private cert
        priv_crt = timelord_server._private_key_path.parent / "valid.crt"
        priv_key = timelord_server._private_key_path.parent / "valid.key"
        generate_ca_signed_cert(
            timelord_server.ca_private_crt_path.read_bytes(),
            timelord_server.ca_private_key_path.read_bytes(),
            priv_crt,
            priv_key,
        )
        ssl_context = ssl_context_for_client(
            timelord_server.ca_private_crt_path,
            timelord_server.ca_private_key_path, priv_crt, priv_key)
        connected = await establish_connection(timelord_server, 12312,
                                               ssl_context)
        assert connected is False
Beispiel #2
0
    async def test_harvester(self, harvester_farmer):
        harvester, farmer_api = harvester_farmer
        harvester_server = harvester.server

        # harvester should not accept incoming connections
        pub_crt = harvester_server._private_key_path.parent / "p2p.crt"
        pub_key = harvester_server._private_key_path.parent / "p2p.key"
        generate_ca_signed_cert(
            harvester_server.chia_ca_crt_path.read_bytes(),
            harvester_server.chia_ca_key_path.read_bytes(),
            pub_crt,
            pub_key,
        )
        ssl_context = ssl_context_for_client(harvester_server.chia_ca_crt_path,
                                             harvester_server.chia_ca_key_path,
                                             pub_crt, pub_key)
        connected = await establish_connection(harvester_server, 12312,
                                               ssl_context)
        assert connected is False

        # Not even signed by private cert
        priv_crt = harvester_server._private_key_path.parent / "valid.crt"
        priv_key = harvester_server._private_key_path.parent / "valid.key"
        generate_ca_signed_cert(
            harvester_server.ca_private_crt_path.read_bytes(),
            harvester_server.ca_private_key_path.read_bytes(),
            priv_crt,
            priv_key,
        )
        ssl_context = ssl_context_for_client(
            harvester_server.ca_private_crt_path,
            harvester_server.ca_private_key_path, priv_crt, priv_key)
        connected = await establish_connection(harvester_server, 12312,
                                               ssl_context)
        assert connected is False
Beispiel #3
0
    async def test_wallet(self, wallet_node):
        full_nodes, wallets = wallet_node
        wallet_node, wallet_server = wallets[0]

        # Wallet should not accept incoming connections
        pub_crt = wallet_server._private_key_path.parent / "p2p.crt"
        pub_key = wallet_server._private_key_path.parent / "p2p.key"
        generate_ca_signed_cert(wallet_server.chia_ca_crt_path.read_bytes(),
                                wallet_server.chia_ca_key_path.read_bytes(),
                                pub_crt, pub_key)
        ssl_context = ssl_context_for_client(wallet_server.chia_ca_crt_path,
                                             wallet_server.chia_ca_key_path,
                                             pub_crt, pub_key)
        connected = await establish_connection(wallet_server, 12312,
                                               ssl_context)
        assert connected is False

        # Not even signed by private cert
        priv_crt = wallet_server._private_key_path.parent / "valid.crt"
        priv_key = wallet_server._private_key_path.parent / "valid.key"
        generate_ca_signed_cert(
            wallet_server.ca_private_crt_path.read_bytes(),
            wallet_server.ca_private_key_path.read_bytes(),
            priv_crt,
            priv_key,
        )
        ssl_context = ssl_context_for_client(wallet_server.ca_private_crt_path,
                                             wallet_server.ca_private_key_path,
                                             priv_crt, priv_key)
        connected = await establish_connection(wallet_server, 12312,
                                               ssl_context)
        assert connected is False
Beispiel #4
0
async def connect_to_daemon_and_validate(
        root_path: Path) -> Optional[DaemonProxy]:
    """
    Connect to the local daemon and do a ping to ensure that something is really
    there and running.
    """
    try:
        net_config = load_config(root_path, "config.yaml")
        crt_path = root_path / net_config["daemon_ssl"]["private_crt"]
        key_path = root_path / net_config["daemon_ssl"]["private_key"]
        ca_crt_path = root_path / net_config["private_ssl_ca"]["crt"]
        ca_key_path = root_path / net_config["private_ssl_ca"]["key"]
        ssl_context = ssl_context_for_client(ca_crt_path, ca_key_path,
                                             crt_path, key_path)
        connection = await connect_to_daemon(net_config["self_hostname"],
                                             net_config["daemon_port"],
                                             ssl_context)
        r = await connection.ping()

        if "value" in r["data"] and r["data"]["value"] == "pong":
            return connection
    except Exception:
        print("Daemon not started yet")
        return None
    return None
async def connect_to_keychain_and_validate(
    root_path: Path, log: logging.Logger, *, user: str = None, testing: bool = False
) -> Optional[KeychainProxy]:
    """
    Connect to the local daemon and do a ping to ensure that something is really
    there and running.
    """
    try:
        net_config = load_config(root_path, "config.yaml")
        crt_path = root_path / net_config["daemon_ssl"]["private_crt"]
        key_path = root_path / net_config["daemon_ssl"]["private_key"]
        ca_crt_path = root_path / net_config["private_ssl_ca"]["crt"]
        ca_key_path = root_path / net_config["private_ssl_ca"]["key"]
        ssl_context = ssl_context_for_client(ca_crt_path, ca_key_path, crt_path, key_path, log=log)
        connection = await connect_to_keychain(
            net_config["self_hostname"], net_config["daemon_port"], ssl_context, log, user, testing
        )

        # If proxying to a local keychain, don't attempt to ping
        if connection.use_local_keychain():
            return connection

        r = await connection.ping()

        if "value" in r["data"] and r["data"]["value"] == "pong":
            return connection
    except Exception as e:
        print(f"Keychain(daemon) not started yet: {e}")
        return None
    return None
Beispiel #6
0
    async def test_large_message_disconnect_and_ban(self, setup_two_nodes):
        nodes, _ = setup_two_nodes
        server_1 = nodes[0].full_node.server
        server_2 = nodes[1].full_node.server

        # Use the server_2 ssl information to connect to server_1, and send a huge message
        timeout = ClientTimeout(total=10)
        session = ClientSession(timeout=timeout)
        url = f"wss://{self_hostname}:{server_1._port}/ws"

        ssl_context = ssl_context_for_client(server_2.chia_ca_crt_path,
                                             server_2.chia_ca_key_path,
                                             server_2.p2p_crt_path,
                                             server_2.p2p_key_path)
        ws = await session.ws_connect(url,
                                      autoclose=True,
                                      autoping=True,
                                      heartbeat=60,
                                      ssl=ssl_context,
                                      max_msg_size=100 * 1024 * 1024)
        assert not ws.closed
        await ws.close()
        assert ws.closed

        ws = await session.ws_connect(url,
                                      autoclose=True,
                                      autoping=True,
                                      heartbeat=60,
                                      ssl=ssl_context,
                                      max_msg_size=100 * 1024 * 1024)
        assert not ws.closed

        large_msg: bytes = bytes([0] * (60 * 1024 * 1024))
        await ws.send_bytes(large_msg)

        response: WSMessage = await ws.receive()
        print(response)
        assert response.type == WSMsgType.CLOSE
        assert response.data == WSCloseCode.MESSAGE_TOO_BIG
        await ws.close()

        # Now test that the ban is active
        await asyncio.sleep(5)
        assert ws.closed
        try:
            ws = await session.ws_connect(url,
                                          autoclose=True,
                                          autoping=True,
                                          heartbeat=60,
                                          ssl=ssl_context,
                                          max_msg_size=100 * 1024 * 1024)
            response: WSMessage = await ws.receive()
            assert response.type == WSMsgType.CLOSE
        except ServerDisconnectedError:
            pass
        await session.close()
Beispiel #7
0
    async def test_bad_handshake_and_ban(self, setup_two_nodes):
        nodes, _ = setup_two_nodes
        server_1 = nodes[0].full_node.server
        server_2 = nodes[1].full_node.server

        server_1.invalid_protocol_ban_seconds = 10
        # Use the server_2 ssl information to connect to server_1, and send a huge message
        timeout = ClientTimeout(total=10)
        session = ClientSession(timeout=timeout)
        url = f"wss://{self_hostname}:{server_1._port}/ws"

        ssl_context = ssl_context_for_client(server_2.chia_ca_crt_path,
                                             server_2.chia_ca_key_path,
                                             server_2.p2p_crt_path,
                                             server_2.p2p_key_path)
        ws = await session.ws_connect(url,
                                      autoclose=True,
                                      autoping=True,
                                      heartbeat=60,
                                      ssl=ssl_context,
                                      max_msg_size=100 * 1024 * 1024)
        await ws.send_bytes(bytes([1] * 1024))

        response: WSMessage = await ws.receive()
        print(response)
        assert response.type == WSMsgType.CLOSE
        assert response.data == WSCloseCode.PROTOCOL_ERROR
        await ws.close()

        # Now test that the ban is active
        await asyncio.sleep(5)
        assert ws.closed
        try:
            ws = await session.ws_connect(url,
                                          autoclose=True,
                                          autoping=True,
                                          heartbeat=60,
                                          ssl=ssl_context,
                                          max_msg_size=100 * 1024 * 1024)
            response: WSMessage = await ws.receive()
            assert response.type == WSMsgType.CLOSE
        except ServerDisconnectedError:
            pass
        await asyncio.sleep(6)

        # Ban expired
        await session.ws_connect(url,
                                 autoclose=True,
                                 autoping=True,
                                 heartbeat=60,
                                 ssl=ssl_context,
                                 max_msg_size=100 * 1024 * 1024)

        await session.close()
Beispiel #8
0
 async def create(cls, self_hostname: str, port: uint16, root_path,
                  net_config):
     self = cls()
     self.url = f"https://{self_hostname}:{str(port)}/"
     self.session = aiohttp.ClientSession()
     ca_crt_path, ca_key_path = private_ssl_ca_paths(root_path, net_config)
     crt_path = root_path / net_config["daemon_ssl"]["private_crt"]
     key_path = root_path / net_config["daemon_ssl"]["private_key"]
     self.ssl_context = ssl_context_for_client(ca_crt_path, ca_key_path,
                                               crt_path, key_path)
     self.closing_task = None
     return self
Beispiel #9
0
    async def test_farmer(self, harvester_farmer):
        harvester_service, farmer_service = harvester_farmer
        farmer_api = farmer_service._api

        farmer_server = farmer_api.farmer.server
        # Create valid cert (valid meaning signed with private CA)
        priv_crt = farmer_server._private_key_path.parent / "valid.crt"
        priv_key = farmer_server._private_key_path.parent / "valid.key"
        generate_ca_signed_cert(
            farmer_server.ca_private_crt_path.read_bytes(),
            farmer_server.ca_private_key_path.read_bytes(),
            priv_crt,
            priv_key,
        )
        ssl_context = ssl_context_for_client(farmer_server.ca_private_crt_path,
                                             farmer_server.ca_private_key_path,
                                             priv_crt, priv_key)
        connected = await establish_connection(farmer_server, 12312,
                                               ssl_context)
        assert connected is True

        # Create not authenticated cert
        pub_crt = farmer_server._private_key_path.parent / "non_valid.crt"
        pub_key = farmer_server._private_key_path.parent / "non_valid.key"
        generate_ca_signed_cert(farmer_server.chia_ca_crt_path.read_bytes(),
                                farmer_server.chia_ca_key_path.read_bytes(),
                                pub_crt, pub_key)
        ssl_context = ssl_context_for_client(farmer_server.chia_ca_crt_path,
                                             farmer_server.chia_ca_key_path,
                                             pub_crt, pub_key)
        connected = await establish_connection(farmer_server, 12312,
                                               ssl_context)
        assert connected is False
        ssl_context = ssl_context_for_client(farmer_server.ca_private_crt_path,
                                             farmer_server.ca_private_key_path,
                                             pub_crt, pub_key)
        connected = await establish_connection(farmer_server, 12312,
                                               ssl_context)
        assert connected is False
Beispiel #10
0
    async def test_introducer(self, introducer):
        introducer_api, introducer_server = introducer

        # Create not authenticated cert
        pub_crt = introducer_server.chia_ca_key_path.parent / "p2p.crt"
        pub_key = introducer_server.chia_ca_key_path.parent / "p2p.key"
        generate_ca_signed_cert(
            introducer_server.chia_ca_crt_path.read_bytes(),
            introducer_server.chia_ca_key_path.read_bytes(),
            pub_crt,
            pub_key,
        )
        ssl_context = ssl_context_for_client(
            introducer_server.chia_ca_crt_path,
            introducer_server.chia_ca_key_path, pub_crt, pub_key)
        connected = await establish_connection(introducer_server, 12312,
                                               ssl_context)
        assert connected is True
async def add_dummy_connection(
        server: ChiaServer,
        dummy_port: int,
        type: NodeType = NodeType.FULL_NODE) -> Tuple[asyncio.Queue, bytes32]:
    timeout = aiohttp.ClientTimeout(total=10)
    session = aiohttp.ClientSession(timeout=timeout)
    incoming_queue: asyncio.Queue = asyncio.Queue()
    dummy_crt_path = server._private_key_path.parent / "dummy.crt"
    dummy_key_path = server._private_key_path.parent / "dummy.key"
    generate_ca_signed_cert(server.chia_ca_crt_path.read_bytes(),
                            server.chia_ca_key_path.read_bytes(),
                            dummy_crt_path, dummy_key_path)
    ssl_context = ssl_context_for_client(server.chia_ca_crt_path,
                                         server.chia_ca_key_path,
                                         dummy_crt_path, dummy_key_path)
    pem_cert = x509.load_pem_x509_certificate(dummy_crt_path.read_bytes(),
                                              default_backend())
    der_cert = x509.load_der_x509_certificate(
        pem_cert.public_bytes(serialization.Encoding.DER), default_backend())
    peer_id = bytes32(der_cert.fingerprint(hashes.SHA256()))
    url = f"wss://{self_hostname}:{server._port}/ws"
    ws = await session.ws_connect(url,
                                  autoclose=True,
                                  autoping=True,
                                  ssl=ssl_context)
    wsc = WSChiaConnection(
        type,
        ws,
        server._port,
        log,
        True,
        False,
        self_hostname,
        incoming_queue,
        lambda x, y: x,
        peer_id,
        100,
        30,
    )
    handshake = await wsc.perform_handshake(server._network_id,
                                            protocol_version, dummy_port,
                                            NodeType.FULL_NODE)
    assert handshake is True
    return incoming_queue, peer_id
Beispiel #12
0
    async def test_full_node(self, wallet_node):
        full_nodes, wallets = wallet_node
        full_node_api = full_nodes[0]
        full_node_server = full_node_api.full_node.server

        # Create not authenticated cert
        pub_crt = full_node_server._private_key_path.parent / "p2p.crt"
        pub_key = full_node_server._private_key_path.parent / "p2p.key"
        generate_ca_signed_cert(
            full_node_server.chia_ca_crt_path.read_bytes(),
            full_node_server.chia_ca_key_path.read_bytes(),
            pub_crt,
            pub_key,
        )
        ssl_context = ssl_context_for_client(full_node_server.chia_ca_crt_path,
                                             full_node_server.chia_ca_key_path,
                                             pub_crt, pub_key)
        connected = await establish_connection(full_node_server, 12312,
                                               ssl_context)
        assert connected is True
Beispiel #13
0
    async def test_invalid_protocol_handshake(self, setup_two_nodes):
        nodes, _ = setup_two_nodes
        server_1 = nodes[0].full_node.server
        server_2 = nodes[1].full_node.server

        server_1.invalid_protocol_ban_seconds = 10
        # Use the server_2 ssl information to connect to server_1
        timeout = ClientTimeout(total=10)
        session = ClientSession(timeout=timeout)
        url = f"wss://{self_hostname}:{server_1._port}/ws"

        ssl_context = ssl_context_for_client(server_2.chia_ca_crt_path,
                                             server_2.chia_ca_key_path,
                                             server_2.p2p_crt_path,
                                             server_2.p2p_key_path)
        ws = await session.ws_connect(url,
                                      autoclose=True,
                                      autoping=True,
                                      heartbeat=60,
                                      ssl=ssl_context,
                                      max_msg_size=100 * 1024 * 1024)

        # Construct an otherwise valid handshake message
        handshake: Handshake = Handshake("test", "0.0.32", "1.0.0.0", 3456, 1,
                                         [(1, "1")])
        outbound_handshake: Message = Message(
            2, None, bytes(handshake))  # 2 is an invalid ProtocolType
        await ws.send_bytes(bytes(outbound_handshake))

        response: WSMessage = await ws.receive()
        print(response)
        assert response.type == WSMsgType.CLOSE
        assert response.data == WSCloseCode.PROTOCOL_ERROR
        assert response.extra == str(
            int(Err.INVALID_HANDSHAKE.value
                ))  # We want INVALID_HANDSHAKE and not UNKNOWN
        await ws.close()
        await session.close()
        await asyncio.sleep(1)  # give some time for cleanup to work