From 3edb20d21b08c404d818cf41354254a75f75b212 Mon Sep 17 00:00:00 2001 From: Nicole Rappe Date: Sun, 26 Oct 2025 03:11:57 -0600 Subject: [PATCH] Validate Engine TLS material before starting Socket.IO --- Data/Engine/bootstrapper.py | 49 ++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/Data/Engine/bootstrapper.py b/Data/Engine/bootstrapper.py index 3658ba3..e24caa8 100644 --- a/Data/Engine/bootstrapper.py +++ b/Data/Engine/bootstrapper.py @@ -9,9 +9,10 @@ legacy server defaults by binding to ``0.0.0.0:5001`` and honouring the from __future__ import annotations import os +from pathlib import Path from typing import Any, Dict -from .server import create_app +from .server import EngineContext, create_app DEFAULT_HOST = "0.0.0.0" @@ -28,6 +29,41 @@ def _build_runtime_config() -> Dict[str, Any]: } +def _prepare_tls_run_kwargs(context: EngineContext) -> Dict[str, Any]: + """Validate and return TLS arguments for the Socket.IO runner.""" + + run_kwargs: Dict[str, Any] = {} + + key_path_value = context.tls_key_path + if not key_path_value: + return run_kwargs + + key_path = Path(key_path_value) + if not key_path.is_file(): + raise RuntimeError(f"Engine TLS key file not found: {key_path}") + + cert_candidates = [] + if context.tls_bundle_path: + cert_candidates.append(context.tls_bundle_path) + if context.tls_cert_path and context.tls_cert_path not in cert_candidates: + cert_candidates.append(context.tls_cert_path) + + if not cert_candidates: + raise RuntimeError("Engine TLS certificate path not configured; ensure certificates are provisioned.") + + missing_candidates = [] + for candidate in cert_candidates: + candidate_path = Path(candidate) + if candidate_path.is_file(): + run_kwargs["certfile"] = str(candidate_path) + run_kwargs["keyfile"] = str(key_path) + return run_kwargs + missing_candidates.append(str(candidate_path)) + + checked = ", ".join(missing_candidates) + raise RuntimeError(f"Engine TLS certificate file not found. Checked: {checked}") + + def main() -> None: config = _build_runtime_config() app, socketio, context = create_app(config) @@ -36,8 +72,15 @@ def main() -> None: port = int(config.get("PORT", DEFAULT_PORT)) run_kwargs: Dict[str, Any] = {"host": host, "port": port} - if context.tls_bundle_path and context.tls_key_path: - run_kwargs.update({"certfile": context.tls_bundle_path, "keyfile": context.tls_key_path}) + try: + tls_kwargs = _prepare_tls_run_kwargs(context) + except RuntimeError as exc: + context.logger.error("TLS configuration error: %s", exc) + raise + else: + if tls_kwargs: + run_kwargs.update(tls_kwargs) + context.logger.info("Engine TLS enabled using certificate %s", tls_kwargs["certfile"]) socketio.run(app, **run_kwargs)