diff options
Diffstat (limited to 'Tools/ProtoProxy')
-rw-r--r-- | Tools/ProtoProxy/.gitignore | 1 | ||||
-rw-r--r-- | Tools/ProtoProxy/CMakeLists.txt | 84 | ||||
-rw-r--r-- | Tools/ProtoProxy/Connection.cpp | 99 | ||||
-rw-r--r-- | Tools/ProtoProxy/Connection.h | 14 | ||||
-rw-r--r-- | Tools/ProtoProxy/Globals.h | 17 | ||||
-rw-r--r-- | Tools/ProtoProxy/Server.cpp | 8 | ||||
-rw-r--r-- | Tools/ProtoProxy/Server.h | 8 |
7 files changed, 89 insertions, 142 deletions
diff --git a/Tools/ProtoProxy/.gitignore b/Tools/ProtoProxy/.gitignore index 8def77d0b..158a30080 100644 --- a/Tools/ProtoProxy/.gitignore +++ b/Tools/ProtoProxy/.gitignore @@ -1,6 +1,7 @@ Debug Release Logs/ +lib/ *.log *.nbt *.sln diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt index f8a01a134..01f1e88ad 100644 --- a/Tools/ProtoProxy/CMakeLists.txt +++ b/Tools/ProtoProxy/CMakeLists.txt @@ -3,69 +3,19 @@ cmake_minimum_required (VERSION 2.6) project (ProtoProxy) +include(../../SetFlags.cmake) - -macro(add_flags_cxx FLAGS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS}") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS}") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS}") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS}") -endmacro() - - - - -# Add the preprocessor macros used for distinguishing between debug and release builds (CMake does this automatically for MSVC): -if (NOT MSVC) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG") -endif() - - - -if(MSVC) - # Make build use multiple threads under MSVC: - add_flags_cxx("/MP") - - # Make release builds use link-time code generation: - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL") - set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG") - set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG") - set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} /LTCG") -elseif(APPLE) - #on os x clang adds pthread for us but we need to add it for gcc - if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - add_flags_cxx("-pthread") - endif() -else() - # Let gcc / clang know that we're compiling a multi-threaded app: - add_flags_cxx("-pthread") -endif() - - - - -# Use static CRT in MSVC builds: -if (MSVC) - string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") - string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") - string(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - string(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") -endif() - - +set_flags() +set_lib_flags() # Set include paths to the used libraries: include_directories("../../lib") +include_directories("../../lib/polarssl/include") include_directories("../../src") + function(flatten_files arg1) set(res "") foreach(f ${${arg1}}) @@ -75,20 +25,10 @@ function(flatten_files arg1) set(${arg1} "${res}" PARENT_SCOPE) endfunction() +include(../../lib/polarssl.cmake) +add_subdirectory(../../lib/zlib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/lib/zlib) -# Include the libraries: -file(GLOB CRYPTOPP_SRC "../../lib/cryptopp/*.cpp") -file(GLOB CRYPTOPP_HDR "../../lib/cryptopp/*.h") -flatten_files(CRYPTOPP_SRC) -flatten_files(CRYPTOPP_HDR) -source_group("CryptoPP" FILES ${CRYPTOPP_SRC} ${CRYPTOPP_HDR}) - -file(GLOB ZLIB_SRC "../../lib/zlib/*.c") -file(GLOB ZLIB_HDR "../../lib/zlib/*.h") -flatten_files(ZLIB_SRC) -flatten_files(ZLIB_HDR) -source_group("ZLib" FILES ${ZLIB_SRC} ${ZLIB_HDR}) - +set_exe_flags() # Include the shared files: set(SHARED_SRC @@ -96,12 +36,14 @@ set(SHARED_SRC ../../src/StringUtils.cpp ../../src/Log.cpp ../../src/MCLogger.cpp + ../../src/Crypto.cpp ) set(SHARED_HDR ../../src/ByteBuffer.h ../../src/StringUtils.h ../../src/Log.h ../../src/MCLogger.h + ../../src/Crypto.h ) set(SHARED_OSS_SRC ../../src/OSSupport/CriticalSection.cpp @@ -145,9 +87,7 @@ add_executable(ProtoProxy ${SHARED_HDR} ${SHARED_OSS_SRC} ${SHARED_OSS_HDR} - ${CRYPTOPP_SRC} - ${CRYPTOPP_HDR} - ${ZLIB_SRC} - ${ZLIB_HDR} ) +target_link_libraries(ProtoProxy zlib polarssl) + diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index cd66e2dfd..d9b8e3dd1 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -131,8 +131,6 @@ } \ } - -#define MAX_ENC_LEN 1024 @@ -243,7 +241,8 @@ void cConnection::Run(void) FD_ZERO(&ReadFDs); FD_SET(m_ServerSocket, &ReadFDs); FD_SET(m_ClientSocket, &ReadFDs); - int res = select(2, &ReadFDs, NULL, NULL, NULL); + SOCKET MaxSocket = std::max(m_ServerSocket, m_ClientSocket); + int res = select(MaxSocket + 1, &ReadFDs, NULL, NULL, NULL); if (res <= 0) { printf("select() failed: %d; aborting client", SocketError); @@ -377,19 +376,19 @@ bool cConnection::RelayFromServer(void) } case csEncryptedUnderstood: { - m_ServerDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res); + 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); + m_ServerDecryptor.ProcessData((Byte *)Buffer, (Byte *)Buffer, res); DataLog(Buffer, res, "Decrypted %d bytes from the SERVER", res); return CLIENTSEND(Buffer, res); } } - - return true; + ASSERT(!"Unhandled server state while relaying from server"); + return false; } @@ -422,12 +421,12 @@ bool cConnection::RelayFromClient(void) case csEncryptedUnknown: { DataLog(Buffer, res, "Decrypted %d bytes from the CLIENT", res); - m_ServerEncryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res); + m_ServerEncryptor.ProcessData((Byte *)Buffer, (Byte *)Buffer, res); return SERVERSEND(Buffer, res); } } - - return true; + ASSERT(!"Unhandled server state while relaying from client"); + return false; } @@ -443,11 +442,11 @@ double cConnection::GetRelativeTime(void) -bool cConnection::SendData(SOCKET a_Socket, const char * a_Data, int a_Size, const char * a_Peer) +bool cConnection::SendData(SOCKET a_Socket, const char * a_Data, size_t a_Size, const char * a_Peer) { - DataLog(a_Data, a_Size, "Sending data to %s, %d bytes", a_Peer, a_Size); + DataLog(a_Data, a_Size, "Sending data to %s, %u bytes", a_Peer, (unsigned)a_Size); - int res = send(a_Socket, a_Data, a_Size, 0); + int res = send(a_Socket, a_Data, (int)a_Size, 0); if (res <= 0) { Log("%s closed the socket: %d, %d; aborting connection", a_Peer, res, SocketError); @@ -472,14 +471,14 @@ bool cConnection::SendData(SOCKET a_Socket, cByteBuffer & a_Data, const char * a -bool cConnection::SendEncryptedData(SOCKET a_Socket, Encryptor & a_Encryptor, const char * a_Data, int a_Size, const char * a_Peer) +bool cConnection::SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, const char * a_Data, size_t a_Size, const char * a_Peer) { DataLog(a_Data, a_Size, "Encrypting %d bytes to %s", a_Size, a_Peer); - const byte * Data = (const byte *)a_Data; + const Byte * Data = (const Byte *)a_Data; while (a_Size > 0) { - byte Buffer[64 KiB]; - int NumBytes = (a_Size > sizeof(Buffer)) ? sizeof(Buffer) : a_Size; + Byte Buffer[64 KiB]; + size_t 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) @@ -496,7 +495,7 @@ bool cConnection::SendEncryptedData(SOCKET a_Socket, Encryptor & a_Encryptor, co -bool cConnection::SendEncryptedData(SOCKET a_Socket, Encryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer) +bool cConnection::SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, cByteBuffer & a_Data, const char * a_Peer) { AString All; a_Data.ReadAll(All); @@ -1301,6 +1300,7 @@ bool cConnection::HandleServerLoginEncryptionKeyRequest(void) } Log("Got PACKET_ENCRYPTION_KEY_REQUEST from the SERVER:"); Log(" ServerID = %s", ServerID.c_str()); + DataLog(PublicKey.data(), PublicKey.size(), " Public key (%u bytes)", (unsigned)PublicKey.size()); // Reply to the server: SendEncryptionKeyResponse(PublicKey, Nonce); @@ -2261,7 +2261,9 @@ bool cConnection::HandleServerSpawnObjectVehicle(void) HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw); HANDLE_SERVER_PACKET_READ(ReadBEInt, int, DataIndicator); AString ExtraData; - short VelocityX, VelocityY, VelocityZ; + short VelocityX = 0; + short VelocityY = 0; + short VelocityZ = 0; if (DataIndicator != 0) { HANDLE_SERVER_PACKET_READ(ReadBEShort, short, SpeedX); @@ -2695,12 +2697,12 @@ bool cConnection::ParseMetadata(cByteBuffer & a_Buffer, AString & a_Metadata) a_Metadata.push_back(x); while (x != 0x7f) { - int Index = ((unsigned)((unsigned char)x)) & 0x1f; // Lower 5 bits = index + // int Index = ((unsigned)((unsigned char)x)) & 0x1f; // Lower 5 bits = index int Type = ((unsigned)((unsigned char)x)) >> 5; // Upper 3 bits = type int Length = 0; switch (Type) { - case 0: Length = 1; break; // byte + case 0: Length = 1; break; // Byte case 1: Length = 2; break; // short case 2: Length = 4; break; // int case 3: Length = 4; break; // float @@ -2770,7 +2772,7 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount) { int Index = ((unsigned)((unsigned char)a_Metadata[pos])) & 0x1f; // Lower 5 bits = index int Type = ((unsigned)((unsigned char)a_Metadata[pos])) >> 5; // Upper 3 bits = type - int Length = 0; + // int Length = 0; switch (Type) { case 0: @@ -2825,7 +2827,7 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount) ASSERT(!"Cannot parse item description from metadata"); return; } - int After = bb.GetReadableSpace(); + // int After = bb.GetReadableSpace(); int BytesConsumed = BytesLeft - bb.GetReadableSpace(); Log("%sslot[%d] = %s (%d bytes)", Indent.c_str(), Index, ItemDesc.c_str(), BytesConsumed); @@ -2859,37 +2861,42 @@ void cConnection::LogMetadata(const AString & a_Metadata, size_t a_IndentCount) 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]; + 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); - RandomPool rng; - time_t CurTime = time(NULL); - rng.Put((const byte *)&CurTime, sizeof(CurTime)); - 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, true))(Name::FeedbackSize(), 1)); - m_ServerDecryptor.SetKey(SharedSecret, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(SharedSecret, 16, true))(Name::FeedbackSize(), 1)); + cPublicKey PubKey(a_ServerPublicKey); + int res = PubKey.Encrypt(SharedSecret, sizeof(SharedSecret), EncryptedSecret, sizeof(EncryptedSecret)); + if (res < 0) + { + Log("Shared secret encryption failed: %d (0x%x)", res, res); + return; + } + + m_ServerEncryptor.Init(SharedSecret, SharedSecret); + m_ServerDecryptor.Init(SharedSecret, SharedSecret); // Encrypt the nonce: - byte EncryptedNonce[128]; - rsaEncryptor.Encrypt(rng, (const byte *)(a_Nonce.data()), a_Nonce.size(), EncryptedNonce); + Byte EncryptedNonce[128]; + res = PubKey.Encrypt((const Byte *)a_Nonce.data(), a_Nonce.size(), EncryptedNonce, sizeof(EncryptedNonce)); + if (res < 0) + { + Log("Nonce encryption failed: %d (0x%x)", res, res); + return; + } // Send the packet to the server: Log("Sending PACKET_ENCRYPTION_KEY_RESPONSE to the SERVER"); cByteBuffer ToServer(1024); ToServer.WriteByte(0x01); // To server: Encryption key response - ToServer.WriteBEShort(EncryptedLength); - ToServer.WriteBuf(EncryptedSecret, EncryptedLength); - ToServer.WriteBEShort(EncryptedLength); - ToServer.WriteBuf(EncryptedNonce, EncryptedLength); + ToServer.WriteBEShort((short)sizeof(EncryptedSecret)); + ToServer.WriteBuf(EncryptedSecret, sizeof(EncryptedSecret)); + ToServer.WriteBEShort((short)sizeof(EncryptedNonce)); + ToServer.WriteBuf(EncryptedNonce, sizeof(EncryptedNonce)); + DataLog(EncryptedSecret, sizeof(EncryptedSecret), "Encrypted secret (%u bytes)", (unsigned)sizeof(EncryptedSecret)); + DataLog(EncryptedNonce, sizeof(EncryptedNonce), "Encrypted nonce (%u bytes)", (unsigned)sizeof(EncryptedNonce)); + cByteBuffer Len(5); + Len.WriteVarInt(ToServer.GetReadableSpace()); + SERVERSEND(Len); SERVERSEND(ToServer); m_ServerState = csEncryptedUnderstood; m_IsServerEncrypted = true; diff --git a/Tools/ProtoProxy/Connection.h b/Tools/ProtoProxy/Connection.h index abb8b6cd0..9e04994b7 100644 --- a/Tools/ProtoProxy/Connection.h +++ b/Tools/ProtoProxy/Connection.h @@ -62,14 +62,12 @@ public: void LogFlush(void); 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; + cAESCFBDecryptor m_ServerDecryptor; + cAESCFBEncryptor m_ServerEncryptor; AString m_ServerEncryptionBuffer; // Buffer for the data to be sent to the server once encryption is established @@ -105,16 +103,16 @@ protected: 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); + bool SendData(SOCKET a_Socket, const char * a_Data, size_t 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); + bool SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & a_Encryptor, const char * a_Data, size_t 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); + bool SendEncryptedData(SOCKET a_Socket, cAESCFBEncryptor & 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); diff --git a/Tools/ProtoProxy/Globals.h b/Tools/ProtoProxy/Globals.h index 7415c9e62..e2f5aa860 100644 --- a/Tools/ProtoProxy/Globals.h +++ b/Tools/ProtoProxy/Globals.h @@ -22,6 +22,8 @@ #define ALIGN_8 #define ALIGN_16 + #define FORMATSTRING(formatIndex, va_argsIndex) + #elif defined(__GNUC__) // TODO: Can GCC explicitly mark classes as abstract (no instances can be created)? @@ -37,6 +39,8 @@ // Some portability macros :) #define stricmp strcasecmp + + #define FORMATSTRING(formatIndex, va_argsIndex) #else @@ -59,6 +63,9 @@ #define ALIGN_16 */ + #define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) + + #endif @@ -74,6 +81,8 @@ typedef unsigned long long UInt64; typedef unsigned int UInt32; typedef unsigned short UInt16; +typedef unsigned char Byte; + @@ -223,16 +232,12 @@ public: -#include "cryptopp/randpool.h" -#include "cryptopp/aes.h" -#include "cryptopp/rsa.h" -#include "cryptopp/modes.h" +#include "../../src/Crypto.h" -using namespace CryptoPP; #define LOGERROR printf #define LOGINFO printf -#define LOGWARNING printf
\ No newline at end of file +#define LOGWARNING printf diff --git a/Tools/ProtoProxy/Server.cpp b/Tools/ProtoProxy/Server.cpp index 71b5ecb94..bb042b259 100644 --- a/Tools/ProtoProxy/Server.cpp +++ b/Tools/ProtoProxy/Server.cpp @@ -34,12 +34,8 @@ int cServer::Init(short a_ListenPort, short a_ConnectPort) #endif // _WIN32 printf("Generating protocol encryption keypair...\n"); - time_t CurTime = time(NULL); - RandomPool rng; - rng.Put((const byte *)&CurTime, sizeof(CurTime)); - m_PrivateKey.GenerateRandomWithKeySize(rng, 1024); - RSA::PublicKey pk(m_PrivateKey); - m_PublicKey = pk; + m_PrivateKey.Generate(); + m_PublicKeyDER = m_PrivateKey.GetPubKeyDER(); m_ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in local; diff --git a/Tools/ProtoProxy/Server.h b/Tools/ProtoProxy/Server.h index e69dbb5e0..85f817a4d 100644 --- a/Tools/ProtoProxy/Server.h +++ b/Tools/ProtoProxy/Server.h @@ -17,8 +17,8 @@ class cServer { SOCKET m_ListenSocket; - RSA::PrivateKey m_PrivateKey; - RSA::PublicKey m_PublicKey; + cRSAPrivateKey m_PrivateKey; + AString m_PublicKeyDER; short m_ConnectPort; public: @@ -27,8 +27,8 @@ public: int Init(short a_ListenPort, short a_ConnectPort); void Run(void); - RSA::PrivateKey & GetPrivateKey(void) { return m_PrivateKey; } - RSA::PublicKey & GetPublicKey (void) { return m_PublicKey; } + cRSAPrivateKey & GetPrivateKey(void) { return m_PrivateKey; } + const AString & GetPublicKeyDER (void) { return m_PublicKeyDER; } short GetConnectPort(void) const { return m_ConnectPort; } } ; |