Internal
Public Access
Fix Apple DH auth wire-order bug, add type 33 fallback, fix missing VNC password prompt
Live testing against a real macOS Screen Sharing server surfaced two real bugs, independent of each other: 1. SessionTab::requestConnectOptions() never prompted for a password on VNC profiles (only SSH/RDP) -- every VNC connection went out with an empty password regardless of what the server needed. VNC now gets its own prompt; an empty password is allowed through (unlike RDP's hard requirement) since no-auth VNC servers exist and there's no way to know client-side before the security-type negotiation happens. 2. VncSessionBackend's Apple DH (type 30) response sent the client's public key before the encrypted credentials. Cross-checking against neatvnc's rfb-proto.h (an independent, authoritative reference: both the wire struct definitions and the full server-side verification code, matched field-by-field against this implementation) showed the correct order is credentials first, then public key -- exactly backwards from what was implemented. Fixed, with a new regression test that decrypts the credentials back out using the trailing public-key bytes to derive the shared secret, which would fail if the fields were swapped again. Also adds security type 33 (RSA + AES, src/vnc_apple_rsa_auth.h) as a fallback Apple auth scheme, sourced from the `asyncvnc` PyPI package. Preference when multiple are offered: None > AppleDH(30) > AppleRSA(33) > VNCAuth(2). Neither scheme has been gotten working live yet against the specific macOS Tahoe (26.6.2) server available for testing -- type 30's wire format is now verified correct byte-for-byte against the independent reference above, but the server still rejects it with a generic "Authentication or authorization failure"; type 33 is rejected even earlier, right after the initial host-key request. macOS Tahoe was released after this assistant's knowledge cutoff, so there may be a protocol or permission-model change specific to it that isn't reflected in either reference. Documented as an open issue in docs/PROGRESS.md rather than claimed as working. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -981,6 +981,28 @@ void SessionTab::requestConnectOptions(
|
||||
|
||||
const bool isSsh = m_profile.protocol.compare(QStringLiteral("SSH"), Qt::CaseInsensitive) == 0;
|
||||
const bool isRdp = m_profile.protocol.compare(QStringLiteral("RDP"), Qt::CaseInsensitive) == 0;
|
||||
const bool isVnc = m_profile.protocol.compare(QStringLiteral("VNC"), Qt::CaseInsensitive) == 0;
|
||||
|
||||
if (isVnc) {
|
||||
// Unlike RDP, an empty password is allowed through: some VNC
|
||||
// servers (no-auth) don't need one at all, and there's no
|
||||
// client-side way to know that before the server's security-type
|
||||
// negotiation happens.
|
||||
showPasswordPrompt(
|
||||
QStringLiteral("VNC password for %1 (leave blank if the server doesn't require one):")
|
||||
.arg(m_profile.host),
|
||||
[baseOptions, callback](std::optional<QString> password) {
|
||||
if (!password.has_value()) {
|
||||
callback(std::nullopt);
|
||||
return;
|
||||
}
|
||||
|
||||
SessionConnectOptions options = baseOptions;
|
||||
options.password = password.value();
|
||||
callback(options);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isSsh && !isRdp) {
|
||||
callback(baseOptions);
|
||||
|
||||
Reference in New Issue
Block a user