sending IV to client before DKDN, DKUP and DKRP (the most sensitive messages). unit tests to support changes. made crypto stream tests a bit less spammy by using NiceMock.

This commit is contained in:
Nick Bolton
2013-04-09 18:56:19 +00:00
parent 23998fc06c
commit 7010de9cc4
37 changed files with 490 additions and 227 deletions

View File

@@ -150,7 +150,7 @@ CClientListener::handleClientConnecting(const CEvent&, void*)
stream = new CPacketStreamFilter(stream, true);
if (s_cryptoEnabled) {
CCryptoStream* cryptoStream = new CCryptoStream(*EVENTQUEUE, stream, true);
CCryptoStream* cryptoStream = new CCryptoStream(EVENTQUEUE, stream, true);
cryptoStream->setKeyWithIv(g_key, sizeof(g_key), g_iv);
stream = cryptoStream;
}

View File

@@ -25,8 +25,6 @@
namespace synergy { class IStream; }
const int g_encryptionEnabled = true;
//! Generic proxy for client
class CClientProxy : public CBaseClientProxy {
public:
@@ -49,12 +47,6 @@ public:
//! @name accessors
//@{
//! Get stream (unmodified)
/*!
Returns the original stream passed to the c'tor.
*/
synergy::IStream* getStreamUnmodified() const;
//! Get stream
/*!
Returns a crypto stream if the user has this enabled,
@@ -125,6 +117,7 @@ public:
virtual void gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2) = 0;
virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2) = 0;
virtual void gameDeviceTimingReq() = 0;
virtual void cryptoIv(const UInt8* iv) = 0;
private:
synergy::IStream* m_stream;

View File

@@ -29,29 +29,30 @@
// CClientProxy1_0
//
CClientProxy1_0::CClientProxy1_0(const CString& name, synergy::IStream* stream) :
CClientProxy1_0::CClientProxy1_0(const CString& name, synergy::IStream* stream, IEventQueue* eventQueue) :
CClientProxy(name, stream),
m_heartbeatTimer(NULL),
m_parser(&CClientProxy1_0::parseHandshakeMessage)
m_parser(&CClientProxy1_0::parseHandshakeMessage),
m_eventQueue(eventQueue)
{
// install event handlers
EVENTQUEUE->adoptHandler(stream->getInputReadyEvent(),
m_eventQueue->adoptHandler(stream->getInputReadyEvent(),
stream->getEventTarget(),
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleData, NULL));
EVENTQUEUE->adoptHandler(stream->getOutputErrorEvent(),
m_eventQueue->adoptHandler(stream->getOutputErrorEvent(),
stream->getEventTarget(),
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleWriteError, NULL));
EVENTQUEUE->adoptHandler(stream->getInputShutdownEvent(),
m_eventQueue->adoptHandler(stream->getInputShutdownEvent(),
stream->getEventTarget(),
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleDisconnect, NULL));
EVENTQUEUE->adoptHandler(stream->getOutputShutdownEvent(),
m_eventQueue->adoptHandler(stream->getOutputShutdownEvent(),
stream->getEventTarget(),
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleWriteError, NULL));
EVENTQUEUE->adoptHandler(CEvent::kTimer, this,
m_eventQueue->adoptHandler(CEvent::kTimer, this,
new TMethodEventJob<CClientProxy1_0>(this,
&CClientProxy1_0::handleFlatline, NULL));
@@ -71,22 +72,22 @@ CClientProxy1_0::disconnect()
{
removeHandlers();
getStream()->close();
EVENTQUEUE->addEvent(CEvent(getDisconnectedEvent(), getEventTarget()));
m_eventQueue->addEvent(CEvent(getDisconnectedEvent(), getEventTarget()));
}
void
CClientProxy1_0::removeHandlers()
{
// uninstall event handlers
EVENTQUEUE->removeHandler(getStream()->getInputReadyEvent(),
m_eventQueue->removeHandler(getStream()->getInputReadyEvent(),
getStream()->getEventTarget());
EVENTQUEUE->removeHandler(getStream()->getOutputErrorEvent(),
m_eventQueue->removeHandler(getStream()->getOutputErrorEvent(),
getStream()->getEventTarget());
EVENTQUEUE->removeHandler(getStream()->getInputShutdownEvent(),
m_eventQueue->removeHandler(getStream()->getInputShutdownEvent(),
getStream()->getEventTarget());
EVENTQUEUE->removeHandler(getStream()->getOutputShutdownEvent(),
m_eventQueue->removeHandler(getStream()->getOutputShutdownEvent(),
getStream()->getEventTarget());
EVENTQUEUE->removeHandler(CEvent::kTimer, this);
m_eventQueue->removeHandler(CEvent::kTimer, this);
// remove timer
removeHeartbeatTimer();
@@ -96,7 +97,7 @@ void
CClientProxy1_0::addHeartbeatTimer()
{
if (m_heartbeatAlarm > 0.0) {
m_heartbeatTimer = EVENTQUEUE->newOneShotTimer(m_heartbeatAlarm, this);
m_heartbeatTimer = m_eventQueue->newOneShotTimer(m_heartbeatAlarm, this);
}
}
@@ -104,7 +105,7 @@ void
CClientProxy1_0::removeHeartbeatTimer()
{
if (m_heartbeatTimer != NULL) {
EVENTQUEUE->deleteTimer(m_heartbeatTimer);
m_eventQueue->deleteTimer(m_heartbeatTimer);
m_heartbeatTimer = NULL;
}
}
@@ -171,7 +172,7 @@ CClientProxy1_0::parseHandshakeMessage(const UInt8* code)
// future messages get parsed by parseMessage
m_parser = &CClientProxy1_0::parseMessage;
if (recvInfo()) {
EVENTQUEUE->addEvent(CEvent(getReadyEvent(), getEventTarget()));
m_eventQueue->addEvent(CEvent(getReadyEvent(), getEventTarget()));
addHeartbeatTimer();
return true;
}
@@ -184,7 +185,7 @@ CClientProxy1_0::parseMessage(const UInt8* code)
{
if (memcmp(code, kMsgDInfo, 4) == 0) {
if (recvInfo()) {
EVENTQUEUE->addEvent(
m_eventQueue->addEvent(
CEvent(getShapeChangedEvent(), getEventTarget()));
return true;
}
@@ -385,6 +386,13 @@ CClientProxy1_0::gameDeviceTimingReq()
LOG((CLOG_DEBUG "gameDeviceTimingReq not supported"));
}
void
CClientProxy1_0::cryptoIv(const UInt8* iv)
{
// ignore -- not supported in protocol 1.0
LOG((CLOG_DEBUG "cryptoIv not supported"));
}
void
CClientProxy1_0::screensaver(bool on)
{
@@ -484,7 +492,7 @@ CClientProxy1_0::recvClipboard()
CClipboardInfo* info = new CClipboardInfo;
info->m_id = id;
info->m_sequenceNumber = seqNum;
EVENTQUEUE->addEvent(CEvent(getClipboardChangedEvent(),
m_eventQueue->addEvent(CEvent(getClipboardChangedEvent(),
getEventTarget(), info));
return true;
@@ -510,7 +518,7 @@ CClientProxy1_0::recvGrabClipboard()
CClipboardInfo* info = new CClipboardInfo;
info->m_id = id;
info->m_sequenceNumber = seqNum;
EVENTQUEUE->addEvent(CEvent(getClipboardGrabbedEvent(),
m_eventQueue->addEvent(CEvent(getClipboardGrabbedEvent(),
getEventTarget(), info));
return true;

View File

@@ -25,11 +25,12 @@
class CEvent;
class CEventQueueTimer;
class IEventQueue;
//! Proxy for client implementing protocol version 1.0
class CClientProxy1_0 : public CClientProxy {
public:
CClientProxy1_0(const CString& name, synergy::IStream* adoptedStream);
CClientProxy1_0(const CString& name, synergy::IStream* adoptedStream, IEventQueue* eventQueue);
~CClientProxy1_0();
// IScreen
@@ -62,6 +63,7 @@ public:
virtual void gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2);
virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2);
virtual void gameDeviceTimingReq();
virtual void cryptoIv(const UInt8* iv);
protected:
virtual bool parseHandshakeMessage(const UInt8* code);
@@ -103,6 +105,7 @@ private:
double m_heartbeatAlarm;
CEventQueueTimer* m_heartbeatTimer;
MessageParser m_parser;
IEventQueue* m_eventQueue;
};
#endif

View File

@@ -25,8 +25,8 @@
// CClientProxy1_1
//
CClientProxy1_1::CClientProxy1_1(const CString& name, synergy::IStream* stream) :
CClientProxy1_0(name, stream)
CClientProxy1_1::CClientProxy1_1(const CString& name, synergy::IStream* stream, IEventQueue* eventQueue) :
CClientProxy1_0(name, stream, eventQueue)
{
// do nothing
}

View File

@@ -24,7 +24,7 @@
//! Proxy for client implementing protocol version 1.1
class CClientProxy1_1 : public CClientProxy1_0 {
public:
CClientProxy1_1(const CString& name, synergy::IStream* adoptedStream);
CClientProxy1_1(const CString& name, synergy::IStream* adoptedStream, IEventQueue* eventQueue);
~CClientProxy1_1();
// IClient overrides

View File

@@ -24,8 +24,8 @@
// CClientProxy1_1
//
CClientProxy1_2::CClientProxy1_2(const CString& name, synergy::IStream* stream) :
CClientProxy1_1(name, stream)
CClientProxy1_2::CClientProxy1_2(const CString& name, synergy::IStream* stream, IEventQueue* eventQueue) :
CClientProxy1_1(name, stream, eventQueue)
{
// do nothing
}

View File

@@ -21,10 +21,12 @@
#include "CClientProxy1_1.h"
class IEventQueue;
//! Proxy for client implementing protocol version 1.2
class CClientProxy1_2 : public CClientProxy1_1 {
public:
CClientProxy1_2(const CString& name, synergy::IStream* adoptedStream);
CClientProxy1_2(const CString& name, synergy::IStream* adoptedStream, IEventQueue* eventQueue);
~CClientProxy1_2();
// IClient overrides

View File

@@ -28,8 +28,8 @@
// CClientProxy1_3
//
CClientProxy1_3::CClientProxy1_3(const CString& name, synergy::IStream* stream) :
CClientProxy1_2(name, stream),
CClientProxy1_3::CClientProxy1_3(const CString& name, synergy::IStream* stream, IEventQueue* eventQueue) :
CClientProxy1_2(name, stream, eventQueue),
m_keepAliveRate(kKeepAliveRate),
m_keepAliveTimer(NULL)
{

View File

@@ -24,7 +24,7 @@
//! Proxy for client implementing protocol version 1.3
class CClientProxy1_3 : public CClientProxy1_2 {
public:
CClientProxy1_3(const CString& name, synergy::IStream* adoptedStream);
CClientProxy1_3(const CString& name, synergy::IStream* adoptedStream, IEventQueue* eventQueue);
~CClientProxy1_3();
// IClient overrides

View File

@@ -24,13 +24,14 @@
#include <cstring>
#include <memory>
#include "CServer.h"
#include "CCryptoStream.h"
//
// CClientProxy1_4
//
CClientProxy1_4::CClientProxy1_4(const CString& name, synergy::IStream* stream, CServer* server) :
CClientProxy1_3(name, stream), m_server(server)
CClientProxy1_4::CClientProxy1_4(const CString& name, synergy::IStream* stream, CServer* server, IEventQueue* eventQueue) :
CClientProxy1_3(name, stream, eventQueue), m_server(server)
{
assert(m_server != NULL);
}
@@ -67,6 +68,43 @@ CClientProxy1_4::gameDeviceTimingReq()
CProtocolUtil::writef(getStream(), kMsgCGameTimingReq);
}
void
CClientProxy1_4::keyDown(KeyID key, KeyModifierMask mask, KeyButton button)
{
cryptoIv();
CClientProxy1_3::keyDown(key, mask, button);
}
void
CClientProxy1_4::keyRepeat(KeyID key, KeyModifierMask mask, SInt32 count, KeyButton button)
{
cryptoIv();
CClientProxy1_3::keyRepeat(key, mask, count, button);
}
void
CClientProxy1_4::keyUp(KeyID key, KeyModifierMask mask, KeyButton button)
{
cryptoIv();
CClientProxy1_3::keyUp(key, mask, button);
}
void
CClientProxy1_4::cryptoIv()
{
CCryptoStream* cryptoStream = dynamic_cast<CCryptoStream*>(getStream());
if (cryptoStream == NULL) {
return;
}
byte iv[CRYPTO_IV_SIZE];
cryptoStream->newIv(iv);
CString data(reinterpret_cast<const char*>(iv), CRYPTO_IV_SIZE);
LOG((CLOG_DEBUG2 "send crypto iv change to \"%s\"", getName().c_str()));
CProtocolUtil::writef(getStream(), kMsgDCryptoIv, &data);
}
bool
CClientProxy1_4::parseMessage(const UInt8* code)
{

View File

@@ -26,7 +26,7 @@ class CServer;
//! Proxy for client implementing protocol version 1.4
class CClientProxy1_4 : public CClientProxy1_3 {
public:
CClientProxy1_4(const CString& name, synergy::IStream* adoptedStream, CServer* server);
CClientProxy1_4(const CString& name, synergy::IStream* adoptedStream, CServer* server, IEventQueue* eventQueue);
~CClientProxy1_4();
// IClient overrides
@@ -34,6 +34,12 @@ public:
virtual void gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2);
virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2);
virtual void gameDeviceTimingReq();
virtual void keyDown(KeyID key, KeyModifierMask mask, KeyButton button);
virtual void keyRepeat(KeyID key, KeyModifierMask mask, SInt32 count, KeyButton button);
virtual void keyUp(KeyID key, KeyModifierMask mask, KeyButton button);
//! Send IV to make
void cryptoIv();
protected:
// CClientProxy overrides

View File

@@ -219,23 +219,23 @@ CClientProxyUnknown::handleData(const CEvent&, void*)
if (major == 1) {
switch (minor) {
case 0:
m_proxy = new CClientProxy1_0(name, m_stream);
m_proxy = new CClientProxy1_0(name, m_stream, EVENTQUEUE);
break;
case 1:
m_proxy = new CClientProxy1_1(name, m_stream);
m_proxy = new CClientProxy1_1(name, m_stream, EVENTQUEUE);
break;
case 2:
m_proxy = new CClientProxy1_2(name, m_stream);
m_proxy = new CClientProxy1_2(name, m_stream, EVENTQUEUE);
break;
case 3:
m_proxy = new CClientProxy1_3(name, m_stream);
m_proxy = new CClientProxy1_3(name, m_stream, EVENTQUEUE);
break;
case 4:
m_proxy = new CClientProxy1_4(name, m_stream, m_server);
m_proxy = new CClientProxy1_4(name, m_stream, m_server, EVENTQUEUE);
break;
}
}

View File

@@ -51,6 +51,7 @@ CEvent::Type CServer::s_lockCursorToScreen = CEvent::kUnknown;
CEvent::Type CServer::s_screenSwitched = CEvent::kUnknown;
CServer::CServer(const CConfig& config, CPrimaryClient* primaryClient, CScreen* screen) :
m_mock(false),
m_primaryClient(primaryClient),
m_active(primaryClient),
m_seqNum(0),
@@ -202,6 +203,10 @@ CServer::CServer(const CConfig& config, CPrimaryClient* primaryClient, CScreen*
CServer::~CServer()
{
if (m_mock) {
return;
}
// remove event handlers and timers
EVENTQUEUE->removeHandler(IPlatformScreen::getKeyDownEvent(*EVENTQUEUE),
m_inputFilter);

View File

@@ -103,6 +103,10 @@ public:
*/
CServer(const CConfig& config, CPrimaryClient* primaryClient, CScreen* screen);
~CServer();
#ifdef TEST_ENV
CServer() { }
#endif
//! @name manipulators
//@{
@@ -394,6 +398,9 @@ private:
// force the cursor off of \p client
void forceLeaveClient(CBaseClientProxy* client);
public:
bool m_mock;
private:
class CClipboardInfo {