- Allow dead_code on module (used via CLI subcommand, not direct calls)
- Simplify bool toggle: in_quote = !in_quote
- Use iterator instead of index loop in deduplicate_names
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
- 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>
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>
- 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>
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>
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>
- 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>
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>
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>
- 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>
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>
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>