windows installer fixes
CI Test Suite / Run Component Tests & Pipeline Verification (push) Successful in 1m9s
Release Binaries & Packages / Build & Release Standalone Binaries (Linux & Windows Cross-Compilation) (push) Successful in 10m27s

This commit is contained in:
2026-09-26 21:21:36 +02:00
parent 8287af3129
commit 157229a84e
9 changed files with 244 additions and 14 deletions
+8
View File
@@ -11,6 +11,14 @@ import warnings
from datetime import datetime, timezone, timedelta
from typing import Optional
# Ensure script directory and repo root are in sys.path
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
if SCRIPT_DIR not in sys.path:
sys.path.insert(0, SCRIPT_DIR)
REPO_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
if REPO_ROOT not in sys.path:
sys.path.insert(0, REPO_ROOT)
# Suppress cryptography / pgpy deprecation notices
warnings.filterwarnings("ignore")
+42 -7
View File
@@ -17,6 +17,14 @@ import threading
from datetime import datetime, timezone, timedelta
from typing import Dict, Any, List, Optional, Tuple
# Ensure script directory and repo root are in sys.path
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
if SCRIPT_DIR not in sys.path:
sys.path.insert(0, SCRIPT_DIR)
REPO_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
if REPO_ROOT not in sys.path:
sys.path.insert(0, REPO_ROOT)
# Suppress cryptography / pgpy deprecation notices for a clean terminal output
warnings.filterwarnings("ignore")
@@ -910,6 +918,12 @@ def init_mtls_server_context(cert_dir: str = "certs") -> ssl.SSLContext:
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ctx.load_cert_chain(certfile=srv_cert, keyfile=srv_key)
ctx.load_verify_locations(cafile=ca_file)
upstream_file = os.path.join(cert_dir, "upstream_ca.crt")
if os.path.exists(upstream_file):
try:
ctx.load_verify_locations(cafile=upstream_file)
except Exception:
pass
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.minimum_version = ssl.TLSVersion.TLSv1_3
return ctx
@@ -926,6 +940,12 @@ def reload_mtls_context(ssl_ctx: ssl.SSLContext, cert_dir: str = "certs"):
ssl_ctx.load_cert_chain(certfile=srv_cert, keyfile=srv_key)
ssl_ctx.load_verify_locations(cafile=ca_file)
upstream_file = os.path.join(cert_dir, "upstream_ca.crt")
if os.path.exists(upstream_file):
try:
ssl_ctx.load_verify_locations(cafile=upstream_file)
except Exception:
pass
def check_and_rotate_server_certs(
@@ -1347,6 +1367,18 @@ def enroll_client(req: ClientEnrollRequest, request: Request = None):
conn.close()
raise HTTPException(status_code=500, detail="Root CA not loaded on server")
# Ensure full trust chain (subordinate CA + upstream root CA if present) is delivered to edge clients
cert_dir = SERVER_STATE.get("config", {}).get("cert_dir", "certs")
upstream_ca_path = os.path.join(cert_dir, "upstream_ca.crt")
if os.path.exists(upstream_ca_path):
try:
with open(upstream_ca_path, "r", encoding="utf-8") as f:
upstream_pem = f.read().strip()
if upstream_pem and upstream_pem not in ca_cert_pem:
ca_cert_pem = ca_cert_pem.strip() + "\n" + upstream_pem
except Exception:
pass
# 2. Check if client_id already registered
c.execute("SELECT status FROM clients WHERE client_id = ?", (req.client_id,))
client_row = c.fetchone()
@@ -1766,14 +1798,17 @@ async def import_signed_license(req: Request):
except Exception:
raise HTTPException(status_code=400, detail="Invalid JSON body")
raw_input = body.get("ca_cert") or body.get("lic") or body.get("raw") or body.get("license") or body.get("license_file")
if not raw_input:
raise HTTPException(status_code=400, detail="Missing 'lic' or 'ca_cert' payload in request")
if isinstance(raw_input, dict):
raw_text = json.dumps(raw_input)
if isinstance(body, dict):
if "master_root_ca" in body or "upstream_ca" in body:
raw_text = json.dumps(body)
elif "lic" in body:
raw_text = json.dumps(body["lic"]) if isinstance(body["lic"], dict) else str(body["lic"])
elif "ca_cert" in body and not body.get("master_root_ca"):
raw_text = str(body["ca_cert"])
else:
raw_text = json.dumps(body)
else:
raw_text = str(raw_input)
raw_text = str(body)
config = SERVER_STATE.get("config", {})
cert_dir = config.get("cert_dir", "certs")
+8
View File
@@ -10,6 +10,14 @@ import warnings
from datetime import datetime, timezone, timedelta
from typing import Optional
# Ensure script directory and repo root are in sys.path
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
if SCRIPT_DIR not in sys.path:
sys.path.insert(0, SCRIPT_DIR)
REPO_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, ".."))
if REPO_ROOT not in sys.path:
sys.path.insert(0, REPO_ROOT)
# Suppress cryptography / pgpy deprecation notices
warnings.filterwarnings("ignore")
+17 -1
View File
@@ -251,8 +251,24 @@ def generate_server_cert_if_needed(
encryption_algorithm=serialization.NoEncryption()
).decode("utf-8")
# Bundle subordinate CA and upstream CA into server.crt for complete TLS handshake chain
full_server_cert_pem = server_cert_pem
ca_cert_path = os.path.join(cert_dir, "ca.crt")
if os.path.exists(ca_cert_path):
with open(ca_cert_path, "r", encoding="utf-8") as f:
ca_pem = f.read().strip()
if ca_pem and ca_pem not in full_server_cert_pem:
full_server_cert_pem = full_server_cert_pem.strip() + "\n" + ca_pem
upstream_ca_path = os.path.join(cert_dir, "upstream_ca.crt")
if os.path.exists(upstream_ca_path):
with open(upstream_ca_path, "r", encoding="utf-8") as f:
upstream_pem = f.read().strip()
if upstream_pem and upstream_pem not in full_server_cert_pem:
full_server_cert_pem = full_server_cert_pem.strip() + "\n" + upstream_pem
with open(server_cert_path, "w", encoding="utf-8") as f:
f.write(server_cert_pem)
f.write(full_server_cert_pem)
with open(server_key_path, "w", encoding="utf-8") as f:
f.write(server_key_pem)