Make this VNC server interoperate with OS X's builtin VNC client
by pretending to support V3.3 of the protocol and implementing dummy VNC
authentication.
Also initializes the pixel-format defaults in case a client does not
send the "SetPixelFormat" message.
Bug: 151186027
Change-Id: I9c919a542dd917fc139cce61640d87b08145c071
diff --git a/host/frontend/vnc_server/vnc_client_connection.cpp b/host/frontend/vnc_server/vnc_client_connection.cpp
index b4cc24b..c15d46c 100644
--- a/host/frontend/vnc_server/vnc_client_connection.cpp
+++ b/host/frontend/vnc_server/vnc_client_connection.cpp
@@ -195,12 +195,22 @@
void VncClientConnection::SetupProtocol() {
static constexpr char kRFBVersion[] = "RFB 003.008\n";
+ static constexpr char kRFBVersionOld[] = "RFB 003.003\n";
static constexpr auto kVersionLen = (sizeof kRFBVersion) - 1;
client_.SendNoSignal(reinterpret_cast<const std::uint8_t*>(kRFBVersion),
kVersionLen);
auto client_protocol = client_.Recv(kVersionLen);
if (std::memcmp(&client_protocol[0], kRFBVersion,
std::min(kVersionLen, client_protocol.size())) != 0) {
+ if (!std::memcmp(
+ &client_protocol[0],
+ kRFBVersionOld,
+ std::min(kVersionLen, client_protocol.size()))) {
+ // We'll deal with V3.3 as well.
+ client_is_old_ = true;
+ return;
+ }
+
client_protocol.push_back('\0');
LOG(ERROR) << "vnc client wants a different protocol: "
<< reinterpret_cast<const char*>(&client_protocol[0]);
@@ -208,6 +218,23 @@
}
void VncClientConnection::SetupSecurityType() {
+ if (client_is_old_) {
+ static constexpr std::uint8_t kVNCSecurity[4] = { 0x00, 0x00, 0x00, 0x02 };
+ client_.SendNoSignal(kVNCSecurity);
+
+ static constexpr std::uint8_t kChallenge[16] =
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ client_.SendNoSignal(kChallenge);
+
+ auto clientResponse = client_.Recv(16);
+ (void)clientResponse; // Accept any response, we're not interested in actual security.
+
+ static constexpr std::uint8_t kSuccess[4] = { 0x00, 0x00, 0x00, 0x00 };
+ client_.SendNoSignal(kSuccess);
+ return;
+ }
+
static constexpr std::uint8_t kNoneSecurity = 0x1;
// The first '0x1' indicates the number of items that follow
static constexpr std::uint8_t kOnlyNoneSecurity[] = {0x01, kNoneSecurity};
diff --git a/host/frontend/vnc_server/vnc_client_connection.h b/host/frontend/vnc_server/vnc_client_connection.h
index 73beae1..9f4fb96 100644
--- a/host/frontend/vnc_server/vnc_client_connection.h
+++ b/host/frontend/vnc_server/vnc_client_connection.h
@@ -151,20 +151,22 @@
PixelFormat pixel_format_ GUARDED_BY(m_) = {
std::uint8_t{32}, // bits per pixel
- std::uint8_t{8}, // depth
- std::uint8_t{}, // big_endian
- std::uint8_t{}, // true_color
- std::uint16_t{}, // red_max, (maxes not used when true color flag is 0)
- std::uint16_t{}, // green_max
- std::uint16_t{}, // blue_max
- std::uint8_t{}, // red_shift (shifts not used when true color flag is 0)
- std::uint8_t{}, // green_shift
- std::uint8_t{}, // blue_shift
+ std::uint8_t{24}, // depth
+ std::uint8_t{0}, // big_endian
+ std::uint8_t{1}, // true_color
+ std::uint16_t{0xff}, // red_max, (maxes not used when true color flag is 0)
+ std::uint16_t{0xff}, // green_max
+ std::uint16_t{0xff}, // blue_max
+ std::uint8_t{0}, // red_shift (shifts not used when true color flag is 0)
+ std::uint8_t{8}, // green_shift
+ std::uint8_t{16}, // blue_shift
};
bool supports_desktop_size_encoding_ = false;
ScreenOrientation current_orientation_ GUARDED_BY(m_) =
ScreenOrientation::Portrait;
+
+ bool client_is_old_ = false;
};
} // namespace vnc