diff options
Diffstat (limited to 'common/rfb/SConnection.cxx')
-rw-r--r-- | common/rfb/SConnection.cxx | 137 |
1 files changed, 112 insertions, 25 deletions
diff --git a/common/rfb/SConnection.cxx b/common/rfb/SConnection.cxx index a0a1c373..c698b991 100644 --- a/common/rfb/SConnection.cxx +++ b/common/rfb/SConnection.cxx @@ -26,6 +26,11 @@ #include <algorithm> +#include <core/LogWriter.h> +#include <core/string.h> + +#include <rdr/OutStream.h> + #include <rfb/Exception.h> #include <rfb/Security.h> #include <rfb/clipboardTypes.h> @@ -38,13 +43,10 @@ #include <rfb/encodings.h> #include <rfb/EncodeManager.h> #include <rfb/SSecurity.h> -#include <rfb/util.h> - -#include <rfb/LogWriter.h> using namespace rfb; -static LogWriter vlog("SConnection"); +static core::LogWriter vlog("SConnection"); SConnection::SConnection(AccessRights accessRights_) : readyForSetColourMapEntries(false), is(nullptr), os(nullptr), @@ -133,10 +135,10 @@ bool SConnection::processVersionMsg() if (client.majorVersion != 3) { // unknown protocol version - failConnection(format("Client needs protocol version %d.%d, " - "server has %d.%d", - client.majorVersion, client.minorVersion, - defaultMajorVersion, defaultMinorVersion)); + failConnection(core::format( + "Client needs protocol version %d.%d, server has %d.%d", + client.majorVersion, client.minorVersion, + defaultMajorVersion, defaultMinorVersion)); } if (client.minorVersion != 3 && client.minorVersion != 7 && client.minorVersion != 8) { @@ -152,8 +154,6 @@ bool SConnection::processVersionMsg() client.majorVersion,client.minorVersion); } - versionReceived(); - std::list<uint8_t> secTypes; std::list<uint8_t>::iterator i; secTypes = security.GetEnabledSecTypes(); @@ -166,9 +166,9 @@ bool SConnection::processVersionMsg() if (*i == secTypeNone || *i == secTypeVncAuth) break; } if (i == secTypes.end()) { - failConnection(format("No supported security type for " - "%d.%d client", - client.majorVersion, client.minorVersion)); + failConnection( + core::format("No supported security type for %d.%d client", + client.majorVersion, client.minorVersion)); } os->writeU32(*i); @@ -278,7 +278,7 @@ bool SConnection::processInitMsg() return reader_->readClientInit(); } -void SConnection::handleAuthFailureTimeout(Timer* /*t*/) +void SConnection::handleAuthFailureTimeout(core::Timer* /*t*/) { if (state_ != RFBSTATE_SECURITY_FAILURE) { close("SConnection::handleAuthFailureTimeout: Invalid state"); @@ -344,6 +344,8 @@ bool SConnection::accessCheck(AccessRights ar) const void SConnection::setEncodings(int nEncodings, const int32_t* encodings) { int i; + bool firstFence, firstContinuousUpdates, firstLEDState, + firstQEMUKeyEvent, firstExtMouseButtonsEvent; preferredEncoding = encodingRaw; for (i = 0;i < nEncodings;i++) { @@ -353,7 +355,26 @@ void SConnection::setEncodings(int nEncodings, const int32_t* encodings) } } - SMsgHandler::setEncodings(nEncodings, encodings); + firstFence = !client.supportsFence(); + firstContinuousUpdates = !client.supportsContinuousUpdates(); + firstLEDState = !client.supportsLEDState(); + firstQEMUKeyEvent = !client.supportsEncoding(pseudoEncodingQEMUKeyEvent); + firstExtMouseButtonsEvent = !client.supportsEncoding(pseudoEncodingExtendedMouseButtons); + + client.setEncodings(nEncodings, encodings); + + supportsLocalCursor(); + + if (client.supportsFence() && firstFence) + supportsFence(); + if (client.supportsContinuousUpdates() && firstContinuousUpdates) + supportsContinuousUpdates(); + if (client.supportsLEDState() && firstLEDState) + supportsLEDState(); + if (client.supportsEncoding(pseudoEncodingQEMUKeyEvent) && firstQEMUKeyEvent) + writer()->writeQEMUKeyEvent(); + if (client.supportsEncoding(pseudoEncodingExtendedMouseButtons) && firstExtMouseButtonsEvent) + writer()->writeExtendedMouseButtonsSupport(); if (client.supportsEncoding(pseudoEncodingExtendedClipboard)) { uint32_t sizes[] = { 0 }; @@ -373,9 +394,54 @@ void SConnection::clientCutText(const char* str) clientClipboard = str; hasRemoteClipboard = true; + if (!accessCheck(AccessCutText)) + return; + handleClipboardAnnounce(true); } +void SConnection::handleClipboardCaps(uint32_t flags, const uint32_t* lengths) +{ + int i; + + vlog.debug("Got client clipboard capabilities:"); + for (i = 0;i < 16;i++) { + if (flags & (1 << i)) { + const char *type; + + switch (1 << i) { + case clipboardUTF8: + type = "Plain text"; + break; + case clipboardRTF: + type = "Rich text"; + break; + case clipboardHTML: + type = "HTML"; + break; + case clipboardDIB: + type = "Images"; + break; + case clipboardFiles: + type = "Files"; + break; + default: + vlog.debug(" Unknown format 0x%x", 1 << i); + continue; + } + + if (lengths[i] == 0) + vlog.debug(" %s (only notify)", type); + else { + vlog.debug(" %s (automatically send up to %s)", + type, core::iecPrefix(lengths[i], "B").c_str()); + } + } + } + + client.setClipboardCaps(flags, lengths); +} + void SConnection::handleClipboardRequest(uint32_t flags) { if (!(flags & rfb::clipboardUTF8)) { @@ -386,6 +452,8 @@ void SConnection::handleClipboardRequest(uint32_t flags) vlog.debug("Ignoring unexpected clipboard request"); return; } + if (!accessCheck(AccessCutText)) + return; handleClipboardRequest(); } @@ -401,10 +469,15 @@ void SConnection::handleClipboardNotify(uint32_t flags) if (flags & rfb::clipboardUTF8) { hasLocalClipboard = false; + if (!accessCheck(AccessCutText)) + return; handleClipboardAnnounce(true); } else { + if (!accessCheck(AccessCutText)) + return; handleClipboardAnnounce(false); } + } void SConnection::handleClipboardProvide(uint32_t flags, @@ -417,28 +490,33 @@ void SConnection::handleClipboardProvide(uint32_t flags, } // FIXME: This conversion magic should be in SMsgReader - if (!isValidUTF8((const char*)data[0], lengths[0])) { + if (!core::isValidUTF8((const char*)data[0], lengths[0])) { vlog.error("Invalid UTF-8 sequence in clipboard - ignoring"); return; } - clientClipboard = convertLF((const char*)data[0], lengths[0]); + clientClipboard = core::convertLF((const char*)data[0], lengths[0]); hasRemoteClipboard = true; + if (!accessCheck(AccessCutText)) + return; + // FIXME: Should probably verify that this data was actually requested handleClipboardData(clientClipboard.c_str()); } -void SConnection::supportsQEMUKeyEvent() +void SConnection::supportsLocalCursor() { - writer()->writeQEMUKeyEvent(); } -void SConnection::supportsExtendedMouseButtons() +void SConnection::supportsFence() { - writer()->writeExtendedMouseButtonsSupport(); } -void SConnection::versionReceived() +void SConnection::supportsContinuousUpdates() +{ +} + +void SConnection::supportsLEDState() { } @@ -500,13 +578,13 @@ void SConnection::close(const char* /*reason*/) void SConnection::setPixelFormat(const PixelFormat& pf) { - SMsgHandler::setPixelFormat(pf); + client.setPF(pf); readyForSetColourMapEntries = true; if (!pf.trueColour) writeFakeColourMap(); } -void SConnection::framebufferUpdateRequest(const Rect& /*r*/, +void SConnection::framebufferUpdateRequest(const core::Rect& /*r*/, bool /*incremental*/) { if (!readyForSetColourMapEntries) { @@ -549,6 +627,9 @@ void SConnection::handleClipboardData(const char* /*data*/) void SConnection::requestClipboard() { + if (!accessCheck(AccessCutText)) + return; + if (hasRemoteClipboard) { handleClipboardData(clientClipboard.c_str()); return; @@ -561,6 +642,9 @@ void SConnection::requestClipboard() void SConnection::announceClipboard(bool available) { + if (!accessCheck(AccessCutText)) + return; + hasLocalClipboard = available; unsolicitedClipboardAttempt = false; @@ -587,10 +671,13 @@ void SConnection::announceClipboard(bool available) void SConnection::sendClipboardData(const char* data) { + if (!accessCheck(AccessCutText)) + return; + if (client.supportsEncoding(pseudoEncodingExtendedClipboard) && (client.clipboardFlags() & rfb::clipboardProvide)) { // FIXME: This conversion magic should be in SMsgWriter - std::string filtered(convertCRLF(data)); + std::string filtered(core::convertCRLF(data)); size_t sizes[1] = { filtered.size() + 1 }; const uint8_t* datas[1] = { (const uint8_t*)filtered.c_str() }; |