SHELL BYPASS 403 |
Modern UI.
Responsive.
Powerful.
import getpass
import json
import os
import socket
import time
from typing import Union
from .exceptions import InvalidArgumentError, JsonRpcClientError, MethodNotFoundError
from .payload import Params, ParamsType, Payload
DEFAULT_ROOT_SOCKET_PATH = "/var/run/hc_mds/root_mds.socket"
DEFAULT_USER_SOCKET_PATH = "/var/run/hc_mds/user_mds.socket"
DEFAULT_USER_TOKEN_FILE_FMT = (
"/var/cpanel/userdata/{}/hc_mds.token" # nosec bandit B105
)
RPC_VERSION = "2.0"
class Client:
def __init__(
self, socket_path: Union[str, None] = None, token: Union[str, None] = None
):
self._socket_path = socket_path
self._token = token
self._transport = None
@classmethod
def is_root(cls) -> bool:
return os.geteuid() == 0
@property
def token(self):
if not self._token and not self.is_root():
with open(
DEFAULT_USER_TOKEN_FILE_FMT.format(getpass.getuser()),
"r",
encoding="utf-8",
) as f:
self._token = f.read().strip()
return self._token
@classmethod
def _get_socket_path(cls) -> str:
if cls.is_root():
return DEFAULT_ROOT_SOCKET_PATH
return DEFAULT_USER_SOCKET_PATH
@property
def socket_path(self) -> str:
if not self._socket_path:
self._socket_path = self._get_socket_path()
return self._socket_path
def _prepare_payload(
self, method: str, params: Union[ParamsType, "Params"]
) -> dict:
if not isinstance(params, Params):
_params = Params.from_dict(params)
else:
_params = params.model_copy(deep=True)
_params.metadata.token = self.token # type: ignore
return Payload(
method=method,
params=_params, # type: ignore
jsonrpc=RPC_VERSION,
id=int(time.time()),
).model_dump()
@staticmethod
def _encode_json(payload: dict) -> bytes:
return json.dumps(payload).encode("utf-8")
@staticmethod
def _decode_json(payload: bytes) -> dict:
return json.loads(payload.decode("utf-8"))
@property
def transport(self):
if not self._transport:
self._transport = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self._transport.connect(self.socket_path)
return self._transport
def _execute(self, payload: dict) -> dict:
self.transport.sendall(self._encode_json(payload))
response = self.transport.recv(1024)
return self._decode_json(response)
@staticmethod
def _validate_response(response: dict) -> None:
if error := response.get("error", None):
if error["code"] == -32601:
raise MethodNotFoundError(error["message"])
if error["code"] == -32602:
raise InvalidArgumentError(error["message"])
raise JsonRpcClientError(response["error"]["message"])
def send(self, params: Union[ParamsType, "Params"], method: str = "event") -> dict:
response = self._execute(self._prepare_payload(method, params))
self._validate_response(response)
return response