XChaCha20-Poly1305 via libsodium
This commit is contained in:
@@ -2,13 +2,6 @@
|
||||
#include "AccountConnector.h"
|
||||
#include "Packet.h"
|
||||
#include "PythonNetworkStream.h"
|
||||
#include "EterBase/tea.h"
|
||||
#include "PackLib/PackManager.h"
|
||||
|
||||
// CHINA_CRYPT_KEY
|
||||
extern DWORD g_adwEncryptKey[4];
|
||||
extern DWORD g_adwDecryptKey[4];
|
||||
// END_OF_CHINA_CRYPT_KEY
|
||||
|
||||
void CAccountConnector::SetHandler(PyObject* poHandler)
|
||||
{
|
||||
@@ -29,14 +22,9 @@ void CAccountConnector::ClearLoginInfo( void )
|
||||
|
||||
bool CAccountConnector::Connect(const char * c_szAddr, int iPort, const char * c_szAccountAddr, int iAccountPort)
|
||||
{
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
__BuildClientKey();
|
||||
#endif
|
||||
|
||||
m_strAddr = c_szAddr;
|
||||
m_iPort = iPort;
|
||||
__OfflineState_Set();
|
||||
__BuildClientKey_20050304Myevan();
|
||||
|
||||
return CNetworkStream::Connect(c_szAccountAddr, iAccountPort);
|
||||
}
|
||||
@@ -84,21 +72,12 @@ bool CAccountConnector::__HandshakeState_Process()
|
||||
if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing))
|
||||
return false;
|
||||
|
||||
// TODO : 차후 서버와 동일하게 가변길이 data serialize & deserialize 작업해야 한다.
|
||||
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys))
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CAccountConnector::__AuthState_RecvKeyChallenge))
|
||||
return false;
|
||||
|
||||
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB))
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CAccountConnector::__AuthState_RecvKeyComplete))
|
||||
return false;
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT, sizeof(TPacketKeyAgreement), &CAccountConnector::__AuthState_RecvKeyAgreement))
|
||||
return false;
|
||||
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT_COMPLETED, sizeof(TPacketKeyAgreementCompleted), &CAccountConnector::__AuthState_RecvKeyAgreementCompleted))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -122,22 +101,10 @@ bool CAccountConnector::__AuthState_Process()
|
||||
if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake))
|
||||
return false;
|
||||
|
||||
if (!__AnalyzePacket(HEADER_GC_PANAMA_PACK, sizeof(TPacketGCPanamaPack), &CAccountConnector::__AuthState_RecvPanamaPack))
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CAccountConnector::__AuthState_RecvKeyChallenge))
|
||||
return false;
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT, sizeof(TPacketKeyAgreement), &CAccountConnector::__AuthState_RecvKeyAgreement))
|
||||
return false;
|
||||
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT_COMPLETED, sizeof(TPacketKeyAgreementCompleted), &CAccountConnector::__AuthState_RecvKeyAgreementCompleted))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// TODO : 차후 서버와 동일하게 가변길이 data serialize & deserialize 작업해야 한다.
|
||||
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys))
|
||||
return false;
|
||||
|
||||
if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB))
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CAccountConnector::__AuthState_RecvKeyComplete))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -162,11 +129,6 @@ bool CAccountConnector::__AuthState_RecvPhase()
|
||||
}
|
||||
else if (kPacketPhase.phase == PHASE_AUTH)
|
||||
{
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
const char* key = GetSecurityKey();
|
||||
SetSecurityMode(true, key);
|
||||
#endif
|
||||
|
||||
TPacketCGLogin3 LoginPacket;
|
||||
LoginPacket.header = HEADER_CG_LOGIN3;
|
||||
|
||||
@@ -175,16 +137,12 @@ bool CAccountConnector::__AuthState_RecvPhase()
|
||||
LoginPacket.name[ID_MAX_NUM] = '\0';
|
||||
LoginPacket.pwd[PASS_MAX_NUM] = '\0';
|
||||
|
||||
// 비밀번호를 메모리에 계속 갖고 있는 문제가 있어서, 사용 즉시 날리는 것으로 변경
|
||||
ClearLoginInfo();
|
||||
CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance();
|
||||
rkNetStream.ClearLoginInfo();
|
||||
|
||||
m_strPassword = "";
|
||||
|
||||
for (DWORD i = 0; i < 4; ++i)
|
||||
LoginPacket.adwClientKey[i] = g_adwEncryptKey[i];
|
||||
|
||||
if (!Send(sizeof(LoginPacket), &LoginPacket))
|
||||
{
|
||||
Tracen(" CAccountConnector::__AuthState_RecvPhase - SendLogin3 Error");
|
||||
@@ -208,71 +166,93 @@ bool CAccountConnector::__AuthState_RecvHandshake()
|
||||
if (!Recv(sizeof(kPacketHandshake), &kPacketHandshake))
|
||||
return false;
|
||||
|
||||
// HandShake
|
||||
Tracenf("HANDSHAKE RECV %u %d", kPacketHandshake.dwTime, kPacketHandshake.lDelta);
|
||||
|
||||
ELTimer_SetServerMSec(kPacketHandshake.dwTime+ kPacketHandshake.lDelta);
|
||||
|
||||
kPacketHandshake.dwTime = kPacketHandshake.dwTime + kPacketHandshake.lDelta + kPacketHandshake.lDelta;
|
||||
kPacketHandshake.lDelta = 0;
|
||||
|
||||
Tracenf("HANDSHAKE SEND %u", kPacketHandshake.dwTime);
|
||||
|
||||
if (!Send(sizeof(kPacketHandshake), &kPacketHandshake))
|
||||
{
|
||||
Tracenf("HANDSHAKE RECV %u %d", kPacketHandshake.dwTime, kPacketHandshake.lDelta);
|
||||
|
||||
ELTimer_SetServerMSec(kPacketHandshake.dwTime+ kPacketHandshake.lDelta);
|
||||
|
||||
//DWORD dwBaseServerTime = kPacketHandshake.dwTime+ kPacketHandshake.lDelta;
|
||||
//DWORD dwBaseClientTime = ELTimer_GetMSec();
|
||||
|
||||
kPacketHandshake.dwTime = kPacketHandshake.dwTime + kPacketHandshake.lDelta + kPacketHandshake.lDelta;
|
||||
kPacketHandshake.lDelta = 0;
|
||||
|
||||
Tracenf("HANDSHAKE SEND %u", kPacketHandshake.dwTime);
|
||||
|
||||
if (!Send(sizeof(kPacketHandshake), &kPacketHandshake))
|
||||
{
|
||||
Tracen(" CAccountConnector::__AuthState_RecvHandshake - SendHandshake Error");
|
||||
return false;
|
||||
}
|
||||
Tracen(" CAccountConnector::__AuthState_RecvHandshake - SendHandshake Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAccountConnector::__AuthState_RecvPanamaPack()
|
||||
bool CAccountConnector::__AuthState_RecvKeyChallenge()
|
||||
{
|
||||
TPacketGCPanamaPack kPacket;
|
||||
|
||||
if (!Recv(sizeof(TPacketGCPanamaPack), &kPacket))
|
||||
TPacketGCKeyChallenge packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
return false;
|
||||
|
||||
Tracen("KEY_CHALLENGE RECV - Starting secure key exchange");
|
||||
|
||||
SecureCipher& cipher = GetSecureCipher();
|
||||
if (!cipher.Initialize())
|
||||
{
|
||||
Tracen("SecureCipher initialization failed");
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cipher.ComputeClientKeys(packet.server_pk))
|
||||
{
|
||||
Tracen("Failed to compute client session keys");
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
TPacketCGKeyResponse response;
|
||||
response.bHeader = HEADER_CG_KEY_RESPONSE;
|
||||
cipher.GetPublicKey(response.client_pk);
|
||||
cipher.ComputeResponse(packet.challenge, response.challenge_response);
|
||||
|
||||
if (!Send(sizeof(response), &response))
|
||||
{
|
||||
Tracen("Failed to send key response");
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracen("KEY_RESPONSE SEND - Awaiting key completion");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAccountConnector::__AuthState_RecvHybridCryptKeys(int iTotalSize)
|
||||
bool CAccountConnector::__AuthState_RecvKeyComplete()
|
||||
{
|
||||
int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize();
|
||||
|
||||
TPacketGCHybridCryptKeys kPacket(iTotalSize-iFixedHeaderSize);
|
||||
|
||||
if (!Recv(iFixedHeaderSize, &kPacket))
|
||||
TPacketGCKeyComplete packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
return false;
|
||||
|
||||
if (!Recv(kPacket.iKeyStreamLen, kPacket.m_pStream))
|
||||
return false;
|
||||
Tracen("KEY_COMPLETE RECV - Decrypting session token");
|
||||
|
||||
SecureCipher& cipher = GetSecureCipher();
|
||||
|
||||
uint8_t session_token[SecureCipher::SESSION_TOKEN_SIZE];
|
||||
if (crypto_aead_xchacha20poly1305_ietf_decrypt(
|
||||
session_token, nullptr,
|
||||
nullptr,
|
||||
packet.encrypted_token, sizeof(packet.encrypted_token),
|
||||
nullptr, 0,
|
||||
packet.nonce,
|
||||
cipher.GetRxKey()) != 0)
|
||||
{
|
||||
Tracen("Failed to decrypt session token - authentication failed");
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
cipher.SetSessionToken(session_token);
|
||||
cipher.SetActivated(true);
|
||||
|
||||
Tracen("Secure channel established - encryption activated");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAccountConnector::__AuthState_RecvHybridCryptSDB(int iTotalSize)
|
||||
{
|
||||
int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize();
|
||||
|
||||
TPacketGCHybridSDB kPacket(iTotalSize-iFixedHeaderSize);
|
||||
|
||||
if (!Recv(iFixedHeaderSize, &kPacket))
|
||||
return false;
|
||||
|
||||
if (!Recv(kPacket.iSDBStreamLen, kPacket.m_pStream))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CAccountConnector::__AuthState_RecvPing()
|
||||
{
|
||||
TPacketGCPing kPacketPing;
|
||||
@@ -309,8 +289,6 @@ bool CAccountConnector::__AuthState_RecvAuthSuccess()
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD dwPanamaKey = kAuthSuccessPacket.dwLoginKey ^ g_adwEncryptKey[0] ^ g_adwEncryptKey[1] ^ g_adwEncryptKey[2] ^ g_adwEncryptKey[3];
|
||||
|
||||
CPythonNetworkStream & rkNet = CPythonNetworkStream::Instance();
|
||||
rkNet.SetLoginKey(kAuthSuccessPacket.dwLoginKey);
|
||||
rkNet.Connect(m_strAddr.c_str(), m_iPort);
|
||||
@@ -331,72 +309,9 @@ bool CAccountConnector::__AuthState_RecvAuthFailure()
|
||||
if (m_poHandler)
|
||||
PyCallClassMemberFunc(m_poHandler, "OnLoginFailure", Py_BuildValue("(s)", packet_failure.szStatus));
|
||||
|
||||
// __OfflineState_Set();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
bool CAccountConnector::__AuthState_RecvKeyAgreement()
|
||||
{
|
||||
TPacketKeyAgreement packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracenf("KEY_AGREEMENT RECV %u", packet.wDataLength);
|
||||
|
||||
TPacketKeyAgreement packetToSend;
|
||||
size_t dataLength = TPacketKeyAgreement::MAX_DATA_LEN;
|
||||
size_t agreedLength = Prepare(packetToSend.data, &dataLength);
|
||||
if (agreedLength == 0)
|
||||
{
|
||||
// 초기화 실패
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
assert(dataLength <= TPacketKeyAgreement::MAX_DATA_LEN);
|
||||
|
||||
if (Activate(packet.wAgreedLength, packet.data, packet.wDataLength))
|
||||
{
|
||||
// Key agreement 성공, 응답 전송
|
||||
packetToSend.bHeader = HEADER_CG_KEY_AGREEMENT;
|
||||
packetToSend.wAgreedLength = (WORD)agreedLength;
|
||||
packetToSend.wDataLength = (WORD)dataLength;
|
||||
|
||||
if (!Send(sizeof(packetToSend), &packetToSend))
|
||||
{
|
||||
Tracen(" CAccountConnector::__AuthState_RecvKeyAgreement - SendKeyAgreement Error");
|
||||
return false;
|
||||
}
|
||||
Tracenf("KEY_AGREEMENT SEND %u", packetToSend.wDataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 키 협상 실패
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAccountConnector::__AuthState_RecvKeyAgreementCompleted()
|
||||
{
|
||||
TPacketKeyAgreementCompleted packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracenf("KEY_AGREEMENT_COMPLETED RECV");
|
||||
|
||||
ActivateCipher();
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif // _IMPROVED_PACKET_ENCRYPTION_
|
||||
|
||||
bool CAccountConnector::__AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CAccountConnector::*pfnDispatchPacket)())
|
||||
{
|
||||
BYTE bHeader;
|
||||
@@ -412,27 +327,6 @@ bool CAccountConnector::__AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CA
|
||||
return (this->*pfnDispatchPacket)();
|
||||
}
|
||||
|
||||
bool CAccountConnector::__AnalyzeVarSizePacket(UINT uHeader, bool (CAccountConnector::*pfnDispatchPacket)(int))
|
||||
{
|
||||
BYTE bHeader;
|
||||
if (!Peek(sizeof(bHeader), &bHeader))
|
||||
return true;
|
||||
|
||||
if (bHeader!=uHeader)
|
||||
return true;
|
||||
|
||||
TDynamicSizePacketHeader dynamicHeader;
|
||||
|
||||
if (!Peek(sizeof(dynamicHeader), &dynamicHeader))
|
||||
return true;
|
||||
|
||||
if (!Peek(dynamicHeader.size))
|
||||
return true;
|
||||
|
||||
return (this->*pfnDispatchPacket)(dynamicHeader.size);
|
||||
}
|
||||
|
||||
|
||||
void CAccountConnector::__OfflineState_Set()
|
||||
{
|
||||
__Inialize();
|
||||
@@ -463,7 +357,6 @@ void CAccountConnector::OnConnectSuccess()
|
||||
|
||||
void CAccountConnector::OnRemoteDisconnect()
|
||||
{
|
||||
// Matrix Card Number 를 보내 놓았는데 close 되면 프로그램을 종료 한다.
|
||||
if (m_isWaitKey)
|
||||
{
|
||||
if (m_poHandler)
|
||||
@@ -481,17 +374,6 @@ void CAccountConnector::OnDisconnect()
|
||||
__OfflineState_Set();
|
||||
}
|
||||
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
void CAccountConnector::__BuildClientKey()
|
||||
{
|
||||
for (DWORD i = 0; i < 4; ++i)
|
||||
g_adwEncryptKey[i] = random();
|
||||
|
||||
const BYTE * c_pszKey = (const BYTE *) "JyTxtHljHJlVJHorRM301vf@4fvj10-v";
|
||||
tea_encrypt((DWORD *) g_adwDecryptKey, (const DWORD *) g_adwEncryptKey, (const DWORD *) c_pszKey, 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CAccountConnector::__Inialize()
|
||||
{
|
||||
m_eState=STATE_OFFLINE;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma
|
||||
#pragma once
|
||||
|
||||
#include "EterLib/NetStream.h"
|
||||
#include "EterLib/FuncObject.h"
|
||||
@@ -49,22 +49,10 @@ class CAccountConnector : public CNetworkStream, public CSingleton<CAccountConne
|
||||
bool __AuthState_SendPong();
|
||||
bool __AuthState_RecvAuthSuccess();
|
||||
bool __AuthState_RecvAuthFailure();
|
||||
bool __AuthState_RecvPanamaPack();
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
bool __AuthState_RecvKeyAgreement();
|
||||
bool __AuthState_RecvKeyAgreementCompleted();
|
||||
#endif
|
||||
bool __AuthState_RecvHybridCryptKeys(int VarSize);
|
||||
bool __AuthState_RecvHybridCryptSDB(int VarSize);
|
||||
bool __AuthState_RecvKeyChallenge();
|
||||
bool __AuthState_RecvKeyComplete();
|
||||
|
||||
bool __AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CAccountConnector::*pfnDispatchPacket)());
|
||||
// TODO: 지금 현재는 임시다. header뒤에 size 4byte가 무조건 온다는 가정임.
|
||||
// 제대로 하려면 Packet System Refactoring해야 한다.
|
||||
bool __AnalyzeVarSizePacket(UINT uHeader, bool (CAccountConnector::*pfnDispatchPacket)(int));
|
||||
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
void __BuildClientKey();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
UINT m_eState;
|
||||
@@ -77,7 +65,4 @@ class CAccountConnector : public CNetworkStream, public CSingleton<CAccountConne
|
||||
|
||||
PyObject * m_poHandler;
|
||||
|
||||
// CHINA_CRYPT_KEY
|
||||
void __BuildClientKey_20050304Myevan();
|
||||
// END_OF_CHINA_CRYPT_KEY
|
||||
};
|
||||
|
||||
@@ -24,8 +24,7 @@ target_link_libraries(UserInterface
|
||||
SpeedTreeLib
|
||||
SphereLib
|
||||
PackLib
|
||||
|
||||
cryptopp-static
|
||||
|
||||
lzo2
|
||||
libzstd_static
|
||||
mio
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "PythonCharacterManager.h"
|
||||
#include "PythonTextTail.h"
|
||||
#include "Packet.h"
|
||||
#include "PackLib/PackManager.h"
|
||||
|
||||
// MARK_BUG_FIX
|
||||
struct SMarkIndex
|
||||
@@ -193,15 +192,12 @@ UINT CGuildMarkDownloader::__GetPacketSize(UINT header)
|
||||
return sizeof(TPacketGCMarkBlock);
|
||||
case HEADER_GC_GUILD_SYMBOL_DATA:
|
||||
return sizeof(TPacketGCGuildSymbolData);
|
||||
case HEADER_GC_MARK_DIFF_DATA: // 사용하지 않음
|
||||
case HEADER_GC_MARK_DIFF_DATA:
|
||||
return sizeof(BYTE);
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
case HEADER_GC_KEY_AGREEMENT:
|
||||
return sizeof(TPacketKeyAgreement);
|
||||
case HEADER_GC_KEY_AGREEMENT_COMPLETED:
|
||||
return sizeof(TPacketKeyAgreementCompleted);
|
||||
|
||||
#endif
|
||||
case HEADER_GC_KEY_CHALLENGE:
|
||||
return sizeof(TPacketGCKeyChallenge);
|
||||
case HEADER_GC_KEY_COMPLETE:
|
||||
return sizeof(TPacketGCKeyComplete);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -222,16 +218,14 @@ bool CGuildMarkDownloader::__DispatchPacket(UINT header)
|
||||
return __LoginState_RecvMarkBlock();
|
||||
case HEADER_GC_GUILD_SYMBOL_DATA:
|
||||
return __LoginState_RecvSymbolData();
|
||||
case HEADER_GC_MARK_DIFF_DATA: // 사용하지 않음
|
||||
case HEADER_GC_MARK_DIFF_DATA:
|
||||
return true;
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
case HEADER_GC_KEY_AGREEMENT:
|
||||
return __LoginState_RecvKeyAgreement();
|
||||
case HEADER_GC_KEY_AGREEMENT_COMPLETED:
|
||||
return __LoginState_RecvKeyAgreementCompleted();
|
||||
#endif
|
||||
case HEADER_GC_KEY_CHALLENGE:
|
||||
return __LoginState_RecvKeyChallenge();
|
||||
case HEADER_GC_KEY_COMPLETE:
|
||||
return __LoginState_RecvKeyComplete();
|
||||
}
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
// END_OF_MARK_BUG_FIX
|
||||
|
||||
@@ -279,11 +273,6 @@ bool CGuildMarkDownloader::__LoginState_RecvPhase()
|
||||
|
||||
if (kPacketPhase.phase == PHASE_LOGIN)
|
||||
{
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
const char* key = GetSecurityKey();
|
||||
SetSecurityMode(true, key);
|
||||
#endif
|
||||
|
||||
switch (m_dwTodo)
|
||||
{
|
||||
case TODO_RECV_NONE:
|
||||
@@ -428,66 +417,63 @@ bool CGuildMarkDownloader::__LoginState_RecvMarkBlock()
|
||||
}
|
||||
// END_OF_MARK_BUG_FIX
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
bool CGuildMarkDownloader::__LoginState_RecvKeyAgreement()
|
||||
bool CGuildMarkDownloader::__LoginState_RecvKeyChallenge()
|
||||
{
|
||||
TPacketKeyAgreement packet;
|
||||
TPacketGCKeyChallenge packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracenf("KEY_AGREEMENT RECV %u", packet.wDataLength);
|
||||
Tracen("KEY_CHALLENGE RECV");
|
||||
|
||||
TPacketKeyAgreement packetToSend;
|
||||
size_t dataLength = TPacketKeyAgreement::MAX_DATA_LEN;
|
||||
size_t agreedLength = Prepare(packetToSend.data, &dataLength);
|
||||
if (agreedLength == 0)
|
||||
SecureCipher& cipher = GetSecureCipher();
|
||||
if (!cipher.Initialize())
|
||||
{
|
||||
// 초기화 실패
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
assert(dataLength <= TPacketKeyAgreement::MAX_DATA_LEN);
|
||||
|
||||
if (Activate(packet.wAgreedLength, packet.data, packet.wDataLength))
|
||||
if (!cipher.ComputeClientKeys(packet.server_pk))
|
||||
{
|
||||
// Key agreement 성공, 응답 전송
|
||||
packetToSend.bHeader = HEADER_CG_KEY_AGREEMENT;
|
||||
packetToSend.wAgreedLength = (WORD)agreedLength;
|
||||
packetToSend.wDataLength = (WORD)dataLength;
|
||||
|
||||
if (!Send(sizeof(packetToSend), &packetToSend))
|
||||
{
|
||||
Tracen(" CAccountConnector::__AuthState_RecvKeyAgreement - SendKeyAgreement Error");
|
||||
return false;
|
||||
}
|
||||
Tracenf("KEY_AGREEMENT SEND %u", packetToSend.wDataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 키 협상 실패
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
TPacketCGKeyResponse response;
|
||||
response.bHeader = HEADER_CG_KEY_RESPONSE;
|
||||
cipher.GetPublicKey(response.client_pk);
|
||||
cipher.ComputeResponse(packet.challenge, response.challenge_response);
|
||||
|
||||
if (!Send(sizeof(response), &response))
|
||||
return false;
|
||||
|
||||
Tracen("KEY_RESPONSE SENT");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGuildMarkDownloader::__LoginState_RecvKeyAgreementCompleted()
|
||||
bool CGuildMarkDownloader::__LoginState_RecvKeyComplete()
|
||||
{
|
||||
TPacketKeyAgreementCompleted packet;
|
||||
TPacketGCKeyComplete packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
return false;
|
||||
|
||||
Tracen("KEY_COMPLETE RECV");
|
||||
|
||||
SecureCipher& cipher = GetSecureCipher();
|
||||
|
||||
uint8_t session_token[SecureCipher::SESSION_TOKEN_SIZE];
|
||||
if (!cipher.DecryptToken(packet.encrypted_token, sizeof(packet.encrypted_token),
|
||||
packet.nonce, session_token))
|
||||
{
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracenf("KEY_AGREEMENT_COMPLETED RECV");
|
||||
|
||||
ActivateCipher();
|
||||
cipher.SetSessionToken(session_token);
|
||||
cipher.SetActivated(true);
|
||||
|
||||
Tracen("SECURE CIPHER ACTIVATED");
|
||||
return true;
|
||||
}
|
||||
#endif // _IMPROVED_PACKET_ENCRYPTION_
|
||||
|
||||
bool CGuildMarkDownloader::__SendSymbolCRCList()
|
||||
{
|
||||
|
||||
@@ -54,10 +54,8 @@ class CGuildMarkDownloader : public CNetworkStream, public CSingleton<CGuildMark
|
||||
bool __LoginState_RecvMarkIndex();
|
||||
bool __LoginState_RecvMarkBlock();
|
||||
bool __LoginState_RecvSymbolData();
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
bool __LoginState_RecvKeyAgreement();
|
||||
bool __LoginState_RecvKeyAgreementCompleted();
|
||||
#endif
|
||||
bool __LoginState_RecvKeyChallenge();
|
||||
bool __LoginState_RecvKeyComplete();
|
||||
bool __SendMarkIDXList();
|
||||
bool __SendMarkCRCList();
|
||||
bool __SendSymbolCRCList();
|
||||
|
||||
@@ -272,13 +272,11 @@ bool CGuildMarkUploader::__LoginState_Process()
|
||||
if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CGuildMarkUploader::__LoginState_RecvPing))
|
||||
return false;
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT, sizeof(TPacketKeyAgreement), &CGuildMarkUploader::__LoginState_RecvKeyAgreement))
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_CHALLENGE, sizeof(TPacketGCKeyChallenge), &CGuildMarkUploader::__LoginState_RecvKeyChallenge))
|
||||
return false;
|
||||
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_AGREEMENT_COMPLETED, sizeof(TPacketKeyAgreementCompleted), &CGuildMarkUploader::__LoginState_RecvKeyAgreementCompleted))
|
||||
if (!__AnalyzePacket(HEADER_GC_KEY_COMPLETE, sizeof(TPacketGCKeyComplete), &CGuildMarkUploader::__LoginState_RecvKeyComplete))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -330,11 +328,6 @@ bool CGuildMarkUploader::__LoginState_RecvPhase()
|
||||
|
||||
if (kPacketPhase.phase==PHASE_LOGIN)
|
||||
{
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
const char* key = GetSecurityKey();
|
||||
SetSecurityMode(true, key);
|
||||
#endif
|
||||
|
||||
if (SEND_TYPE_MARK == m_dwSendType)
|
||||
{
|
||||
if (!__SendMarkPacket())
|
||||
@@ -384,66 +377,63 @@ bool CGuildMarkUploader::__LoginState_RecvPing()
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
bool CGuildMarkUploader::__LoginState_RecvKeyAgreement()
|
||||
bool CGuildMarkUploader::__LoginState_RecvKeyChallenge()
|
||||
{
|
||||
TPacketKeyAgreement packet;
|
||||
TPacketGCKeyChallenge packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracenf("KEY_AGREEMENT RECV %u", packet.wDataLength);
|
||||
Tracen("KEY_CHALLENGE RECV");
|
||||
|
||||
TPacketKeyAgreement packetToSend;
|
||||
size_t dataLength = TPacketKeyAgreement::MAX_DATA_LEN;
|
||||
size_t agreedLength = Prepare(packetToSend.data, &dataLength);
|
||||
if (agreedLength == 0)
|
||||
SecureCipher& cipher = GetSecureCipher();
|
||||
if (!cipher.Initialize())
|
||||
{
|
||||
// 초기화 실패
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
assert(dataLength <= TPacketKeyAgreement::MAX_DATA_LEN);
|
||||
|
||||
if (Activate(packet.wAgreedLength, packet.data, packet.wDataLength))
|
||||
if (!cipher.ComputeClientKeys(packet.server_pk))
|
||||
{
|
||||
// Key agreement 성공, 응답 전송
|
||||
packetToSend.bHeader = HEADER_CG_KEY_AGREEMENT;
|
||||
packetToSend.wAgreedLength = (WORD)agreedLength;
|
||||
packetToSend.wDataLength = (WORD)dataLength;
|
||||
|
||||
if (!Send(sizeof(packetToSend), &packetToSend))
|
||||
{
|
||||
Tracen(" CAccountConnector::__AuthState_RecvKeyAgreement - SendKeyAgreement Error");
|
||||
return false;
|
||||
}
|
||||
Tracenf("KEY_AGREEMENT SEND %u", packetToSend.wDataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 키 협상 실패
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
TPacketCGKeyResponse response;
|
||||
response.bHeader = HEADER_CG_KEY_RESPONSE;
|
||||
cipher.GetPublicKey(response.client_pk);
|
||||
cipher.ComputeResponse(packet.challenge, response.challenge_response);
|
||||
|
||||
if (!Send(sizeof(response), &response))
|
||||
return false;
|
||||
|
||||
Tracen("KEY_RESPONSE SENT");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGuildMarkUploader::__LoginState_RecvKeyAgreementCompleted()
|
||||
bool CGuildMarkUploader::__LoginState_RecvKeyComplete()
|
||||
{
|
||||
TPacketKeyAgreementCompleted packet;
|
||||
TPacketGCKeyComplete packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
return false;
|
||||
|
||||
Tracen("KEY_COMPLETE RECV");
|
||||
|
||||
SecureCipher& cipher = GetSecureCipher();
|
||||
|
||||
uint8_t session_token[SecureCipher::SESSION_TOKEN_SIZE];
|
||||
if (!cipher.DecryptToken(packet.encrypted_token, sizeof(packet.encrypted_token),
|
||||
packet.nonce, session_token))
|
||||
{
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracenf("KEY_AGREEMENT_COMPLETED RECV");
|
||||
|
||||
ActivateCipher();
|
||||
cipher.SetSessionToken(session_token);
|
||||
cipher.SetActivated(true);
|
||||
|
||||
Tracen("SECURE CIPHER ACTIVATED");
|
||||
return true;
|
||||
}
|
||||
#endif // _IMPROVED_PACKET_ENCRYPTION_
|
||||
|
||||
bool CGuildMarkUploader::__AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CGuildMarkUploader::*pfnDispatchPacket)())
|
||||
{
|
||||
|
||||
@@ -88,10 +88,8 @@ class CGuildMarkUploader : public CNetworkStream, public CSingleton<CGuildMarkUp
|
||||
bool __LoginState_RecvPhase();
|
||||
bool __LoginState_RecvHandshake();
|
||||
bool __LoginState_RecvPing();
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
bool __LoginState_RecvKeyAgreement();
|
||||
bool __LoginState_RecvKeyAgreementCompleted();
|
||||
#endif
|
||||
bool __LoginState_RecvKeyChallenge();
|
||||
bool __LoginState_RecvKeyComplete();
|
||||
|
||||
bool __AnalyzePacket(UINT uHeader, UINT uPacketSize, bool (CGuildMarkUploader::*pfnDispatchPacket)());
|
||||
|
||||
|
||||
@@ -6,12 +6,6 @@
|
||||
|
||||
#include <windowsx.h>
|
||||
|
||||
#ifndef LSS_SECURITY_KEY
|
||||
#define LSS_SECURITY_KEY "testtesttesttest"
|
||||
#endif
|
||||
|
||||
std::string __SECURITY_KEY_STRING__ = LSS_SECURITY_KEY;
|
||||
|
||||
char MULTI_LOCALE_PATH_COMMON[256] = "locale/common";
|
||||
char MULTI_LOCALE_PATH[256] = "locale/en";
|
||||
char MULTI_LOCALE_NAME[256] = "en";
|
||||
@@ -100,11 +94,6 @@ int GetSkillPower(unsigned level)
|
||||
return SKILL_POWERS[level];
|
||||
}
|
||||
|
||||
const char* GetSecurityKey()
|
||||
{
|
||||
return __SECURITY_KEY_STRING__.c_str();
|
||||
}
|
||||
|
||||
const char* GetLocaleName()
|
||||
{
|
||||
return MULTI_LOCALE_NAME;
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
const char* GetLocaleName();
|
||||
const char* GetLocalePath();
|
||||
const char* GetLocalePathCommon();
|
||||
const char* GetSecurityKey();
|
||||
|
||||
bool IsRTL();
|
||||
int StringCompareCI( LPCSTR szStringLeft, LPCSTR szStringRight, size_t sizeLength );
|
||||
void LoadConfig(const char* fileName);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#define _IMPROVED_PACKET_ENCRYPTION_
|
||||
|
||||
#define ENABLE_COSTUME_SYSTEM
|
||||
#define ENABLE_ENERGY_SYSTEM
|
||||
#define ENABLE_DRAGON_SOUL_SYSTEM
|
||||
|
||||
@@ -11,7 +11,6 @@ enum
|
||||
/////////////////////////////////////////////////
|
||||
// To Server
|
||||
// HEADER_BLANK is the not use(for future use)
|
||||
HEADER_CG_LOGIN = 1,
|
||||
HEADER_CG_ATTACK = 2,
|
||||
HEADER_CG_CHAT = 3,
|
||||
HEADER_CG_PLAYER_CREATE = 4, // 새로운 플래이어를 생성
|
||||
@@ -131,7 +130,8 @@ enum
|
||||
HEADER_CG_DRAGON_SOUL_REFINE = 205,
|
||||
HEADER_CG_STATE_CHECKER = 206,
|
||||
|
||||
HEADER_CG_KEY_AGREEMENT = 0xfb, // _IMPROVED_PACKET_ENCRYPTION_
|
||||
HEADER_CG_KEY_RESPONSE = 0xf9, // Secure key exchange response
|
||||
HEADER_CG_LOGIN_SECURE = 0xf6, // Secure login packet
|
||||
HEADER_CG_TIME_SYNC = 0xfc,
|
||||
HEADER_CG_CLIENT_VERSION = 0xfd,
|
||||
HEADER_CG_CLIENT_VERSION2 = 0xf1,
|
||||
@@ -288,21 +288,15 @@ enum
|
||||
// END_OF_SUPPORT_BGM
|
||||
|
||||
HEADER_GC_AUTH_SUCCESS = 150,
|
||||
HEADER_GC_PANAMA_PACK = 151,
|
||||
|
||||
//HYBRID CRYPT
|
||||
HEADER_GC_HYBRIDCRYPT_KEYS = 152,
|
||||
HEADER_GC_HYBRIDCRYPT_SDB = 153, // SDB means Supplmentary Data Blocks
|
||||
//HYBRID CRYPT
|
||||
|
||||
HEADER_GC_SPECIFIC_EFFECT = 208,
|
||||
HEADER_GC_DRAGON_SOUL_REFINE = 209,
|
||||
HEADER_GC_DRAGON_SOUL_REFINE = 209,
|
||||
HEADER_GC_RESPOND_CHANNELSTATUS = 210,
|
||||
|
||||
HEADER_GC_ITEM_GET = 211,
|
||||
|
||||
HEADER_GC_KEY_AGREEMENT_COMPLETED = 0xfa, // _IMPROVED_PACKET_ENCRYPTION_
|
||||
HEADER_GC_KEY_AGREEMENT = 0xfb, // _IMPROVED_PACKET_ENCRYPTION_
|
||||
HEADER_GC_KEY_CHALLENGE = 0xf8, // Secure key exchange challenge
|
||||
HEADER_GC_KEY_COMPLETE = 0xf7, // Secure key exchange complete
|
||||
HEADER_GC_HANDSHAKE_OK = 0xfc, // 252
|
||||
HEADER_GC_PHASE = 0xfd, // 253
|
||||
HEADER_GC_BINDUDP = 0xfe, // 254
|
||||
@@ -479,20 +473,12 @@ typedef struct command_checkin
|
||||
char pwd[PASS_MAX_NUM+1];
|
||||
} TPacketCGCheckin;
|
||||
|
||||
typedef struct command_login
|
||||
{
|
||||
uint8_t header;
|
||||
char name[ID_MAX_NUM + 1];
|
||||
char pwd[PASS_MAX_NUM + 1];
|
||||
} TPacketCGLogin;
|
||||
|
||||
// start - 권한 서버 접속을 위한 패킷들
|
||||
typedef struct command_login2
|
||||
{
|
||||
uint8_t header;
|
||||
char name[ID_MAX_NUM + 1];
|
||||
uint32_t login_key;
|
||||
uint32_t adwClientKey[4];
|
||||
} TPacketCGLogin2;
|
||||
|
||||
typedef struct command_login3
|
||||
@@ -500,7 +486,6 @@ typedef struct command_login3
|
||||
uint8_t header;
|
||||
char name[ID_MAX_NUM + 1];
|
||||
char pwd[PASS_MAX_NUM + 1];
|
||||
uint32_t adwClientKey[4];
|
||||
} TPacketCGLogin3;
|
||||
|
||||
typedef struct command_direct_enter
|
||||
@@ -2468,70 +2453,6 @@ typedef struct SPacketGCResetOnTime
|
||||
uint8_t header;
|
||||
} TPacketGCResetOnTime;
|
||||
|
||||
typedef struct SPacketGCPanamaPack
|
||||
{
|
||||
uint8_t bHeader;
|
||||
char szPackName[256];
|
||||
uint8_t abIV[32];
|
||||
} TPacketGCPanamaPack;
|
||||
|
||||
typedef struct SPacketGCHybridCryptKeys
|
||||
{
|
||||
private:
|
||||
SPacketGCHybridCryptKeys() : m_pStream(NULL) {}
|
||||
|
||||
public:
|
||||
SPacketGCHybridCryptKeys(int32_t iStreamSize) : iKeyStreamLen(iStreamSize)
|
||||
{
|
||||
m_pStream = new uint8_t[iStreamSize];
|
||||
}
|
||||
~SPacketGCHybridCryptKeys()
|
||||
{
|
||||
if( m_pStream )
|
||||
{
|
||||
delete[] m_pStream;
|
||||
m_pStream = NULL;
|
||||
}
|
||||
}
|
||||
static int32_t GetFixedHeaderSize()
|
||||
{
|
||||
return sizeof(uint8_t)+sizeof(uint16_t)+sizeof(int32_t);
|
||||
}
|
||||
|
||||
uint8_t bHeader;
|
||||
uint16_t wDynamicPacketSize;
|
||||
int32_t iKeyStreamLen;
|
||||
uint8_t* m_pStream;
|
||||
|
||||
} TPacketGCHybridCryptKeys;
|
||||
|
||||
|
||||
typedef struct SPacketGCHybridSDB
|
||||
{
|
||||
private:
|
||||
SPacketGCHybridSDB() : m_pStream(NULL) {}
|
||||
|
||||
public:
|
||||
SPacketGCHybridSDB(int32_t iStreamSize) : iSDBStreamLen(iStreamSize)
|
||||
{
|
||||
m_pStream = new uint8_t[iStreamSize];
|
||||
}
|
||||
~SPacketGCHybridSDB()
|
||||
{
|
||||
delete[] m_pStream;
|
||||
m_pStream = NULL;
|
||||
}
|
||||
static int32_t GetFixedHeaderSize()
|
||||
{
|
||||
return sizeof(uint8_t)+sizeof(uint16_t)+sizeof(int32_t);
|
||||
}
|
||||
|
||||
uint8_t bHeader;
|
||||
uint16_t wDynamicPacketSize;
|
||||
int32_t iSDBStreamLen;
|
||||
uint8_t* m_pStream;
|
||||
|
||||
} TPacketGCHybridSDB;
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Client To Client
|
||||
|
||||
@@ -2556,22 +2477,43 @@ typedef struct packet_autoban_quiz
|
||||
} TPacketGCAutoBanQuiz;
|
||||
// END_OF_AUTOBAN
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
struct TPacketKeyAgreement
|
||||
// Secure authentication packets (libsodium/XChaCha20-Poly1305)
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// Server -> Client: Key exchange challenge
|
||||
struct TPacketGCKeyChallenge
|
||||
{
|
||||
static const int32_t MAX_DATA_LEN = 256;
|
||||
uint8_t bHeader;
|
||||
uint16_t wAgreedLength;
|
||||
uint16_t wDataLength;
|
||||
uint8_t data[MAX_DATA_LEN];
|
||||
uint8_t bHeader; // HEADER_GC_KEY_CHALLENGE (0xf8)
|
||||
uint8_t server_pk[32]; // Server's X25519 public key
|
||||
uint8_t challenge[32]; // Random challenge bytes
|
||||
};
|
||||
|
||||
struct TPacketKeyAgreementCompleted
|
||||
// Client -> Server: Key exchange response
|
||||
struct TPacketCGKeyResponse
|
||||
{
|
||||
uint8_t bHeader;
|
||||
uint8_t data[3]; // dummy (not used)
|
||||
uint8_t bHeader; // HEADER_CG_KEY_RESPONSE (0xf9)
|
||||
uint8_t client_pk[32]; // Client's X25519 public key
|
||||
uint8_t challenge_response[32]; // HMAC(challenge, rx_key)
|
||||
};
|
||||
#endif // _IMPROVED_PACKET_ENCRYPTION_
|
||||
|
||||
// Server -> Client: Key exchange complete
|
||||
struct TPacketGCKeyComplete
|
||||
{
|
||||
uint8_t bHeader; // HEADER_GC_KEY_COMPLETE (0xf7)
|
||||
uint8_t encrypted_token[32 + 16]; // Session token + Poly1305 tag
|
||||
uint8_t nonce[24]; // XChaCha20 nonce
|
||||
};
|
||||
|
||||
// Client -> Server: Secure login
|
||||
struct TPacketCGLoginSecure
|
||||
{
|
||||
uint8_t bHeader; // HEADER_CG_LOGIN_SECURE (0xf6)
|
||||
char name[ID_MAX_NUM + 1];
|
||||
char pwd[PASS_MAX_NUM + 1];
|
||||
uint8_t session_token[32]; // Session token from KeyComplete
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct SPacketGCSpecificEffect
|
||||
{
|
||||
|
||||
@@ -108,10 +108,9 @@ class CMainPacketHeaderMap : public CNetworkPacketHeaderMap
|
||||
Set(HEADER_GC_BINDUDP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCBindUDP), STATIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_OWNERSHIP, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCOwnership), STATIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_CREATE_FLY, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCCreateFly), STATIC_SIZE_PACKET));
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
Set(HEADER_GC_KEY_AGREEMENT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketKeyAgreement), STATIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_KEY_AGREEMENT_COMPLETED, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketKeyAgreementCompleted), STATIC_SIZE_PACKET));
|
||||
#endif
|
||||
// Secure key exchange (libsodium)
|
||||
Set(HEADER_GC_KEY_CHALLENGE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCKeyChallenge), STATIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_KEY_COMPLETE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCKeyComplete), STATIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_ADD_FLY_TARGETING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCFlyTargeting), STATIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_FLY_TARGETING, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCFlyTargeting), STATIC_SIZE_PACKET));
|
||||
|
||||
@@ -174,8 +173,6 @@ class CMainPacketHeaderMap : public CNetworkPacketHeaderMap
|
||||
Set(HEADER_GC_DIG_MOTION, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDigMotion), STATIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_DAMAGE_INFO, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDamageInfo), STATIC_SIZE_PACKET));
|
||||
|
||||
Set(HEADER_GC_HYBRIDCRYPT_KEYS, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCHybridCryptKeys), DYNAMIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_HYBRIDCRYPT_SDB, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCHybridSDB), DYNAMIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_SPECIFIC_EFFECT, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCSpecificEffect), STATIC_SIZE_PACKET));
|
||||
Set(HEADER_GC_DRAGON_SOUL_REFINE, CNetworkPacketHeaderMap::TPacketType(sizeof(TPacketGCDragonSoulRefine), STATIC_SIZE_PACKET));
|
||||
|
||||
|
||||
@@ -270,13 +270,10 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton<CPythonNet
|
||||
bool RecvHandshakePacket();
|
||||
bool RecvHandshakeOKPacket();
|
||||
|
||||
bool RecvHybridCryptKeyPacket();
|
||||
bool RecvHybridCryptSDBPacket();
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
bool RecvKeyAgreementPacket();
|
||||
bool RecvKeyAgreementCompletedPacket();
|
||||
// Secure key exchange (libsodium/XChaCha20-Poly1305)
|
||||
bool RecvKeyChallenge();
|
||||
bool RecvKeyComplete();
|
||||
|
||||
#endif
|
||||
// ETC
|
||||
DWORD GetMainActorVID();
|
||||
DWORD GetMainActorRace();
|
||||
@@ -299,9 +296,7 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton<CPythonNet
|
||||
void ClosePhase();
|
||||
|
||||
// Login Phase
|
||||
bool SendLoginPacket(const char * c_szName, const char * c_szPassword);
|
||||
bool SendLoginPacketNew(const char * c_szName, const char * c_szPassword);
|
||||
bool SendDirectEnterPacket(const char * c_szName, const char * c_szPassword, UINT uChrSlot);
|
||||
|
||||
bool SendEnterGame();
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ PyObject* netSendLoginPacket(PyObject* poSelf, PyObject* poArgs)
|
||||
return Py_BuildException();
|
||||
|
||||
CPythonNetworkStream& rkNetStream=CPythonNetworkStream::Instance();
|
||||
rkNetStream.SendLoginPacket(szName, szPwd);
|
||||
rkNetStream.SendLoginPacketNew(szName, szPwd);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
|
||||
@@ -598,30 +598,17 @@ void CPythonNetworkStream::GamePhase()
|
||||
RecvHandshakeOKPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
|
||||
case HEADER_GC_KEY_CHALLENGE:
|
||||
RecvKeyChallenge();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
case HEADER_GC_KEY_COMPLETE:
|
||||
RecvKeyComplete();
|
||||
return;
|
||||
break;
|
||||
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
case HEADER_GC_KEY_AGREEMENT:
|
||||
RecvKeyAgreementPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_KEY_AGREEMENT_COMPLETED:
|
||||
RecvKeyAgreementCompletedPacket();
|
||||
return;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case HEADER_GC_SPECIFIC_EFFECT:
|
||||
ret = RecvSpecificEffect();
|
||||
break;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "PythonNetworkStream.h"
|
||||
#include "PythonApplication.h"
|
||||
#include "Packet.h"
|
||||
#include "PackLib/PackManager.h"
|
||||
|
||||
// HandShake ---------------------------------------------------------------------------
|
||||
void CPythonNetworkStream::HandShakePhase()
|
||||
@@ -22,7 +21,7 @@ void CPythonNetworkStream::HandShakePhase()
|
||||
case HEADER_GC_BINDUDP:
|
||||
{
|
||||
TPacketGCBindUDP BindUDP;
|
||||
|
||||
|
||||
if (!Recv(sizeof(TPacketGCBindUDP), &BindUDP))
|
||||
return;
|
||||
|
||||
@@ -39,9 +38,6 @@ void CPythonNetworkStream::HandShakePhase()
|
||||
|
||||
ELTimer_SetServerMSec(m_HandshakeData.dwTime+ m_HandshakeData.lDelta);
|
||||
|
||||
//m_dwBaseServerTime = m_HandshakeData.dwTime+ m_HandshakeData.lDelta;
|
||||
//m_dwBaseClientTime = ELTimer_GetMSec();
|
||||
|
||||
m_HandshakeData.dwTime = m_HandshakeData.dwTime + m_HandshakeData.lDelta + m_HandshakeData.lDelta;
|
||||
m_HandshakeData.lDelta = 0;
|
||||
|
||||
@@ -57,32 +53,21 @@ void CPythonNetworkStream::HandShakePhase()
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case HEADER_GC_PING:
|
||||
RecvPingPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
case HEADER_GC_KEY_CHALLENGE:
|
||||
RecvKeyChallenge();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
case HEADER_GC_KEY_COMPLETE:
|
||||
RecvKeyComplete();
|
||||
return;
|
||||
break;
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
case HEADER_GC_KEY_AGREEMENT:
|
||||
RecvKeyAgreementPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_KEY_AGREEMENT_COMPLETED:
|
||||
RecvKeyAgreementCompletedPacket();
|
||||
return;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
RecvErrorPacket(header);
|
||||
@@ -107,7 +92,6 @@ void CPythonNetworkStream::SetHandShakePhase()
|
||||
|
||||
if (__DirectEnterMode_IsSet())
|
||||
{
|
||||
// None
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -125,7 +109,7 @@ bool CPythonNetworkStream::RecvHandshakePacket()
|
||||
|
||||
m_kServerTimeSync.m_dwChangeServerTime = kHandshakeData.dwTime + kHandshakeData.lDelta;
|
||||
m_kServerTimeSync.m_dwChangeClientTime = ELTimer_GetMSec();
|
||||
|
||||
|
||||
kHandshakeData.dwTime = kHandshakeData.dwTime + kHandshakeData.lDelta + kHandshakeData.lDelta;
|
||||
kHandshakeData.lDelta = 0;
|
||||
|
||||
@@ -157,103 +141,71 @@ bool CPythonNetworkStream::RecvHandshakeOKPacket()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::RecvHybridCryptKeyPacket()
|
||||
// Secure key exchange handlers (libsodium/XChaCha20-Poly1305)
|
||||
bool CPythonNetworkStream::RecvKeyChallenge()
|
||||
{
|
||||
int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize();
|
||||
|
||||
TDynamicSizePacketHeader header;
|
||||
if( !Peek( sizeof(header), &header) )
|
||||
return false;
|
||||
|
||||
TPacketGCHybridCryptKeys kPacket(header.size-iFixedHeaderSize);
|
||||
|
||||
if (!Recv(iFixedHeaderSize, &kPacket))
|
||||
return false;
|
||||
|
||||
if (!Recv(kPacket.iKeyStreamLen, kPacket.m_pStream))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::RecvHybridCryptSDBPacket()
|
||||
{
|
||||
int iFixedHeaderSize = TPacketGCHybridSDB::GetFixedHeaderSize();
|
||||
|
||||
TDynamicSizePacketHeader header;
|
||||
if( !Peek( sizeof(header), &header) )
|
||||
return false;
|
||||
|
||||
TPacketGCHybridSDB kPacket(header.size-iFixedHeaderSize);
|
||||
|
||||
if (!Recv(iFixedHeaderSize, &kPacket))
|
||||
return false;
|
||||
|
||||
if (!Recv(kPacket.iSDBStreamLen, kPacket.m_pStream))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
bool CPythonNetworkStream::RecvKeyAgreementPacket()
|
||||
{
|
||||
TPacketKeyAgreement packet;
|
||||
TPacketGCKeyChallenge packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracenf("KEY_AGREEMENT RECV %u", packet.wDataLength);
|
||||
Tracen("SECURE KEY_CHALLENGE RECV");
|
||||
|
||||
TPacketKeyAgreement packetToSend;
|
||||
size_t dataLength = TPacketKeyAgreement::MAX_DATA_LEN;
|
||||
size_t agreedLength = Prepare(packetToSend.data, &dataLength);
|
||||
if (agreedLength == 0)
|
||||
SecureCipher& cipher = GetSecureCipher();
|
||||
if (!cipher.Initialize())
|
||||
{
|
||||
// 초기화 실패
|
||||
TraceError("Failed to initialize SecureCipher");
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
assert(dataLength <= TPacketKeyAgreement::MAX_DATA_LEN);
|
||||
|
||||
if (Activate(packet.wAgreedLength, packet.data, packet.wDataLength))
|
||||
if (!cipher.ComputeClientKeys(packet.server_pk))
|
||||
{
|
||||
// Key agreement 성공, 응답 전송
|
||||
packetToSend.bHeader = HEADER_CG_KEY_AGREEMENT;
|
||||
packetToSend.wAgreedLength = (WORD)agreedLength;
|
||||
packetToSend.wDataLength = (WORD)dataLength;
|
||||
|
||||
if (!Send(sizeof(packetToSend), &packetToSend))
|
||||
{
|
||||
assert(!"Failed Sending KeyAgreement");
|
||||
return false;
|
||||
}
|
||||
Tracenf("KEY_AGREEMENT SEND %u", packetToSend.wDataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 키 협상 실패
|
||||
TraceError("Failed to compute client session keys");
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
TPacketCGKeyResponse response;
|
||||
response.bHeader = HEADER_CG_KEY_RESPONSE;
|
||||
cipher.GetPublicKey(response.client_pk);
|
||||
cipher.ComputeChallengeResponse(packet.challenge, response.challenge_response);
|
||||
|
||||
if (!Send(sizeof(response), &response))
|
||||
{
|
||||
TraceError("Failed to send KeyResponse");
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracen("SECURE KEY_RESPONSE SENT");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::RecvKeyAgreementCompletedPacket()
|
||||
bool CPythonNetworkStream::RecvKeyComplete()
|
||||
{
|
||||
TPacketKeyAgreementCompleted packet;
|
||||
TPacketGCKeyComplete packet;
|
||||
if (!Recv(sizeof(packet), &packet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracenf("KEY_AGREEMENT_COMPLETED RECV");
|
||||
Tracen("SECURE KEY_COMPLETE RECV");
|
||||
|
||||
ActivateCipher();
|
||||
DecryptAlreadyReceivedData();
|
||||
SecureCipher& cipher = GetSecureCipher();
|
||||
|
||||
uint8_t decrypted_token[SecureCipher::SESSION_TOKEN_SIZE];
|
||||
if (!cipher.DecryptToken(packet.encrypted_token, sizeof(packet.encrypted_token),
|
||||
packet.nonce, decrypted_token))
|
||||
{
|
||||
TraceError("Failed to decrypt session token");
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
cipher.SetSessionToken(decrypted_token);
|
||||
cipher.SetActivated(true);
|
||||
|
||||
Tracen("SECURE CIPHER ACTIVATED");
|
||||
return true;
|
||||
}
|
||||
#endif // _IMPROVED_PACKET_ENCRYPTION_
|
||||
|
||||
@@ -142,17 +142,16 @@ void CPythonNetworkStream::LoadingPhase()
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
case HEADER_GC_KEY_CHALLENGE:
|
||||
RecvKeyChallenge();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
case HEADER_GC_KEY_COMPLETE:
|
||||
RecvKeyComplete();
|
||||
return;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
GamePhase();
|
||||
return;
|
||||
|
||||
@@ -47,13 +47,13 @@ void CPythonNetworkStream::LoginPhase()
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
case HEADER_GC_KEY_CHALLENGE:
|
||||
RecvKeyChallenge();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
case HEADER_GC_KEY_COMPLETE:
|
||||
RecvKeyComplete();
|
||||
return;
|
||||
break;
|
||||
|
||||
@@ -68,11 +68,6 @@ void CPythonNetworkStream::LoginPhase()
|
||||
|
||||
void CPythonNetworkStream::SetLoginPhase()
|
||||
{
|
||||
const char* key = GetSecurityKey();
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
SetSecurityMode(true, key);
|
||||
#endif
|
||||
|
||||
if ("Login" != m_strPhase)
|
||||
m_phaseLeaveFunc.Run();
|
||||
|
||||
@@ -87,26 +82,25 @@ void CPythonNetworkStream::SetLoginPhase()
|
||||
|
||||
m_dwChangingPhaseTime = ELTimer_GetMSec();
|
||||
|
||||
if (0 == m_dwLoginKey)
|
||||
{
|
||||
TraceError("SetLoginPhase: no login key - cannot login without auth server");
|
||||
ClearLoginInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
if (__DirectEnterMode_IsSet())
|
||||
{
|
||||
if (0 != m_dwLoginKey)
|
||||
SendLoginPacketNew(m_stID.c_str(), m_stPassword.c_str());
|
||||
else
|
||||
SendLoginPacket(m_stID.c_str(), m_stPassword.c_str());
|
||||
SendLoginPacketNew(m_stID.c_str(), m_stPassword.c_str());
|
||||
|
||||
// 비밀번호를 메모리에 계속 갖고 있는 문제가 있어서, 사용 즉시 날리는 것으로 변경
|
||||
ClearLoginInfo();
|
||||
CAccountConnector & rkAccountConnector = CAccountConnector::Instance();
|
||||
rkAccountConnector.ClearLoginInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != m_dwLoginKey)
|
||||
SendLoginPacketNew(m_stID.c_str(), m_stPassword.c_str());
|
||||
else
|
||||
SendLoginPacket(m_stID.c_str(), m_stPassword.c_str());
|
||||
SendLoginPacketNew(m_stID.c_str(), m_stPassword.c_str());
|
||||
|
||||
// 비밀번호를 메모리에 계속 갖고 있는 문제가 있어서, 사용 즉시 날리는 것으로 변경
|
||||
ClearLoginInfo();
|
||||
CAccountConnector & rkAccountConnector = CAccountConnector::Instance();
|
||||
rkAccountConnector.ClearLoginInfo();
|
||||
@@ -208,43 +202,6 @@ bool CPythonNetworkStream::__RecvLoginFailurePacket()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::SendDirectEnterPacket(const char* c_szID, const char* c_szPassword, UINT uChrSlot)
|
||||
{
|
||||
TPacketCGDirectEnter kPacketDirectEnter;
|
||||
kPacketDirectEnter.bHeader=HEADER_CG_DIRECT_ENTER;
|
||||
kPacketDirectEnter.index=uChrSlot;
|
||||
strncpy(kPacketDirectEnter.login, c_szID, ID_MAX_NUM);
|
||||
strncpy(kPacketDirectEnter.passwd, c_szPassword, PASS_MAX_NUM);
|
||||
|
||||
if (!Send(sizeof(kPacketDirectEnter), &kPacketDirectEnter))
|
||||
{
|
||||
Tracen("SendDirectEnter");
|
||||
return false;
|
||||
}
|
||||
|
||||
return SendSequence();
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::SendLoginPacket(const char* c_szName, const char* c_szPassword)
|
||||
{
|
||||
TPacketCGLogin LoginPacket;
|
||||
LoginPacket.header = HEADER_CG_LOGIN;
|
||||
|
||||
strncpy(LoginPacket.name, c_szName, sizeof(LoginPacket.name)-1);
|
||||
strncpy(LoginPacket.pwd, c_szPassword, sizeof(LoginPacket.pwd)-1);
|
||||
|
||||
LoginPacket.name[ID_MAX_NUM]='\0';
|
||||
LoginPacket.pwd[PASS_MAX_NUM]='\0';
|
||||
|
||||
if (!Send(sizeof(LoginPacket), &LoginPacket))
|
||||
{
|
||||
Tracen("SendLogin Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
return SendSequence();
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::SendLoginPacketNew(const char * c_szName, const char * c_szPassword)
|
||||
{
|
||||
TPacketCGLogin2 LoginPacket;
|
||||
@@ -254,11 +211,6 @@ bool CPythonNetworkStream::SendLoginPacketNew(const char * c_szName, const char
|
||||
strncpy(LoginPacket.name, c_szName, sizeof(LoginPacket.name)-1);
|
||||
LoginPacket.name[ID_MAX_NUM]='\0';
|
||||
|
||||
extern DWORD g_adwEncryptKey[4];
|
||||
extern DWORD g_adwDecryptKey[4];
|
||||
for (DWORD i = 0; i < 4; ++i)
|
||||
LoginPacket.adwClientKey[i] = g_adwEncryptKey[i];
|
||||
|
||||
if (!Send(sizeof(LoginPacket), &LoginPacket))
|
||||
{
|
||||
Tracen("SendLogin Error");
|
||||
@@ -273,9 +225,6 @@ bool CPythonNetworkStream::SendLoginPacketNew(const char * c_szName, const char
|
||||
|
||||
__SendInternalBuffer();
|
||||
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
SetSecurityMode(true, (const char *) g_adwEncryptKey, (const char *) g_adwDecryptKey);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
#include "PythonNetworkStream.h"
|
||||
#include "Packet.h"
|
||||
|
||||
extern DWORD g_adwEncryptKey[4];
|
||||
extern DWORD g_adwDecryptKey[4];
|
||||
|
||||
// Select Character ---------------------------------------------------------------------------
|
||||
void CPythonNetworkStream::SetSelectPhase()
|
||||
{
|
||||
@@ -15,11 +12,7 @@ void CPythonNetworkStream::SetSelectPhase()
|
||||
Tracen("## Network - Select Phase ##");
|
||||
Tracen("");
|
||||
|
||||
m_strPhase = "Select";
|
||||
|
||||
#ifndef _IMPROVED_PACKET_ENCRYPTION_
|
||||
SetSecurityMode(true, (const char *) g_adwEncryptKey, (const char *) g_adwDecryptKey);
|
||||
#endif
|
||||
m_strPhase = "Select";
|
||||
|
||||
m_dwChangingPhaseTime = ELTimer_GetMSec();
|
||||
m_phaseProcessFunc.Set(this, &CPythonNetworkStream::SelectPhase);
|
||||
@@ -103,29 +96,16 @@ void CPythonNetworkStream::SelectPhase()
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_KEYS:
|
||||
RecvHybridCryptKeyPacket();
|
||||
case HEADER_GC_KEY_CHALLENGE:
|
||||
RecvKeyChallenge();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_HYBRIDCRYPT_SDB:
|
||||
RecvHybridCryptSDBPacket();
|
||||
case HEADER_GC_KEY_COMPLETE:
|
||||
RecvKeyComplete();
|
||||
return;
|
||||
break;
|
||||
|
||||
|
||||
#ifdef _IMPROVED_PACKET_ENCRYPTION_
|
||||
case HEADER_GC_KEY_AGREEMENT:
|
||||
RecvKeyAgreementPacket();
|
||||
return;
|
||||
break;
|
||||
|
||||
case HEADER_GC_KEY_AGREEMENT_COMPLETED:
|
||||
RecvKeyAgreementCompletedPacket();
|
||||
return;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case HEADER_GC_PLAYER_POINT_CHANGE:
|
||||
TPacketGCPointChange PointChange;
|
||||
Recv(sizeof(TPacketGCPointChange), &PointChange);
|
||||
|
||||
@@ -1,42 +1,5 @@
|
||||
#include "StdAfx.h"
|
||||
#include "PackLib/PackManager.h"
|
||||
#include "EterBase/tea.h"
|
||||
|
||||
// CHINA_CRYPT_KEY
|
||||
DWORD g_adwEncryptKey[4];
|
||||
DWORD g_adwDecryptKey[4];
|
||||
|
||||
#include "AccountConnector.h"
|
||||
|
||||
inline const BYTE* GetKey_20050304Myevan()
|
||||
{
|
||||
volatile static DWORD s_adwKey[1938];
|
||||
|
||||
volatile DWORD seed=1491971513;
|
||||
for (UINT i=0; i<BYTE(seed); i++)
|
||||
{
|
||||
seed^=2148941891;
|
||||
seed+=3592385981;
|
||||
s_adwKey[i]=seed;
|
||||
}
|
||||
|
||||
return (const BYTE*)s_adwKey;
|
||||
}
|
||||
|
||||
//#include <eterCrypt.h>
|
||||
|
||||
void CAccountConnector::__BuildClientKey_20050304Myevan()
|
||||
{
|
||||
const BYTE * c_pszKey = GetKey_20050304Myevan();
|
||||
memcpy(g_adwEncryptKey, c_pszKey+157, 16);
|
||||
|
||||
for (DWORD i = 0; i < 4; ++i)
|
||||
g_adwEncryptKey[i] = random();
|
||||
|
||||
tea_encrypt((DWORD *) g_adwDecryptKey, (const DWORD *) g_adwEncryptKey, (const DWORD *) (c_pszKey+37), 16);
|
||||
// TEA_Encrypt((DWORD *) g_adwDecryptKey, (const DWORD *) g_adwEncryptKey, (const DWORD *) (c_pszKey+37), 16);
|
||||
}
|
||||
// END_OF_CHINA_CRYPT_KEY
|
||||
|
||||
PyObject * packExist(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <utf8.h>
|
||||
#include <sodium.h>
|
||||
|
||||
extern "C" {
|
||||
extern int _fltused;
|
||||
@@ -290,6 +291,12 @@ static bool Main(HINSTANCE hInstance, LPSTR lpCmdLine)
|
||||
OpenLogFile(false); // false == uses syserr.txt only
|
||||
#endif
|
||||
|
||||
if (sodium_init() < 0)
|
||||
{
|
||||
LogBox("sodium_init() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
static CLZO lzo;
|
||||
CPackManager packMgr;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user