Metadata-Version: 2.4
Name: remote-desktop-dashboard
Version: 0.2.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. Connecting is **brokered** — the dashboard launches the session and
never hands out a reusable `.rdp` file. Access is enforced on the host through a configurable
**enforcement mode** (the real "teeth"; a browser app alone cannot stop native `mstsc.exe`).

## What's new in 0.2.0

- **No more `.rdp` download.** Connect now launches an ephemeral, single-use session file that is
  deleted seconds after `mstsc` reads it — nothing reusable is ever handed to the user.
- **Three enforcement modes** (Admin → Settings, or `RDD_ENFORCEMENT`):
  - `firewall` — lock the target's TCP 3389 to the current holder's IP (per-IP rules over WinRM). *Strongest.*
  - `rdp-toggle` — no per-IP firewall edits; RDP is enabled on the host only while it's reserved, disabled when free. *Answers "how do you control without firewall rules."*
  - `advisory` — reservation lock only; **no host enforcement** (native RDP is honestly *not* blocked).
- **Real audit log** (`audit_log` table): reserve, connect, release, force-release, add/delete machine, onboarding, and mode changes are all recorded with actor + timestamp.
- **Admin force-release** to override a stuck/abandoned hold, and a guided **Onboard** action that tests connectivity, applies the secured baseline for the active mode, and marks the machine `secured`/`failed`.

## 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) | Brokered, ephemeral `mstsc.exe` launch — no reusable `.rdp` file is created |
| Per-IP firewall lockdown to the gateway | Per-IP firewall lockdown to the **holder's** IP (`firewall` mode), or host-level RDP on/off (`rdp-toggle` mode), pushed over WinRM |
| Backend records intent, executes on endpoint | Reservation records enforcement status (`applied`/`failed`/`advisory`/`skipped`) + allowed IP; every action lands in the audit log |
| Reservation / lock & release | One active reservation per machine, auto-released on expiry; admin **force-release** |
| Onboarding (admin) | Connectivity test → apply secured baseline for the active mode → mark `secured`/`failed` |
| Audit log | Real `audit_log` table; plus live session view via `quser`, tool-activity + serial-port probes |

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 **brokered** `mstsc.exe` launch — an ephemeral, single-use connection file (clipboard,
  drives, USB, printers, smart cards, audio, multi-monitor, dynamic resolution, keyboard hook, font
  smoothing all enabled) is written, consumed, and deleted; nothing is handed to the user.
- **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` |
| Enforcement mode | `firewall` | `RDD_ENFORCEMENT=firewall\|rdp-toggle\|advisory` |
| 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 switch the enforcement mode at runtime from **Admin → Settings** (persisted in SQLite),
and run **Admin → Manage Machines → Onboard / Force-release** per machine.

## 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
