81 Commits

Author SHA1 Message Date
Dave Kempe b5d31b13ce Add dedicated web sessions doc, fix credential docs, global policy warning
- New docs/web-sessions.md: comprehensive guide with autofill, domain
  allowlisting, login scripts (Playwright + shell examples), clipboard
  control, API reference, and troubleshooting
- Fix integrations.md: web sessions DO use credentials (for autofill
  and login scripts)
- Add global Chromium policy warning to security.md and web-sessions.md
- Add web-sessions.md to in-app docs (build.rs)
- Condense overview.md web section to link to new dedicated doc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.6.0
2026-03-07 07:30:09 +11:00
Dave Kempe a11395df7c Merge pull request #47 from sol1/dependabot/cargo/tokio-1.50.0
deps: bump tokio from 1.49.0 to 1.50.0
2026-03-07 07:20:17 +11:00
Dave Kempe 8710f45164 Merge pull request #46 from sol1/dependabot/cargo/uuid-1.22.0
deps: bump uuid from 1.21.0 to 1.22.0
2026-03-07 07:20:13 +11:00
Dave Kempe 3497d641e3 Merge pull request #45 from sol1/dependabot/cargo/toml-1.0.4spec-1.1.0
deps: bump toml from 1.0.3+spec-1.1.0 to 1.0.4+spec-1.1.0
2026-03-07 07:20:10 +11:00
Dave Kempe 5318c9d4c5 Merge pull request #41 from sol1/dependabot/github_actions/docker/setup-qemu-action-4
ci: bump docker/setup-qemu-action from 3 to 4
2026-03-07 07:18:45 +11:00
Dave Kempe 99d79fe05d v0.6.0: Web autofill, domain allowlisting, clipboard control, Guacamole import
New features:
- Native Chromium autofill: pre-populate Login Data SQLite before launch,
  zero external deps (no Node.js/Playwright needed for simple login flows)
- Per-entry domain allowlisting: restrict which domains Chromium can reach
  via --host-rules (separate from server-side web_allowed_networks CIDR)
- Per-entry clipboard control: disable-copy and disable-paste for all
  session types (SSH, RDP, VNC, Web) via guacd native parameters
- Guacamole import: `rustguac import-guacamole` parses mysqldump SQL and
  writes entries to Vault address book

Security hardening:
- Comprehensive Chromium managed policy deployed via install.sh, Dockerfile,
  and debian/postinst (blocks DevTools, downloads, file dialogs, extensions,
  dangerous URL schemes)
- Profile isolation: each web session gets a unique UUID-based profile dir
- Autofill credentials encrypted with Chromium's native os_crypt (AES-128-CBC)

Documentation:
- Updated README, docs/api.md, docs/security.md, docs/configuration.md,
  docs/overview.md, docs/integrations.md with all new features
- Clarified two-layer domain restriction (web_allowed_networks vs allowed_domains)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 00:54:26 +11:00
dependabot[bot] 5495d0346d deps: bump tokio from 1.49.0 to 1.50.0
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.49.0 to 1.50.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.49.0...tokio-1.50.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 09:22:09 +00:00
dependabot[bot] e8345b6b91 deps: bump uuid from 1.21.0 to 1.22.0
Bumps [uuid](https://github.com/uuid-rs/uuid) from 1.21.0 to 1.22.0.
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.21.0...v1.22.0)

---
updated-dependencies:
- dependency-name: uuid
  dependency-version: 1.22.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 09:21:47 +00:00
dependabot[bot] 699907445a deps: bump toml from 1.0.3+spec-1.1.0 to 1.0.4+spec-1.1.0
Bumps [toml](https://github.com/toml-rs/toml) from 1.0.3+spec-1.1.0 to 1.0.4+spec-1.1.0.
- [Commits](https://github.com/toml-rs/toml/compare/toml-v1.0.3...toml-v1.0.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 09:21:31 +00:00
dependabot[bot] 20b8d3fc4a ci: bump docker/setup-qemu-action from 3 to 4
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3 to 4.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 09:21:05 +00:00
Dave Kempe 83f3da874e Update README: add VNC, SSH jump hosts, Kerberos NLA, themes
Add missing headline features to the README feature list and
architecture diagram. Update GitHub repo description to match.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 10:07:46 +11:00
Dave Kempe 3f8e4b7716 Update aws-lc-rs 1.16.1 / aws-lc-sys 0.38.0 (fix Dependabot alerts)
Resolves PKCS7_verify signature/chain validation bypass and AES-CCM
timing side-channel vulnerabilities in aws-lc-sys.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 08:27:59 +11:00
Dave Kempe fcd164a6bf Merge patches 003+004 to fix Docker build conflict
Patches 003 (null guards) and 004 (config.h includes) both modified
disp.c and input.c, causing git apply to fail when applied sequentially
in the Docker build. Combined into a single 003-null-guard-and-config-h
patch that applies cleanly after 001 and 002.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.5.1
2026-03-04 17:27:28 +11:00
Dave Kempe 4c11d40eec Update aws-lc-rs to 1.16.1 (fixes Dependabot security alert)
Bumps aws-lc-sys from 0.37.1 to 0.38.0 via aws-lc-rs 1.16.1,
resolving the security_update_not_possible failures in Dependabot.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:17:02 +11:00
Dave Kempe 2bf34440e6 v0.5.1: RDP resize fix, new themes, Docker config persistence
- Fix RDP display resize for FreeRDP 3.x (patch 004: config.h struct layout)
- Add aurora theme (midnight blue with ambient glow gradients)
- Add jaguar theme (racing green & gold with subtle gradients)
- Add bg_pattern support for CSS gradient backgrounds in themes
- Fix Docker config.toml persistence across rebuilds (#38)
- Add Docker Compose volume mount documentation
- Increase API rate limit to 5/s burst 30 (fix spurious 429s)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:08:14 +11:00
Dave Kempe 5e158eecf4 Fix arm64 .deb: change Architecture from amd64 to any
debian/control had Architecture: amd64 hardcoded, causing
dpkg-buildpackage to skip the package entirely on arm64 hosts
("no binary artifacts found").

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.5.0
2026-03-01 16:27:39 +11:00
Dave Kempe 043e52195b Fix debian/rules: move DEB_HOST_MULTIARCH to file-scope Make variable
The := assignment was inside a recipe (tab-indented) where lines are
shell commands, not Make directives. Move to file scope with ?= so
dpkg-buildpackage can override, and Make expands it in recipe lines.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:48:43 +11:00
Dave Kempe 996faa1e4a Fix arm64 .deb build: use DEB_HOST_MULTIARCH for FreeRDP plugin path
debian/rules hardcoded x86_64-linux-gnu for the FreeRDP plugin directory,
causing empty packages on arm64 (aarch64-linux-gnu).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:24:17 +11:00
Dave Kempe ea72c52a31 v0.5.0: Theme system, ARM64 builds, Docker fixes, dependency updates
Theme system:
- 6 built-in presets (dark, light, high-contrast, terminal, nord, corporate)
- Admin configures preset + per-color overrides in [theme] config section
- Client-side theme switching via localStorage (flash-free)
- All static pages updated with 28 CSS custom properties

Proxy telemetry:
- Track which side terminated connection (guacd/browser/cancelled)
- Timing-based log levels (guacd close <5s = warning)
- Clamp session dimensions to safe ranges (width 640-8192, height 480-8192, DPI 16-384)

Docker fixes (#37):
- Fix port mismatch: Dockerfile now uses 8089 consistently
- Auto-generate admin API key on first run
- Add API key setup docs and recordings volume to compose example

ARM64 support:
- Multi-platform Docker builds (linux/amd64 + linux/arm64)
- Native ARM64 .deb and tarball builds via ubuntu-24.04-arm runner

Dependency updates:
- rustls 0.23.37, chrono 0.4.44, clap 4.5.60, toml 1.0.3
- futures-util 0.3.32, uuid 1.21.0, pulldown-cmark 0.13.1
- actions/upload-artifact v7, actions/download-artifact v8

Also: FreeRDP 3.x NULL deref patch (003), .gitignore for .playwright-mcp/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 15:05:41 +11:00
Dave Kempe f58695c7eb Fix deb config: move misplaced keys out of [recording] section (#25)
The default config.toml shipped in the .deb had db_path, static_path,
and other top-level keys placed after the [recording] header, causing
TOML to scope them under [recording] where serde silently ignored them.
The top-level db_path defaulted to ./rustguac.db which the rustguac
user cannot create in the root-owned /opt/rustguac directory.

Fixes: move all top-level keys above section headers in the template.
Adds a postinst migration that detects and repairs broken configs on
upgrade (backs up config first).

Closes #25

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.4.1 v0.4.2-rc2 v0.4.2-rc4 v0.4.2-rc3
2026-02-14 19:36:12 +11:00
Dave Kempe 066a063304 Improve RDP display sizing: match browser dimensions on connect and resize
- Send actual browser window dimensions at session creation (addressbook,
  sessions) instead of defaulting to 1920x1080
- Send initial sendSize() on WebSocket connect so guacd can resize the
  remote display via Display Update channel
- Debounce window resize handler (250ms) to avoid overwhelming RDP server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.4.0
2026-02-14 10:55:40 +11:00
Dave Kempe f8744603f8 Update dependencies: russh 0.57, toml 1.0, clap 4.5.58, libc 0.2.182
- russh 0.54 → 0.57: Marvin attack mitigation (RSA), server-side ping,
  ML-KEM post-quantum key exchange, extension algo kex fix
- toml 0.9 → 1.0: stable release
- clap 4.5.57 → 4.5.58: patch update
- libc 0.2.180 → 0.2.182: patch update
- rand stays at 0.9: rand 0.10 requires stable rand_core 0.10.0 which
  conflicts with russh 0.57's rand_core 0.10.0-rc-3 pin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:47:10 +11:00
Dave Kempe 3cb8111591 Add RDP RemoteApp/RAIL, recording rotation, per-entry recording overrides
RemoteApp/RAIL (closes #19):
- Pass remote-app, remote-app-dir, remote-app-args through to guacd
- Address book UI: collapsible RemoteApp section for RDP entries

Recording rotation:
- New [recording] config section (backwards-compatible with recording_path)
- Automatic disk-space management: max_disk_percent, max_recordings thresholds
- Background rotation task with configurable interval
- Sidecar .meta JSON files track address book entry per recording

Per-entry recording overrides:
- Address book entries can enable/disable recording and set max recordings
- Per-entry rotation runs on session disconnect
- UI: collapsible Recording Settings section for all connection types

Bump version to 0.4.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:39:25 +11:00
Dave Kempe 54c1d5be17 Security hardening: open redirect, cookie flags, constant-time auth, fuzz targets
- Fix open redirect via protocol-relative URLs (//evil.com) in OIDC next parameter
- Add Secure flag to all cookie-clearing Set-Cookie headers
- Add single-quote escaping to html_escape() (defence-in-depth)
- Cross-check OIDC state cookie against state query parameter in callback
- Switch API key and user token validation to constant-time hash comparison (subtle)
- Add 3 new fuzz targets: api_input, vault_response, websocket_message
- Bump version to 0.3.3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.3.3
2026-02-12 08:42:33 +11:00
Dave Kempe 7f454ecda0 Fix custom link port parameter: omit when unset instead of sending empty string
An empty &port= causes "invalid digit found in string" parse error.
Use {% if %} conditional to only include &port= when remote_port is set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.3.2
2026-02-11 19:26:23 +11:00
Dave Kempe 6caf1ef138 Bump version to 0.3.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:15:37 +11:00
Dave Kempe 3cf21933ea Add credential prompting for /api/connect deep-links, fix NetBox webhook docs
When an address book entry has prompt_credentials: true or no stored
credentials, /api/connect now returns an inline credential form instead
of failing or connecting without auth. The form POSTs to the existing
connect endpoint and redirects to the client page.

Fix NetBox webhook body template docs: use "type" not "session_type"
(matches Vault storage format), replace regex_replace/cut filters with
standard Jinja2 equivalents (lower, split) since NetBox's Jinja2
environment doesn't include Ansible or Django template filters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:14:53 +11:00
Dave Kempe 5331f25176 Add NetBox integration: GET /api/connect endpoint, OIDC deep-links
- New GET /api/connect quick-connect endpoint for external integrations
  - Ad-hoc mode (poweruser+): hostname/protocol/port params, redirects to client
  - Address book mode (operator+): scope/folder/entry params, credentials from Vault
  - Unauthenticated users redirected through SSO login and back automatically
- OIDC deep-link support: login handler accepts ?next= param, stores as cookie,
  callback redirects there instead of /addressbook.html after authentication
- New docs/netbox.md integration guide: Custom Fields, Custom Links with
  console_enabled/console_mode gating, webhook-driven address book sync
- Updated docs/api.md with GET /api/connect endpoint documentation
- Updated screenshots/screenshots.md with descriptions for all screenshots
- Bump version to 0.3.1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.3.1
2026-02-11 11:52:16 +11:00
Dave Kempe a2d79629c5 Bump russh 0.49 → 0.54 (CVE-2025-54804), drop russh-keys and async-trait
russh 0.54.1 fixes CVE-2025-54804 (integer overflow panic in channel
window adjust). Adapts tunnel.rs to the new API: AuthResult enum
instead of bool, native async trait instead of #[async_trait], and
keys module re-exported from russh directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.3.0
2026-02-11 08:48:15 +11:00
Dave Kempe 76c93bc502 Add multi-hop SSH tunnels, VNC sessions, and web session tunnel support
Multi-hop SSH tunnel chains allow routing any session type through
multiple bastion hosts. VNC is now a first-class session type.
Web browser sessions can tunnel through jump hosts with automatic
URL rewriting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 08:22:34 +11:00
Dave Kempe c094a91575 Add files via upload 2026-02-11 07:25:29 +11:00
Dave Kempe 45b1522432 Create screenshots.md 2026-02-11 07:25:08 +11:00
Dave Kempe e595ff437a Bump version to 0.2.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.2.2
2026-02-10 10:39:49 +11:00
Dave Kempe d07d79c4f2 Add Kerberos NLA support for RDP and credential prompting
- Patch guacd with Kerberos NLA support (002-kerberos-nla.patch),
  based on upstream GUACAMOLE-2057 PR #581, adapted for FreeRDP 3.x
- Add per-entry auth_pkg, kdc_url, and prompt_credentials settings
  to the address book (configurable in admin UI)
- Frontend credential prompt for entries without stored credentials
  or with prompt_credentials enabled (never stored, session-only)
- Wire auth-pkg, kdc-url, kerberos-cache params through rustguac
  to the guacd RDP handshake
- Comprehensive Kerberos NLA docs: krb5.conf setup, KDC discovery
  options, FQDN requirements, troubleshooting guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 10:39:18 +11:00
Dave Kempe 02f93fe67a Redesign login page: prominent SSO button, collapsible API key form
SSO button is now the primary action on the login page — larger,
bolder, and displayed first. API key login is hidden behind a
chevron toggle for admin use. Falls back to showing the API key
form directly when OIDC is not configured.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.2.1
2026-02-08 09:10:43 +11:00
Dave Kempe 8ec9a65279 Bump version to 0.2.0
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.2.0
2026-02-07 16:14:56 +11:00
Dave Kempe 2f0a41d52b Fix db.rs formatting (cargo fmt)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 16:04:16 +11:00
Dave Kempe 997b5f099c Fix auth.rs formatting (cargo fmt)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:52:28 +11:00
Dave Kempe 1b86b20fe6 Fix formatting (cargo fmt)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:11:39 +11:00
Dave Kempe a94b743d6c Add user API tokens with role-based access and audit logging
User API tokens allow OIDC users to authenticate via bearer token for
automation and scripting. Powerusers and admins can create their own
tokens; admins can create tokens for operators. Tokens use SHA-256
hashing, optional max_role caps, optional expiry, and full audit
logging of create/revoke operations with client IPs.

- DB schema: user_api_tokens and token_audit_log tables
- Auth middleware: validates user tokens as fallback after admin keys
- API: 7 new endpoints (self-service + admin token management)
- UI: tokens.html (self-service) + admin.html token/audit sections
- Nav: Tokens link added to all pages (visible for operator+)
- Docs: API reference, security model, roles/access control updated
- Background cleanup: expired tokens + 90-day audit log retention

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:02:54 +11:00
Dave Kempe 065367451b Add Default derive for InstructionParser (clippy fix)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v0.1.3
2026-02-07 14:21:40 +11:00
Dave Kempe a2bbce73ee Add guacd parser fuzz harness and document fuzzing findings
libFuzzer+ASan+UBSan harness for guac_parser_append() — the C state
machine that parses all Guacamole wire-format input in guacd. 3.2M
iterations found no memory corruption; one non-exploitable signed
integer overflow (UBSan) in the length prefix accumulator noted in
FINDINGS.md.

Also adds FINDINGS.md for the Rust protocol parser fuzzer documenting
the UTF-8 boundary panic fix from v0.1.3.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 14:17:42 +11:00
Dave Kempe 1922bd9987 Add fuzz testing infrastructure and fix UTF-8 boundary panic
Add cargo-fuzz targets for the Guacamole protocol parser:
- protocol_parse: single instruction parsing
- protocol_stream: streaming parser with chunked input

Fix panic in Instruction::parse when a length prefix splits a multi-byte
UTF-8 character (found by fuzzer within seconds). Now returns
ParseError::Truncated instead of panicking on invalid char boundary.

Run with: cargo +nightly fuzz run protocol_parse
          cargo +nightly fuzz run protocol_stream

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 13:39:16 +11:00
Dave Kempe eab04ba2bd Fix clippy type_complexity for OIDC pending flows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 12:06:47 +11:00
Dave Kempe 4e4279dc5f Bump version to 0.1.3 and fix formatting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 11:40:06 +11:00
Dave Kempe 2187cfc1e4 Security hardening: 5 fixes from audit
- Vault TLS: replace hardcoded danger_accept_invalid_certs(true) with
  configurable tls_skip_verify option (default: false)
- Share tokens: use constant-time SHA-256 hash comparison to prevent
  timing side-channel attacks
- OIDC pending states: add 10-minute TTL, evict stale entries on each
  login to prevent unbounded HashMap growth
- Recording path traversal: add canonical path validation as defense-
  in-depth alongside existing string checks
- Frontend XSS: escape all user-controlled data (filenames, paths) in
  innerHTML via escapeHtml/escapeAttr in client.html and recordings.html

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 11:34:54 +11:00
Dave Kempe 32c60469e4 Merge pull request #5 from sol1/dependabot/github_actions/actions/checkout-6
ci: bump actions/checkout from 4 to 6
2026-02-07 11:25:24 +11:00
Dave Kempe bf49438ae7 Merge pull request #6 from sol1/dependabot/github_actions/actions/upload-artifact-6
ci: bump actions/upload-artifact from 4 to 6
2026-02-07 11:25:12 +11:00
Dave Kempe 577a28dbcb Merge pull request #7 from sol1/dependabot/github_actions/actions/download-artifact-7
ci: bump actions/download-artifact from 4 to 7
2026-02-07 11:25:00 +11:00
Dave Kempe 177dbda605 Merge pull request #14 from sol1/dependabot/cargo/rcgen-0.14.7
deps: bump rcgen from 0.13.2 to 0.14.7
2026-02-07 11:24:00 +11:00