Metadata-Version: 2.4
Name: remote-desktop-dashboard
Version: 0.1.0
Summary: Python browser dashboard for reserving, locking, and launching shared Windows Remote Desktop machines, with per-IP firewall lockdown over WinRM.
Author: Remote Desktop Dashboard Contributors
License: MIT
Project-URL: Homepage, https://pypi.org/project/remote-desktop-dashboard/
Keywords: rdp,remote-desktop,dashboard,winrm,firewall,reservation,windows
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Web Environment
Classifier: Framework :: FastAPI
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi
Requires-Dist: uvicorn[standard]
Requires-Dist: jinja2
Requires-Dist: python-multipart
Dynamic: license-file

# Remote Desktop Dashboard

A Python-based, browser-driven dashboard for managing a pool of shared **Windows** machines:
see every machine, see who is using which one, **reserve / lock** a machine so others can't grab
it, and connect with one click. When a machine is reserved, the dashboard pushes a **per-IP
firewall lockdown** to the target over WinRM so only the reserver can RDP in — native `mstsc.exe`
from anyone else is dropped at the network layer.

## Install

```powershell
pip install remote-desktop-dashboard
remote-desktop-dashboard
```

The dashboard opens at http://127.0.0.1:8000. It binds to `0.0.0.0` so other laptops on your LAN
can reach it via the host machine's IP (use the host's LAN address, **not** `localhost`, so the
server can read each user's real client IP for the firewall rules).

## How it relates to the build spec

The reference spec calls for a clientless **Apache Guacamole** HTML5 gateway that streams the
desktop *inside* the browser. That requires standing up `guacd` + the Guacamole web app as
separate infrastructure. This tool implements the same **enforcement principle** — the dashboard
is the sole legitimate gatekeeper and every other path is blocked at the host firewall — but using
a **zero-infrastructure** model suited to a single Windows host on a LAN:

| Spec component | This tool |
| --- | --- |
| Clientless HTML5 gateway (Guacamole) | One-click local `mstsc.exe` launch + downloadable `.rdp` fallback |
| Per-IP firewall lockdown to the gateway | Per-IP firewall lockdown to the **reserver's** client IP, pushed over WinRM |
| Backend records intent, executes on endpoint | Reservation records firewall status (`applied`/`failed`/`disabled`/`skipped`) + allowed IP |
| Reservation / lock & release | One active reservation per machine, auto-released on expiry |
| Audit-style visibility | Live session view via `quser`, tool-activity + serial-port probes, audit-style reservation log |

Swapping in a true Guacamole gateway for in-browser streaming is the natural extension point.

## Features

- Dark dashboard with machine list, sectioned detail card, admin modal, and audit log.
- SQLite persistence under `%LOCALAPPDATA%\RemoteDesktopDashboard\data` by default on Windows.
- One active reservation per machine, auto-released on expiry.
- One-click local `mstsc.exe` launch with a downloadable `.rdp` fallback (clipboard, drives, USB,
  printers, smart cards, audio, multi-monitor, dynamic resolution, keyboard hook, font smoothing
  all enabled).
- **Live machine detail card** with four sections:
  - **Status** — reservation, firewall lock, allowed IP, auto-release time.
  - **Sessions** — every row from `quser`: console (physical) user + every RDP user, each tagged.
  - **Tool activity** — remote `Get-CimInstance Win32_Process` over WinRM showing who is running
    `ETGui.exe`, `ETOU.exe`, `MobaXterm.exe`, `MobaXterm_Personal.exe`, and `putty.exe`.
  - **Serial ports** — live list of COM ports on the target host.
- **Favorites** — per-browser favourite machines (localStorage), pinned to the top, with
  "★ Favorites only" / "Free only" filter chips.
- **Windows firewall lockdown ON by default**: on reservation, the target's port 3389 is
  restricted to the reserver's IP and an explicit Block-Other-RDP rule is pushed.
- Per-machine **Verify lock** + **Diagnose** buttons return structured WinRM/ping/firewall reports.
- Admin PIN gate with single browser-session unlock and bulk delete/release/refresh controls.
- Admin modal split into Settings, Inventory, and Manage Machines tabs.

## Configuration

| Setting | Default | Override env var |
| --- | --- | --- |
| Admin PIN | `admin` | `ADMIN_PIN` |
| Bind host | `0.0.0.0` | `RDD_HOST` |
| Browser launch host | `127.0.0.1` | `RDD_BROWSER_HOST` |
| Port | `8000` | `RDD_PORT` |
| Data dir | `%LOCALAPPDATA%\RemoteDesktopDashboard\data` | `RDD_DATA_DIR` |
| Default domain | `EU` | `RDP_DOMAIN` |
| Firewall lock | ON | `RDD_ENFORCE_WINDOWS_FIREWALL=0` to disable |
| Background session refresh | ON | `RDD_AUTO_REFRESH_SESSIONS=0` to disable |
| Session refresh interval | 30s | `RDD_SESSION_REFRESH_SECONDS` |
| Firewall PowerShell timeout | 20s | `RDD_FIREWALL_TIMEOUT_SECONDS` |
| Auto-open browser | yes | `RDD_OPEN_BROWSER=0` to disable |

You can also toggle the firewall lock at runtime from **Admin → Settings → RDP lock ON/OFF**
(persisted in SQLite).

## How the native-RDP block works

When RDP lock is ON, on every reservation the dashboard runs the following on the target over WinRM:

1. Tighten every inbound `Remote Desktop` rule's `RemoteAddress` filter to the reserver's IP.
2. Add `RDD-Block-Other-RDP` (Block, TCP 3389, RemoteAddress=Any).
3. Add `RDD-Block-Other-RDP-Allow` (Allow, TCP 3389, RemoteAddress=<reserver IP>).

On release/revoke/delete those `RDD-*` rules are removed and the Remote Desktop rules are restored
to `RemoteAddress=Any`.

Requirements for this to actually block native RDP:

- The dashboard host is Windows and runs as a user that can `Invoke-Command` on the targets.
- WinRM (`winrm quickconfig` / `Enable-PSRemoting`) is enabled on every target.
- Users open the dashboard via the server's LAN hostname/IP, **not** `localhost`.

Use **Admin → Manage Machines → Verify lock / Diagnose** to confirm the lock and read the exact
WinRM/ping/firewall state.

## Development

```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
uvicorn remote_desktop_dashboard.main:app --reload --host 0.0.0.0 --port 8000
```

## Out of scope (extension points)

Multi-gateway/HA, true Guacamole in-browser streaming, session recording, scheduled/timed
reservations, calendar booking, and Active Directory group sync are not built in.

## License

MIT
