Support WebSocket license sync and bootstrap .lic import in Server.py
This commit is contained in:
+42
-17
@@ -1645,16 +1645,21 @@ def main():
|
|||||||
lic_file = args.import_lic or args.import_ca
|
lic_file = args.import_lic or args.import_ca
|
||||||
if lic_file:
|
if lic_file:
|
||||||
try:
|
try:
|
||||||
res = enrollment.import_license_package(lic_file, cert_dir=cert_dir)
|
res = enrollment.import_license_package(
|
||||||
|
lic_file,
|
||||||
|
cert_dir=cert_dir,
|
||||||
|
server_fingerprint=config.get("server_fingerprint", ""),
|
||||||
|
hostname=config.get("server_name", "")
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"[-] Invalid license file {lic_file}: {e}")
|
print(f"[-] Invalid license file {lic_file}: {e}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
info = res["license_info"]
|
info = res.get("license_info", {})
|
||||||
new_seats = info.get("seats") or config.get("max_seats", 10)
|
new_seats = res.get("seats") or info.get("seats") or config.get("max_seats", 10)
|
||||||
config["max_seats"] = new_seats
|
config["max_seats"] = new_seats
|
||||||
conn = sqlite3.connect(config["db_path"])
|
conn = sqlite3.connect(config["db_path"])
|
||||||
conn.execute("UPDATE license_config SET max_seats = ?, license_id = ? WHERE id = 1", (new_seats, info.get("license_id")))
|
conn.execute("UPDATE license_config SET max_seats = ?, license_id = ? WHERE id = 1", (new_seats, res.get("license_id") or info.get("license_id")))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
@@ -1669,24 +1674,44 @@ def main():
|
|||||||
|
|
||||||
print(f"[+] Successfully imported and activated signed license!")
|
print(f"[+] Successfully imported and activated signed license!")
|
||||||
print(f" - Granted Seats: {new_seats}")
|
print(f" - Granted Seats: {new_seats}")
|
||||||
print(f" - License ID: {info.get('license_id')}")
|
print(f" - License ID: {res.get('license_id') or info.get('license_id')}")
|
||||||
print(f" - Expires: {info.get('not_valid_after')}")
|
print(f" - Expires: {info.get('not_valid_after') or res.get('expires_at') or 'N/A'}")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
# Handle standalone CLI license sync / update against master server
|
# Handle standalone CLI license sync / update against master server
|
||||||
if args.sync_license:
|
if args.sync_license:
|
||||||
lic_server = config.get("license_server_url", "https://logar.eibl.tech")
|
lic_server = config.get("license_server_url", "wss://logar.eibl.tech/ws/license")
|
||||||
print(f"[*] Connecting to master authority at {lic_server} via mTLS to sync license...")
|
print(f"[*] Connecting to master authority at {lic_server} via WebSocket to sync license...")
|
||||||
success, msg, new_pem = enrollment.renew_ca_cert_mtls(
|
|
||||||
cert_dir=cert_dir,
|
ca_info = {}
|
||||||
license_server_url=lic_server
|
ca_path = os.path.join(cert_dir, "ca.crt")
|
||||||
)
|
if os.path.exists(ca_path):
|
||||||
if not success or not new_pem:
|
with open(ca_path, "r", encoding="utf-8") as f:
|
||||||
print(f"[-] License sync failed: {msg}")
|
ca_info = enrollment.extract_license_info_from_cert(f.read())
|
||||||
sys.exit(1)
|
|
||||||
|
ws_url = lic_server if ("ws://" in lic_server or "wss://" in lic_server) else f"{lic_server.replace('https://', 'wss://').replace('http://', 'ws://').rstrip('/')}/ws/license"
|
||||||
|
success, msg, res = enrollment.enroll_and_sync_license_ws(
|
||||||
|
cert_dir=cert_dir,
|
||||||
|
license_id=ca_info.get("license_id"),
|
||||||
|
license_authority_ws_url=ws_url,
|
||||||
|
server_fingerprint=config.get("server_fingerprint", ""),
|
||||||
|
hostname=config.get("server_name", "")
|
||||||
|
)
|
||||||
|
|
||||||
|
if not success or not res:
|
||||||
|
# Fallback to mTLS HTTP sync
|
||||||
|
print(f"[!] WebSocket sync returned: {msg}. Falling back to mTLS renewal...")
|
||||||
|
http_url = lic_server.replace("wss://", "https://").replace("ws://", "http://").replace("/ws/license", "")
|
||||||
|
success, msg, new_pem = enrollment.renew_ca_cert_mtls(cert_dir=cert_dir, license_server_url=http_url)
|
||||||
|
if not success or not new_pem:
|
||||||
|
print(f"[-] License sync failed: {msg}")
|
||||||
|
sys.exit(1)
|
||||||
|
info = enrollment.extract_license_info_from_cert(new_pem)
|
||||||
|
new_seats = info.get("seats") or config.get("max_seats", 10)
|
||||||
|
else:
|
||||||
|
info = res.get("license_info", {})
|
||||||
|
new_seats = res.get("seats", config.get("max_seats", 10))
|
||||||
|
|
||||||
info = enrollment.extract_license_info_from_cert(new_pem)
|
|
||||||
new_seats = info.get("seats") or config.get("max_seats", 10)
|
|
||||||
config["max_seats"] = new_seats
|
config["max_seats"] = new_seats
|
||||||
conn = sqlite3.connect(config["db_path"])
|
conn = sqlite3.connect(config["db_path"])
|
||||||
conn.execute("UPDATE license_config SET max_seats = ?, license_id = ? WHERE id = 1", (new_seats, info.get("license_id")))
|
conn.execute("UPDATE license_config SET max_seats = ?, license_id = ? WHERE id = 1", (new_seats, info.get("license_id")))
|
||||||
|
|||||||
Reference in New Issue
Block a user