Files
wifi-gps-mapper-public/cracklab/client/config.py
T
2026-10-06 21:08:12 +03:00

107 lines
2.9 KiB
Python

from __future__ import annotations
import json
from dataclasses import dataclass
from pathlib import Path
CONFIG_NAME = "config.json"
@dataclass(frozen=True)
class ClientConfig:
hashcat_exe: Path
potfile_path: Path
client_root: Path
wordlists: dict[str, Path]
poll_seconds: int
max_parallel_jobs: int
def load_config(script_dir: Path) -> ClientConfig:
path = script_dir / CONFIG_NAME
if not path.is_file():
raise FileNotFoundError(
f"Missing {path}. "
"Copy config.example.json to config.json and edit it."
)
try:
data = json.loads(path.read_text(encoding="utf-8"))
except json.JSONDecodeError as exc:
raise ValueError(f"Invalid JSON in {path}: {exc}") from exc
if not isinstance(data, dict):
raise ValueError("Client config must contain a JSON object.")
required = (
"hashcat_exe",
"potfile_path",
"client_root",
"wordlists",
"poll_seconds",
"max_parallel_jobs",
)
missing = [name for name in required if name not in data]
if missing:
raise ValueError(
"Missing required config fields: "
+ ", ".join(missing)
)
for name in (
"hashcat_exe",
"potfile_path",
"client_root",
):
if not isinstance(data[name], str) or not data[name].strip():
raise ValueError(
f"Config field {name!r} must be a non-empty string."
)
if not isinstance(data["wordlists"], dict) or not data["wordlists"]:
raise ValueError(
"Config field 'wordlists' must be a non-empty object."
)
for name, path_value in data["wordlists"].items():
if not isinstance(name, str) or not name.strip():
raise ValueError(
"Each wordlists key must be a non-empty string."
)
if not isinstance(path_value, str) or not path_value.strip():
raise ValueError(
f"Wordlist {name!r} path must be a non-empty string."
)
for name in (
"poll_seconds",
"max_parallel_jobs",
):
value = data[name]
if isinstance(value, bool) or not isinstance(value, int):
raise ValueError(
f"Config field {name!r} must be an integer."
)
if value <= 0:
raise ValueError(
f"Config field {name!r} must be greater than zero."
)
return ClientConfig(
hashcat_exe=Path(data["hashcat_exe"]).expanduser().resolve(),
potfile_path=Path(data["potfile_path"]).expanduser().resolve(),
client_root=Path(data["client_root"]).expanduser().resolve(),
wordlists={
name: Path(path_value).expanduser().resolve()
for name, path_value in data["wordlists"].items()
},
poll_seconds=data["poll_seconds"],
max_parallel_jobs=data["max_parallel_jobs"],
)