async def test_bad_cmd(alice_backend_sock): await alice_backend_sock.send(packb({"cmd": "dummy"})) rep = await alice_backend_sock.recv() assert unpackb(rep) == { "status": "unknown_command", "reason": "Unknown command" }
async def check_allowed_cmds(backend_sock, cmds): for cmd in cmds: if cmd == "events_listen": # Must pass wait option otherwise backend will hang forever await backend_sock.send(packb({"cmd": cmd, "wait": False})) else: await backend_sock.send(packb({"cmd": cmd})) rep = await backend_sock.recv() assert unpackb(rep)["status"] != "unknown_command"
async def test_handshake_invalid_format(backend, server_factory): async with server_factory(backend.handle_client) as server: stream = server.connection_factory() transport = await Transport.init_for_client(stream, server.addr.hostname) await transport.recv() # Get challenge req = {"handshake": "dummy", "client_api_version": API_VERSION} await transport.send(packb(req)) result_req = await transport.recv() assert unpackb(result_req) == { "handshake": "result", "result": "bad_protocol", "help": "{'handshake': ['Invalid value, should be `answer`']}", }
async def _handle_client_loop(self, transport, client_ctx): # Retrieve the allowed commands according to api version and auth type api_cmds = self.apis[client_ctx.handshake_type] raw_req = None while True: # raw_req can be already defined if we received a new request # while processing a command raw_req = raw_req or await transport.recv() req = unpackb(raw_req) if get_log_level() <= LOG_LEVEL_DEBUG: client_ctx.logger.debug("Request", req=_filter_binary_fields(req)) try: cmd = req.get("cmd", "<missing>") if not isinstance(cmd, str): raise KeyError() cmd_func = api_cmds[cmd] except KeyError: rep = {"status": "unknown_command", "reason": "Unknown command"} else: try: rep = await cmd_func(client_ctx, req) except InvalidMessageError as exc: rep = { "status": "bad_message", "errors": exc.errors, "reason": "Invalid message.", } except ProtocolError as exc: rep = {"status": "bad_message", "reason": str(exc)} except CancelledByNewRequest as exc: # Long command handling such as message_get can be cancelled # when the peer send a new request raw_req = exc.new_raw_req continue if get_log_level() <= LOG_LEVEL_DEBUG: client_ctx.logger.debug("Response", rep=_filter_binary_fields(rep)) else: client_ctx.logger.info("Request", cmd=cmd, status=rep["status"]) raw_rep = packb(rep) await transport.send(raw_rep) raw_req = None
def test_build_bad_outcomes(alice, method, expected_result): sh = ServerHandshake() sh.build_challenge_req() answer = { "handshake": "answer", "type": HandshakeType.AUTHENTICATED.value, "client_api_version": API_V2_VERSION, "organization_id": alice.organization_id, "device_id": alice.device_id, "rvk": alice.root_verify_key.encode(), "answer": alice.signing_key.sign(sh.challenge), } sh.process_answer_req(packb(answer)) req = getattr(sh, method)() assert unpackb(req) == { "handshake": "result", "result": expected_result, "help": ANY }
async def test_anonymous_handshake_invalid_format(backend, server_factory): async with server_factory(backend.handle_client) as server: stream = server.connection_factory() transport = await Transport.init_for_client(stream, server.addr.hostname) await transport.recv() # Get challenge req = { "handshake": "foo", "type": "anonymous", "client_api_version": ApiVersion(1, 1), "organization_id": "zob", } await transport.send(packb(req)) result_req = await transport.recv() assert unpackb(result_req) == { "handshake": "result", "result": "bad_protocol", "help": "{'handshake': ['Invalid value, should be `answer`']}", }
async def test_handshake_incompatible_version(backend, server_factory): async with server_factory(backend.handle_client) as server: stream = server.connection_factory() transport = await Transport.init_for_client(stream, server.addr.hostname) incompatible_version = ApiVersion(API_VERSION.version + 1, 0) await transport.recv() # Get challenge req = { "handshake": "answer", "type": "anonymous", "client_api_version": incompatible_version, "organization_id": OrganizationID("Org"), "token": "whatever", } await transport.send(packb(req)) result_req = await transport.recv() assert unpackb(result_req) == { "handshake": "result", "result": "bad_protocol", "help": "No overlap between client API versions {3.0} and backend API versions {2.0, 1.2}", }
async def test_connection(alice_backend_sock): await alice_backend_sock.send(packb({"cmd": "ping", "ping": "42"})) rep = await alice_backend_sock.recv() assert unpackb(rep) == {"status": "ok", "pong": "42"}