Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ The `jump_hosts` array defines an ordered chain of SSH bastion hops. Each hop co
| `session_type` | string | All | `ssh`, `rdp`, `vnc`, `spice`, `proxmox`, `web`, or `vdi` (required) |
| `hostname` | string | SSH, RDP, VNC | Target hostname or IP |
| `port` | integer | SSH, RDP, VNC | Target port (defaults: SSH=22, RDP=3389, VNC=5900) |
| `username` | string | SSH, RDP | Username for authentication |
| `username` | string | SSH, RDP, VNC | Username for authentication (VNC: only for servers with username auth, e.g. VeNCrypt, RealVNC, macOS) |
| `password` | string | SSH, RDP, VNC | Password (VNC uses this as the VNC password) |
| `private_key` | string | SSH | OpenSSH PEM private key |
| `generate_keypair` | boolean | SSH | Generate an ephemeral Ed25519 keypair |
Expand Down Expand Up @@ -553,7 +553,7 @@ Create a connection entry. The body includes a `name` field plus all entry field
| `type` | string | All | `ssh`, `rdp`, `vnc`, `spice`, `proxmox`, `web`, or `vdi` |
| `hostname` | string | SSH, RDP, VNC | Target hostname or IP |
| `port` | integer | SSH, RDP, VNC | Target port |
| `username` | string | SSH, RDP | Username |
| `username` | string | SSH, RDP, VNC | Username |
| `password` | string | SSH, RDP, VNC | Password |
| `private_key` | string | SSH | OpenSSH PEM private key |
| `url` | string | Web | Target URL |
Expand Down
2 changes: 1 addition & 1 deletion docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Supports optional [multi-hop SSH tunnel chains](#ssh-tunnel--jump-hosts) and [Ke

### VNC

Connects guacd to a target VNC server. Supports password-based authentication. Useful for accessing existing VNC servers on the network (e.g., KVM/IPMI consoles, remote desktops, virtual machine displays).
Connects guacd to a target VNC server. Supports password-based authentication, plus username + password for servers that require it (VeNCrypt, RealVNC, macOS Screen Sharing). Useful for accessing existing VNC servers on the network (e.g., KVM/IPMI consoles, remote desktops, virtual machine displays).

Supports optional [multi-hop SSH tunnel chains](#ssh-tunnel--jump-hosts) to reach VNC targets through bastion hosts.

Expand Down
3 changes: 3 additions & 0 deletions src/guacd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ pub struct SshParams {
pub struct VncParams {
pub hostname: String,
pub port: u16,
/// Only used by servers with username auth (VeNCrypt, RealVNC, macOS).
pub username: Option<String>,
pub password: Option<String>,
pub color_depth: Option<u8>,
pub width: u32,
Expand Down Expand Up @@ -322,6 +324,7 @@ pub async fn connect_and_handshake(
"width" => p.width.to_string(),
"height" => p.height.to_string(),
"dpi" => p.dpi.to_string(),
"username" => p.username.clone().unwrap_or_default(),
"password" => p.password.clone().unwrap_or_default(),
"color-depth" => p.color_depth.map_or("24".into(), |d| d.to_string()),
"cursor" => "local".into(),
Expand Down
2 changes: 2 additions & 0 deletions src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,7 @@ impl SessionManager {
let params = guacd::ConnectionParams::Vnc(guacd::VncParams {
hostname: connect_host,
port,
username: req.username.clone().filter(|u| !u.is_empty()),
password: req.password.clone(),
color_depth: req.color_depth,
width,
Expand Down Expand Up @@ -1436,6 +1437,7 @@ impl SessionManager {
let params = guacd::ConnectionParams::Vnc(guacd::VncParams {
hostname: "127.0.0.1".into(),
port: 0, // placeholder — updated after browser spawn
username: None,
password: None,
color_depth: None,
width,
Expand Down
17 changes: 11 additions & 6 deletions static/connections.html
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,9 @@ <h3 id="entry-modal-title">New Entry</h3>
<label>Port
<input type="number" id="em-vnc-port" value="5900">
</label>
<label>Username <span style="color:var(--text-muted);font-size:0.85em">(optional, for VeNCrypt / RealVNC / macOS)</span>
<input type="text" id="em-vnc-username">
</label>
<label>Password
<div class="pw-wrap"><input type="password" id="em-vnc-password"><button type="button" class="pw-toggle" onclick="togglePw(this)" title="Show/hide">&#9679;</button></div>
</label>
Expand All @@ -624,7 +627,7 @@ <h3 id="entry-modal-title">New Entry</h3>
<label style="margin-top:0.8em">
<input type="checkbox" id="em-vnc-prompt-creds" style="display:inline;width:auto;margin-right:0.4em"> Prompt for credentials at connect time
</label>
<div class="field-hint">When enabled, users will be asked for a password even if one is stored.</div>
<div class="field-hint">When enabled, users will be asked for credentials even if they are stored.</div>
</div>
<div id="em-spice-fields" style="display:none">
<label>Hostname
Expand Down Expand Up @@ -2835,15 +2838,13 @@ <h3 id="cred-modal-title">Enter Credentials</h3>
var isRdp = entry.session_type === 'rdp';
var isVnc = entry.session_type === 'vnc';
document.getElementById('cred-domain-row').style.display = isRdp ? '' : 'none';
// VNC has password only — hide username row
document.getElementById('cred-username-row').style.display = isVnc ? 'none' : '';
// Pre-fill username if the entry has one stored
document.getElementById('cred-username').value = isVnc ? '' : (entry.username || '');
// Pre-fill username if the entry has one stored (optional for VNC)
document.getElementById('cred-username').value = entry.username || '';
document.getElementById('cred-password').value = '';
document.getElementById('cred-domain').value = entry.domain || '';
document.getElementById('cred-error').textContent = '';
document.getElementById('cred-modal').classList.add('active');
// Focus password if username is pre-filled or VNC, otherwise focus username
// Focus password if username is pre-filled or optional (VNC), otherwise focus username
if (entry.username || isVnc) {
document.getElementById('cred-password').focus();
} else {
Expand Down Expand Up @@ -3679,6 +3680,7 @@ <h3 id="cred-modal-title">Enter Credentials</h3>
document.getElementById('em-ssh-prompt-creds').checked = false;
document.getElementById('em-vnc-hostname').value = '';
document.getElementById('em-vnc-port').value = '5900';
document.getElementById('em-vnc-username').value = '';
document.getElementById('em-vnc-password').value = '';
document.getElementById('em-vnc-color-depth').value = '';
document.getElementById('em-vnc-prompt-creds').checked = false;
Expand Down Expand Up @@ -3839,6 +3841,7 @@ <h3 id="cred-modal-title">Enter Credentials</h3>
} else if (type === 'vnc') {
document.getElementById('em-vnc-hostname').value = entryData.hostname || '';
document.getElementById('em-vnc-port').value = entryData.port || '5900';
document.getElementById('em-vnc-username').value = entryData.username || '';
document.getElementById('em-vnc-color-depth').value = entryData.color_depth ? String(entryData.color_depth) : '';
document.getElementById('em-vnc-prompt-creds').checked = !!entryData.prompt_credentials;
} else if (type === 'spice') {
Expand Down Expand Up @@ -4064,6 +4067,8 @@ <h3 id="cred-modal-title">Enter Credentials</h3>
if (h) entry.hostname = h;
var p = parseInt(document.getElementById('em-vnc-port').value);
if (p) entry.port = p;
var u = document.getElementById('em-vnc-username').value.trim();
if (u) entry.username = u;
var pw = document.getElementById('em-vnc-password').value;
if (pw) entry.password = pw;
var cd = document.getElementById('em-vnc-color-depth').value;
Expand Down
5 changes: 5 additions & 0 deletions static/sessions.html
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ <h1>rustguac</h1>
<label>Port
<input type="number" id="vnc-port" value="5900">
</label>
<label>Username (optional)
<input type="text" id="vnc-username">
</label>
<label>Password (optional)
<input type="password" id="vnc-password">
</label>
Expand Down Expand Up @@ -504,6 +507,8 @@ <h1>rustguac</h1>
body.session_type = 'vnc';
body.hostname = document.getElementById('vnc-hostname').value;
body.port = parseInt(document.getElementById('vnc-port').value) || 5900;
var un = document.getElementById('vnc-username').value;
if (un) body.username = un;
var pw = document.getElementById('vnc-password').value;
if (pw) body.password = pw;
} else if (sessionType.value === 'rdp') {
Expand Down