diff --git a/checker/src/checker.py b/checker/src/checker.py index f41aa3c..6be13d2 100644 --- a/checker/src/checker.py +++ b/checker/src/checker.py @@ -23,7 +23,12 @@ from util import ( create_devenv, do_create_devenv, + do_create_devenv_file, + do_delete_devenv_file, + do_get_devenv, do_get_devenv_file_content, + do_get_devenv_files, + do_patch_devenv, do_repl_auth, do_set_devenv_file_content, do_user_login, @@ -381,5 +386,40 @@ async def getnoise1( assert_equals(noise.strip(), payload.strip(), "Wrong file content") +@checker.havoc(1) +async def havoc1( + client: AsyncClient, + logger: LoggerAdapter, +): + username = "".join(random.choice(string.ascii_lowercase) for _ in range(35)) + password = "".join(random.choice(string.ascii_lowercase) for _ in range(35)) + await do_user_register(client, logger, username, password) + cookies = await do_user_login(client, logger, username, password) + + name = "".join(random.choice(string.ascii_lowercase) for _ in range(10)) + buildCmd = "".join(random.choice(string.ascii_lowercase) for _ in range(10)) + runCmd = "".join(random.choice(string.ascii_lowercase) for _ in range(10)) + + devenvUuid = await do_create_devenv(client, logger, cookies, name, buildCmd, runCmd) + devenv = await do_get_devenv(client, logger, cookies, devenvUuid) + assert_equals(name, devenv["name"], "Devenv has invalid name") + assert_equals(buildCmd, devenv["buildCmd"], "Devenv has invalid buildCmd") + assert_equals(runCmd, devenv["runCmd"], "Devenv has invalid runCmd") + + name = "".join(random.choice(string.ascii_lowercase) for _ in range(10)) + await do_patch_devenv(client, logger, cookies, devenvUuid, name=name) + devenv = await do_get_devenv(client, logger, cookies, devenvUuid) + assert_equals(name, devenv["name"], "After patch: Devenv has invalid name") + + filename = "".join(random.choice(string.ascii_lowercase) for _ in range(10)) + await do_create_devenv_file(client, logger, cookies, devenvUuid, filename) + files = await do_get_devenv_files(client, logger, cookies, devenvUuid) + assert_equals(filename in files, True, "Create file did not create file") + + await do_delete_devenv_file(client, logger, cookies, devenvUuid, filename) + files = await do_get_devenv_files(client, logger, cookies, devenvUuid) + assert_equals(filename not in files, True, "Delete file did not delete file") + + if __name__ == "__main__": checker.run() diff --git a/checker/src/util.py b/checker/src/util.py index f54b792..75084d5 100644 --- a/checker/src/util.py +++ b/checker/src/util.py @@ -1,4 +1,5 @@ import asyncio +import collections.abc import random import re import string @@ -203,6 +204,109 @@ async def create_devenv( return devenvUuid +async def do_get_devenv( + client: AsyncClient, + logger: LoggerAdapter, + cookies: Cookies, + devenvUuid: str, +): + + response = await client.get( + "/api/devenv/" + devenvUuid, + follow_redirects=True, + headers={"Cookie": "session=" + (cookies.get("session") or "")}, + ) + logger.info(f"Server answered: {response.status_code} - {response.text}") + assert_equals(response.status_code < 300, True, "Getting devenv failed") + return response.json() + + +async def do_patch_devenv( + client: AsyncClient, + logger: LoggerAdapter, + cookies: Cookies, + devenvUuid: str, + name: str = "", + buildCmd: str = "", + runCmd: str = "", +): + response = await client.patch( + "/api/devenv/" + devenvUuid, + json={ + "name": name, + "buildCmd": buildCmd, + "runCmd": runCmd, + }, + follow_redirects=True, + headers={ + "Cookie": "session=" + (cookies.get("session") or ""), + }, + ) + logger.info(f"Server answered: {response.status_code} - {response.text}") + assert_equals(response.status_code < 300, True, "Patching devenv failed") + + +async def do_get_devenv_files( + client: AsyncClient, + logger: LoggerAdapter, + cookies: Cookies, + devenvUuid: str, +): + response = await client.get( + "/api/devenv/" + devenvUuid + "/files", + follow_redirects=True, + headers={ + "Cookie": "session=" + (cookies.get("session") or ""), + }, + ) + logger.info(f"Server answered: {response.status_code} - {response.text}") + assert_equals(response.status_code < 300, True, "Getting devenv files failed") + files = response.json() + assert_equals( + isinstance(files, collections.abc.Sequence), + True, + "Get files did not return array", + ) + return files + + +async def do_create_devenv_file( + client: AsyncClient, + logger: LoggerAdapter, + cookies: Cookies, + devenvUuid: str, + filename: str, +): + response = await client.post( + "/api/devenv/" + devenvUuid + "/files", + json={"name": filename}, + follow_redirects=True, + headers={ + "Cookie": "session=" + (cookies.get("session") or ""), + }, + ) + logger.info(f"Server answered: {response.status_code} - {response.text}") + assert_equals(response.status_code < 300, True, "Creating devenv file failed") + + +async def do_delete_devenv_file( + client: AsyncClient, + logger: LoggerAdapter, + cookies: Cookies, + devenvUuid: str, + filename: str, +): + response = await client.delete( + "/api/devenv/" + devenvUuid + "/files/" + filename, + follow_redirects=True, + headers={ + "Cookie": "session=" + (cookies.get("session") or ""), + }, + ) + logger.info(f"Server answered: {response.status_code} - {response.text}") + assert_equals(response.status_code < 300, True, "Deleting devenv file failed") + + async def do_set_devenv_file_content( client: AsyncClient, logger: LoggerAdapter, diff --git a/documentation/benchmark/main.py b/documentation/benchmark/main.py index 668c4c5..9f63832 100644 --- a/documentation/benchmark/main.py +++ b/documentation/benchmark/main.py @@ -51,7 +51,7 @@ def get_ip_address(ifname): VARIANTS: TVariants = { 0: ["putflag", "getflag", "exploit", "putnoise", "getnoise"], - 1: ["putflag", "getflag", "exploit", "putnoise", "getnoise"], + 1: ["putflag", "getflag", "exploit", "putnoise", "getnoise", "havoc"], } TICKS = 3 MULTIPLIER = 1 @@ -143,6 +143,10 @@ def putnoise_chain_id(self) -> str: def getnoise_chain_id(self) -> str: return f"{self.chain_prefix}_noise_s0_r{self.round_id}_t0_i0" + @property + def havoc_chain_id(self) -> str: + return f"{self.chain_prefix}_havoc_s0_r{self.round_id}_t0_i0" + @property def putflag_payload(self) -> CheckerPayload: payload = self.payload_stub @@ -183,6 +187,13 @@ def getnoise_payload(self) -> CheckerPayload: payload["taskChainId"] = self.getnoise_chain_id return payload + @property + def havoc_payload(self) -> CheckerPayload: + payload = self.payload_stub + payload["method"] = "havoc" + payload["taskChainId"] = self.getnoise_chain_id + return payload + async def request(self, method: TMethod): if method not in self.methods: return None @@ -198,6 +209,8 @@ async def request(self, method: TMethod): payload = self.putnoise_payload case "getnoise": payload = self.getnoise_payload + case "havoc": + payload = self.havoc_payload start = time.monotonic() response = await self.session.post("/", json=payload) if response.status == 200: @@ -257,7 +270,7 @@ async def main(): tasks: List[asyncio.Task] = [] async with aiohttp.ClientSession(CHECKER_ADDR) as client: - for i in range(10): + for i in range(1): round = Round( client, curr_round, @@ -265,8 +278,9 @@ async def main(): multiplier=MULTIPLIER, exploits_amount=EXPLOITS_AMOUNT, ) - await round.request("putnoise") - await round.request("getnoise") + await round.request("havoc") + # await round.request("putnoise") + # await round.request("getnoise") curr_round += 1 # for i in range(10): # round = Round(