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_crt_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_crt_path, priv_crt, priv_key) connected = await establish_connection(wallet_server, 12312, ssl_context) assert connected is False
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_crt_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_crt_path, priv_crt, priv_key) connected = await establish_connection(timelord_server, 12312, ssl_context) assert connected is False
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_crt_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_crt_path, priv_crt, priv_key) connected = await establish_connection(harvester_server, 12312, ssl_context) assert connected is False
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 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() cert_path, key_path = load_ssl_paths(root_path, net_config) self.ssl_context = ssl_context_for_client(cert_path, key_path, auth=True) self.closing_task = None return self
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()
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
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()
async def test_farmer(self, harvester_farmer): harvester_api, farmer_api = harvester_farmer 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_crt_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_crt_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_crt_path, pub_crt, pub_key) connected = await establish_connection(farmer_server, 12312, ssl_context) assert connected is False
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_crt_path, pub_crt, pub_key) connected = await establish_connection(introducer_server, 12312, ssl_context) assert connected is True
async def connect_to_daemon_and_validate(root_path): """ 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") cert_path, key_path = load_ssl_paths(root_path, net_config) ssl_context = ssl_context_for_client(cert_path, key_path, auth=True) connection = await connect_to_daemon(net_config["self_hostname"], net_config["daemon_port"], ssl_context) r = await connection.ping() if r["data"]["value"] == "pong": return connection except Exception: print("Daemon not started yet") return None
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_crt_path, pub_crt, pub_key) connected = await establish_connection(full_node_server, 12312, ssl_context) assert connected is True
async def add_dummy_connection( server: ChiaServer, dummy_port: int) -> 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( NodeType.FULL_NODE, ws, server._port, log, True, False, self_hostname, incoming_queue, lambda x: x, peer_id, ) handshake = await wsc.perform_handshake(server._network_id, protocol_version, dummy_port, NodeType.FULL_NODE) assert handshake is True return incoming_queue, peer_id