221 Commits

Author SHA1 Message Date
Dave Kempe 22c3638d00 cargo fmt v1.5.2 2026-04-09 21:26:13 +10:00
Dave Kempe 958b675fd2 SSH tunnel: host key verification with UI-driven pinning
check_server_key no longer blindly accepts all keys. Jump hosts now
support a host_key field stored in Vault alongside credentials.

- New POST /api/ssh/probe-host-key endpoint probes an SSH server and
  returns its public key, fingerprint, and algorithm
- Address book UI: "Verify Host Key" button per jump host probes the
  server, shows fingerprint for confirmation, stores key on save
- TunnelHandler verifies the server key against the stored key on
  connect — rejects with detailed error on mismatch
- Unpinned keys accepted with TOFU warning log for backward compat
- host_key preserved through credential merging on entry update

Closes #95
2026-04-09 21:22:36 +10:00
Dave Kempe f43738f54a H.264: remove frame dropping, sync gating approach only
Frame dropping at queue depth 5 triggered during normal operation and
broke the H.264 reference chain, corrupting output until the next
keyframe. Remove frame dropping entirely — sync gating alone provides
sufficient flow control by delaying the sync response until decodes
complete, giving guacd accurate backpressure.
v1.5.1
2026-04-09 07:59:03 +10:00
Dave Kempe 175c30b705 H.264: fix unbounded stream lag via sync gating and frame dropping
The H.264 decode path bypassed the Guacamole sync mechanism — the sync
response fired immediately without waiting for WebCodecs to finish
decoding. guacd thought the client was keeping up and sent at full rate,
causing the decode queue to grow without bound (30+ seconds of lag
observed over time).

Fix: gate the sync response on H.264 decode completion so guacd gets
real backpressure. Also drop delta frames when the decode queue exceeds
5 frames as a safety valve for transient overload (tab backgrounding).

- Add pending-decode tracking and per-frame position capture to
  H264Decoder.js (fixes shared mutable state race)
- Add waitForPending() with 1s safety timeout for sync gating
- Add frame dropping when decodeQueueSize > 5 (never drops keyframes)
- Add stats() method for console debugging (__guac_client._h264Decoder.stats())
- Gate sync response in Client.js on H.264 decode completion

Closes #93
2026-04-08 07:21:23 +10:00
Dave Kempe 2e046ea4a8 OIDC: native CA trust, custom CA cert, TLS skip-verify, better errors
Switch reqwest from rustls-tls-webpki-roots to rustls-tls-native-roots
so the OS trust store is used by default — private CAs installed
system-wide now work without extra config.

Add ca_cert and tls_skip_verify options to [oidc] for environments
where the system store isn't available or for debugging TLS issues.
Improve OIDC discovery error formatting to surface the actual cause
(issuer mismatch, TLS failure, etc.) instead of opaque "Request failed".

Closes #94
2026-04-08 06:31:14 +10:00
Dave Kempe 5c7eb84886 README overhaul: badges, VDI, updated features, remove RHEL
- GitHub badges (CI, release, license, Docker pulls)
- VDI featured in architecture, features, and quick start
- Feature tables for session types, security, connectivity
- Removed RPM/RHEL references (build from source for others)
- Complete docs index with all current pages
- Cleaner quick start with Docker+VDI instructions
2026-04-06 08:25:00 +10:00
Dave Kempe 75eae2b43f cargo fmt v1.5.0 2026-04-05 10:33:01 +10:00
Dave Kempe fb0f965bb2 Fix nav: Logout + Settings float right together on all pages
Logout link moved inside the float-right user-menu-wrapper so both
Logout and Settings appear on the far right of the nav bar. Fixed
addressbook.html Settings font size to match other pages (1.3em).
2026-04-05 10:20:10 +10:00
Dave Kempe 318725e8db Config docs: add [recording] and [vdi] sections, missing fields
- [recording] section: enabled, max_disk_percent, max_recordings, rotation
- [vdi] section: full reference with all 8 fields, prerequisites link
- Added missing top-level fields: rate_limit, session_history_retention_days
2026-04-05 10:03:06 +10:00
Dave Kempe c48be9ed3f Move Logout button out of Settings dropdown on all pages
Logout is now a standalone nav link next to Settings (Logout Settings
order, right-aligned). Applied consistently across all 7 HTML pages.
Removed Logout from the settings dropdown menu.
2026-04-05 10:01:35 +10:00
Dave Kempe a9a966e675 VDI: detect image change and clear stale thumbnails
- start_or_reuse checks if existing container's image differs from
  the requested image. If so, stops the old container and creates
  a new one with the new image.
- Clear stale VDI thumbnail when starting a new session, so old
  screenshots don't linger from previous images/failed sessions.
2026-04-05 08:33:42 +10:00
Dave Kempe 7283cdb2d7 Dockerfile: VDI support (commented out, documented)
- Run example with Docker socket mount and group-add for VDI
- Commented-out [vdi] section in default config template
- vdi-homes directory and volume for persistent home dirs
- No changes to default behavior — VDI stays disabled unless configured
2026-04-05 08:29:21 +10:00
Dave Kempe 6a2a759abf Docs: VDI prerequisites — Docker install and usermod instructions
Installation guide and VDI docs page now document that Docker must be
installed separately and rustguac user added to docker group manually.
2026-04-05 08:27:21 +10:00
Dave Kempe 985a9de45c Overview docs: add VDI references throughout
VDI mentioned alongside SSH/RDP/VNC/Web in: intro, why section,
similarities, architecture description, tunnel section.
2026-04-05 08:16:57 +10:00
Dave Kempe 9114e2b78e Add VDI to overview docs page
Architecture diagram, session type section, comparison table,
project structure, and docs index updated with VDI references.
2026-04-05 08:13:56 +10:00
Dave Kempe 3d39685f58 Add VDI documentation page
Comprehensive docs covering: config, image requirements, address book
setup, container lifecycle, persistent homes, active sessions,
per-entry settings, security notes.
2026-04-05 08:11:00 +10:00
Dave Kempe c0e194fa6a v1.5.0: VDI Docker desktop containers
Major release adding ephemeral Docker desktop containers (VDI), session
thumbnails with active sessions UI, and session-ended overlay.

VDI:
- New session type: VDI (Docker) — per-user ephemeral desktop containers
- VdiDriver trait for downstream extensibility (JumpboxVDI)
- DockerDriver: bollard API, deterministic naming, start/reuse/stop
- Container lifecycle: persist after disconnect, reap after idle timeout
- Per-entry idle timeout override via address book
- Persistent home dirs via bind mount (home_base config)
- Server disconnect detection (10.disconnect;) stops container on logout
- Test image: contrib/vdi-test-image (Debian + xrdp + xfce4)

Thumbnails & Active Sessions:
- Client captures display screenshot every 10s (JPEG, 320px)
- Active Sessions section in address book with thumbnail grid
- Dormant VDI containers shown with last captured thumbnail
- Click thumbnail to reconnect via address book connect flow

UI:
- Session ended overlay with Reconnect/Close buttons (all session types)
- Sessions page: collapsible ad-hoc form, VDI option
- Logout button moved out of settings dropdown

Security:
- Thumbnail endpoints require authentication
- JPEG magic byte validation on upload
- Path traversal protection on container thumbnails
- Env var name/value validation for containers
- Home base path traversal check

Dependencies:
- Added bollard 0.18 (Docker API client)
- Updated russh 0.59, tokio 1.51, toml 1.1.2, libc 0.2.184
2026-04-05 08:09:02 +10:00
Dave Kempe bf19574a0d Update docs: VDI architecture in CLAUDE.md, test image README
- CLAUDE.md: VDI session type, Docker architecture, VdiDriver trait,
  container lifecycle, config options, test image reference
- contrib/vdi-test-image/README.md: build, usage, image requirements
- Fix: RDP was missing from session types description
2026-04-05 08:07:07 +10:00
Dave Kempe b5566f7ce8 Security hardening for VDI and thumbnails
- Move thumbnail endpoints to authenticated routes (was unauthenticated)
- Validate JPEG magic bytes on thumbnail upload
- Require session to exist before accepting thumbnail
- Path traversal protection on VDI container thumbnail endpoint
- Validate container env var names (alphanumeric + underscore only)
- Reject env var values containing newlines
- Path traversal check on home_base bind mount
2026-04-05 08:05:34 +10:00
Dave Kempe 8567d93c4f Sessions page: collapsible ad-hoc form, VDI option
- New Session form collapsed by default (click to expand)
- Added VDI (Docker) to session type dropdown with container image field
- Jump hosts hidden for VDI sessions (local containers)
2026-04-05 07:59:38 +10:00
Dave Kempe 3273e47bbc VDI: per-entry idle timeout for containers
Address book entries can now set container_idle_timeout_mins to override
the global idle_timeout_mins. Stored as a Docker label on the container
so the reaper reads it without needing session state. Reaper also cleans
up VDI thumbnails when removing idle containers.
2026-04-05 07:55:50 +10:00
Dave Kempe 697b6f7d75 Active Sessions with thumbnails, dormant VDI containers
Client captures display thumbnail every 10s (JPEG, 320px), uploads
to server. Address book shows "Active Sessions" section with thumbnail
grid — click to reconnect via address book connect flow.

- PUT/GET /api/sessions/{id}/thumbnail endpoints
- GET /api/vdi/containers — list running VDI containers for current user
- VDI container labels: rustguac.entry, rustguac.image for reconnect
- Thumbnail copied to container-keyed file on disconnect (persists)
- Dormant VDI containers shown with last thumbnail
- Cache-busting on thumbnail images for live updates
- Moved logout button out of settings dropdown
- Fixed: VDI containers endpoint in authenticated route group
- Fixed: thumbnail click uses address book connect (not stale session URL)
2026-04-05 07:51:00 +10:00
Dave Kempe 8ff256f5df Session ended overlay with Reconnect/Close buttons
Show a centered overlay when the Guacamole client disconnects or
errors, instead of leaving a frozen canvas. Offers Reconnect (reload)
and Close (navigate to home) buttons. Applies to all session types.
2026-04-05 07:18:26 +10:00
Dave Kempe bfadf34a9b VDI: detect server-side disconnect to stop container on logout
Sniff for guacd's 10.disconnect; instruction in the proxy stream to
distinguish server-initiated disconnects (user logout, crash) from
browser-initiated disconnects (tab close, network drop).

- Logout from desktop → container stopped and removed immediately
- Tab close / network drop → container persists for reconnection
- Normal RDP/SSH/VNC sessions unaffected (flag only acted on for VDI)
2026-04-05 07:03:34 +10:00
Dave Kempe 690997d4eb VDI: persistent home dirs and logout stops container
- Add home_base config: bind-mounts {home_base}/{username} into container
  so user files persist across container restarts
- When guacd ends the connection (user logout / session crash), stop and
  remove the VDI container immediately
- Browser disconnect (tab close, network drop) keeps container running
  for reconnection — idle reaper handles eventual cleanup
2026-04-05 06:44:33 +10:00
Dave Kempe 501bd14a0d VDI Docker driver: ephemeral container desktops
Add 5th session type (Vdi) that spawns Docker containers with xrdp
and connects via RDP through guacd. Containers persist after disconnect
for configurable idle timeout, allowing reconnection to same desktop.

- VdiDriver trait (dyn-compatible) for downstream extensibility
- DockerDriver: bollard API, deterministic container naming per user,
  start/reuse/stop lifecycle, TCP+settle readiness polling
- Background reaper removes idle containers after timeout
- Address book: container_image, cpu/mem limits, env vars fields
- Config: [vdi] section with enabled, docker_socket, limits, timeouts
- Test image: contrib/vdi-test-image (Debian trixie + xrdp + xfce4)
2026-04-05 06:28:03 +10:00
Dave Kempe bcf203e79a Merge pull request #91 from sol1/dependabot/cargo/libc-0.2.184
deps: bump libc from 0.2.183 to 0.2.184
2026-04-04 06:06:54 +00:00
Dave Kempe e6a4aded80 Merge pull request #92 from sol1/dependabot/cargo/toml-1.1.2spec-1.1.0
deps: bump toml from 1.1.0+spec-1.1.0 to 1.1.2+spec-1.1.0
2026-04-04 06:06:47 +00:00
Dave Kempe 9d201bcf00 Merge pull request #89 from sol1/dependabot/cargo/tokio-1.51.0
deps: bump tokio from 1.50.0 to 1.51.0
2026-04-04 06:06:42 +00:00
Dave Kempe fabf6b75a7 Merge pull request #90 from sol1/dependabot/cargo/russh-0.59.0
deps: bump russh from 0.58.1 to 0.59.0
2026-04-04 06:06:15 +00:00
dependabot[bot] f0d28a8498 deps: bump toml from 1.1.0+spec-1.1.0 to 1.1.2+spec-1.1.0
Bumps [toml](https://github.com/toml-rs/toml) from 1.1.0+spec-1.1.0 to 1.1.2+spec-1.1.0.
- [Commits](https://github.com/toml-rs/toml/compare/toml-v1.1.0...toml-v1.1.2)

---
updated-dependencies:
- dependency-name: toml
  dependency-version: 1.1.2+spec-1.1.0
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-03 09:17:18 +00:00
dependabot[bot] 81a75fd783 deps: bump libc from 0.2.183 to 0.2.184
Bumps [libc](https://github.com/rust-lang/libc) from 0.2.183 to 0.2.184.
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.184/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.183...0.2.184)

---
updated-dependencies:
- dependency-name: libc
  dependency-version: 0.2.184
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-03 09:17:07 +00:00
dependabot[bot] addbd8d6b9 deps: bump russh from 0.58.1 to 0.59.0
Bumps [russh](https://github.com/warp-tech/russh) from 0.58.1 to 0.59.0.
- [Release notes](https://github.com/warp-tech/russh/releases)
- [Commits](https://github.com/warp-tech/russh/commits/v0.59.0)

---
updated-dependencies:
- dependency-name: russh
  dependency-version: 0.59.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-03 09:16:55 +00:00
dependabot[bot] 178964e85a deps: bump tokio from 1.50.0 to 1.51.0
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.50.0 to 1.51.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.50.0...tokio-1.51.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.51.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-03 09:16:43 +00:00
Dave Kempe faf941eb06 Pin guacamole-server to known-good commit 2980cf0
Upstream GUACAMOLE-2221 introduced -Werror=maybe-uninitialized failure.
Pin all build paths (CI, Dockerfile, install.sh) to last known-good commit.
Update guacd version deliberately, not on every upstream push.
v1.0.2
2026-04-01 10:33:48 +11:00
Dave Kempe 836db3c9ec Fix window title: entry name persists after site_title loads 2026-04-01 09:39:50 +11:00
Dave Kempe 5d938c6009 v1.0.2: entry name in window title, recordings page enriched 2026-04-01 09:21:33 +11:00
Dave Kempe 9f7cc820dc Recordings page: show entry/user/type/folder, search, sortable columns 2026-04-01 08:59:51 +11:00
Dave Kempe ef1f194838 Show address book entry name in session window title 2026-03-31 15:55:12 +11:00
Dave Kempe 06250475bd Docker: fix FreeRDP plugin name (guac-common-svc.so symlink) and deterministic paths
FreeRDP loads plugins by short name ('guac-common-svc') which resolves
to 'guac-common-svc.so', but guacamole-server installs it as
'libguac-common-svc-client.so'. Create symlink with expected name.

Also: removed find-based plugin discovery, use deterministic paths.
Closes #87.
v1.0.1
2026-03-31 06:54:09 +11:00
Dave Kempe 33105d9670 Docs: RPM is build-from-source only, not pre-built 2026-03-30 21:35:06 +11:00
Dave Kempe 9f123cb331 v1.0.1: field name fix, centered login, Docker plugin fix
- Fix enable_desktop_composition field name mismatch in address book JS
- Center login panel on index page
- Docker: improved FreeRDP plugin discovery with debug output (#87)
- Docs: updated for merged setup script, Desktop Composition clarified
- contrib/setup-xrdp-gfx.sh: major rewrite (merged audio, --desktop,
  --diagnose, --help, MATE default, PipeWire switch, phase ordering)
2026-03-30 21:23:54 +11:00
Dave Kempe fbd470048b Center login panel on index page 2026-03-30 21:21:05 +11:00
Dave Kempe 6188c026e3 Docs: Desktop Composition is Windows-only, not needed for xrdp 2026-03-30 21:19:34 +11:00
Dave Kempe 5ef1049a19 Fix enable_desktop_comp field name mismatch (should be enable_desktop_composition) 2026-03-30 21:19:04 +11:00
Dave Kempe bcb376e2d7 Update docs for merged setup script (single command, --desktop flag) 2026-03-30 21:18:05 +11:00
Dave Kempe 74863326cb setup-xrdp-gfx.sh: install firefox-esr and chromium with desktop 2026-03-30 20:22:07 +11:00
Dave Kempe 3c6616fb78 setup-xrdp-gfx.sh: verify/create autostart for xrdp audio module 2026-03-30 19:10:47 +11:00
Dave Kempe 140be13389 setup-xrdp-gfx.sh: add --help with option docs and phase overview 2026-03-30 19:00:32 +11:00
Dave Kempe a8be5360f2 setup-xrdp-gfx.sh: split --diagnose into user/root sections 2026-03-30 18:59:44 +11:00