mirror of
https://github.com/kuitoi/kuitoi-Server.git
synced 2026-04-11 18:36:11 +00:00
Start adding RCON part!
This commit is contained in:
92
src/modules/ConsoleSystem/RCON.py
Normal file
92
src/modules/ConsoleSystem/RCON.py
Normal file
@@ -0,0 +1,92 @@
|
||||
import hashlib
|
||||
import os
|
||||
from base64 import b64decode, b64encode
|
||||
|
||||
from cryptography.hazmat.primitives import padding
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
||||
|
||||
from core import get_logger
|
||||
|
||||
"""
|
||||
shared key: SHA256 of "password"
|
||||
<header>: "\x00\x00\x00\x00" (Byte order: Little Endian) - like you use
|
||||
<iv>: A set of random bytes packed in base64 (New for each message)
|
||||
-> To server
|
||||
<- From server
|
||||
|
||||
Open TCP connection /
|
||||
| -> "<iv>:hello" Without header, immediately with AES encryption (shared key)
|
||||
| *Decrypt and some processes*
|
||||
| Fail /
|
||||
| | <- ":E:Bad key" | ":E:Error Message" Without header, without AES encryption
|
||||
| | tcp.close() # End
|
||||
| Success /
|
||||
| | <- "<iv>:hello" with header, with AES encryption
|
||||
| | (Next, everywhere with header, with AES encryption)
|
||||
| -> "<iv>:<header>Cs:ver"
|
||||
| <- "<iv>:<header>Os:KuiToi 0.4.3 | "<iv>:<header>Os:BeamMP 3.2.0"
|
||||
| # Prints server and they version
|
||||
| -> "<iv>:<header>Cs:commands"
|
||||
| <- "<iv>:<header>Os:stop,help,plugins" | "<iv>:<header>Os:SKIP" For an autocomplete; "SKIP" For no autocomplete;
|
||||
| *Ready to handle commands*
|
||||
| -> "<iv>:<header>C:help"
|
||||
| <- "<iv>:<header>O:stop: very cool stop\nhelp: Yayayayoy"
|
||||
| -> "<iv>:<header>C:...."
|
||||
| <- "<iv>:<header>O:...."
|
||||
| -> "<iv>:<header>C:exit"
|
||||
| tcp.close()
|
||||
|
||||
Codes:
|
||||
* "hello" - Hello message
|
||||
* "E:error_message" - Send RCON error
|
||||
* "C:command" - Receive command
|
||||
* "Cs:" - Receive system command
|
||||
* "O:output" - Send command output
|
||||
* "Os:" - Send system output
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class RCONSystem:
|
||||
console = None
|
||||
|
||||
def __init__(self, key, host, port):
|
||||
self.log = get_logger("RCON")
|
||||
self.key = key
|
||||
self.host = host
|
||||
self.port = port
|
||||
|
||||
def encrypt(self, message, key):
|
||||
self.log.debug(f"Encrypt message: {message}")
|
||||
key = hashlib.sha256(key).digest()
|
||||
iv = os.urandom(16)
|
||||
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
|
||||
encryptor = cipher.encryptor()
|
||||
padder = padding.PKCS7(algorithms.AES.block_size).padder()
|
||||
padded_data = padder.update(message.encode('utf-8')) + padder.finalize()
|
||||
encrypted_data = encryptor.update(padded_data) + encryptor.finalize()
|
||||
encoded_data = b64encode(encrypted_data)
|
||||
encoded_iv = b64encode(iv)
|
||||
return encoded_iv + b":" + encoded_data
|
||||
|
||||
def decrypt(self, ciphertext, key):
|
||||
self.log.debug(f"Dencrypt message: {ciphertext}")
|
||||
key = hashlib.sha256(key).digest()
|
||||
encoded_iv, encoded_data = ciphertext.split(":")
|
||||
iv = b64decode(encoded_iv)
|
||||
encrypted_data = b64decode(encoded_data)
|
||||
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
|
||||
decryptor = cipher.decryptor()
|
||||
unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
|
||||
decrypted_data = decryptor.update(encrypted_data) + decryptor.finalize()
|
||||
unpadded_data = unpadder.update(decrypted_data) + unpadder.finalize()
|
||||
return unpadded_data.decode('utf-8')
|
||||
|
||||
async def handle_client(self):
|
||||
pass
|
||||
|
||||
async def start(self):
|
||||
self.log.info("TODO: RCON")
|
||||
|
||||
async def stop(self):
|
||||
pass
|
||||
@@ -1,36 +1,34 @@
|
||||
class Console(object):
|
||||
from logging import Logger
|
||||
from typing import AnyStr
|
||||
|
||||
def __init__(self,
|
||||
prompt_in: str = ">",
|
||||
prompt_out: str = "]:",
|
||||
not_found: str = "Command \"%s\" not found in alias.") -> None: ...
|
||||
from core import get_logger
|
||||
|
||||
def __getitem__(self, item): ...
|
||||
@property
|
||||
def alias(self) -> dict: ...
|
||||
def add(self, key: str, func: function) -> dict: ...
|
||||
def log(self, s: str, r='\r') -> None: ...
|
||||
def write(self, s: str, r='\r') -> None: ...
|
||||
def __lshift__(self, s: AnyStr) -> None: ...
|
||||
def logger_hook(self) -> None: ...
|
||||
def builtins_hook(self) -> None: ...
|
||||
async def start(self) -> None: ...
|
||||
|
||||
class console(object):
|
||||
class RCONSystem:
|
||||
console = None
|
||||
|
||||
def __init__(self, key, host, port):
|
||||
self.log = get_logger("RCON")
|
||||
self.key = key
|
||||
self.host = host
|
||||
self.port = port
|
||||
|
||||
async def start(self): ...
|
||||
async def stop(self): ...
|
||||
|
||||
class console:
|
||||
rcon: RCONSystem = RCONSystem
|
||||
|
||||
@staticmethod
|
||||
def alias() -> dict: ...
|
||||
@staticmethod
|
||||
def add_command(key: str, func: function) -> dict: ...
|
||||
|
||||
def add_command(key: str, func, man: str = None, desc: str = None, custom_completer: dict = None) -> dict: ...
|
||||
@staticmethod
|
||||
async def start() -> None: ...
|
||||
|
||||
@staticmethod
|
||||
def builtins_hook() -> None: ...
|
||||
@staticmethod
|
||||
def logger_hook() -> None: ...
|
||||
|
||||
@staticmethod
|
||||
def log(s: str) -> None: ...
|
||||
@staticmethod
|
||||
|
||||
@@ -18,6 +18,7 @@ from prompt_toolkit.output.win32 import NoConsoleScreenBufferError
|
||||
from prompt_toolkit.patch_stdout import patch_stdout
|
||||
|
||||
from core import get_logger
|
||||
from modules.ConsoleSystem import RCON
|
||||
|
||||
|
||||
class Console:
|
||||
@@ -45,6 +46,9 @@ class Console:
|
||||
self.add_command("help", self.__create_help_message, i18n.man_message_help, i18n.help_message_help,
|
||||
custom_completer={"help": {"--raw": None}})
|
||||
self.completer = NestedCompleter.from_nested_dict(self.__alias)
|
||||
rcon = RCON
|
||||
rcon.console = self
|
||||
self.rcon = rcon
|
||||
|
||||
def __debug(self, *x):
|
||||
self.__logger.debug(f"{x}")
|
||||
|
||||
Reference in New Issue
Block a user