feat: Dynamic client Barrier/Synergy hello back response to server

This commit is contained in:
sithlord48 2024-10-14 13:13:49 -04:00 committed by Nick Bolton
parent 199f682e27
commit 47366f1272
5 changed files with 43 additions and 14 deletions

View file

@ -674,22 +674,31 @@ bool Client::isCompatible(int major, int minor) const
void Client::handleHello(const Event &, void *) void Client::handleHello(const Event &, void *)
{ {
SInt16 major, minor; SInt16 major, minor;
if (!ProtocolUtil::readf(m_stream, kMsgHello, &major, &minor)) {
sendConnectionFailedEvent("Protocol error from server, check encryption settings"); // as luck would have it, both "Synergy" and "Barrier" are 7 chars,
// so we eat 7 chars and then test for either protocol name.
// we cannot re-use `readf` to check for various hello messages,
// as `readf` eats bytes (advances the stream position reference).
std::string protocolName;
ProtocolUtil::readf(m_stream, kMsgHello, &protocolName, &major, &minor);
if (protocolName != kSynergyProtocolName && protocolName != kBarrierProtocolName) {
sendConnectionFailedEvent("got invalid hello message from server");
cleanupTimer(); cleanupTimer();
cleanupConnection(); cleanupConnection();
return; return;
} }
// check versions // check versions
LOG((CLOG_DEBUG1 "got hello version %d.%d", major, minor)); LOG_DEBUG("got hello version %s, %d.%d", protocolName.c_str(), major, minor);
SInt16 helloBackMajor = kProtocolMajorVersion; SInt16 helloBackMajor = kProtocolMajorVersion;
SInt16 helloBackMinor = kProtocolMinorVersion; SInt16 helloBackMinor = kProtocolMinorVersion;
if (isCompatible(major, minor)) { if (isCompatible(major, minor)) {
// because 1.6 is comptable with 1.7 and 1.8 - downgrading protocol for // because 1.6 is compatable with 1.7 and 1.8 - downgrading protocol for
// server // server
LOG((CLOG_NOTE "downgrading protocol version for server")); LOG_NOTE("downgrading protocol version for server");
helloBackMinor = minor; helloBackMinor = minor;
} else if (major < kProtocolMajorVersion || (major == kProtocolMajorVersion && minor < kProtocolMinorVersion)) { } else if (major < kProtocolMajorVersion || (major == kProtocolMajorVersion && minor < kProtocolMinorVersion)) {
sendConnectionFailedEvent(XIncompatibleClient(major, minor).what()); sendConnectionFailedEvent(XIncompatibleClient(major, minor).what());
@ -699,8 +708,12 @@ void Client::handleHello(const Event &, void *)
} }
// say hello back // say hello back
LOG((CLOG_DEBUG1 "say hello version %d.%d", helloBackMajor, helloBackMinor)); LOG_DEBUG("say hello version %s %d.%d", protocolName.c_str(), helloBackMajor, helloBackMinor);
ProtocolUtil::writef(m_stream, kMsgHelloBack, helloBackMajor, helloBackMinor, &m_name);
// dynamically build write format for hello back since `writef` doesn't
// support fixed length strings yet.
std::string helloBackMessage = protocolName + "%2i%2i%s";
ProtocolUtil::writef(m_stream, helloBackMessage.c_str(), helloBackMajor, helloBackMinor, &m_name);
// now connected but waiting to complete handshake // now connected but waiting to complete handshake
setupScreen(); setupScreen();

View file

@ -502,11 +502,15 @@ void ProtocolUtil::readVector4BytesInt(deskflow::IStream *stream, std::vector<UI
void ProtocolUtil::readBytes(deskflow::IStream *stream, UInt32 len, String *destination) void ProtocolUtil::readBytes(deskflow::IStream *stream, UInt32 len, String *destination)
{ {
assert(len == 0);
// read the string length // read the string length
UInt8 buffer[128]; UInt8 buffer[128];
len = read4BytesInt(stream);
// when string length is 0, this implies that the size of the string is
// variable and embedded and will be found in the stream.
if (len == 0) {
len = read4BytesInt(stream);
}
// use a fixed size buffer if its big enough // use a fixed size buffer if its big enough
const bool useFixed = (len <= sizeof(buffer)); const bool useFixed = (len <= sizeof(buffer));

View file

@ -18,9 +18,13 @@
#include "deskflow/protocol_types.h" #include "deskflow/protocol_types.h"
// Keep the "Synergy" name for hello to preserve compatibility with Synergy const char *const kSynergyProtocolName = "Synergy";
const char *const kMsgHello = "Synergy%2i%2i"; const char *const kBarrierProtocolName = "Barrier";
const char *const kMsgHelloBack = "Synergy%2i%2i%s";
// The protocol name string within the hello and hello back messages must be
// 7 chars for backward compatibility (Synergy and Barrier are 7 chars).
const char *const kMsgHello = "%7s%2i%2i";
const char *const kMsgHelloBack = "%7s%2i%2i%s";
const char *const kMsgCNoop = "CNOP"; const char *const kMsgCNoop = "CNOP";
const char *const kMsgCClose = "CBYE"; const char *const kMsgCClose = "CBYE";
const char *const kMsgCEnter = "CINN%2i%2i%4i%2i"; const char *const kMsgCEnter = "CINN%2i%2i%4i%2i";

View file

@ -106,6 +106,12 @@ enum EDataReceived
// greeting handshake messages // greeting handshake messages
// //
// used to say hello back to the server as Synergy
extern const char *const kSynergyProtocolName;
// used to say hello back to the server as Barrier
extern const char *const kBarrierProtocolName;
// say hello to client; primary -> secondary // say hello to client; primary -> secondary
// $1 = protocol major version number supported by server. $2 = // $1 = protocol major version number supported by server. $2 =
// protocol minor version number supported by server. $3 = server // protocol minor version number supported by server. $3 = server

View file

@ -224,7 +224,9 @@ void ClientProxyUnknown::handleData(const Event &, void *)
// parse the reply to hello // parse the reply to hello
SInt16 major, minor; SInt16 major, minor;
if (!ProtocolUtil::readf(m_stream, kMsgHelloBack, &major, &minor, &name)) { std::string protocolName;
if (!ProtocolUtil::readf(
m_stream, kMsgHelloBack, &protocolName, &major, &minor, &name)) {
throw XBadClient(); throw XBadClient();
} }