aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb/SConnection.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'common/rfb/SConnection.cxx')
-rw-r--r--common/rfb/SConnection.cxx137
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() };