Patch by Jerry:

* wrote CCryptoStream and supporting unit tests
* changed CStreamFilter to accept CMockEventQueue
* changed CStreamFilter's dtor to virtual because it is inherited
This commit is contained in:
Nick Bolton 2013-04-04 16:17:25 +00:00
parent 7040905632
commit 3aaebd9e50
13 changed files with 227 additions and 111 deletions

View File

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

View File

@ -20,6 +20,7 @@
#define CSTREAMFILTER_H
#include "IStream.h"
#include "IEventQueue.h"
//! A stream filter
/*!
@ -33,8 +34,8 @@ public:
this object takes ownership of the stream and will delete it in the
d'tor.
*/
CStreamFilter(synergy::IStream* stream, bool adoptStream = true);
~CStreamFilter();
CStreamFilter(IEventQueue& eventQueue, synergy::IStream* stream, bool adoptStream = true);
virtual ~CStreamFilter();
// IStream overrides
// These all just forward to the underlying stream except getEventTarget.

View File

@ -158,9 +158,9 @@ public:
//@}
private:
IEventQueue& m_eventQueue;
IEventQueue& m_eventQueue;
private:
static CEvent::Type s_inputReadyEvent;
static CEvent::Type s_outputFlushedEvent;
static CEvent::Type s_outputErrorEvent;

View File

@ -1,42 +0,0 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012 Bolton Software Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* 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 "CCrypto.h"
#include "cryptlib.h"
#include "default.h"
#include "modes.h"
#include "aes.h"
#include "randpool.h"
#include "files.h"
#include "hex.h"
#include "rsa.h"
#include <time.h>
using namespace CryptoPP;
static OFB_Mode<AES>::Encryption s_globalRNG;
void CCrypto::test()
{
std::string seed = IntToString(time(NULL));
seed.resize(16);
s_globalRNG.SetKeyWithIV((byte *)seed.data(), 16, (byte *)seed.data());
}

View File

@ -1,24 +0,0 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012 Bolton Software Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* 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
class CCrypto {
public:
void test();
};

View File

@ -0,0 +1,58 @@
/*
* 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 "CCryptoStream.h"
// TODO: these are just for testing -- make sure they're gone by release!
const byte g_key1[] = "aaaaaaaaaaaaaaa";
const byte g_key2[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
const byte g_iv1[] = "aaaaaaaaaaaaaaa";
const byte g_iv2[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
using namespace CryptoPP;
CCryptoStream::CCryptoStream(IEventQueue& eventQueue, synergy::IStream* stream) :
CStreamFilter(eventQueue, stream, false)
{
m_encryption.SetKeyWithIV(g_key1, sizeof(g_key1), g_iv1);
m_decryption.SetKeyWithIV(g_key1, sizeof(g_key1), g_iv1);
}
CCryptoStream::~CCryptoStream()
{
}
UInt32
CCryptoStream::read(void* out, UInt32 n)
{
byte* in = new byte[n];
int result = getStream()->read(in, n);
m_decryption.ProcessData(static_cast<byte*>(out), in, n);
delete[] in;
return result;
}
void
CCryptoStream::write(const void* in, UInt32 n)
{
byte* out = new byte[n];
m_encryption.ProcessData(out, static_cast<const byte*>(in), n);
getStream()->write(out, n);
delete[] out;
}

View File

@ -0,0 +1,54 @@
/*
* 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 "BasicTypes.h"
#include "CStreamFilter.h"
#include "cryptopp562/gcm.h"
#include "cryptopp562/aes.h"
//! Bidirectional encrypted stream
/*!
Encrypts (on write) and decrypts (on read) to and from an underlying stream.
*/
class CCryptoStream : public CStreamFilter {
public:
CCryptoStream(IEventQueue& eventQueue, synergy::IStream* stream);
virtual ~CCryptoStream();
//! @name manipulators
//@{
//! Read from stream
/*!
Read up to \p n bytes into \p buffer to the stream using encryption.
Returns the number of bytes read by the underlying stream.
*/
virtual UInt32 read(void* out, UInt32 n);
//! Write to stream
/*!
Write \c n bytes from \c buffer to the stream using encryption.
*/
virtual void write(const void* in, UInt32 n);
private:
// TODO: allow user to change between GCM/CTR/CFB
CryptoPP::GCM<CryptoPP::AES>::Encryption m_encryption;
CryptoPP::GCM<CryptoPP::AES>::Decryption m_decryption;
};

View File

@ -50,7 +50,7 @@ set(inc
IAppUtil.h
CEventGameDevice.h
CVncClient.h
CCrypto.h
CCryptoStream.h
)
set(src
@ -82,7 +82,7 @@ set(src
CEventGameDevice.cpp
CVncClient.cpp
CGameDevice.cpp
CCrypto.cpp
CCryptoStream.cpp
)
if (WIN32)
@ -114,7 +114,7 @@ set(inc
../server
../synergy
../..
../../../tools/cryptopp562
../../../tools
)
if (UNIX)

View File

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

View File

@ -28,7 +28,7 @@ set(src
synergy/CClipboardTests.cpp
synergy/CKeyStateTests.cpp
client/CServerProxyTests.cpp
synergy/CCryptoTests.cpp
synergy/CCryptoStreamTests.cpp
)
set(inc
@ -43,7 +43,7 @@ set(inc
../../lib/synergy
../../../tools/gtest-1.6.0/include
../../../tools/gmock-1.6.0/include
# ../../../tools/cryptopp561
../../../tools
io
synergy
)

View File

@ -0,0 +1,97 @@
/*
* 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 "CCryptoStream.h"
#include "CMockStream.h"
#include "CMockEventQueue.h"
using ::testing::_;
using ::testing::Invoke;
using namespace std;
void assertWrite(const void* in, UInt32 n);
UInt8 mockRead(void* out, UInt32 n);
TEST(CCryptoTests, write)
{
const UInt32 size = 4;
UInt8* buffer = new UInt8[size];
buffer[0] = 'D';
buffer[1] = 'K';
buffer[2] = 'D';
buffer[3] = 'N';
CMockEventQueue eventQueue;
CMockStream innerStream(eventQueue);
ON_CALL(innerStream, write(_, _)).WillByDefault(Invoke(assertWrite));
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);
cs.write(buffer, size);
}
TEST(CCryptoTests, read)
{
CMockEventQueue eventQueue;
CMockStream innerStream(eventQueue);
ON_CALL(innerStream, read(_, _)).WillByDefault(Invoke(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);
const UInt32 size = 4;
UInt8* buffer = new UInt8[size];
cs.read(buffer, size);
EXPECT_EQ('D', buffer[0]);
EXPECT_EQ('K', buffer[1]);
EXPECT_EQ('D', buffer[2]);
EXPECT_EQ('N', buffer[3]);
}
void
assertWrite(const void* in, UInt32 n)
{
UInt8* buffer = static_cast<UInt8*>(const_cast<void*>(in));
EXPECT_EQ(55, buffer[0]);
EXPECT_EQ(142, buffer[1]);
EXPECT_EQ(189, buffer[2]);
EXPECT_EQ(237, buffer[3]);
}
UInt8
mockRead(void* out, UInt32 n)
{
UInt8* buffer = static_cast<UInt8*>(out);
buffer[0] = 55;
buffer[1] = 142;
buffer[2] = 189;
buffer[3] = 237;
return n;
}

View File

@ -1,28 +0,0 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012 Bolton Software Ltd.
* Copyright (C) 2011 Nick Bolton
*
* 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 "CCrypto.h"
using namespace std;
TEST(CCryptoTests, test)
{
CCrypto crypto;
crypto.test();
}

View File

@ -1,6 +1,5 @@
# synergy -- mouse and keyboard sharing utility
# Copyright (C) 2012 Bolton Software Ltd.
# Copyright (C) 2011 Nick Bolton
# 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