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

@ -48,16 +48,12 @@ CEvent::Type CClient::s_connectedEvent = CEvent::kUnknown;
CEvent::Type CClient::s_connectionFailedEvent = CEvent::kUnknown; CEvent::Type CClient::s_connectionFailedEvent = CEvent::kUnknown;
CEvent::Type CClient::s_disconnectedEvent = CEvent::kUnknown; CEvent::Type CClient::s_disconnectedEvent = CEvent::kUnknown;
CClient::CClient(IEventQueue& eventQueue) : CClient::CClient(IEventQueue* eventQueue,
m_eventQueue(eventQueue)
{
}
CClient::CClient(IEventQueue& eventQueue,
const CString& name, const CNetworkAddress& address, const CString& name, const CNetworkAddress& address,
ISocketFactory* socketFactory, ISocketFactory* socketFactory,
IStreamFilterFactory* streamFilterFactory, IStreamFilterFactory* streamFilterFactory,
CScreen* screen) : CScreen* screen) :
m_mock(false),
m_name(name), m_name(name),
m_serverAddress(address), m_serverAddress(address),
m_socketFactory(socketFactory), m_socketFactory(socketFactory),
@ -71,25 +67,25 @@ CClient::CClient(IEventQueue& eventQueue,
m_suspended(false), m_suspended(false),
m_connectOnResume(false), m_connectOnResume(false),
m_eventQueue(eventQueue), m_eventQueue(eventQueue),
m_mock(false) m_cryptoStream(NULL)
{ {
assert(m_socketFactory != NULL); assert(m_socketFactory != NULL);
assert(m_screen != NULL); assert(m_screen != NULL);
// register suspend/resume event handlers // register suspend/resume event handlers
m_eventQueue.adoptHandler(IScreen::getSuspendEvent(), m_eventQueue->adoptHandler(IScreen::getSuspendEvent(),
getEventTarget(), getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleSuspend)); &CClient::handleSuspend));
m_eventQueue.adoptHandler(IScreen::getResumeEvent(), m_eventQueue->adoptHandler(IScreen::getResumeEvent(),
getEventTarget(), getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleResume)); &CClient::handleResume));
EVENTQUEUE->adoptHandler(IPlatformScreen::getGameDeviceTimingRespEvent(), m_eventQueue->adoptHandler(IPlatformScreen::getGameDeviceTimingRespEvent(),
getEventTarget(), getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleGameDeviceTimingResp)); &CClient::handleGameDeviceTimingResp));
EVENTQUEUE->adoptHandler(IPlatformScreen::getGameDeviceFeedbackEvent(), m_eventQueue->adoptHandler(IPlatformScreen::getGameDeviceFeedbackEvent(),
getEventTarget(), getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleGameDeviceFeedback)); &CClient::handleGameDeviceFeedback));
@ -97,13 +93,13 @@ CClient::CClient(IEventQueue& eventQueue,
CClient::~CClient() CClient::~CClient()
{ {
// HACK: can't disable dtor with mocks if (m_mock) {
if (m_mock)
return; return;
}
m_eventQueue.removeHandler(IScreen::getSuspendEvent(), m_eventQueue->removeHandler(IScreen::getSuspendEvent(),
getEventTarget()); getEventTarget());
m_eventQueue.removeHandler(IScreen::getResumeEvent(), m_eventQueue->removeHandler(IScreen::getResumeEvent(),
getEventTarget()); getEventTarget());
cleanupTimer(); cleanupTimer();
@ -153,9 +149,9 @@ CClient::connect()
m_stream = new CPacketStreamFilter(m_stream, true); m_stream = new CPacketStreamFilter(m_stream, true);
if (s_cryptoEnabled) { if (s_cryptoEnabled) {
CCryptoStream* cryptoStream = new CCryptoStream(*EVENTQUEUE, m_stream, true); m_cryptoStream = new CCryptoStream(m_eventQueue, m_stream, true);
cryptoStream->setKeyWithIv(g_key, sizeof(g_key), g_iv); m_cryptoStream->setKeyWithIv(g_key, sizeof(g_key), g_iv);
m_stream = cryptoStream; m_stream = m_cryptoStream;
} }
// connect // connect
@ -199,6 +195,14 @@ CClient::handshakeComplete()
sendEvent(getConnectedEvent(), NULL); sendEvent(getConnectedEvent(), NULL);
} }
void
CClient::setCryptoIv(const UInt8* iv)
{
if (m_cryptoStream != NULL) {
m_cryptoStream->setIv(iv);
}
}
bool bool
CClient::isConnected() const CClient::isConnected() const
{ {
@ -444,7 +448,7 @@ CClient::sendClipboard(ClipboardID id)
void void
CClient::sendEvent(CEvent::Type type, void* data) CClient::sendEvent(CEvent::Type type, void* data)
{ {
m_eventQueue.addEvent(CEvent(type, getEventTarget(), data)); m_eventQueue->addEvent(CEvent(type, getEventTarget(), data));
} }
void void
@ -453,7 +457,7 @@ CClient::sendConnectionFailedEvent(const char* msg)
CFailInfo* info = new CFailInfo(msg); CFailInfo* info = new CFailInfo(msg);
info->m_retry = true; info->m_retry = true;
CEvent event(getConnectionFailedEvent(), getEventTarget(), info, CEvent::kDontFreeData); CEvent event(getConnectionFailedEvent(), getEventTarget(), info, CEvent::kDontFreeData);
EVENTQUEUE->addEvent(event); m_eventQueue->addEvent(event);
} }
void void
@ -461,11 +465,11 @@ CClient::setupConnecting()
{ {
assert(m_stream != NULL); assert(m_stream != NULL);
m_eventQueue.adoptHandler(IDataSocket::getConnectedEvent(), m_eventQueue->adoptHandler(IDataSocket::getConnectedEvent(),
m_stream->getEventTarget(), m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleConnected)); &CClient::handleConnected));
m_eventQueue.adoptHandler(IDataSocket::getConnectionFailedEvent(), m_eventQueue->adoptHandler(IDataSocket::getConnectionFailedEvent(),
m_stream->getEventTarget(), m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleConnectionFailed)); &CClient::handleConnectionFailed));
@ -476,23 +480,23 @@ CClient::setupConnection()
{ {
assert(m_stream != NULL); assert(m_stream != NULL);
m_eventQueue.adoptHandler(ISocket::getDisconnectedEvent(), m_eventQueue->adoptHandler(ISocket::getDisconnectedEvent(),
m_stream->getEventTarget(), m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleDisconnected)); &CClient::handleDisconnected));
m_eventQueue.adoptHandler(m_stream->getInputReadyEvent(), m_eventQueue->adoptHandler(m_stream->getInputReadyEvent(),
m_stream->getEventTarget(), m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleHello)); &CClient::handleHello));
m_eventQueue.adoptHandler(m_stream->getOutputErrorEvent(), m_eventQueue->adoptHandler(m_stream->getOutputErrorEvent(),
m_stream->getEventTarget(), m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleOutputError)); &CClient::handleOutputError));
m_eventQueue.adoptHandler(m_stream->getInputShutdownEvent(), m_eventQueue->adoptHandler(m_stream->getInputShutdownEvent(),
m_stream->getEventTarget(), m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleDisconnected)); &CClient::handleDisconnected));
m_eventQueue.adoptHandler(m_stream->getOutputShutdownEvent(), m_eventQueue->adoptHandler(m_stream->getOutputShutdownEvent(),
m_stream->getEventTarget(), m_stream->getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleDisconnected)); &CClient::handleDisconnected));
@ -504,12 +508,12 @@ CClient::setupScreen()
assert(m_server == NULL); assert(m_server == NULL);
m_ready = false; m_ready = false;
m_server = new CServerProxy(this, m_stream, *EVENTQUEUE); m_server = new CServerProxy(this, m_stream, m_eventQueue);
m_eventQueue.adoptHandler(IScreen::getShapeChangedEvent(), m_eventQueue->adoptHandler(IScreen::getShapeChangedEvent(),
getEventTarget(), getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleShapeChanged)); &CClient::handleShapeChanged));
m_eventQueue.adoptHandler(IScreen::getClipboardGrabbedEvent(), m_eventQueue->adoptHandler(IScreen::getClipboardGrabbedEvent(),
getEventTarget(), getEventTarget(),
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleClipboardGrabbed)); &CClient::handleClipboardGrabbed));
@ -520,8 +524,8 @@ CClient::setupTimer()
{ {
assert(m_timer == NULL); assert(m_timer == NULL);
m_timer = m_eventQueue.newOneShotTimer(15.0, NULL); m_timer = m_eventQueue->newOneShotTimer(15.0, NULL);
m_eventQueue.adoptHandler(CEvent::kTimer, m_timer, m_eventQueue->adoptHandler(CEvent::kTimer, m_timer,
new TMethodEventJob<CClient>(this, new TMethodEventJob<CClient>(this,
&CClient::handleConnectTimeout)); &CClient::handleConnectTimeout));
} }
@ -530,9 +534,9 @@ void
CClient::cleanupConnecting() CClient::cleanupConnecting()
{ {
if (m_stream != NULL) { if (m_stream != NULL) {
m_eventQueue.removeHandler(IDataSocket::getConnectedEvent(), m_eventQueue->removeHandler(IDataSocket::getConnectedEvent(),
m_stream->getEventTarget()); m_stream->getEventTarget());
m_eventQueue.removeHandler(IDataSocket::getConnectionFailedEvent(), m_eventQueue->removeHandler(IDataSocket::getConnectionFailedEvent(),
m_stream->getEventTarget()); m_stream->getEventTarget());
} }
} }
@ -541,15 +545,15 @@ void
CClient::cleanupConnection() CClient::cleanupConnection()
{ {
if (m_stream != NULL) { if (m_stream != NULL) {
m_eventQueue.removeHandler(m_stream->getInputReadyEvent(), m_eventQueue->removeHandler(m_stream->getInputReadyEvent(),
m_stream->getEventTarget()); m_stream->getEventTarget());
m_eventQueue.removeHandler(m_stream->getOutputErrorEvent(), m_eventQueue->removeHandler(m_stream->getOutputErrorEvent(),
m_stream->getEventTarget()); m_stream->getEventTarget());
m_eventQueue.removeHandler(m_stream->getInputShutdownEvent(), m_eventQueue->removeHandler(m_stream->getInputShutdownEvent(),
m_stream->getEventTarget()); m_stream->getEventTarget());
m_eventQueue.removeHandler(m_stream->getOutputShutdownEvent(), m_eventQueue->removeHandler(m_stream->getOutputShutdownEvent(),
m_stream->getEventTarget()); m_stream->getEventTarget());
m_eventQueue.removeHandler(ISocket::getDisconnectedEvent(), m_eventQueue->removeHandler(ISocket::getDisconnectedEvent(),
m_stream->getEventTarget()); m_stream->getEventTarget());
delete m_stream; delete m_stream;
m_stream = NULL; m_stream = NULL;
@ -564,9 +568,9 @@ CClient::cleanupScreen()
m_screen->disable(); m_screen->disable();
m_ready = false; m_ready = false;
} }
m_eventQueue.removeHandler(IScreen::getShapeChangedEvent(), m_eventQueue->removeHandler(IScreen::getShapeChangedEvent(),
getEventTarget()); getEventTarget());
m_eventQueue.removeHandler(IScreen::getClipboardGrabbedEvent(), m_eventQueue->removeHandler(IScreen::getClipboardGrabbedEvent(),
getEventTarget()); getEventTarget());
delete m_server; delete m_server;
m_server = NULL; m_server = NULL;
@ -577,8 +581,8 @@ void
CClient::cleanupTimer() CClient::cleanupTimer()
{ {
if (m_timer != NULL) { if (m_timer != NULL) {
m_eventQueue.removeHandler(CEvent::kTimer, m_timer); m_eventQueue->removeHandler(CEvent::kTimer, m_timer);
m_eventQueue.deleteTimer(m_timer); m_eventQueue->deleteTimer(m_timer);
m_timer = NULL; m_timer = NULL;
} }
} }
@ -708,7 +712,7 @@ CClient::handleHello(const CEvent&, void*)
// receive another event for already pending messages so we fake // receive another event for already pending messages so we fake
// one. // one.
if (m_stream->isReady()) { if (m_stream->isReady()) {
m_eventQueue.addEvent(CEvent(m_stream->getInputReadyEvent(), m_eventQueue->addEvent(CEvent(m_stream->getInputReadyEvent(),
m_stream->getEventTarget())); m_stream->getEventTarget()));
} }
} }

View File

@ -32,6 +32,7 @@ class ISocketFactory;
namespace synergy { class IStream; } namespace synergy { class IStream; }
class IStreamFilterFactory; class IStreamFilterFactory;
class IEventQueue; class IEventQueue;
class CCryptoStream;
//! Synergy client //! Synergy client
/*! /*!
@ -46,22 +47,23 @@ public:
CString m_what; CString m_what;
}; };
protected:
CClient(IEventQueue& eventQueue);
public: public:
/*! /*!
This client will attempt to connect to the server using \p name This client will attempt to connect to the server using \p name
as its name and \p address as the server's address and \p factory as its name and \p address as the server's address and \p factory
to create the socket. \p screen is the local screen. to create the socket. \p screen is the local screen.
*/ */
CClient(IEventQueue& eventQueue, CClient(IEventQueue* eventQueue,
const CString& name, const CNetworkAddress& address, const CString& name, const CNetworkAddress& address,
ISocketFactory* socketFactory, ISocketFactory* socketFactory,
IStreamFilterFactory* streamFilterFactory, IStreamFilterFactory* streamFilterFactory,
CScreen* screen); CScreen* screen);
~CClient(); ~CClient();
#ifdef TEST_ENV
CClient() { }
#endif
//! @name manipulators //! @name manipulators
//@{ //@{
@ -82,7 +84,10 @@ public:
/*! /*!
Notifies the client that the connection handshake has completed. Notifies the client that the connection handshake has completed.
*/ */
void handshakeComplete(); virtual void handshakeComplete();
//! Set crypto IV
virtual void setCryptoIv(const UInt8* iv);
//@} //@}
//! @name accessors //! @name accessors
@ -190,6 +195,9 @@ private:
void handleGameDeviceTimingResp(const CEvent& event, void*); void handleGameDeviceTimingResp(const CEvent& event, void*);
void handleGameDeviceFeedback(const CEvent& event, void*); void handleGameDeviceFeedback(const CEvent& event, void*);
public:
bool m_mock;
private: private:
CString m_name; CString m_name;
CNetworkAddress m_serverAddress; CNetworkAddress m_serverAddress;
@ -207,8 +215,8 @@ private:
bool m_sentClipboard[kClipboardEnd]; bool m_sentClipboard[kClipboardEnd];
IClipboard::Time m_timeClipboard[kClipboardEnd]; IClipboard::Time m_timeClipboard[kClipboardEnd];
CString m_dataClipboard[kClipboardEnd]; CString m_dataClipboard[kClipboardEnd];
IEventQueue& m_eventQueue; IEventQueue* m_eventQueue;
bool m_mock; CCryptoStream* m_cryptoStream;
static CEvent::Type s_connectedEvent; static CEvent::Type s_connectedEvent;
static CEvent::Type s_connectionFailedEvent; static CEvent::Type s_connectionFailedEvent;

View File

@ -35,10 +35,9 @@
// CServerProxy // CServerProxy
// //
CServerProxy::CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue& eventQueue) : CServerProxy::CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue* eventQueue) :
m_client(client), m_client(client),
m_stream(stream), m_stream(stream),
m_cryptoStream(NULL),
m_seqNum(0), m_seqNum(0),
m_compressMouse(false), m_compressMouse(false),
m_compressMouseRelative(false), m_compressMouseRelative(false),
@ -60,7 +59,7 @@ CServerProxy::CServerProxy(CClient* client, synergy::IStream* stream, IEventQueu
m_modifierTranslationTable[id] = id; m_modifierTranslationTable[id] = id;
// handle data on stream // handle data on stream
m_eventQueue.adoptHandler(m_stream->getInputReadyEvent(), m_eventQueue->adoptHandler(m_stream->getInputReadyEvent(),
m_stream->getEventTarget(), m_stream->getEventTarget(),
new TMethodEventJob<CServerProxy>(this, new TMethodEventJob<CServerProxy>(this,
&CServerProxy::handleData)); &CServerProxy::handleData));
@ -72,7 +71,7 @@ CServerProxy::CServerProxy(CClient* client, synergy::IStream* stream, IEventQueu
CServerProxy::~CServerProxy() CServerProxy::~CServerProxy()
{ {
setKeepAliveRate(-1.0); setKeepAliveRate(-1.0);
m_eventQueue.removeHandler(m_stream->getInputReadyEvent(), m_eventQueue->removeHandler(m_stream->getInputReadyEvent(),
m_stream->getEventTarget()); m_stream->getEventTarget());
} }
@ -80,14 +79,14 @@ void
CServerProxy::resetKeepAliveAlarm() CServerProxy::resetKeepAliveAlarm()
{ {
if (m_keepAliveAlarmTimer != NULL) { if (m_keepAliveAlarmTimer != NULL) {
m_eventQueue.removeHandler(CEvent::kTimer, m_keepAliveAlarmTimer); m_eventQueue->removeHandler(CEvent::kTimer, m_keepAliveAlarmTimer);
m_eventQueue.deleteTimer(m_keepAliveAlarmTimer); m_eventQueue->deleteTimer(m_keepAliveAlarmTimer);
m_keepAliveAlarmTimer = NULL; m_keepAliveAlarmTimer = NULL;
} }
if (m_keepAliveAlarm > 0.0) { if (m_keepAliveAlarm > 0.0) {
m_keepAliveAlarmTimer = m_keepAliveAlarmTimer =
m_eventQueue.newOneShotTimer(m_keepAliveAlarm, NULL); m_eventQueue->newOneShotTimer(m_keepAliveAlarm, NULL);
m_eventQueue.adoptHandler(CEvent::kTimer, m_keepAliveAlarmTimer, m_eventQueue->adoptHandler(CEvent::kTimer, m_keepAliveAlarmTimer,
new TMethodEventJob<CServerProxy>(this, new TMethodEventJob<CServerProxy>(this,
&CServerProxy::handleKeepAliveAlarm)); &CServerProxy::handleKeepAliveAlarm));
} }
@ -306,6 +305,10 @@ CServerProxy::parseMessage(const UInt8* code)
gameDeviceTimingReq(); gameDeviceTimingReq();
} }
else if (memcmp(code, kMsgDCryptoIv, 4) == 0) {
cryptoIv();
}
else if (memcmp(code, kMsgCClose, 4) == 0) { else if (memcmp(code, kMsgCClose, 4) == 0) {
// server wants us to hangup // server wants us to hangup
LOG((CLOG_DEBUG1 "recv close")); LOG((CLOG_DEBUG1 "recv close"));
@ -826,6 +829,18 @@ CServerProxy::gameDeviceTimingReq()
m_client->gameDeviceTimingReq(); m_client->gameDeviceTimingReq();
} }
void
CServerProxy::cryptoIv()
{
// parse
CString s;
CProtocolUtil::readf(m_stream, kMsgDCryptoIv + 4, &s);
LOG((CLOG_DEBUG2 "recv crypto iv size=%i", s.size()));
// forward
m_client->setCryptoIv(reinterpret_cast<const UInt8*>(s.c_str()));
}
void void
CServerProxy::screensaver() CServerProxy::screensaver()
{ {

View File

@ -30,7 +30,6 @@ class CEventQueueTimer;
class IClipboard; class IClipboard;
namespace synergy { class IStream; } namespace synergy { class IStream; }
class IEventQueue; class IEventQueue;
class CCryptoStream;
//! Proxy for server //! Proxy for server
/*! /*!
@ -43,7 +42,7 @@ public:
Process messages from the server on \p stream and forward to Process messages from the server on \p stream and forward to
\p client. \p client.
*/ */
CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue& eventQueue); CServerProxy(CClient* client, synergy::IStream* stream, IEventQueue* eventQueue);
~CServerProxy(); ~CServerProxy();
//! @name manipulators //! @name manipulators
@ -57,6 +56,10 @@ public:
//@} //@}
#ifdef TEST_ENV
void handleDataForTest() { handleData(NULL, NULL); }
#endif
protected: protected:
enum EResult { kOkay, kUnknown, kDisconnect }; enum EResult { kOkay, kUnknown, kDisconnect };
EResult parseHandshakeMessage(const UInt8* code); EResult parseHandshakeMessage(const UInt8* code);
@ -96,6 +99,7 @@ private:
void gameDeviceSticks(); void gameDeviceSticks();
void gameDeviceTriggers(); void gameDeviceTriggers();
void gameDeviceTimingReq(); void gameDeviceTimingReq();
void cryptoIv();
void screensaver(); void screensaver();
void resetOptions(); void resetOptions();
void setOptions(); void setOptions();
@ -107,7 +111,6 @@ private:
CClient* m_client; CClient* m_client;
synergy::IStream* m_stream; synergy::IStream* m_stream;
CCryptoStream* m_cryptoStream;
UInt32 m_seqNum; UInt32 m_seqNum;
@ -124,7 +127,7 @@ private:
CEventQueueTimer* m_keepAliveAlarmTimer; CEventQueueTimer* m_keepAliveAlarmTimer;
MessageParser m_parser; MessageParser m_parser;
IEventQueue& m_eventQueue; IEventQueue* m_eventQueue;
}; };
#endif #endif

View File

@ -24,21 +24,21 @@
// CStreamFilter // CStreamFilter
// //
CStreamFilter::CStreamFilter(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream) : CStreamFilter::CStreamFilter(IEventQueue* eventQueue, synergy::IStream* stream, bool adoptStream) :
IStream(eventQueue), IStream(eventQueue),
m_stream(stream), m_stream(stream),
m_adopted(adoptStream) m_adopted(adoptStream)
{ {
// replace handlers for m_stream // replace handlers for m_stream
m_eventQueue.removeHandlers(m_stream->getEventTarget()); getEventQueue().removeHandlers(m_stream->getEventTarget());
m_eventQueue.adoptHandler(CEvent::kUnknown, m_stream->getEventTarget(), getEventQueue().adoptHandler(CEvent::kUnknown, m_stream->getEventTarget(),
new TMethodEventJob<CStreamFilter>(this, new TMethodEventJob<CStreamFilter>(this,
&CStreamFilter::handleUpstreamEvent)); &CStreamFilter::handleUpstreamEvent));
} }
CStreamFilter::~CStreamFilter() CStreamFilter::~CStreamFilter()
{ {
m_eventQueue.removeHandler(CEvent::kUnknown, m_stream->getEventTarget()); getEventQueue().removeHandler(CEvent::kUnknown, m_stream->getEventTarget());
if (m_adopted) { if (m_adopted) {
delete m_stream; delete m_stream;
} }
@ -107,7 +107,7 @@ CStreamFilter::getStream() const
void void
CStreamFilter::filterEvent(const CEvent& event) CStreamFilter::filterEvent(const CEvent& event)
{ {
m_eventQueue.dispatchEvent(CEvent(event.getType(), getEventQueue().dispatchEvent(CEvent(event.getType(),
getEventTarget(), event.getData())); getEventTarget(), event.getData()));
} }

View File

@ -34,7 +34,7 @@ public:
this object takes ownership of the stream and will delete it in the this object takes ownership of the stream and will delete it in the
d'tor. d'tor.
*/ */
CStreamFilter(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream = true); CStreamFilter(IEventQueue* eventQueue, synergy::IStream* stream, bool adoptStream = true);
virtual ~CStreamFilter(); virtual ~CStreamFilter();
// IStream overrides // IStream overrides

View File

@ -34,34 +34,41 @@ CEvent::Type IStream::s_outputShutdownEvent = CEvent::kUnknown;
CEvent::Type CEvent::Type
IStream::getInputReadyEvent() IStream::getInputReadyEvent()
{ {
return m_eventQueue.registerTypeOnce(s_inputReadyEvent, return m_eventQueue->registerTypeOnce(s_inputReadyEvent,
"IStream::inputReady"); "IStream::inputReady");
} }
CEvent::Type CEvent::Type
IStream::getOutputFlushedEvent() IStream::getOutputFlushedEvent()
{ {
return m_eventQueue.registerTypeOnce(s_outputFlushedEvent, return m_eventQueue->registerTypeOnce(s_outputFlushedEvent,
"IStream::outputFlushed"); "IStream::outputFlushed");
} }
CEvent::Type CEvent::Type
IStream::getOutputErrorEvent() IStream::getOutputErrorEvent()
{ {
return m_eventQueue.registerTypeOnce(s_outputErrorEvent, return m_eventQueue->registerTypeOnce(s_outputErrorEvent,
"IStream::outputError"); "IStream::outputError");
} }
CEvent::Type CEvent::Type
IStream::getInputShutdownEvent() IStream::getInputShutdownEvent()
{ {
return m_eventQueue.registerTypeOnce(s_inputShutdownEvent, return m_eventQueue->registerTypeOnce(s_inputShutdownEvent,
"IStream::inputShutdown"); "IStream::inputShutdown");
} }
CEvent::Type CEvent::Type
IStream::getOutputShutdownEvent() IStream::getOutputShutdownEvent()
{ {
return m_eventQueue.registerTypeOnce(s_outputShutdownEvent, return m_eventQueue->registerTypeOnce(s_outputShutdownEvent,
"IStream::outputShutdown"); "IStream::outputShutdown");
} }
IEventQueue&
IStream::getEventQueue() const
{
assert(m_eventQueue != NULL);
return *m_eventQueue;
}

View File

@ -33,8 +33,8 @@ Defines the interface for all streams.
*/ */
class IStream : public IInterface { class IStream : public IInterface {
public: public:
IStream() : m_eventQueue(*EVENTQUEUE) { } IStream() : m_eventQueue(EVENTQUEUE) { }
IStream(IEventQueue& eventQueue) : m_eventQueue(eventQueue) { } IStream(IEventQueue* eventQueue) : m_eventQueue(eventQueue) { }
//! @name manipulators //! @name manipulators
//@{ //@{
@ -156,9 +156,10 @@ public:
*/ */
virtual CEvent::Type getOutputShutdownEvent(); virtual CEvent::Type getOutputShutdownEvent();
//@} //! Get the event queue
IEventQueue& getEventQueue() const;
IEventQueue& m_eventQueue; //@}
private: private:
static CEvent::Type s_inputReadyEvent; static CEvent::Type s_inputReadyEvent;
@ -166,6 +167,8 @@ private:
static CEvent::Type s_outputErrorEvent; static CEvent::Type s_outputErrorEvent;
static CEvent::Type s_inputShutdownEvent; static CEvent::Type s_inputShutdownEvent;
static CEvent::Type s_outputShutdownEvent; static CEvent::Type s_outputShutdownEvent;
IEventQueue* m_eventQueue;
}; };
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,13 +24,14 @@
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#include "CServer.h" #include "CServer.h"
#include "CCryptoStream.h"
// //
// CClientProxy1_4 // CClientProxy1_4
// //
CClientProxy1_4::CClientProxy1_4(const CString& name, synergy::IStream* stream, CServer* server) : CClientProxy1_4::CClientProxy1_4(const CString& name, synergy::IStream* stream, CServer* server, IEventQueue* eventQueue) :
CClientProxy1_3(name, stream), m_server(server) CClientProxy1_3(name, stream, eventQueue), m_server(server)
{ {
assert(m_server != NULL); assert(m_server != NULL);
} }
@ -67,6 +68,43 @@ CClientProxy1_4::gameDeviceTimingReq()
CProtocolUtil::writef(getStream(), kMsgCGameTimingReq); 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 bool
CClientProxy1_4::parseMessage(const UInt8* code) CClientProxy1_4::parseMessage(const UInt8* code)
{ {

View File

@ -26,7 +26,7 @@ class CServer;
//! Proxy for client implementing protocol version 1.4 //! Proxy for client implementing protocol version 1.4
class CClientProxy1_4 : public CClientProxy1_3 { class CClientProxy1_4 : public CClientProxy1_3 {
public: 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(); ~CClientProxy1_4();
// IClient overrides // IClient overrides
@ -34,6 +34,12 @@ public:
virtual void gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2); virtual void gameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2);
virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2); virtual void gameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2);
virtual void gameDeviceTimingReq(); 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: protected:
// CClientProxy overrides // CClientProxy overrides

View File

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

View File

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

View File

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

View File

@ -396,7 +396,7 @@ CClient*
CClientApp::openClient(const CString& name, const CNetworkAddress& address, CScreen* screen) CClientApp::openClient(const CString& name, const CNetworkAddress& address, CScreen* screen)
{ {
CClient* client = new CClient( CClient* client = new CClient(
*EVENTQUEUE, name, address, new CTCPSocketFactory, NULL, screen); EVENTQUEUE, name, address, new CTCPSocketFactory, NULL, screen);
try { try {
EVENTQUEUE->adoptHandler( EVENTQUEUE->adoptHandler(

View File

@ -22,7 +22,7 @@
using namespace CryptoPP; using namespace CryptoPP;
CCryptoStream::CCryptoStream(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream) : CCryptoStream::CCryptoStream(IEventQueue* eventQueue, synergy::IStream* stream, bool adoptStream) :
CStreamFilter(eventQueue, stream, adoptStream), CStreamFilter(eventQueue, stream, adoptStream),
m_key(NULL), m_key(NULL),
m_keyLength(0) m_keyLength(0)

View File

@ -32,7 +32,7 @@ Encrypts (on write) and decrypts (on read) to and from an underlying stream.
*/ */
class CCryptoStream : public CStreamFilter { class CCryptoStream : public CStreamFilter {
public: public:
CCryptoStream(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream = true); CCryptoStream(IEventQueue* eventQueue, synergy::IStream* stream, bool adoptStream = true);
virtual ~CCryptoStream(); virtual ~CCryptoStream();
//! @name manipulators //! @name manipulators

View File

@ -28,7 +28,7 @@
// //
CPacketStreamFilter::CPacketStreamFilter(synergy::IStream* stream, bool adoptStream) : CPacketStreamFilter::CPacketStreamFilter(synergy::IStream* stream, bool adoptStream) :
CStreamFilter(*EVENTQUEUE, stream, adoptStream), CStreamFilter(EVENTQUEUE, stream, adoptStream),
m_size(0), m_size(0),
m_inputShutdown(false) m_inputShutdown(false)
{ {

View File

@ -50,6 +50,7 @@ const char* kMsgDGameButtons = "DGBT%1i%2i";
const char* kMsgDGameSticks = "DGST%1i%2i%2i%2i%2i"; const char* kMsgDGameSticks = "DGST%1i%2i%2i%2i%2i";
const char* kMsgDGameTriggers = "DGTR%1i%1i%1i"; const char* kMsgDGameTriggers = "DGTR%1i%1i%1i";
const char* kMsgDGameFeedback = "DGFB%1i%2i%2i"; const char* kMsgDGameFeedback = "DGFB%1i%2i%2i";
const char* kMsgDCryptoIv = "DCIV%s";
const char* kMsgQInfo = "QINF"; const char* kMsgQInfo = "QINF";
const char* kMsgEIncompatible = "EICV%2i%2i"; const char* kMsgEIncompatible = "EICV%2i%2i";
const char* kMsgEBusy = "EBSY"; const char* kMsgEBusy = "EBSY";

View File

@ -283,6 +283,11 @@ extern const char* kMsgDInfo;
// pairs. // pairs.
extern const char* kMsgDSetOptions; extern const char* kMsgDSetOptions;
// crypto iv: primary -> secondary
// sends a new iv (initialization vector) to the client for the
// cryptography stream.
extern const char* kMsgDCryptoIv;
// //
// query codes // query codes
// //

View File

@ -20,6 +20,8 @@ set(h
synergy/CMockKeyMap.h synergy/CMockKeyMap.h
client/CMockClient.h client/CMockClient.h
io/CMockStream.h io/CMockStream.h
server/CMockServer.h
io/CMockCryptoStream.h
) )
set(src set(src
@ -29,12 +31,14 @@ set(src
synergy/CKeyStateTests.cpp synergy/CKeyStateTests.cpp
client/CServerProxyTests.cpp client/CServerProxyTests.cpp
synergy/CCryptoStreamTests.cpp synergy/CCryptoStreamTests.cpp
server/CClientProxyTests.cpp
) )
set(inc set(inc
../../lib/arch ../../lib/arch
../../lib/base ../../lib/base
../../lib/client ../../lib/client
../../lib/server
../../lib/common ../../lib/common
../../lib/io ../../lib/io
../../lib/mt ../../lib/mt
@ -63,4 +67,4 @@ endif()
include_directories(${inc}) include_directories(${inc})
add_executable(unittests ${src}) add_executable(unittests ${src})
target_link_libraries(unittests target_link_libraries(unittests
arch base client common io net platform server synergy mt gtest gmock cryptopp ${libs}) arch base client server common io net platform server synergy mt gtest gmock cryptopp ${libs})

View File

@ -19,6 +19,8 @@
#pragma once #pragma once
#include <gmock/gmock.h> #include <gmock/gmock.h>
#define TEST_ENV
#include "CClient.h" #include "CClient.h"
class IEventQueue; class IEventQueue;
@ -26,6 +28,9 @@ class IEventQueue;
class CMockClient : public CClient class CMockClient : public CClient
{ {
public: public:
CMockClient(IEventQueue& eventQueue) : CClient(eventQueue) { m_mock = true; } CMockClient() { m_mock = true; }
MOCK_METHOD2(mouseMove, void(SInt32, SInt32)); MOCK_METHOD2(mouseMove, void(SInt32, SInt32));
MOCK_METHOD1(setOptions, void(const COptionsList&));
MOCK_METHOD0(handshakeComplete, void());
MOCK_METHOD1(setCryptoIv, void(const UInt8*));
}; };

View File

@ -16,11 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <gtest/gtest.h>
#define TEST_ENV #define TEST_ENV
#include "Global.h"
#include <gtest/gtest.h>
#include "CServerProxy.h" #include "CServerProxy.h"
#include "CMockClient.h" #include "CMockClient.h"
#include "CMockStream.h" #include "CMockStream.h"
@ -32,60 +30,77 @@ using ::testing::Invoke;
using ::testing::NiceMock; using ::testing::NiceMock;
using ::testing::AnyNumber; using ::testing::AnyNumber;
int streamReads = 0; const UInt8 mouseMove_bufferLen = 16;
UInt8 mouseMove_buffer[mouseMove_bufferLen];
UInt32 mouseMove_bufferIndex = 0;
UInt32 mouseMove_mockRead(void* buffer, UInt32 n);
UInt32 const UInt8 cryptoIv_bufferLen = 20;
streamRead(void* buffer, UInt32 n); UInt8 cryptoIv_buffer[cryptoIv_bufferLen];
UInt32 cryptoIv_bufferIndex = 0;
CString cryptoIv_result;
UInt32 cryptoIv_mockRead(void* buffer, UInt32 n);
void cryptoIv_setCryptoIv(const UInt8*);
// TODO: fix linking in windows (works in unix for some reason). TEST(CServerProxyTests, mouseMove)
#if 0
TEST(CServerProxyTests, parseMessage_mouseMove_valuesCorrect)
{ {
NiceMock<CMockEventQueue> eventQueue; NiceMock<CMockEventQueue> eventQueue;
CMockClient client(eventQueue); NiceMock<CMockClient> client;
CMockStream stream(eventQueue); NiceMock<CMockStream> stream;
ON_CALL(stream, read(_, _)).WillByDefault(Invoke(streamRead)); ON_CALL(stream, read(_, _)).WillByDefault(Invoke(mouseMove_mockRead));
EXPECT_CALL(stream, read(_, _)).Times(4);
EXPECT_CALL(stream, write(_, _)).Times(1);
EXPECT_CALL(stream, isReady()).Times(1);
EXPECT_CALL(stream, getEventTarget()).Times(AnyNumber());
CServerProxy serverProxy(&client, &stream, eventQueue); EXPECT_CALL(client, mouseMove(1, 2)).Times(1);
// skip handshake, go straight to normal parser. const char data[] = "DSOP\0\0\0\0DMMV\0\1\0\2";
serverProxy.m_parser = &CServerProxy::parseMessage; memcpy(mouseMove_buffer, data, sizeof(data));
// assert CServerProxy serverProxy(&client, &stream, &eventQueue);
EXPECT_CALL(client, mouseMove(10, 20)); serverProxy.handleDataForTest();
}
serverProxy.handleData(NULL, NULL);
TEST(CServerProxyTests, cryptoIv)
{
NiceMock<CMockEventQueue> eventQueue;
NiceMock<CMockClient> client;
NiceMock<CMockStream> stream;
ON_CALL(stream, read(_, _)).WillByDefault(Invoke(cryptoIv_mockRead));
ON_CALL(client, setCryptoIv(_)).WillByDefault(Invoke(cryptoIv_setCryptoIv));
const char data[] = "DSOP\0\0\0\0DCIV\0\0\0\4mock";
memcpy(cryptoIv_buffer, data, sizeof(data));
CServerProxy serverProxy(&client, &stream, &eventQueue);
serverProxy.handleDataForTest();
EXPECT_EQ("mock", cryptoIv_result);
} }
#endif
UInt32 UInt32
streamRead(void* buffer, UInt32 n) mouseMove_mockRead(void* buffer, UInt32 n)
{ {
streamReads++; if (mouseMove_bufferIndex >= mouseMove_bufferLen) {
UInt8* code = (UInt8*)buffer;
if (streamReads == 1) {
code[0] = 'D';
code[1] = 'M';
code[2] = 'M';
code[3] = 'V';
return 4;
}
else if (streamReads == 2) {
code[0] = 0;
code[1] = 10;
return 2;
}
else if (streamReads == 3) {
code[0] = 0;
code[1] = 20;
return 2;
}
return 0; return 0;
}
memcpy(buffer, &mouseMove_buffer[mouseMove_bufferIndex], n);
mouseMove_bufferIndex += n;
return n;
}
UInt32
cryptoIv_mockRead(void* buffer, UInt32 n)
{
if (cryptoIv_bufferIndex >= cryptoIv_bufferLen) {
return 0;
}
memcpy(buffer, &cryptoIv_buffer[cryptoIv_bufferIndex], n);
cryptoIv_bufferIndex += n;
return n;
}
void
cryptoIv_setCryptoIv(const UInt8* data)
{
cryptoIv_result = reinterpret_cast<const char*>(data);
} }

View File

@ -0,0 +1,29 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2013 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <gmock/gmock.h>
#include "CCryptoStream.h"
class CMockCryptoStream : public CCryptoStream
{
public:
CMockCryptoStream(IEventQueue* eventQueue, IStream* stream) : CCryptoStream(eventQueue, stream, false) { }
MOCK_METHOD2(read, UInt32(void*, UInt32));
MOCK_METHOD2(write, void(const void*, UInt32));
};

View File

@ -26,13 +26,17 @@ class IEventQueue;
class CMockStream : public synergy::IStream class CMockStream : public synergy::IStream
{ {
public: public:
CMockStream(IEventQueue& eventQueue) : IStream(eventQueue) { } CMockStream() : synergy::IStream(NULL) { }
MOCK_METHOD0(close, void()); MOCK_METHOD0(close, void());
MOCK_METHOD2(read, UInt32(void*, UInt32)); MOCK_METHOD2(read, UInt32(void*, UInt32));
MOCK_METHOD2(write, void(const void*, UInt32)); MOCK_METHOD2(write, void(const void*, UInt32));
MOCK_METHOD0(flush, void()); MOCK_METHOD0(flush, void());
MOCK_METHOD0(shutdownInput, void()); MOCK_METHOD0(shutdownInput, void());
MOCK_METHOD0(shutdownOutput, void()); MOCK_METHOD0(shutdownOutput, void());
MOCK_METHOD0(getInputReadyEvent, CEvent::Type());
MOCK_METHOD0(getOutputErrorEvent, CEvent::Type());
MOCK_METHOD0(getInputShutdownEvent, CEvent::Type());
MOCK_METHOD0(getOutputShutdownEvent, CEvent::Type());
MOCK_CONST_METHOD0(getEventTarget, void*()); MOCK_CONST_METHOD0(getEventTarget, void*());
MOCK_CONST_METHOD0(isReady, bool()); MOCK_CONST_METHOD0(isReady, bool());
MOCK_CONST_METHOD0(getSize, UInt32()); MOCK_CONST_METHOD0(getSize, UInt32());

View File

@ -0,0 +1,96 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2013 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
#include "CClientProxy1_4.h"
#include "CMockServer.h"
#include "CMockStream.h"
#include "CMockCryptoStream.h"
#include "CMockEventQueue.h"
using ::testing::_;
using ::testing::NiceMock;
using ::testing::Invoke;
const byte g_key[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; // +\0, 32-byte/256-bit key.
const byte g_iv[] = "bbbbbbbbbbbbbb"; // +\0, AES block size = 16
const UInt8 cryptoIvWrite_bufferLen = 200;
UInt8 cryptoIvWrite_buffer[cryptoIvWrite_bufferLen];
UInt32 cryptoIvWrite_bufferIndex = 0;
void
cryptoIv_mockWrite(const void* in, UInt32 n);
TEST(CClientProxyTests, cryptoIvWrite)
{
NiceMock<CMockEventQueue> eventQueue;
NiceMock<CMockStream> innerStream;
NiceMock<CMockServer> server;
NiceMock<CMockCryptoStream>* stream = new NiceMock<CMockCryptoStream>(&eventQueue, &innerStream);
stream->setKeyWithIv(g_key, sizeof(g_key), g_iv);
ON_CALL(*stream, write(_, _)).WillByDefault(Invoke(cryptoIv_mockWrite));
CClientProxy1_4 clientProxy("stub", stream, &server, &eventQueue);
// DCIV, then DKDN.
cryptoIvWrite_bufferIndex = 0;
clientProxy.keyDown(1, 2, 3);
EXPECT_EQ('D', cryptoIvWrite_buffer[0]);
EXPECT_EQ('C', cryptoIvWrite_buffer[1]);
EXPECT_EQ('I', cryptoIvWrite_buffer[2]);
EXPECT_EQ('V', cryptoIvWrite_buffer[3]);
EXPECT_EQ('D', cryptoIvWrite_buffer[24]);
EXPECT_EQ('K', cryptoIvWrite_buffer[25]);
EXPECT_EQ('D', cryptoIvWrite_buffer[26]);
EXPECT_EQ('N', cryptoIvWrite_buffer[27]);
// DCIV, then DKUP.
cryptoIvWrite_bufferIndex = 0;
clientProxy.keyUp(1, 2, 3);
EXPECT_EQ('D', cryptoIvWrite_buffer[0]);
EXPECT_EQ('C', cryptoIvWrite_buffer[1]);
EXPECT_EQ('I', cryptoIvWrite_buffer[2]);
EXPECT_EQ('V', cryptoIvWrite_buffer[3]);
EXPECT_EQ('D', cryptoIvWrite_buffer[24]);
EXPECT_EQ('K', cryptoIvWrite_buffer[25]);
EXPECT_EQ('U', cryptoIvWrite_buffer[26]);
EXPECT_EQ('P', cryptoIvWrite_buffer[27]);
// DCIV, then DKRP.
cryptoIvWrite_bufferIndex = 0;
clientProxy.keyRepeat(1, 2, 4, 4);
EXPECT_EQ('D', cryptoIvWrite_buffer[0]);
EXPECT_EQ('C', cryptoIvWrite_buffer[1]);
EXPECT_EQ('I', cryptoIvWrite_buffer[2]);
EXPECT_EQ('V', cryptoIvWrite_buffer[3]);
EXPECT_EQ('D', cryptoIvWrite_buffer[24]);
EXPECT_EQ('K', cryptoIvWrite_buffer[25]);
EXPECT_EQ('R', cryptoIvWrite_buffer[26]);
EXPECT_EQ('P', cryptoIvWrite_buffer[27]);
}
void
cryptoIv_mockWrite(const void* in, UInt32 n)
{
if (cryptoIvWrite_bufferIndex >= cryptoIvWrite_bufferLen) {
return;
}
memcpy(&cryptoIvWrite_buffer[cryptoIvWrite_bufferIndex], in, n);
cryptoIvWrite_bufferIndex += n;
}

View File

@ -0,0 +1,31 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2013 Bolton Software Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <gmock/gmock.h>
#define TEST_ENV
#include "CServer.h"
class IEventQueue;
class CMockServer : public CServer
{
public:
CMockServer() : CServer() { }
};

View File

@ -23,6 +23,7 @@
using ::testing::_; using ::testing::_;
using ::testing::Invoke; using ::testing::Invoke;
using ::testing::NiceMock;
using namespace std; using namespace std;
@ -64,17 +65,12 @@ TEST(CCryptoTests, write)
buffer[2] = 'D'; buffer[2] = 'D';
buffer[3] = 'N'; buffer[3] = 'N';
CMockEventQueue eventQueue; NiceMock<CMockEventQueue> eventQueue;
CMockStream innerStream(eventQueue); NiceMock<CMockStream> innerStream;
ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(write_mockWrite)); ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(write_mockWrite));
EXPECT_CALL(innerStream, write(_, _)).Times(1);
EXPECT_CALL(innerStream, getEventTarget()).Times(3);
EXPECT_CALL(eventQueue, removeHandlers(_)).Times(1);
EXPECT_CALL(eventQueue, adoptHandler(_, _, _)).Times(1);
EXPECT_CALL(eventQueue, removeHandler(_, _)).Times(1);
CCryptoStream cs(eventQueue, &innerStream, false); CCryptoStream cs(&eventQueue, &innerStream, false);
cs.setKeyWithIv(g_key, sizeof(g_key), g_iv); cs.setKeyWithIv(g_key, sizeof(g_key), g_iv);
cs.write(buffer, size); cs.write(buffer, size);
@ -86,17 +82,12 @@ TEST(CCryptoTests, write)
TEST(CCryptoTests, read) TEST(CCryptoTests, read)
{ {
CMockEventQueue eventQueue; NiceMock<CMockEventQueue> eventQueue;
CMockStream innerStream(eventQueue); NiceMock<CMockStream> innerStream;
ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(read_mockRead)); ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(read_mockRead));
EXPECT_CALL(innerStream, read(_, _)).Times(1);
EXPECT_CALL(innerStream, getEventTarget()).Times(3);
EXPECT_CALL(eventQueue, removeHandlers(_)).Times(1);
EXPECT_CALL(eventQueue, adoptHandler(_, _, _)).Times(1);
EXPECT_CALL(eventQueue, removeHandler(_, _)).Times(1);
CCryptoStream cs(eventQueue, &innerStream, false); CCryptoStream cs(&eventQueue, &innerStream, false);
cs.setKeyWithIv(g_key, sizeof(g_key), g_iv); cs.setKeyWithIv(g_key, sizeof(g_key), g_iv);
g_read_buffer[0] = 254; g_read_buffer[0] = 254;
@ -116,19 +107,13 @@ TEST(CCryptoTests, read)
TEST(CCryptoTests, write4Read1) TEST(CCryptoTests, write4Read1)
{ {
CMockEventQueue eventQueue; NiceMock<CMockEventQueue> eventQueue;
CMockStream innerStream(eventQueue); NiceMock<CMockStream> innerStream;
ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(write4Read1_mockWrite)); ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(write4Read1_mockWrite));
ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(write4Read1_mockRead)); ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(write4Read1_mockRead));
EXPECT_CALL(innerStream, write(_, _)).Times(4);
EXPECT_CALL(innerStream, read(_, _)).Times(1);
EXPECT_CALL(innerStream, getEventTarget()).Times(6);
EXPECT_CALL(eventQueue, removeHandlers(_)).Times(2);
EXPECT_CALL(eventQueue, adoptHandler(_, _, _)).Times(2);
EXPECT_CALL(eventQueue, removeHandler(_, _)).Times(2);
CCryptoStream cs1(eventQueue, &innerStream, false); CCryptoStream cs1(&eventQueue, &innerStream, false);
cs1.setKeyWithIv(g_key, sizeof(g_key), g_iv); cs1.setKeyWithIv(g_key, sizeof(g_key), g_iv);
cs1.write("a", 1); cs1.write("a", 1);
@ -136,7 +121,7 @@ TEST(CCryptoTests, write4Read1)
cs1.write("c", 1); cs1.write("c", 1);
cs1.write("d", 1); cs1.write("d", 1);
CCryptoStream cs2(eventQueue, &innerStream, false); CCryptoStream cs2(&eventQueue, &innerStream, false);
cs2.setKeyWithIv(g_key, sizeof(g_key), g_iv); cs2.setKeyWithIv(g_key, sizeof(g_key), g_iv);
UInt8 buffer[4]; UInt8 buffer[4];
@ -150,19 +135,13 @@ TEST(CCryptoTests, write4Read1)
TEST(CCryptoTests, write1Read4) TEST(CCryptoTests, write1Read4)
{ {
CMockEventQueue eventQueue; NiceMock<CMockEventQueue> eventQueue;
CMockStream innerStream(eventQueue); NiceMock<CMockStream> innerStream;
ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(write1Read4_mockWrite)); ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(write1Read4_mockWrite));
ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(write1Read4_mockRead)); ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(write1Read4_mockRead));
EXPECT_CALL(innerStream, write(_, _)).Times(1);
EXPECT_CALL(innerStream, read(_, _)).Times(4);
EXPECT_CALL(innerStream, getEventTarget()).Times(6);
EXPECT_CALL(eventQueue, removeHandlers(_)).Times(2);
EXPECT_CALL(eventQueue, adoptHandler(_, _, _)).Times(2);
EXPECT_CALL(eventQueue, removeHandler(_, _)).Times(2);
CCryptoStream cs1(eventQueue, &innerStream, false); CCryptoStream cs1(&eventQueue, &innerStream, false);
cs1.setKeyWithIv(g_key, sizeof(g_key), g_iv); cs1.setKeyWithIv(g_key, sizeof(g_key), g_iv);
UInt8 bufferIn[4]; UInt8 bufferIn[4];
@ -172,7 +151,7 @@ TEST(CCryptoTests, write1Read4)
bufferIn[3] = 'd'; bufferIn[3] = 'd';
cs1.write(bufferIn, 4); cs1.write(bufferIn, 4);
CCryptoStream cs2(eventQueue, &innerStream, false); CCryptoStream cs2(&eventQueue, &innerStream, false);
cs2.setKeyWithIv(g_key, sizeof(g_key), g_iv); cs2.setKeyWithIv(g_key, sizeof(g_key), g_iv);
UInt8 bufferOut[4]; UInt8 bufferOut[4];
@ -189,22 +168,16 @@ TEST(CCryptoTests, write1Read4)
TEST(CCryptoTests, readWriteIvChanged) TEST(CCryptoTests, readWriteIvChanged)
{ {
CMockEventQueue eventQueue; NiceMock<CMockEventQueue> eventQueue;
CMockStream innerStream(eventQueue); NiceMock<CMockStream> innerStream;
ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(readWriteIvChanged_mockWrite)); ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(readWriteIvChanged_mockWrite));
ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(readWriteIvChanged_mockRead)); ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(readWriteIvChanged_mockRead));
EXPECT_CALL(innerStream, write(_, _)).Times(2);
EXPECT_CALL(innerStream, read(_, _)).Times(2);
EXPECT_CALL(innerStream, getEventTarget()).Times(6);
EXPECT_CALL(eventQueue, removeHandlers(_)).Times(2);
EXPECT_CALL(eventQueue, adoptHandler(_, _, _)).Times(2);
EXPECT_CALL(eventQueue, removeHandler(_, _)).Times(2);
const byte iv1[] = "bbbbbbbbbbbbbbb"; const byte iv1[] = "bbbbbbbbbbbbbbb";
const byte iv2[] = "ccccccccccccccc"; const byte iv2[] = "ccccccccccccccc";
CCryptoStream cs1(eventQueue, &innerStream, false); CCryptoStream cs1(&eventQueue, &innerStream, false);
cs1.setKeyWithIv(g_key, sizeof(g_key), iv1); cs1.setKeyWithIv(g_key, sizeof(g_key), iv1);
UInt8 bufferIn[4]; UInt8 bufferIn[4];
@ -214,7 +187,7 @@ TEST(CCryptoTests, readWriteIvChanged)
bufferIn[3] = 'd'; bufferIn[3] = 'd';
cs1.write(bufferIn, 4); cs1.write(bufferIn, 4);
CCryptoStream cs2(eventQueue, &innerStream, false); CCryptoStream cs2(&eventQueue, &innerStream, false);
cs2.setKeyWithIv(g_key, sizeof(g_key), iv2); cs2.setKeyWithIv(g_key, sizeof(g_key), iv2);
UInt8 bufferOut[4]; UInt8 bufferOut[4];
@ -296,8 +269,6 @@ readWriteIvChanged_mockRead(void* out, UInt32 n)
return n; return n;
} }
// TODO: macro?
void void
readWriteIvChangeTrigger_mockWrite(const void* in, UInt32 n) readWriteIvChangeTrigger_mockWrite(const void* in, UInt32 n)
{ {