diff options
Diffstat (limited to 'iv/orodja/napad/submission.py')
-rwxr-xr-x | iv/orodja/napad/submission.py | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/iv/orodja/napad/submission.py b/iv/orodja/napad/submission.py index fce0a27..4a44947 100755 --- a/iv/orodja/napad/submission.py +++ b/iv/orodja/napad/submission.py @@ -5,6 +5,7 @@ import re import sqlite3 import aiohttp import traceback +import json db = sqlite3.connect(os.getenv("SUBMISSION_DB", "flags.db")) db.execute("CREATE TABLE IF NOT EXISTS flags (id INTEGER PRIMARY KEY, flag TEXT NOT NULL UNIQUE, team INTEGER, service BLOB, round INTEGER, context BLOB, sent INTEGER NOT NULL DEFAULT 0, date TEXT DEFAULT (strftime('%FT%R:%f', 'now')) NOT NULL, status TEXT, msg TEXT) STRICT") flag_regex = re.compile(os.getenv("FLAG_REGEX_MATCH", "^[A-Z0-9]{31}=$").encode(), re.ASCII | re.DOTALL | re.VERBOSE) @@ -45,7 +46,11 @@ async def submitter (): traceback.print_exc() await asyncio.sleep(int(os.getenv("SUBMISSION_DELAY", "15"))) async def handle_client (reader, writer): + linenumber = -1 + http_request = None + http_headers = dict() while True: + linenumber += 1 try: incoming = await reader.readuntil(b'\n') except asyncio.exceptions.IncompleteReadError as e: @@ -55,6 +60,79 @@ async def handle_client (reader, writer): if len(incoming) == 0: break buffer = incoming.replace(b'\r', b'').replace(b'\n', b'') + if http_request: + if len(buffer) == 0: + if http_request[1] == b"/": + with open("index.html", "rb") as index: + if http_request[0] != b"GET": + writer.write(b'HTTP/1.0 405 Method Not Allowed\r\nContent-Type: text/plain\r\n\r\n405 Method Not Allowed. Try GET.\r\n') + break + writer.write(b'HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n') + writer.write(index.read()) + break + elif http_request[1] == b"/python": + if http_request[0] != b"POST": + writer.write(b'HTTP/1.0 405 Method Not Allowed\r\nContent-Type: text/plain\r\n\r\n405 Method Not Allowed. Try POST.\r\n') + break + if b'content-length' not in http_headers.keys(): + writer.write(b'HTTP/1.0 411 Length Required\r\nContent-Type: text/plain\r\n\r\n411 Length Required.\r\n') + break + post_body = None + try: + post_body = await reader.read(int(http_headers.get(b'content-length').decode())) + except Exception as e: + writer.write(b'HTTP/1.0 400 Bad Request\r\nContent-Type: text/plain\r\n\r\nBad request. ' + str(e).encode() + b"\r\n") + raise e + break + try: + writer.write(b"HTTP/1.0 200 OK\r\nContent-Type: application/json\r\n\r\n" + eval(post_body)) + break + except Exception as e: + writer.write(b"HTTP/1.0 500 Internal Server Error\r\nContent-Type: text/plain\r\n\r\n" + str(e).encode() + b"\r\n") + raise e + break + elif http_request[1] == b"/sql": + if http_request[0] != b'POST': + writer.write(b'HTTP/1.0 405 Method Not Allowed\r\nContent-Type: text/plain\r\n\r\n405 Method Not Allowed. Try POST.\r\n') + break + if b'content-length' not in http_headers.keys(): + writer.write(b'HTTP/1.0 411 Length Required\r\nContent-Type: text/plain\r\n\r\n411 Length Required.\r\n') + break + post_body = None + try: + post_body = (await reader.read(int(http_headers.get(b'content-length').decode()))).decode() + except Exception as e: + writer.write(b'HTTP/1.0 400 Bad Request\r\nContent-Type: text/plain\r\n\r\nBad request. ' + str(e).encode() + b"\r\n") + raise e + break + try: + rows = [] + for row in db.execute(post_body): + columns = [] + for column in row: + if type(column) == bytes: + columns.append(column.decode("utf-8", errors="surrogateescape")) + else: + columns.append(column) + rows.append(columns) + response = json.dumps(rows, ensure_ascii=False, indent=1) + except Exception as e: + writer.write(b'HTTP/1.0 500 Internal Server Error\r\nContent-Type: text/plain\r\n\r\n500 Internal Server Error. ' + str(e).encode() + b"\r\n") + raise e + break + else: + writer.write(b'HTTP/1.0 200 OK\r\nContent-Type: application/json\r\n\r\n' + response.encode()) + break + else: + writer.write(b'HTTP/1.0 404 Not Found\r\nContent-Type: text/plain\r\n\r\n404 Not Found') + break + splitbuf = buffer.split(b': ') + headername = splitbuf.pop(0).lower() + http_headers[headername] = b': '.join(splitbuf) + continue + if linenumber == 0 and re.match(b'[A-Z]+ [/A-Za-z0-9?&=%+~]+ HTTP/[0-9.]+', buffer): + http_request = buffer.split(b' ') + continue if buffer.startswith(b' '): for row in db.execute(buffer[1:].decode()): writer.write(str(row).encode() + b'\n') |