94 lines
3.5 KiB
Python
94 lines
3.5 KiB
Python
from lib import config as config_module
|
|
from lib import logging as logging_lib
|
|
from lib import background_job
|
|
from lib import utils
|
|
import asyncio
|
|
import json
|
|
|
|
import os
|
|
import aiofiles.os
|
|
|
|
config = config_module.config
|
|
log = logging_lib.log
|
|
|
|
dangerous_chars = [';', '|', '&', '`', '$', '>', '<', '(', ')', '\\', '!', '"', '\'', '[', ']', '{', '}']
|
|
allowed_commands = ["df"]
|
|
|
|
can_deploy = True
|
|
|
|
async def remove_socket_file(path):
|
|
try:
|
|
file_exists = await aiofiles.os.path.exists(path)
|
|
if file_exists:
|
|
await aiofiles.os.remove(path)
|
|
except Exception:
|
|
pass
|
|
|
|
async def handle_client(reader, writer):
|
|
global can_deploy
|
|
try:
|
|
while True:
|
|
data = await reader.read(1024*64)
|
|
try:
|
|
if not data:
|
|
break
|
|
#print("DATA", data, data.decode())
|
|
parsed_data = json.loads(data.decode())
|
|
if "run_command" in parsed_data and type(parsed_data["run_command"])==str:
|
|
allowed = False
|
|
for allowed_command in allowed_commands:
|
|
if f"{allowed_command} " == parsed_data["run_command"][:len(allowed_command)+1] or allowed_command==parsed_data["run_command"]:
|
|
allowed = True
|
|
break
|
|
if allowed and any(char in parsed_data["run_command"] for char in dangerous_chars):
|
|
allowed = False
|
|
log.debug(f"clore_partner_socket | Received \"{parsed_data["run_command"]}\" | {'allowed' if allowed else 'denied'}")
|
|
if allowed:
|
|
code, stdout, stderr = await utils.async_run_command(
|
|
parsed_data["run_command"]
|
|
)
|
|
writer.write(json.dumps({
|
|
"code": code,
|
|
"stderr": stderr,
|
|
"stdout": stdout
|
|
}).encode())
|
|
else:
|
|
writer.write(json.dumps({
|
|
"code": -1,
|
|
"stderr": 'Command not allowed',
|
|
"stdout": 'Command not allowed'
|
|
}).encode())
|
|
elif "can_deploy" in parsed_data:
|
|
writer.write(json.dumps({
|
|
"can_deploy": can_deploy
|
|
}).encode())
|
|
elif "stop_background_job" in parsed_data and "time" in parsed_data:
|
|
try:
|
|
if isinstance(parsed_data["time"], int):
|
|
background_job.temporarly_disable(parsed_data["time"])
|
|
except Exception as e:
|
|
pass
|
|
else:
|
|
writer.write('?'.encode())
|
|
await writer.drain()
|
|
except Exception as data_exception:
|
|
pass
|
|
break
|
|
except asyncio.CancelledError:
|
|
log.debug(f"clore partner socket | Client handler canceled.")
|
|
finally:
|
|
log.debug(f"clore partner socket | Closing client connection.")
|
|
writer.close()
|
|
await writer.wait_closed()
|
|
|
|
def set_can_deploy(state):
|
|
global can_deploy
|
|
can_deploy = state
|
|
|
|
async def socket_service(location):
|
|
await remove_socket_file(location)
|
|
server = await asyncio.start_unix_server(handle_client, path=location)
|
|
|
|
log.debug(f"clore partner socket | running at {location}")
|
|
async with server:
|
|
await server.serve_forever() |