summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-09-02 23:38:13 +0200
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2012-09-02 23:38:13 +0200
commit532ed91a72b797e11c56f6a7032e8e8f6d582617 (patch)
tree366b6c6dcd2eb28acad5cbcbb4448f7e4581a5b4
parentAdded writing support to cByteBuffer (will be used by ProtoProxy) (diff)
downloadcuberite-532ed91a72b797e11c56f6a7032e8e8f6d582617.tar
cuberite-532ed91a72b797e11c56f6a7032e8e8f6d582617.tar.gz
cuberite-532ed91a72b797e11c56f6a7032e8e8f6d582617.tar.bz2
cuberite-532ed91a72b797e11c56f6a7032e8e8f6d582617.tar.lz
cuberite-532ed91a72b797e11c56f6a7032e8e8f6d582617.tar.xz
cuberite-532ed91a72b797e11c56f6a7032e8e8f6d582617.tar.zst
cuberite-532ed91a72b797e11c56f6a7032e8e8f6d582617.zip
-rw-r--r--ProtoProxy/Connection.cpp515
-rw-r--r--ProtoProxy/Connection.h59
-rw-r--r--ProtoProxy/Globals.h1
-rw-r--r--ProtoProxy/ProtoProxy.vcproj12
4 files changed, 569 insertions, 18 deletions
diff --git a/ProtoProxy/Connection.cpp b/ProtoProxy/Connection.cpp
index fe37d5003..5cc603641 100644
--- a/ProtoProxy/Connection.cpp
+++ b/ProtoProxy/Connection.cpp
@@ -11,12 +11,66 @@
+#define HANDLE_CLIENT_PACKET_READ(Proc, Type, Var) \
+ Type Var; \
+ { \
+ if (!m_ClientBuffer.Proc(Var)) \
+ { \
+ return; \
+ } \
+ }
+
+#define HANDLE_SERVER_PACKET_READ(Proc, Type, Var) \
+ Type Var; \
+ { \
+ if (!m_ServerBuffer.Proc(Var)) \
+ { \
+ return; \
+ } \
+ }
+
+#define CLIENTSEND(...) SendData(m_ClientSocket, __VA_ARGS__, "Client")
+#define SERVERSEND(...) SendData(m_ServerSocket, __VA_ARGS__, "Server")
+#define CLIENTENCRYPTSEND(...) SendEncryptedData(m_ClientSocket, m_ClientEncryptor, __VA_ARGS__, "Client")
+#define SERVERENCRYPTSEND(...) SendEncryptedData(m_ServerSocket, m_ServerEncryptor, __VA_ARGS__, "Server")
+
+#define MAX_ENC_LEN 1024
+
+
+
+typedef unsigned char Byte;
+
+
+
+
+
+enum
+{
+ PACKET_HANDSHAKE = 0x02,
+ PACKET_ENCRYPTION_KEY_RESPONSE = 0xfc,
+ PACKET_ENCRYPTION_KEY_REQUEST = 0xfd,
+ PACKET_PING = 0xfe,
+ PACKET_KICK = 0xff,
+} ;
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cConnection:
+
cConnection::cConnection(SOCKET a_ClientSocket, cServer & a_Server) :
m_Server(a_Server),
m_LogFile(NULL),
m_ClientSocket(a_ClientSocket),
m_ServerSocket(-1),
- m_BeginTick(clock())
+ m_BeginTick(clock()),
+ m_ClientState(csUnencrypted),
+ m_ServerState(csUnencrypted),
+ m_ClientBuffer(64 KiB),
+ m_ServerBuffer(64 KiB),
+ m_Nonce(0)
{
AString fnam;
Printf(fnam, "Log_%d.log", (int)time(NULL));
@@ -55,23 +109,26 @@ void cConnection::Run(void)
if (res <= 0)
{
printf("select() failed: %d; aborting client", WSAGetLastError());
- return;
+ break;
}
if (FD_ISSET(m_ServerSocket, &ReadFDs))
{
if (!RelayFromServer())
{
- return;
+ break;
}
}
if (FD_ISSET(m_ClientSocket, &ReadFDs))
{
if (!RelayFromClient())
{
- return;
+ break;
}
}
}
+ Log("Relaying ended, closing sockets");
+ closesocket(m_ServerSocket);
+ closesocket(m_ClientSocket);
}
@@ -88,8 +145,12 @@ void cConnection::Log(const char * a_Format, ...)
AString FullMsg;
Printf(FullMsg, "[%5.3f] %s\n", GetRelativeTime(), msg.c_str());
+ // Log to file:
cCSLock Lock(m_CSLog);
fputs(FullMsg.c_str(), m_LogFile);
+
+ // Log to screen:
+ puts(FullMsg.c_str());
}
@@ -107,8 +168,12 @@ void cConnection::DataLog(const void * a_Data, int a_Size, const char * a_Format
AString Hex;
Printf(FullMsg, "[%5.3f] %s\n%s", GetRelativeTime(), msg.c_str(), CreateHexDump(Hex, a_Data, a_Size, 16).c_str());
+ // Log to file:
cCSLock Lock(m_CSLog);
fputs(FullMsg.c_str(), m_LogFile);
+
+ // Log to screen:
+ puts(FullMsg.c_str());
}
@@ -131,6 +196,7 @@ bool cConnection::ConnectToServer(void)
printf("connection to server failed: %d\n", WSAGetLastError());
return false;
}
+ Log("Connected to SERVER");
return true;
}
@@ -148,14 +214,27 @@ bool cConnection::RelayFromServer(void)
return false;
}
- DataLog(Buffer, res, "Received %d bytes from the server", res);
- // TODO: Process the data
+ DataLog(Buffer, res, "Received %d bytes from the SERVER", res);
- res = send(m_ClientSocket, Buffer, res, 0);
- if (res <= 0)
+ switch (m_ServerState)
{
- Log("Client closed the socket: %d, %d; aborting connection", res, WSAGetLastError());
- return false;
+ case csUnencrypted:
+ {
+ return DecodeServersPackets(Buffer, res);
+ }
+ case csEncryptedUnderstood:
+ {
+ m_ServerDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
+ DataLog(Buffer, res, "Decrypted %d bytes from the SERVER", res);
+ return DecodeServersPackets(Buffer, res);
+ }
+ case csEncryptedUnknown:
+ {
+ m_ServerDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
+ DataLog(Buffer, res, "Decrypted %d bytes from the SERVER", res);
+ m_ClientEncryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
+ return CLIENTSEND(Buffer, res);
+ }
}
return true;
@@ -175,14 +254,27 @@ bool cConnection::RelayFromClient(void)
return false;
}
- DataLog(Buffer, res, "Received %d bytes from the client", res);
- // TODO: Process the data
+ DataLog(Buffer, res, "Received %d bytes from the CLIENT", res);
- res = send(m_ServerSocket, Buffer, res, 0);
- if (res <= 0)
+ switch (m_ClientState)
{
- Log("Server closed the socket: %d, %d; aborting connection", res, WSAGetLastError());
- return false;
+ case csUnencrypted:
+ {
+ return DecodeClientsPackets(Buffer, res);
+ }
+ case csEncryptedUnderstood:
+ {
+ m_ClientDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
+ DataLog(Buffer, res, "Decrypted %d bytes from the CLIENT", res);
+ return DecodeClientsPackets(Buffer, res);
+ }
+ case csEncryptedUnknown:
+ {
+ m_ClientDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
+ DataLog(Buffer, res, "Decrypted %d bytes from the CLIENT", res);
+ m_ServerEncryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
+ return SERVERSEND(Buffer, res);
+ }
}
return true;
@@ -201,3 +293,394 @@ double cConnection::GetRelativeTime(void)
+
+bool cConnection::SendData(SOCKET a_Socket, const char * a_Data, int a_Size, const char * a_Peer)
+{
+ DataLog(a_Data, a_Size, "Sending data to %s", a_Peer);
+
+ int res = send(a_Socket, a_Data, a_Size, 0);
+ if (res <= 0)
+ {
+ Log("%s closed the socket: %d, %d; aborting connection", a_Peer, res, WSAGetLastError());
+ return false;
+ }
+ return true;
+}
+
+
+
+
+
+bool cConnection::SendData(SOCKET a_Socket, cByteBuffer & a_Data, const char * a_Peer)
+{
+ AString All;
+ a_Data.ReadAll(All);
+ a_Data.CommitRead();
+ return SendData(a_Socket, All.data(), All.size(), a_Peer);
+}
+
+
+
+
+
+bool cConnection::SendEncryptedData(SOCKET a_Socket, Encryptor & a_Encryptor, const char * a_Data, int a_Size, const char * a_Peer)
+{
+ DataLog(a_Data, a_Size, "Sending encrypted %d bytes to %s", a_Size, a_Peer);
+ const byte * Data = (const byte *)a_Data;
+ while (a_Size > 0)
+ {
+ byte Buffer[512];
+ int NumBytes = (a_Size > sizeof(Buffer)) ? sizeof(Buffer) : a_Size;
+ a_Encryptor.ProcessData(Buffer, Data, NumBytes);
+ bool res = SendData(a_Socket, (const char *)Buffer, NumBytes, a_Peer);
+ if (!res)
+ {
+ return false;
+ }
+ Data += NumBytes;
+ a_Size -= NumBytes;
+ }
+ return true;
+}
+
+
+
+
+
+bool cConnection::SendEncryptedData(SOCKET a_Socket, Encryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer)
+{
+ AString All;
+ a_Data.ReadAll(All);
+ a_Data.CommitRead();
+ return SendEncryptedData(a_Socket, a_Encryptor, All.data(), All.size(), a_Peer);
+}
+
+
+
+
+
+bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size)
+{
+ if (!m_ClientBuffer.Write(a_Data, a_Size))
+ {
+ Log("Too much queued data for the server, aborting connection");
+ return false;
+ }
+
+ while (m_ClientBuffer.CanReadBytes(1))
+ {
+ unsigned char PacketType;
+ m_ClientBuffer.ReadByte(PacketType);
+ switch (PacketType)
+ {
+ case PACKET_ENCRYPTION_KEY_RESPONSE: HandleClientEncryptionKeyResponse(); break;
+ case PACKET_HANDSHAKE: HandleClientHandshake(); break;
+ case PACKET_PING: HandleClientPing(); break;
+ default:
+ {
+ if (m_ClientState == csEncryptedUnderstood)
+ {
+ Log("Unknown packet 0x%02x from the client while encrypted; continuing to relay blind only", PacketType);
+ m_ClientState = csEncryptedUnknown;
+ m_ClientBuffer.ResetRead();
+ if (m_ServerState == csUnencrypted)
+ {
+ SERVERSEND(m_ClientBuffer);
+ }
+ else
+ {
+ SERVERENCRYPTSEND(m_ClientBuffer);
+ }
+ return true;
+ }
+ else
+ {
+ Log("Unknown packet 0x%02x from the client while unencrypted; aborting connection", PacketType);
+ return false;
+ }
+ }
+ } // switch (PacketType)
+ m_ClientBuffer.CommitRead();
+ } // while (CanReadBytes(1))
+ return true;
+}
+
+
+
+
+
+bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
+{
+ if (!m_ServerBuffer.Write(a_Data, a_Size))
+ {
+ Log("Too much queued data for the client, aborting connection");
+ return false;
+ }
+
+ if (
+ (m_ServerState == csEncryptedUnderstood) &&
+ (m_ClientState == csUnencrypted)
+ )
+ {
+ // Client hasn't finished encryption handshake yet, don't send them any data yet
+ }
+
+ while (m_ServerBuffer.CanReadBytes(1))
+ {
+ unsigned char PacketType;
+ m_ServerBuffer.ReadByte(PacketType);
+ switch (PacketType)
+ {
+ case PACKET_ENCRYPTION_KEY_REQUEST: HandleServerEncryptionKeyRequest(); break;
+ case PACKET_ENCRYPTION_KEY_RESPONSE: HandleServerEncryptionKeyResponse(); break;
+ case PACKET_KICK: HandleServerKick(); break;
+ default:
+ {
+ if (m_ServerState == csEncryptedUnderstood)
+ {
+ Log("Unknown packet 0x%02x from the server while encrypted; continuing to relay blind only", PacketType);
+ m_ServerState = csEncryptedUnknown;
+ m_ServerBuffer.ResetRead();
+ if (m_ClientState == csUnencrypted)
+ {
+ CLIENTSEND(m_ServerBuffer);
+ }
+ else
+ {
+ CLIENTENCRYPTSEND(m_ServerBuffer);
+ }
+ return true;
+ }
+ else
+ {
+ Log("Unknown packet 0x%02x from the server while unencrypted; aborting connection", PacketType);
+ return false;
+ }
+ }
+ } // switch (PacketType)
+ m_ServerBuffer.CommitRead();
+ } // while (CanReadBytes(1))
+ return true;
+}
+
+
+
+
+
+void cConnection::HandleClientEncryptionKeyResponse(void)
+{
+ HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, EncKeyLength);
+ AString EncKey;
+ if (!m_ClientBuffer.ReadString(EncKey, EncKeyLength))
+ {
+ return;
+ }
+ HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, EncNonceLength);
+ AString EncNonce;
+ if (!m_ClientBuffer.ReadString(EncNonce, EncNonceLength))
+ {
+ return;
+ }
+ if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN))
+ {
+ Log("Client: Too long encryption params");
+ return;
+ }
+ StartClientEncryption(EncKey, EncNonce);
+}
+
+
+
+
+
+void cConnection::HandleClientHandshake(void)
+{
+ // Read the packet from the client:
+ HANDLE_CLIENT_PACKET_READ(ReadByte, Byte, ProtocolVersion);
+ HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Username);
+ HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, ServerHost);
+ HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, ServerPort);
+ m_ClientBuffer.CommitRead();
+
+ // Send the same packet to the server:
+ cByteBuffer ToServer(512);
+ ToServer.WriteByte (PACKET_HANDSHAKE);
+ ToServer.WriteByte (ProtocolVersion);
+ ToServer.WriteBEUTF16String16(Username);
+ ToServer.WriteBEUTF16String16(ServerHost);
+ ToServer.WriteBEInt (m_Server.GetConnectPort());
+ SERVERSEND(ToServer);
+}
+
+
+
+
+
+void cConnection::HandleClientPing(void)
+{
+ Log("Received a PACKET_PING from the CLIENT");
+ m_ClientBuffer.ResetRead();
+ SERVERSEND(m_ClientBuffer);
+}
+
+
+
+
+
+void cConnection::HandleServerEncryptionKeyRequest(void)
+{
+ // Read the packet from the server:
+ HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, ServerID);
+ HANDLE_SERVER_PACKET_READ(ReadBEShort, short, PublicKeyLength);
+ AString PublicKey;
+ if (!m_ServerBuffer.ReadString(PublicKey, PublicKeyLength))
+ {
+ return;
+ }
+ HANDLE_SERVER_PACKET_READ(ReadBEShort, short, NonceLength);
+ AString Nonce;
+ if (!m_ServerBuffer.ReadString(Nonce, NonceLength))
+ {
+ return;
+ }
+ Log("Got PACKET_ENCRYPTION_KEY_REQUEST from the SERVER:");
+ Log(" ServerID = %s", ServerID.c_str());
+
+ // Reply to the server:
+ SendEncryptionKeyResponse(PublicKey, Nonce);
+
+ // Send a 0xFD Encryption Key Request http://wiki.vg/Protocol#0xFD to the client, using our own key:
+ Log("Sending PACKET_ENCRYPTION_KEY_REQUEST to the CLIENT");
+ AString key;
+ StringSink sink(key); // GCC won't allow inline instantiation in the following line, damned temporary refs
+ m_Server.GetPublicKey().Save(sink);
+ cByteBuffer ToClient(512);
+ ToClient.WriteByte (PACKET_ENCRYPTION_KEY_REQUEST);
+ ToClient.WriteBEUTF16String16(ServerID);
+ ToClient.WriteBEShort ((short)key.size());
+ ToClient.WriteBuf (key.data(), key.size());
+ ToClient.WriteBEShort (4);
+ ToClient.WriteBEInt (m_Nonce); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :)
+ CLIENTSEND(ToClient);
+}
+
+
+
+
+
+void cConnection::HandleServerEncryptionKeyResponse(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, Lengths);
+ if (Lengths != 0)
+ {
+ Log("Lengths are not zero!");
+ return;
+ }
+ m_ServerState = csEncryptedUnderstood;
+}
+
+
+
+
+
+void cConnection::HandleServerKick(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Reason);
+ Log("Received PACKET_KICK from the SERVER:");
+ Log(" Reason = \"%s\"", Reason.c_str());
+
+ cByteBuffer ToClient(Reason.size() * 2 + 4);
+ ToClient.WriteByte(PACKET_KICK);
+ ToClient.WriteBEUTF16String16(Reason);
+ CLIENTSEND(ToClient);
+}
+
+
+
+
+
+void cConnection::SendEncryptionKeyResponse(const AString & a_ServerPublicKey, const AString & a_Nonce)
+{
+ // Generate the shared secret and encrypt using the server's public key
+ byte SharedSecret[16];
+ byte EncryptedSecret[128];
+ memset(SharedSecret, 0, sizeof(SharedSecret)); // Use all zeroes for the initial secret
+ RSA::PublicKey pk;
+ CryptoPP::StringSource src(a_ServerPublicKey, true);
+ ByteQueue bq;
+ src.TransferTo(bq);
+ bq.MessageEnd();
+ pk.Load(bq);
+ RSAES<PKCS1v15>::Encryptor rsaEncryptor(pk);
+ AutoSeededRandomPool rng;
+ int EncryptedLength = rsaEncryptor.FixedCiphertextLength();
+ ASSERT(EncryptedLength <= sizeof(EncryptedSecret));
+ rsaEncryptor.Encrypt(rng, SharedSecret, sizeof(SharedSecret), EncryptedSecret);
+ m_ServerEncryptor.SetKey(SharedSecret, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(SharedSecret, 16))(Name::FeedbackSize(), 1));
+ m_ServerDecryptor.SetKey(SharedSecret, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(SharedSecret, 16))(Name::FeedbackSize(), 1));
+
+ // Encrypt the nonce:
+ byte EncryptedNonce[128];
+ rsaEncryptor.Encrypt(rng, (const byte *)(a_Nonce.data()), a_Nonce.size(), EncryptedNonce);
+
+ // Send the packet to the server:
+ Log("Sending PACKET_ENCRYPTION_KEY_RESPONSE to the SERVER");
+ cByteBuffer ToServer(1024);
+ ToServer.WriteByte(PACKET_ENCRYPTION_KEY_RESPONSE);
+ ToServer.WriteBEShort(EncryptedLength);
+ ToServer.WriteBuf(EncryptedSecret, EncryptedLength);
+ ToServer.WriteBEShort(EncryptedLength);
+ ToServer.WriteBuf(EncryptedNonce, EncryptedLength);
+ SERVERSEND(ToServer);
+}
+
+
+
+
+
+void cConnection::StartClientEncryption(const AString & a_EncKey, const AString & a_EncNonce)
+{
+ // Decrypt EncNonce using privkey
+ RSAES<PKCS1v15>::Decryptor rsaDecryptor(m_Server.GetPrivateKey());
+ AutoSeededRandomPool rng;
+ byte DecryptedNonce[MAX_ENC_LEN];
+ DecodingResult res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncNonce.data(), a_EncNonce.size(), DecryptedNonce);
+ if (!res.isValidCoding || (res.messageLength != 4))
+ {
+ Log("Client: Bad nonce length");
+ return;
+ }
+ if (ntohl(*((int *)DecryptedNonce)) != m_Nonce)
+ {
+ Log("Bad nonce value");
+ return;
+ }
+
+ // Decrypt the symmetric encryption key using privkey:
+ byte SharedSecret[MAX_ENC_LEN];
+ res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncKey.data(), a_EncKey.size(), SharedSecret);
+ if (!res.isValidCoding || (res.messageLength != 16))
+ {
+ Log("Bad key length");
+ return;
+ }
+
+ // Send encryption key response:
+ cByteBuffer ToClient(6);
+ ToClient.WriteByte((char)0xfc);
+ ToClient.WriteBEShort(0);
+ ToClient.WriteBEShort(0);
+ CLIENTSEND(ToClient);
+
+ // Start the encryption:
+ m_ClientEncryptor.SetKey(SharedSecret, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(SharedSecret, 16))(Name::FeedbackSize(), 1));
+ m_ClientDecryptor.SetKey(SharedSecret, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(SharedSecret, 16))(Name::FeedbackSize(), 1));
+ m_ClientState = csEncryptedUnderstood;
+
+ // Handle all postponed server data
+ DecodeServersPackets(NULL, 0);
+}
+
+
+
+
diff --git a/ProtoProxy/Connection.h b/ProtoProxy/Connection.h
index decf42435..8022a293f 100644
--- a/ProtoProxy/Connection.h
+++ b/ProtoProxy/Connection.h
@@ -10,6 +10,7 @@
#pragma once
#include <time.h>
+#include "ByteBuffer.h"
@@ -32,6 +33,18 @@ class cConnection
clock_t m_BeginTick; // Tick when the relative time was first retrieved (used for GetRelativeTime())
+ enum eConnectionState
+ {
+ csUnencrypted, // The connection is not encrypted. Packets must be decoded in order to be able to start decryption.
+ csEncryptedUnderstood, // The communication is encrypted and so far all packets have been understood, so they can be still decoded
+ csEncryptedUnknown, // The communication is encrypted, but an unknown packet has been received, so packets cannot be decoded anymore
+ };
+
+ eConnectionState m_ClientState;
+ eConnectionState m_ServerState;
+
+ int m_Nonce;
+
public:
cConnection(SOCKET a_ClientSocket, cServer & a_Server);
~cConnection();
@@ -42,6 +55,18 @@ public:
void DataLog(const void * a_Data, int a_Size, const char * a_Format, ...);
protected:
+ typedef CFB_Mode<AES>::Encryption Encryptor;
+ typedef CFB_Mode<AES>::Decryption Decryptor;
+
+ cByteBuffer m_ClientBuffer;
+ cByteBuffer m_ServerBuffer;
+
+ Decryptor m_ServerDecryptor;
+ Encryptor m_ServerEncryptor;
+
+ Decryptor m_ClientDecryptor;
+ Encryptor m_ClientEncryptor;
+
bool ConnectToServer(void);
/// Relays data from server to client; returns false if connection aborted
@@ -52,6 +77,40 @@ protected:
/// Returns the time relative to the first call of this function, in the fractional seconds elapsed
double GetRelativeTime(void);
+
+ /// Sends data to the specified socket. If sending fails, prints a fail message using a_Peer and returns false.
+ bool SendData(SOCKET a_Socket, const char * a_Data, int a_Size, const char * a_Peer);
+
+ /// Sends data to the specified socket. If sending fails, prints a fail message using a_Peer and returns false.
+ bool SendData(SOCKET a_Socket, cByteBuffer & a_Data, const char * a_Peer);
+
+ /// Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false
+ bool SendEncryptedData(SOCKET a_Socket, Encryptor & a_Encryptor, const char * a_Data, int a_Size, const char * a_Peer);
+
+ /// Sends data to the specfied socket, after encrypting it using a_Encryptor. If sending fails, prints a fail message using a_Peer and returns false
+ bool SendEncryptedData(SOCKET a_Socket, Encryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer);
+
+ /// Decodes packets coming from the client, sends appropriate counterparts to the server; returns false if the connection is to be dropped
+ bool DecodeClientsPackets(const char * a_Data, int a_Size);
+
+ /// Decodes packets coming from the server, sends appropriate counterparts to the client; returns false if the connection is to be dropped
+ bool DecodeServersPackets(const char * a_Data, int a_Size);
+
+ // Packet handling, client-side:
+ void HandleClientEncryptionKeyResponse(void);
+ void HandleClientHandshake(void);
+ void HandleClientPing(void);
+
+ // Packet handling, server-side:
+ void HandleServerEncryptionKeyRequest(void);
+ void HandleServerEncryptionKeyResponse(void);
+ void HandleServerKick(void);
+
+ /// Send EKResp to the server:
+ void SendEncryptionKeyResponse(const AString & a_ServerPublicKey, const AString & a_Nonce);
+
+ /// Starts client encryption based on the parameters received
+ void StartClientEncryption(const AString & a_EncryptedSecret, const AString & a_EncryptedNonce);
} ;
diff --git a/ProtoProxy/Globals.h b/ProtoProxy/Globals.h
index e97d2e561..e962d9a6f 100644
--- a/ProtoProxy/Globals.h
+++ b/ProtoProxy/Globals.h
@@ -208,6 +208,7 @@ public:
#include "CryptoPP/osrng.h"
#include "CryptoPP/rsa.h"
+#include "CryptoPP/modes.h"
using namespace CryptoPP;
diff --git a/ProtoProxy/ProtoProxy.vcproj b/ProtoProxy/ProtoProxy.vcproj
index 2d980bed7..aa1d138c3 100644
--- a/ProtoProxy/ProtoProxy.vcproj
+++ b/ProtoProxy/ProtoProxy.vcproj
@@ -42,7 +42,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..;../source"
- PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -118,7 +118,7 @@
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..;../source"
- PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
@@ -177,6 +177,14 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
+ RelativePath="..\source\ByteBuffer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\ByteBuffer.h"
+ >
+ </File>
+ <File
RelativePath="..\source\cCriticalSection.cpp"
>
</File>