#!/usr/bin/env python3 """Emergency Sunshine pairing bypass — extract client cert from log and inject into state file. Sunshine v2026.516.143833 has a broken PIN validation pipeline. The /api/pin endpoint deadlocks internally even when IP addresses match. This script: 1. Reads the most recent /pair request's clientcert from sunshine.log 2. Decodes the hex-encoded PEM cert 3. Injects it directly into sunshine_state.json as a pre-paired named_device 4. Restarts Sunshine After running, Moonlight must be FULLY CLOSED AND REOPENED — it will see the pre-paired cert and skip the PIN screen. Usage: python3 pairing-bypass-inject-cert.py [--restart] Requirements: - Root not needed (Sunshine runs as the same user) - sunshine_state.json must be writable - Moonlight must have sent at least one /pair request (visible in sunshine.log) """ import json import re import uuid import sys import os import subprocess import time SUNSHINE_LOG = os.path.expanduser("~/.config/sunshine/sunshine.log") SUNSHINE_STATE = os.path.expanduser("~/.config/sunshine/sunshine_state.json") SUNSHINE_CONF = os.path.expanduser("~/.config/sunshine/sunshine.conf") def extract_latest_cert(): with open(SUNSHINE_LOG, "r", encoding="utf-8", errors="replace") as f: content = f.read() matches = re.findall(r'clientcert -- ([0-9a-fA-F]+)', content) if not matches: print("ERROR: No clientcert found in sunshine.log") print("Make sure Moonlight has tried to pair (it should show a PIN screen)") sys.exit(1) hex_cert = matches[-1] pem_cert = bytes.fromhex(hex_cert).decode("utf-8") print(f"Extracted certificate ({len(pem_cert)} bytes)") print(f"Preview: {pem_cert[:60]}...") return pem_cert def inject_cert(pem_cert, client_name="RE-PC"): try: with open(SUNSHINE_STATE, "r") as f: state = json.load(f) except (FileNotFoundError, json.JSONDecodeError): state = {} if "root" not in state: state["root"] = {"uniqueid": "0123456789ABCDEF", "named_devices": []} if "named_devices" not in state["root"]: state["root"]["named_devices"] = [] # Check if client already exists — update cert updated = False for dev in state["root"]["named_devices"]: if dev.get("name") == client_name: dev["cert"] = pem_cert dev["enabled"] = "true" updated = True print(f"Updated existing client '{client_name}'") break if not updated: state["root"]["named_devices"].append({ "name": client_name, "cert": pem_cert, "uuid": str(uuid.uuid4()).upper(), "enabled": "true" }) print(f"Added new client '{client_name}'") # Ensure origin_pin_allowed = pc for easier future pairing try: with open(SUNSHINE_CONF, "r") as f: conf = f.read() if "origin_pin_allowed" not in conf: with open(SUNSHINE_CONF, "a") as f: f.write("\norigin_pin_allowed = pc\n") print("Added origin_pin_allowed = pc to sunshine.conf") except FileNotFoundError: pass with open(SUNSHINE_STATE, "w") as f: json.dump(state, f, indent=4) print(f"Injected into {SUNSHINE_STATE}") def restart_sunshine(): print("Restarting Sunshine...") subprocess.run(["systemctl", "--user", "restart", "sunshine"], check=False) time.sleep(3) result = subprocess.run( ["systemctl", "--user", "status", "sunshine", "--no-pager"], capture_output=True, text=True ) if "active (running)" in result.stdout: print("Sunshine is running.") else: print("WARNING: Sunshine may not have started. Check: systemctl --user status sunshine") def main(): restore = "--restart" in sys.argv cert = extract_latest_cert() inject_cert(cert, client_name=os.environ.get("MOONLIGHT_CLIENT_NAME", "RE-PC")) if restore: restart_sunshine() else: print("\nNow restart Sunshine: systemctl --user restart sunshine") print("\nIMPORTANT: Fully CLOSE Moonlight on the client, then reopen it.") print("It should connect directly to apps without asking for a PIN.") if __name__ == "__main__": main()