#include "StdAfx.h" #include "AccountConnector.h" #include "Packet.h" #include "PythonNetworkStream.h" #include "../EterBase/tea.h" #include "../EterPack/EterPackManager.h" // CHINA_CRYPT_KEY extern DWORD g_adwEncryptKey[4]; extern DWORD g_adwDecryptKey[4]; // END_OF_CHINA_CRYPT_KEY void CAccountConnector::SetHandler(PyObject* poHandler) { m_poHandler = poHandler; } void CAccountConnector::SetLoginInfo(const char * c_szName, const char * c_szPwd) { m_strID = c_szName; m_strPassword = c_szPwd; } void CAccountConnector::ClearLoginInfo( void ) { m_strPassword = ""; } 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(); // CHINA_CRYPT_KEY __BuildClientKey_20050304Myevan(); // END_OF_CHINA_CRYPT_KEY return CNetworkStream::Connect(c_szAccountAddr, iAccountPort); } void CAccountConnector::Disconnect() { CNetworkStream::Disconnect(); __OfflineState_Set(); } void CAccountConnector::Process() { CNetworkStream::Process(); if (!__StateProcess()) { __OfflineState_Set(); Disconnect(); } } bool CAccountConnector::__StateProcess() { switch (m_eState) { case STATE_HANDSHAKE: return __HandshakeState_Process(); break; case STATE_AUTH: return __AuthState_Process(); break; } return true; } bool CAccountConnector::__HandshakeState_Process() { if (!__AnalyzePacket(HEADER_GC_PHASE, sizeof(TPacketGCPhase), &CAccountConnector::__AuthState_RecvPhase)) return false; if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake)) return false; if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing)) return false; if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys)) return false; if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB)) 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; } bool CAccountConnector::__AuthState_Process() { if (!__AnalyzePacket(0, sizeof(BYTE), &CAccountConnector::__AuthState_RecvEmpty)) return true; if (!__AnalyzePacket(HEADER_GC_PHASE, sizeof(TPacketGCPhase), &CAccountConnector::__AuthState_RecvPhase)) return false; if (!__AnalyzePacket(HEADER_GC_PING, sizeof(TPacketGCPing), &CAccountConnector::__AuthState_RecvPing)) return false; if (!__AnalyzePacket(HEADER_GC_AUTH_SUCCESS, sizeof(TPacketGCAuthSuccess), &CAccountConnector::__AuthState_RecvAuthSuccess)) return true; if (!__AnalyzePacket(HEADER_GC_LOGIN_FAILURE, sizeof(TPacketGCAuthSuccess), &CAccountConnector::__AuthState_RecvAuthFailure)) return true; if (!__AnalyzePacket(HEADER_GC_HANDSHAKE, sizeof(TPacketGCHandshake), &CAccountConnector::__AuthState_RecvHandshake)) return false; if (!__AnalyzePacket(HEADER_GC_PANAMA_PACK, sizeof(TPacketGCPanamaPack), &CAccountConnector::__AuthState_RecvPanamaPack)) 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 if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_KEYS, &CAccountConnector::__AuthState_RecvHybridCryptKeys)) return false; if (!__AnalyzeVarSizePacket(HEADER_GC_HYBRIDCRYPT_SDB, &CAccountConnector::__AuthState_RecvHybridCryptSDB)) return false; return true; } bool CAccountConnector::__AuthState_RecvEmpty() { BYTE byEmpty; Recv(sizeof(BYTE), &byEmpty); return true; } bool CAccountConnector::__AuthState_RecvPhase() { TPacketGCPhase kPacketPhase; if (!Recv(sizeof(kPacketPhase), &kPacketPhase)) return false; if (kPacketPhase.phase == PHASE_HANDSHAKE) { __HandshakeState_Set(); } else if (kPacketPhase.phase == PHASE_AUTH) { #ifndef _IMPROVED_PACKET_ENCRYPTION_ const char* key = LocaleService_GetSecurityKey(); SetSecurityMode(true, key); #endif TPacketCGLogin3 LoginPacket; LoginPacket.header = HEADER_CG_LOGIN3; strncpy(LoginPacket.name, m_strID.c_str(), ID_MAX_NUM); strncpy(LoginPacket.pwd, m_strPassword.c_str(), PASS_MAX_NUM); 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"); return false; } if (!SendSequence()) return false; __AuthState_Set(); } return true; } bool CAccountConnector::__AuthState_RecvHandshake() { TPacketGCHandshake kPacketHandshake; if (!Recv(sizeof(kPacketHandshake), &kPacketHandshake)) return false; // HandShake { 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; } } return true; } bool CAccountConnector::__AuthState_RecvPanamaPack() { TPacketGCPanamaPack kPacket; if (!Recv(sizeof(TPacketGCPanamaPack), &kPacket)) return false; CEterPackManager::instance().RegisterPack(kPacket.szPackName, "*", kPacket.abIV); return true; } bool CAccountConnector::__AuthState_RecvHybridCryptKeys(int iTotalSize) { int iFixedHeaderSize = TPacketGCHybridCryptKeys::GetFixedHeaderSize(); TPacketGCHybridCryptKeys kPacket(iTotalSize-iFixedHeaderSize); if (!Recv(iFixedHeaderSize, &kPacket)) return false; if (!Recv(kPacket.iKeyStreamLen, kPacket.m_pStream)) return false; CEterPackManager::Instance().RetrieveHybridCryptPackKeys( kPacket.m_pStream ); 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; CEterPackManager::Instance().RetrieveHybridCryptPackSDB( kPacket.m_pStream ); return true; } bool CAccountConnector::__AuthState_RecvPing() { TPacketGCPing kPacketPing; if (!Recv(sizeof(kPacketPing), &kPacketPing)) return false; __AuthState_SendPong(); return true; } bool CAccountConnector::__AuthState_SendPong() { TPacketCGPong kPacketPong; kPacketPong.bHeader = HEADER_CG_PONG; if (!Send(sizeof(kPacketPong), &kPacketPong)) return false; if (IsSecurityMode()) return SendSequence(); return true; } bool CAccountConnector::__AuthState_RecvAuthSuccess() { TPacketGCAuthSuccess kAuthSuccessPacket; if (!Recv(sizeof(kAuthSuccessPacket), &kAuthSuccessPacket)) return false; if (!kAuthSuccessPacket.bResult) { if (m_poHandler) PyCallClassMemberFunc(m_poHandler, "OnLoginFailure", Py_BuildValue("(s)", "BESAMEKEY")); } else { DWORD dwPanamaKey = kAuthSuccessPacket.dwLoginKey ^ g_adwEncryptKey[0] ^ g_adwEncryptKey[1] ^ g_adwEncryptKey[2] ^ g_adwEncryptKey[3]; CEterPackManager::instance().DecryptPackIV(dwPanamaKey); CPythonNetworkStream & rkNet = CPythonNetworkStream::Instance(); rkNet.SetLoginKey(kAuthSuccessPacket.dwLoginKey); rkNet.Connect(m_strAddr.c_str(), m_iPort); } Disconnect(); __OfflineState_Set(); return true; } bool CAccountConnector::__AuthState_RecvAuthFailure() { TPacketGCLoginFailure packet_failure; if (!Recv(sizeof(TPacketGCLoginFailure), &packet_failure)) return false; 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)) { 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; if (!Peek(sizeof(bHeader), &bHeader)) return true; if (bHeader!=uHeader) return true; if (!PeekNoFetch(uPacketSize)) return true; 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 (!PeekNoFetch(dynamicHeader.size)) return true; return (this->*pfnDispatchPacket)(dynamicHeader.size); } void CAccountConnector::__OfflineState_Set() { __Inialize(); } void CAccountConnector::__HandshakeState_Set() { m_eState=STATE_HANDSHAKE; } void CAccountConnector::__AuthState_Set() { m_eState=STATE_AUTH; } void CAccountConnector::OnConnectFailure() { if (m_poHandler) PyCallClassMemberFunc(m_poHandler, "OnConnectFailure", Py_BuildValue("()")); __OfflineState_Set(); } void CAccountConnector::OnConnectSuccess() { m_eState = STATE_HANDSHAKE; } void CAccountConnector::OnRemoteDisconnect() { if (m_isWaitKey) { if (m_poHandler) { PyCallClassMemberFunc(m_poHandler, "OnExit", Py_BuildValue("()")); return; } } __OfflineState_Set(); } 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; m_isWaitKey = FALSE; } CAccountConnector::CAccountConnector() { m_poHandler = NULL; m_strAddr = ""; m_iPort = 0; SetLoginInfo("", ""); SetRecvBufferSize(1024 * 128); SetSendBufferSize(2048); __Inialize(); } CAccountConnector::~CAccountConnector() { __OfflineState_Set(); } //martysama0134's 2e58d0b8baeb072acdf3afc4a5d1999f