#!/usr/bin/env python3 """ ServerManager — GUI application for managing remote servers. """ import sys import os import subprocess # Add project root to path sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) def _find_active_xauthority(): """Find .Xauthority from the user who owns the active X display.""" # 1. Already set and works if os.environ.get("XAUTHORITY") and os.path.isfile(os.environ["XAUTHORITY"]): return os.environ["XAUTHORITY"] # 2. Search /home/*/.Xauthority for all users try: for entry in os.scandir("/home"): if entry.is_dir(): xauth = os.path.join(entry.path, ".Xauthority") if os.path.isfile(xauth): return xauth except (PermissionError, FileNotFoundError): pass # 3. Check /root/.Xauthority root_xauth = "/root/.Xauthority" if os.path.isfile(root_xauth): return root_xauth return None def _find_active_display(): """Detect active X display from running sessions.""" display = os.environ.get("DISPLAY") if display: return display # Parse from /tmp/.X11-unix sockets x11_dir = "/tmp/.X11-unix" if os.path.isdir(x11_dir): try: sockets = sorted(os.listdir(x11_dir)) for s in sockets: if s.startswith("X"): return ":" + s[1:] except PermissionError: pass # Parse from active X/xrdp/vnc processes try: result = subprocess.run( ["ps", "-eo", "args"], capture_output=True, text=True, timeout=3 ) for line in result.stdout.splitlines(): # Xorg :50 ... or Xvnc :1 ... for prefix in ("Xorg ", "Xvnc ", "Xtigervnc ", "xrdp-sesman"): if prefix in line: for part in line.split(): if part.startswith(":") and part[1:].split(".")[0].isdigit(): return part except (FileNotFoundError, subprocess.TimeoutExpired): pass return ":0" def _ensure_display_access(): """Auto-fix X display authorization for root and non-owner users.""" # Step 1: Find active display display = _find_active_display() os.environ["DISPLAY"] = display # Step 2: Find and set XAUTHORITY from display owner xauth = _find_active_xauthority() if xauth: os.environ["XAUTHORITY"] = xauth # Step 3: Try xhost to allow local connections try: subprocess.run(["xhost", "+local:"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=3) except (FileNotFoundError, subprocess.TimeoutExpired): pass # Step 4: Verify display works, try xauth merge if not try: subprocess.run(["xdpyinfo"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=3, check=True) return # Works! except (FileNotFoundError, subprocess.TimeoutExpired, subprocess.CalledProcessError): pass # Step 5: Last resort — copy xauth cookies from display owner if xauth and xauth != os.path.expanduser("~/.Xauthority"): try: subprocess.run( ["xauth", "merge", xauth], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=5 ) except (FileNotFoundError, subprocess.TimeoutExpired): pass from gui.app import App def main(): if sys.platform != "win32": _ensure_display_access() app = App() app.mainloop() if __name__ == "__main__": main()