#include "stdafx.h" #include "UserInfo.Secure.h" #include "User.h" #include "TempUser.h" #include //================================================================================================== //加密设置的用户列表基准点 util::__LList SecureManager::sCryptedUserListEntry; //加密设置中的用户列表起始点(no TempUser) util::__LList SecureManager::sCryptingUserListEntry; //加密ACK超时用户列表 util::__LList SecureManager::sReleasingUserListEntry; //================================================================================================== SecureManager::SecureManager() : UTIL(FIELD) { util::LList::Init(&sCryptedUserListEntry); util::LList::Init(&sCryptingUserListEntry); util::LList::Init(&sReleasingUserListEntry); } // NOTE:调用AdCrypted User时,不应在查询中. void SecureManager::AddCryptedUser(SecurePackNode4User* node) { SecurePackNode4User& secure = *node; // problem point secure.SECURE_FLAG().STATUS.SetStatus(sSECURE_FLAG::STAT_CRYPTED); util::LList::AddPrev(node, &sCryptedUserListEntry); } void SecureManager::AddCryptedUser(User* user) { AddCryptedUser(&user->GetSecureNode()); } // SecurePackNode4User* SecureManager::RemoveCryptedUser(SecurePackNode4User* node) { return util::LList::Delete(node); } SecurePackNode4User* SecureManager::RemoveCryptedUser(User* user) { return RemoveCryptedUser(&user->GetSecureNode()); } // //BuiltinQuery不会从列表中删除(CRYPTED LIST),添加(CRYPTING LIST). void SecureManager::AddCryptingUser(SecurePackNode4User* node, sSECURE_FLAG::eQUERY_TRANS trans_status) { SecurePackNode4User& secure = *node; ASSERT(sSECURE_FLAG::TRANS_BUILTIN_QUERY != trans_status); secure.SECURE_FLAG().STATUS.SetStatus(sSECURE_FLAG::STAT_CRYPTING); secure.SECURE_FLAG().QUERY.TransEnter(trans_status); util::LList::AddPrev(node, &sCryptingUserListEntry); } void SecureManager::AddCryptingUser(User* user, sSECURE_FLAG::eQUERY_TRANS trans_status) { SecurePackNode4User& secure = user->GetSecureNode(); AddCryptingUser(&secure, trans_status); } // SecurePackNode4User* SecureManager::RemoveCryptingUser(SecurePackNode4User* node) { return util::LList::Delete(node); } SecurePackNode4User* SecureManager::RemoveCryptingUser(User* user) { return RemoveCryptingUser(&user->GetSecureNode()); } //================================================================================================== //分组加密相关对象包 //class CryptPack4Packet CryptPack4Packet::CryptPack4Packet(const CryptPack4Packet& backup) { memcpy(&seq_number_, &(backup.seq_number_), sizeof(seq_number_)); memcpy(&crypt_manager_, &(backup.crypt_manager_), sizeof(crypt_manager_)); }; BYTE CryptPack4Packet::GetCryptAlgorithmInfo(BYTE bySNKey, BYTE* pbyCryptKeyBlock, DWORD _dwUserKey) { return crypt_manager_.GetCryptAlgorithmInfo(bySNKey, pbyCryptKeyBlock, _dwUserKey); } void CryptPack4Packet::InitCryptInfo(DWORD dwUserKey, BYTE byProtoMajorVer, BYTE byProtoMinorVer) { /*C2S_HIGH_VERSION_NO, C2S_MIDDLE_VERSION_NO*/ seq_number_.Initialize(dwUserKey, byProtoMajorVer, byProtoMinorVer); crypt_manager_.Initialize(CryptManager::bServerSession); } //================================================================================================== SecureTransaction::SecureTransaction(User* user) { AgentServer::GetGResource()->SetActiveTransactionUser(user); }; SecureTransaction::~SecureTransaction() { AgentServer::GetGResource()->SetActiveTransactionUser(NULL); }; //================================================================================================== void SecurePackNode4User::Init() { util::LList::Init(this); use_cryptography_ = false; //m_dwFlags = 0; error_flags_ = sSECURE_FLAG::ERR_NOERR; secure_user_timeout_.Instance(); //m_iArmorKitSeed = 0; SECURE_FLAG().ClearFields(); #if USING_HACKSHIELD handle_for_hackshield_ = ANTICPX_INVALID_HANDLE_VALUE; #elif USING_XIGNCODE this->XignCode_Init(); #elif USING_FROST #elif USING_GAMEGUARD gameguard_csauth_.Init(true); #endif } void SecurePackNode4User::Release() { util::LList::Delete(this); use_cryptography_ = false; error_flags_ = sSECURE_FLAG::ERR_NOERR; secure_user_timeout_.Instance(); SECURE_FLAG().ClearFields(); #if USING_HACKSHIELD if (handle_for_hackshield_ != ANTICPX_INVALID_HANDLE_VALUE) { _AhnHS_CloseClientHandle(handle_for_hackshield_); } handle_for_hackshield_ = ANTICPX_INVALID_HANDLE_VALUE; #elif USING_XIGNCODE this->XignCode_Release(); #elif USING_FROST #elif USING_GAMEGUARD gameguard_csauth_.Close(); #endif } void SecurePackNode4User::EnableHeartbeats(BOOL flag) { heartbeat_checker_.SetEnable(flag ? true : false); #ifdef _NA_20100802_SPEED_HACK_DETECTION tick_speed_checker_.SetEnabled(flag ? true : false); #endif } void SecurePackNode4User::SECURE_ROUTINE_CHANGE_OBJECT() { crypt_packet_info_for_active_.GetCryptManager().Release(); if (CryptManager* crypt_manager = &crypt_packet_info_for_active_.GetCryptManager()) { CopyMemory(crypt_manager, &(crypt_packet_info_for_backup_.GetCryptManager()), sizeof(*crypt_manager)); } if (ServerSNKey* sequence_key = &crypt_packet_info_for_active_.GetServerSNKey()) { CopyMemory(sequence_key, &(crypt_packet_info_for_backup_.GetServerSNKey()), sizeof(*sequence_key)); } } void SecurePackNode4User::SECURE_ROUTINE_CHANGE_SNKEY_PATTERN_DUPLEX() { if (ServerSNKey* sequence_key = &crypt_packet_info_for_active_.GetServerSNKey()) { CopyMemory(sequence_key, &(crypt_packet_info_for_backup_.GetServerSNKey()), sizeof(*sequence_key)); } } //分组加密设置用 void SecurePackNode4User::SetEnablePacketCrypt() { use_cryptography_ = true; crypt_packet_info_for_active_.GetCryptManager().StartLogic(use_cryptography_); } void SecurePackNode4User::InitCryptInfo(DWORD dwUserKey, BYTE byProtoMajorVer, BYTE byProtoMinorVer) { crypt_packet_info_for_active_.InitCryptInfo(dwUserKey, byProtoMajorVer, byProtoMinorVer); } //提取分组加密密钥信息 BYTE SecurePackNode4User::GetCryptAlgorithmInfo(BYTE bySNKey, BYTE* pbyCryptInfo, DWORD _dwUserKey) { CryptManager* crypt_manager = &crypt_packet_info_for_active_.GetCryptManager(); return crypt_manager->GetCryptAlgorithmInfo(bySNKey, pbyCryptInfo, _dwUserKey); } //================================================================================================== BOOL SecurePackNode4User::SendPacket_KEYINFO_KEY( UserSession* pCurrSession, UserSession* pPostSession) { TempUser* pTempUser = (TempUser*)pCurrSession; User* pUser = (User*)pPostSession; __TOUCHED(pUser); const DWORD rndUserKeyBase = 0x1319A267; const DWORD rndUserKeyCrypt = 0x316EF35F; static DWORD rndUserKey = (GetTickCount()>>8)%0x0000FFFF; // //在这里决定SN设置和加密协议. rndUserKey = (rndUserKeyBase * (rndUserKey)) + (rndUserKeyCrypt + ((rndUserKey) >> 16)); CryptPack4Packet& rCryptBackup = BACKUP_CRYPT_PACKET_INFO(); rCryptBackup.InitCryptInfo(rndUserKey, C2S_HIGH_VERSION_NO, C2S_MIDDLE_VERSION_NO); BYTE keySTREAM[280]; MSG_CG_CRYPTOGRAPHY_KEY* pMsgKEY = new (keySTREAM) MSG_CG_CRYPTOGRAPHY_KEY(); BYTE byKey = rCryptBackup.GetSendSNKey(); pMsgKEY->SetSNKey(byKey); byKey = rCryptBackup.GetCryptAlgorithmInfo(rCryptBackup.GetSendPairSNKey(), pMsgKEY->GetCryptStream(), rndUserKey); pMsgKEY->SetCryptInfo(byKey); pTempUser->SendPacket(pMsgKEY, sizeof(keySTREAM)); rCryptBackup.NextRoundSNKey4Send(); return true; } #if defined(_KOREA) || defined(_CHINA) //__NA000000_081110_LIVE_SERVICE_TEST_CLINET_SUPPORT__ // (WAVERIX) (090618) (CHANGES)添加现场核安全通过用户(for Test) struct sLiveSecuritySkipUserID { static const DWORD MAX_USERS = 20; static const SIZE_T BUFFER_SIZE = (((ID_MAX_LEN) + ((16) - 1)) & (~((16) - 1))); union { TCHAR userID[BUFFER_SIZE]; DWORD tag; }; }; static const sLiveSecuritySkipUserID LiveSecuritySkipUserID_s[sLiveSecuritySkipUserID::MAX_USERS] = { /* #if defined(_KOREA) "ANGSOO", "CHANL2432840", "CHANL2478029", "CHANL2523927", "CRAZYTOTO", "ELF2LEE", "IIZUMI", "MYKIKI", "S98807112", "SUNQA001", "SUNQA002", "SUNQA003", "SUNQA004", "SUNQA005", "SUNTEST001", "SUNTEST002", "TOPLESS", #elif defined(_CHINA) "SUNB-001", "SUNB-002", "SUNB-003", "SUNB-004", "SUNB-005", #endif */ }; #endif BOOL SecurePackNode4User::SendPacket_KEYINFO_CMD(UserSession* pCurrSession, UserSession* pPostSession) { TempUser* pTempUser = (TempUser*)pCurrSession; User* pUser = (User*)pPostSession; MSG_CG_CRYPTOGRAPHY_CMD msgCMD; pTempUser->SendPacket(&msgCMD, sizeof(msgCMD)); SECURE_ROUTINE_CHANGE_OBJECT(); SetEnablePacketCrypt(); sSECURE_FLAG& rFlag = pUser->GetSecureNode().SECURE_FLAG(); SecureManager::RemoveCryptingUser(pUser); rFlag.STATUS.SetStatus(sSECURE_FLAG::STAT_CRYPTED); SecureManager::AddCryptedUser(pUser); rFlag.STATUS.SetStatus(sSECURE_FLAG::STAT_USERINIT); #if defined(_KOREA) if (AgentServer::GetInstance()->GetMode() == eSERVER_DEV) { SecureManager::RemoveCryptedUser(pUser); } else #endif #if defined(_KOREA) || defined(_CHINA) //__NA000000_081110_LIVE_SERVICE_TEST_CLINET_SUPPORT__ { // <- else block const TCHAR* user_id = pUser->GetUserID(); const sLiveSecuritySkipUserID* it = &LiveSecuritySkipUserID_s[0]; const sLiveSecuritySkipUserID* end = &LiveSecuritySkipUserID_s[_countof(LiveSecuritySkipUserID_s)]; for ( ; it != end; ++it) { BOOLEAN check_cond_ok = it->tag && it->tag == *reinterpret_cast(user_id); if (check_cond_ok == false) { continue; } BOOLEAN is_matched = (0 == strncmp(user_id, it->userID, ID_MAX_LEN)); if (is_matched) { SecureManager::RemoveCryptedUser(pUser); break; } } }; #endif #if USING_HACKSHIELD // NOTE: f110201.4L, 已从Init方法移动。实例句柄(如果需要). if (handle_for_hackshield_ == ANTICPX_INVALID_HANDLE_VALUE) { AHNHS_SERVER_HANDLE server_handle_for_hackshield = AgentServer::GetHANDLEofHS(); handle_for_hackshield_ = _AhnHS_CreateClientObject(server_handle_for_hackshield); if (handle_for_hackshield_ == ANTICPX_INVALID_HANDLE_VALUE) { MessageOut(eCRITICAL_LOG, _T("无法创建客户端")); } }; #elif USING_XIGNCODE #elif USING_FROST ;{ SecureManager::RemoveCryptedUser(pUser); }; #endif return true; } BOOL SecurePackNode4User::OnRecvCG_CRYPTOGRAPHY_ACK(User* pUser) { //告诉客户端现在开始使用那个钥匙还设置服务器。. //此设置结束后发送和接收将使用无条件更改的密钥. BOOL bRet = GetErrStatus() == sSECURE_FLAG::ERR_DUPLEX_SNK; if(bRet) { MSG_CG_CRYPTOGRAPHY_SNK_CMD msgCMD; pUser->SendPacket(&msgCMD, sizeof(msgCMD)); //pUser->CopyCrypt_Temp2Active(); SECURE_ROUTINE_CHANGE_SNKEY_PATTERN_DUPLEX(); SetEnablePacketCrypt(); SecureManager::RemoveCryptingUser(pUser); SecureManager::AddCryptedUser(pUser); SetErrStatus(sSECURE_FLAG::ERR_NOERR); DWORD dwNextTickIntevel = RandomTimeUtil::GetPostQueryTimeout(RandomTimeUtil::SECURE_NEXT_CHECK_INTERVAL_POLE, RandomTimeUtil::SECURE_NEXT_CHECK_INTERVAL_MINMAX_BOUNDARY); secure_user_timeout_.SetNextTimeoutByCurTickBased(dwNextTickIntevel); return true; } return false; } BOOL SecurePackNode4User::OnRecvCG_CRYPTOGRAPHY_NAK(User* pUser) { MessageOutEx(g_pSunLog, CSunLog::cCRITICAL_LOG, CSunLog::cOUTPUT_BOTH, CSunLog::cCATE_CONNECTION, _T("[GUID:%u]密钥交换失败"), pUser->GetUserKey()); SecureManager::RemoveCryptingUser(pUser); pUser->SetDisconnectCode(RC::RC_DISCONNECT_CRYPTOGRAPHY_KEYEXCHANGE_NAK); pUser->DisconnectUser(true); return true; } BOOL SecurePackNode4User::OnRecvCG_CONNECTION_HEARTBEAT_SYN(User* pUser) { __UNUSED(pUser); return true; } ////////////////////////////////////////////////////////////////////////// BOOL SecurePackNode4User::Query_CRYPTOGRAPHY_SNK_KEY(User* pUser, sSECURE_FLAG::eQUERY_TRANS& eSTAT) { DWORD dwRndUserKey = RandomTimeUtil::GetRandomNumber(); // MSG_CG_CRYPTOGRAPHY_SNK_KEY msgKEY; msgKEY.m_dwSNKey = dwRndUserKey; pUser->SendPacket(&msgKEY, sizeof(MSG_CG_CRYPTOGRAPHY_SNK_KEY)); BACKUP_CRYPT_PACKET_INFO().GetServerSNKey().Initialize(dwRndUserKey, C2S_HIGH_VERSION_NO, C2S_MIDDLE_VERSION_NO); eSTAT = sSECURE_FLAG::TRANS_DUPLEX_SNK; SetErrStatus(sSECURE_FLAG::ERR_DUPLEX_SNK); SUNLOG(eFULL_LOG, _T("KEY EXCHANGE CMD")); //// (WAVERIX) //MSG_CG_CRYPTOGRAPHY_SNK_CMD msg; //pUser->SendPacket(&msg, sizeof(MSG_CG_CRYPTOGRAPHY_SNK_CMD)); //bProcess = false; return true; } BOOL SecurePackNode4User::ForcedDisconnectProcess(User* pUser) { //忽略其他所有错误状态进入终止处理程序. SetErrStatus(sSECURE_FLAG::ERR_FORCEDCLOSING); SecureManager::RemoveCryptingUser(pUser); SecureManager::AddCryptingUser(pUser, sSECURE_FLAG::TRANS_FORCEDCLOSING); //设置结束等待时间 DWORD curTick = GetTickCount(); DWORD flagTick = secure_user_timeout_.GetTimeoutTicks(); flagTick = (curTick < flagTick) ? flagTick - curTick : curTick - flagTick; if(RandomTimeUtil::MINUTE < flagTick) { DWORD nextTick = RandomTimeUtil::GetPostQueryTimeoutOver(RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_POLE, RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_MINMAX_BOUNDARY); secure_user_timeout_.SetNextTimeoutByCurTickBased(nextTick); } return true; } #if USING_GAMEGUARD BOOL SecurePackNode4User::Query_GAMEGUARD_SERVER_QUERY_CMD( User* user, sSECURE_FLAG::eQUERY_TRANS& eSTAT ) { const DWORD cur_tick = GetTickCount(); DWORD timeout = ITimeout::INSTANCE; UINT32 return_packet_size = 0; UINT32 err_code = gameguard_csauth_.Get(&return_packet_size); bool is_already_failed = (this->GetErrStatus() == sSECURE_FLAG::ERR_VIOLATION_FLOW_SEQ); if (is_already_failed) { //如果CMD或ACK失败,就不会再传送NAK return FALSE; } if (return_packet_size > 0 && err_code < 3000) { MSG_CG_GAMEGUARD_SERVER_QUERY_CMD packet; packet.clear(); memcpy(packet.buffer, gameguard_csauth_.packet, sizeof(packet.buffer)); packet.query_size = return_packet_size; user->SendPacket(&packet, sizeof(packet)); eSTAT = sSECURE_FLAG::TRANS_GAMEGUARD; SetErrStatus(sSECURE_FLAG::ERR_GAMEGUARD_QUERY); //SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] Send GameGuard Auth Query! query_size: %d", return_packet_size); return TRUE; } else // if (return_packet_size <= 0 || err_code < 3000) { //失败的情况 this->SetErrStatus(sSECURE_FLAG::ERR_VIOLATION_FLOW_SEQ); timeout = RandomTimeUtil::GetPostQueryTimeoutOver( RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_POLE, RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_MINMAX_BOUNDARY); secure_user_timeout_.SetNextTimeoutByCurTickBased(timeout); SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"]GameGuard身份验证失败!(query_size:%d/err_code:%d) [Name:%s, CharGuid:%d]", return_packet_size, err_code, user->GetSelectedCharName(), user->GetSelectedCharGuid()); MSG_CG_GAMEGUARD_SERVER_QUERY_NAK nak_packet; nak_packet.result_code = err_code; user->SendPacket(&nak_packet, sizeof(nak_packet)); return TRUE; } return FALSE; } BOOL SecurePackNode4User::OnRecv_GAMEGUARD_SERVER_QUERY_ACK( User* user, MSG_BASE* packet, WORD wSize ) { MSG_CG_GAMEGUARD_SERVER_QUERY_ACK* recved_packet = static_cast(packet); ZeroMemory(gameguard_csauth_.packet, sizeof(gameguard_csauth_.packet)); memcpy(gameguard_csauth_.packet , recved_packet->buffer, sizeof(gameguard_csauth_.packet)); const DWORD cur_tick = GetTickCount(); DWORD timeout = ITimeout::INSTANCE; // ErrStatus Check bool success = (this->GetErrStatus() == sSECURE_FLAG::ERR_GAMEGUARD_QUERY); // Auth Query Size Check UINT32 result_code = gameguard_csauth_.Check(recved_packet->query_size); if (success == false || result_code >= 3000) { //失败的情况 this->SetErrStatus(sSECURE_FLAG::ERR_VIOLATION_FLOW_SEQ); if ((cur_tick + 30 * RandomTimeUtil::SECOND) < secure_user_timeout_.GetTimeoutTicks()) { timeout = RandomTimeUtil::GetPostQueryTimeoutOver( RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_POLE, RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_MINMAX_BOUNDARY); secure_user_timeout_.SetNextTimeoutByCurTickBased(timeout); } SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] GameGuard Auth Failed! [Name:%s, CharGuid:%d]", user->GetSelectedCharName(), user->GetSelectedCharGuid()); MSG_CG_GAMEGUARD_SERVER_QUERY_NAK nak_packet; nak_packet.result_code = result_code; user->SendPacket(&nak_packet, sizeof(nak_packet)); return FALSE; } else // if (success) { SecureManager::RemoveCryptingUser(this); SecureManager::AddCryptedUser(this); this->SetErrStatus(sSECURE_FLAG::ERR_NOERR); timeout = RandomTimeUtil::GetPostQueryTimeout( RandomTimeUtil::SECURE_NEXT_CHECK_INTERVAL_POLE, RandomTimeUtil::SECURE_NEXT_CHECK_INTERVAL_MINMAX_BOUNDARY); secure_user_timeout_.SetNextTimeoutByCurTickBased(timeout); //SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] ErrStatus is Success! timout_setting: %d", timeout); } //SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] Received GameGuard Auth Query From Client!"); return TRUE; } BOOL SecurePackNode4User::OnRecv_GAMEGUARD_HACKDATA_CMD( User* user, MSG_BASE* packet, WORD size ) { MSG_CG_GAMEGUARD_HACKDATA_CMD* recved_packet = static_cast(packet); UINT32 ret = DecryptHackData("SUN3CN", recved_packet, GAMEGUARD_HACKDATA_PACKET_SIZE); if (ret == -1) { return FALSE; } return TRUE; } #endif // USING_GAMEGUARD BOOL MOLAControl::SendQueryRelease(User* pUser) { SecurePackNode4User& rSecure = pUser->GetSecureNode(); sSECURE_FLAG& rSecureFlag = rSecure.SECURE_FLAG(); __TOUCHED(rSecureFlag); //Secure Transaction是必须的 SecureTransaction SECURE_TRANSACTION(pUser); ISecureWorkNode* pSecureNode = CryptManager::GetISecureWorkNode(); MOLA_QUERY_MSG msgMOLA(pUser->GetUserGUID(), eSECURE_QUERY::DEL_USER, 0, 0, NULL, NULL); return (!!pSecureNode->QueryProcess(&msgMOLA)); } BOOL MOLAControl::SendQueryBuiltinCMD(User* pUser) { //STATUS::CRYPTED (归队时的问题不确定.) SecurePackNode4User& rSecure = pUser->GetSecureNode(); sSECURE_FLAG& rSecureFlag = rSecure.SECURE_FLAG(); BOOL bStatusTrans = rSecureFlag.STATUS.IsTransaction(); BOOL bBuiltinTrans = rSecureFlag.QUERYBUILTIN.IsTransaction(); eZONE_STATE zsSTATE = pUser->GetZoneState(); if((ePRS_AT_LOBBY == zsSTATE) || (ePRS_BEFORE_ENTER_LOBBY == zsSTATE)) return true; if(bStatusTrans) { if(!bBuiltinTrans) { //SecureTransaction是必需的 SecureTransaction SECURE_TRANSACTION(pUser); ISecureWorkNode* pSecureNode = CryptManager::GetISecureWorkNode(); MOLA_QUERY_MSG msgMOLA(pUser->GetUserGUID(), eSECURE_QUERY::BUILTIN_QUERY, 0, 0, NULL, NULL); WorkKeyBuiltin() = pSecureNode->QueryProcess(&msgMOLA); rSecureFlag.QUERYBUILTIN.TransEnter(); //rSecureFlag.STATUS.TransLeave(); return true; } SECURELOG(SECURELOG_USERINFO(pUser, eABUSE_LOGIC_VIOLATION, eABUSE_SUB_LOGIC_VIOLATION_SECURITY_QUERY_DISCONNECT), _T("[MOLAControl::SendQueryBuiltinCMD] Assertion Flow Violation")); MessageOut(eCRITICAL_LOG, _T("MonitorLog [%u][%s]"), pUser->GetUserGUID(), pUser->GetUserID()); return false; //BuiltinQuery不满意 } // Disconnect Control //ASSERT(bStatusTrans); return false; } BOOL MOLAControl::SendQuery(User* pUser, eSECURE_QUERY::IDX_T queryT, MSG_BASE* pMsg, WORD wSize) { SecureTransaction SECURE_TRANSACTION(pUser); if(!((eSECURE_QUERY::MAX_SECURE_PACKET > queryT) && (eSECURE_QUERY::BUILTIN_QUERY != queryT))) return false; ISecureWorkNode* pSecureNode = CryptManager::GetISecureWorkNode(); MOLA_QUERY_MSG rMSG(pUser->GetUserGUID(), queryT, 0, 0, (BYTE*)pMsg, wSize); //如果接到其他命令,请注意纠结. WorkKey() = pSecureNode->QueryProcess(&rMSG); if(WorkKey()) { SecurePackNode4User& rSecure = pUser->GetSecureNode(); rSecure.SetErrStatus(sSECURE_FLAG::ERR_MOLA_CONFIG); if(eSECURE_QUERY::BUILTIN_QUERY == queryT) rSecure.SECURE_FLAG().QUERYBUILTIN.TransEnter(); //else // rSecure.SECURE_FLAG().QUERY.TransEnter(); } return true; } BOOL MOLAControl::RecvQuery(User* pUser, MSG_BASE* pMsg, WORD wSize) { SecureTransaction SECURE_TRANSACTION(pUser); ISecureWorkNode* pSecureNode = CryptManager::GetISecureWorkNode(); SecurePackNode4User& rSecure = pUser->GetSecureNode(); sSECURE_FLAG& rSecureFlag = rSecure.SECURE_FLAG(); MOLA_QUERY_MSG rMSG(pUser->GetUserGUID(), eSECURE_QUERY::NON_OPERATION, WorkKey(), WorkKeyBuiltin(), (BYTE*)pMsg, wSize); DWORD dwRET = pSecureNode->OnRecvPacket(&rMSG); switch(dwRET) { case 1: //SUCCESS (NORMAL WORK) WorkKey() = 0; rSecureFlag.QUERY.TransLeave(); rSecure.SetErrStatus(sSECURE_FLAG::ERR_NOERR); SecureManager::RemoveCryptingUser(&rSecure); SecureManager::AddCryptedUser(&rSecure); return true; case 2: //SUCCESS (BUILTIN WORK) WorkKeyBuiltin() = 0; rSecureFlag.QUERYBUILTIN.TransLeave(); //这与正常查询不符. //rSecure.SetErrStatus(sSECURE_FLAG::ERR_NOERR); return true; } return false; } //================================================================================================== #if USING_HACKSHIELD BOOL SecurePackNode4User::Query_HACKSHIELD_SERVER_EX_QUERY_CMD( User* pUser, sSECURE_FLAG::eQUERY_TRANS& eSTAT) { // HACK SHIELD MSG_CG_HACKSHIELD_SERVER_EX_QUERY_CMD msgCMD; SecurePackNode4User& rSecure = pUser->GetSecureNode(); DWORD dwRET = _AhnHS_MakeRequest(rSecure.HANDLEofClientHS(), &msgCMD.m_HShieldReqBlock); if(ERROR_SUCCESS == dwRET) { pUser->SendPacket(&msgCMD, sizeof(msgCMD)); } else { MessageOut(eCRITICAL_LOG, _T("Can't Make SEED in HackShield [%u]"), dwRET); //下一个玩家也要处理..。事实上就终止吧 } //MessageOutEx(g_pSunLog, CSunLog::cFULL_LOG, CSunLog::cOUTPUT_FILE, CSunLog::cCATE_CONNECTION, _T("HackShield Query")); eSTAT = sSECURE_FLAG::TRANS_HACKSHIELD; SetErrStatus(sSECURE_FLAG::ERR_HACKSHIELD); return true; } BOOL SecurePackNode4User::OnRecvCG_HACKSHIELD_SERVER_EX_QUERY_ACK( User* pUser, MSG_CG_HACKSHIELD_SERVER_EX_QUERY_ACK* pMsgACK, WORD wSize) { SecurePackNode4User& rSecure = pUser->GetSecureNode(); BOOL bProcess = (BOOL)(rSecure.GetErrStatus() == sSECURE_FLAG::ERR_HACKSHIELD); bProcess = bProcess && (sizeof(*pMsgACK) == wSize); DWORD dwCurTick = GetTickCount(); DWORD dwTimeout = ITimeout::INSTANCE; if(bProcess) { AHNHS_TRANS_BUFFER& rBuffer = pMsgACK->m_HShieldAnsBlock; #if HACKSHIELD_VERSION >= 647 DWORD resultCode = 0; DWORD ret = _AhnHS_VerifyResponseEx(rSecure.HANDLEofClientHS(), rBuffer.byBuffer, rBuffer.nLength, &resultCode); if(ret == ANTICPX_RECOMMAND_KEEP_SESSION) #else const DWORD resultCode = _AhnHS_VerifyResponse(rSecure.HANDLEofClientHS(), rBuffer.byBuffer, rBuffer.nLength); if(ERROR_SUCCESS == resultCode) #endif { SecureManager::RemoveCryptingUser(&rSecure); SecureManager::AddCryptedUser(&rSecure); rSecure.SetErrStatus(sSECURE_FLAG::ERR_NOERR); dwTimeout = RandomTimeUtil::GetPostQueryTimeout(RandomTimeUtil::SECURE_NEXT_CHECK_INTERVAL_POLE, RandomTimeUtil::SECURE_NEXT_CHECK_INTERVAL_MINMAX_BOUNDARY); rSecure.secure_user_timeout_.SetNextTimeoutByCurTickBased(dwTimeout); //MessageOutEx(g_pSunLog, CSunLog::cFULL_LOG, CSunLog::cOUTPUT_FILE, CSunLog::cCATE_CONNECTION, // _T("[GUID:%s] Success HS~~ Enabled, TimeInfo Cur[%u], Diff[%u], Next[%u]"), // pUser->GetUserID(), dwCurTick, RandomTimeUtil::SECURE_NEXT_CHECK_INTERVAL_POLE, rSecure.TIMEOUT().TimeoutTick()); return true; } //HackSheld错误状态细节区分 switch(resultCode) { //Client未经HackSheld补丁进入时可能发生. //但是一般来说,旧版本很有可能是一个错误的工具。首先决定降低Abusing Point,采取断开的方式. case ERROR_ANTICPXSVR_UNKNOWN_CLIENT: rSecure.SetErrStatus(sSECURE_FLAG::ERR_HACKSHIELD_VERSION); break; default: rSecure.SetErrStatus(sSECURE_FLAG::ERR_HACKSHIELD_DETECT); break; } dwTimeout = RandomTimeUtil::GetPostQueryTimeoutOver(RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_POLE, RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_MINMAX_BOUNDARY); rSecure.secure_user_timeout_.SetNextTimeoutByCurTickBased(dwTimeout); MessageOutEx(g_pSunLog, CSunLog::cCRITICAL_LOG, CSunLog::cOUTPUT_FILE, CSunLog::cCATE_CONNECTION, _T("Disconnect Process by Hackshield Query Failed - [ID:%s][GUID:%u] ErrCode [%08X]\n"), pUser->GetUserID(), pUser->GetUserGUID(), resultCode); return false; } rSecure.SetErrStatus(sSECURE_FLAG::ERR_VIOLATION_FLOW_SEQ); //失败的情况 if((dwCurTick + 30 * RandomTimeUtil::SECOND) < rSecure.secure_user_timeout_.GetTimeoutTicks()) { dwTimeout = RandomTimeUtil::GetPostQueryTimeoutOver(RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_POLE, RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_MINMAX_BOUNDARY); rSecure.secure_user_timeout_.SetNextTimeoutByCurTickBased(dwTimeout); } return false; } #endif //USING_HACKSHIELD //================================================================================================== //之后将User等设置的信息移动到这里. VOID SecureManager::SetInformation(DWORD dwUpdateInterval, DWORD dwUserTimeout4ACK) { //LList::Init(&sCryptedUserListEntry); //LList::Init(&sCryptingUserListEntry); //LList::Init(&sReleasingUserListEntry); FIELD.m_dwStatus = 0; FIELD.update_timer_.Stop(); FIELD.m_dwUpdateInterval = dwUpdateInterval; FIELD.m_dwUserTimeout4ACK = dwUserTimeout4ACK; } // BOOL SecureManager::DoInit() { FIELD.update_timer_.SetTimer(FIELD.m_dwUpdateInterval); return true; } //#include "UserManager.h" BOOL SecureManager::DoProcess() { if (FIELD.update_timer_.IsExpired() == false) { return true; }; // // LOGIC... // <>要处理的逻辑()相关处理 // // <1> 在交换加密分组的用户列表中,提取能够安全接收分组的用户. // 向该玩家发送辨别密钥交换命令或是否启动内存的CMD. // 异同:虽然只选择了一名玩家进行了密钥交换,但是以多个玩家为对象,有两种类型 // 选择/降低CMD. // (2) 接受密钥交换或内存操作与否辨别命令的ACK,由Packet Handler处理 // 执行。该程序的DoProcess不参与其中. // <3> 以接受该命令并接受ACK的玩家为对象,检查限制时间(timeout), // 如果离开,强制终止. // ProcessCryptedUsers(); //上一个m_dwUserTimeout4ACK ProcessCryptingUsers(); return true; } BOOL SecureManager::IsComplete() { return false; } BOOL SecureManager::DoRelease() { return true; } VOID SecureManager::OnMsg(sSIG_MSG* pSIG_MSG) { __UNUSED(pSIG_MSG); } //================================================================================================== // #define PROCESS_TEST_CODE (0) //================================================================================================== //安全查询处理对象筛选和查询 //目标:之前分组加密的用户及之前查询处理成功的用户列表&!(角色选择 VOID SecureManager::ProcessCryptedUsers() { SecurePackNode4User* pWorkNode = GetCryptedUserListEntry(); if(util::LList::IsEmpty(pWorkNode)) return; ////////////////////////////////////////////////////////////////////////// // Used Auto Variable DWORD dwCurTick = GetTickCount(); //