Files
2022-10-26 12:25:11 +08:00

1307 lines
47 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include "UserInfo.Secure.h"
#include "User.h"
#include "TempUser.h"
#include <ServerOptionParserEx.h>
//==================================================================================================
//加密设置的用户列表基准点
util::__LList<SecurePackNode4User>
SecureManager::sCryptedUserListEntry;
//加密设置中的用户列表起始点(no TempUser)
util::__LList<SecurePackNode4User>
SecureManager::sCryptingUserListEntry;
//加密ACK超时用户列表
util::__LList<SecurePackNode4User>
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;
// <Cryptography>
//在这里决定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<const DWORD*>(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();
// <SNKey>
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<MSG_CG_GAMEGUARD_SERVER_QUERY_ACK*>(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<MSG_CG_GAMEGUARD_HACKDATA_CMD*>(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;
}
// <INTERFACE><IMPLEMENTATION>
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)
//==================================================================================================
//安全查询处理对象筛选和查询
//目标:之前分组加密的用户及之前查询处理成功的用户列表&amp;!(角色选择
VOID SecureManager::ProcessCryptedUsers()
{
SecurePackNode4User* pWorkNode = GetCryptedUserListEntry();
if(util::LList::IsEmpty(pWorkNode))
return;
//////////////////////////////////////////////////////////////////////////
// Used Auto Variable
DWORD dwCurTick = GetTickCount(); // <TIME INFO>
__TOUCHED(dwCurTick);
DWORD dwUserCount = 0; // <USER COUNT>
BOOL bProcess = true; //每个循环是否执行该用户的安全查询
do {
sSECURE_FLAG::eQUERY_TRANS eStat = sSECURE_FLAG::TRANS_NOTRANS; //状态值
//选择下一个玩家
pWorkNode = UTIL.GetNextNode(pWorkNode);
SecurePackNode4User& rSecure = *pWorkNode;
sSECURE_FLAG& rSecureFlag = rSecure.SECURE_FLAG();
//通过以下条件意味着安全查询处理对象
if(!rSecureFlag.STATUS.IsTransaction() //不是在移动中,
&& (sSECURE_FLAG::STAT_CRYPTED == rSecureFlag.STATUS.GetStatus()) //是查询对象,
&& rSecure.secure_user_timeout_.IsExpired()) //到了查询的时间,
{
//获得当前节点的User Object
User* pUser = (User*)CONTAINING_RECORD(pWorkNode, User, SECUREINFO);
#if PROCESS_TEST_CODE
MessageOutEx(g_pSunLog, CSunLog::cCRITICAL_LOG, CSunLog::cOUTPUT_BOTH, CSunLog::cCATE_CONNECTION,
_T("密钥交换对象[GUID:%u], CurrentTick : Timeout = %u : %u"), pUser->GetUserKey(), dwCurTick, rSecure.secure_user_timeout_.GetTimeoutTicks());
// 如果第一次转换为sSECURE FLAG:STAT CRYPTED,那么Time outTick将处于INSTANCE状态.
if(ITimeout::INSTANCE == rSecure.secure_user_timeout_.GetTimeoutTicks())
{
bProcess = rSecure.Query_HACKSHIELD_SERVER_EX_QUERY_CMD(pUser, eStat);
//寻求错误处理(需要采取其他措施。)
//if(!bProcess)
}
else
{
bProcess = ProcessQuery(pUser, rSecure, eStat);
}
#endif
bProcess = ProcessQuery(pUser, rSecure, eStat);
if(bProcess)
{
//LIVE的话,以180秒为基准+/-30秒
//HACKSHIELD以10秒为基准。把所有的查询以10秒为基准,并使其符合.
// (WAVERIX)(080707)(LOGIC-CHANGE)
// - [120, 140] return timeout (unit:second)
if (rSecure.GetErrStatus() != sSECURE_FLAG::ERR_VIOLATION_FLOW_SEQ)
{
DWORD dwTimeout = RandomTimeUtil::GetPostQueryTimeoutOver(
RandomTimeUtil::SECURE_KEYEXCHANGE_TIMEOUT_POLE,
RandomTimeUtil::SECURE_KEYEXCHANGE_TIMEOUT_MINMAX_BOUNDARY);
rSecure.secure_user_timeout_.SetNextTimeoutByCurTickBased(dwTimeout);
}
//切换到玩家待机状态后,选择下一个要处理的玩家
SecurePackNode4User* pTmpListNode = RemoveCryptedUser(pWorkNode);
AddCryptingUser(pWorkNode, eStat);
pWorkNode = pTmpListNode; //要处理所有用户,请删除break。
}
//
if(!(MAX_PROCESSING_USERS_IN_ONE_CYCLE > ++dwUserCount))
break;
}
} while(GetCryptedUserListEntry() != pWorkNode->next);
}
BOOL SecureManager::ProcessQuery(User* pUser, SecurePackNode4User& rSecure,
sSECURE_FLAG::eQUERY_TRANS& eSTAT)
{
const DWORD cdwRandomNoUB = 10; //随机号码位
DWORD dwRandomNo = cdwRandomNoUB; //随机号码
BOOL bProcess = false;
//获得0~9之间的随机号码
dwRandomNo = 4; // HackShield
switch(dwRandomNo)
{
case 0:
bProcess = rSecure.MOLAController().SendQuery(pUser, eSECURE_QUERY::BUILTIN_QUERY, NULL, 0);
break;
case 1:
case 5:
case 6:
case 7:
bProcess = rSecure.Query_CRYPTOGRAPHY_SNK_KEY(pUser, eSTAT);
break;
case 2:
// Send Dummy Packet
bProcess = false;
# if PROCESS_TEST_CODE
SUNLOG(eFULL_LOG, _T("SKIP"));
# endif
break;
case 3:
//bProcess = rSecure.Query_SIMPLEX_SNK_CMD(pUser, eSTAT);
bProcess = false;
break;
case 4:
#if USING_HACKSHIELD
bProcess = rSecure.Query_HACKSHIELD_SERVER_EX_QUERY_CMD(pUser, eSTAT);
#elif USING_XIGNCODE
bProcess = rSecure.Query_XIGNCODE_SERVER_QUERY_CMD(pUser, eSTAT);
#elif USING_GAMEGUARD
bProcess = rSecure.Query_GAMEGUARD_SERVER_QUERY_CMD(pUser, eSTAT);
#elif USING_FROST
#endif
break;
case 8:
bProcess = false;
break;
case 9:
bProcess = false;
break;
default:
// 不规则的
SUNLOG(eCRITICAL_LOG, _T("号码不正确 %u"), dwRandomNo);
break;
}
return bProcess;
}
//处理未对正在查询中的用户进行响应的用户的逻辑
//
VOID SecureManager::ProcessCryptingUsers()
{//该函数会导致玩家掉线,需要理清代码逻辑 by:十里坡剑神 2021-07-01
//return;
SecurePackNode4User* pWorkNode = GetCryptingUserListEntry();
if(util::LList::IsEmpty(pWorkNode))
return;
DWORD dwMaxInterval = RandomTimeUtil::SECURE_KEYEXCHANGE_TIMEOUT_POLE+RandomTimeUtil::SECURE_KEYEXCHANGE_TIMEOUT_MINMAX_BOUNDARY;
DWORD dwCurTick = GetTickCount();
do {
//选择下一个玩家
pWorkNode = UTIL.GetNextNode(pWorkNode);
SecurePackNode4User& rSecure = *pWorkNode;
sSECURE_FLAG& rSecureFlag = rSecure.SECURE_FLAG();
DWORD rUserTimeout = rSecure.secure_user_timeout_.GetTimeoutTicks();
if(dwCurTick < rUserTimeout)
{
DWORD dwDiff = (rUserTimeout - dwCurTick);
if(dwDiff > dwMaxInterval)
{
MessageOut(eCRITICAL_LOG, _T("CProcessing Time Value %u"), (dwDiff));
rSecure.secure_user_timeout_.SetNextTimeoutByCurTickBased(dwMaxInterval);
}
}
//结束处理对象,即被暂停的情况.
if(!(rSecureFlag.STATUS.IsTransaction() || (dwCurTick<rUserTimeout)))
{
User* pUser = (User*)CONTAINING_RECORD(pWorkNode, User, SECUREINFO);
const sSECURE_FLAG::eQUERY_ERRCTRL eErrStat = rSecure.GetErrStatus();
//
RC::eCONNECTION_RESULT eResult;
TCHAR* pErrMsg;
//添加错误状态
switch(eErrStat)
{
case sSECURE_FLAG::ERR_SIMPLEX_SNK: //sSECURE_CONTROL_STATUS::CRYPTFAIL_EX1:
eResult = RC::RC_DISCONNECT_CRYPTOGRAPHY_INCORRECT_SNKEY;
pErrMsg = _T("断开用户连接 : Cracked Client #1");
break;
case sSECURE_FLAG::ERR_DEFAULT_TRANS: //sSECURE_CONTROL_STATUS::CRYPTFAIL_EX2:
eResult = RC::RC_DISCONNECT_CRYPTOGRAPHY_INCORRECT_SNKEY;
pErrMsg = _T("断开用户连接 : Cracked Client #2");
break;
case sSECURE_FLAG::ERR_CORRUPTED_PACKET:// sSECURE_CONTROL_STATUS::RECEIVED_CRACKED_PACKET:
eResult = RC::RC_DISCONNECT_CRYPTOGRAPHY_INCORRECT_SNKEY;
pErrMsg = _T("断开用户连接 : Cracked Client #3");
break;
case sSECURE_FLAG::ERR_DUPLEX_SNK: //sSECURE_CONTROL_STATUS::CRYPTFAIL
eResult = RC::RC_DISCONNECT_CRYPTOGRAPHY_KEYEXCHANGE_NAK;
pErrMsg = _T("断开用户连接 : Cracked Client #4 - CryptSeq冲突");
break;
case sSECURE_FLAG::ERR_HACKSHIELD:
eResult = RC::RC_DISCONNECT_ARMORKIT_NOT_SERVICED;
pErrMsg = _T("断开用户连接 : Cracked Client #5 - [HackShield] Disabled");
break;
case sSECURE_FLAG::ERR_HACKSHIELD_DETECT:
eResult = RC::RC_DISCONNECT_ARMORKIT_NOT_SERVICED;
pErrMsg = _T("断开用户连接 : Cracked Client #6 - [HackShield] 损坏的数据");
break;
case sSECURE_FLAG::ERR_ARMORKIT:
eResult = RC::RC_DISCONNECT_ARMORKIT_NOT_SERVICED;
pErrMsg = _T("按ArmorKit禁用状态断开用户连接");
break;
case sSECURE_FLAG::ERR_VIOLATION_FLOW_SEQ:
eResult = RC::RC_DISCONNECT_ARMORKIT_NOT_SERVICED;
pErrMsg = _T("通过消息逻辑流冲突断开用户连接");
break;
case sSECURE_FLAG::ERR_HACKSHIELD_VERSION:
eResult = RC::RC_DISCONNECT_ARMORKIT_NOT_SERVICED;
pErrMsg = _T("断开用户连接 : Cracked Client #6 - [HackShield] (非客户端Bot)或(未修补客户端版本)");
break;
case sSECURE_FLAG::ERR_FORCEDCLOSING:
eResult = RC::RC_DISCONNECT_ARMORKIT_NOT_SERVICED;
pErrMsg = _T("断开用户连接 [强制或阻止]");
break;
case sSECURE_FLAG::ERR_GAMEGUARD_QUERY:
if (rSecureFlag.STATUS.GetStatus() == sSECURE_FLAG::STAT_CRYPTING)
{
//没有收到客户端的认证查询响应时
//认证查询请求的处理
RemoveCryptingUser(&rSecure);
AddCryptedUser(&rSecure);
}
return;
default:
eResult = RC::RC_DISCONNECT_CRYPTOGRAPHY_KEYEXCHANGE_TIMEOUT;
pErrMsg = _T("通过加密序列断开用户连接-超时冲突 %d");
break;
};
//该玩家的Disconnect
// pUser->SetDisconnectCode(eResult);
// pUser->DisconnectUser(true);
DWORD dwTimeoutTick = dwCurTick - rUserTimeout;
switch(eErrStat)
{
case sSECURE_FLAG::ERR_HACKSHIELD:
case sSECURE_FLAG::ERR_HACKSHIELD_DETECT:
SECURELOG(SECURELOG_USERINFO(pUser, eABUSE_LOGIC_VIOLATION, eABUSE_SUB_LOGIC_VIOLATION_HACKSHIELD_DISCONNECT), pErrMsg, dwTimeoutTick);
break;
case sSECURE_FLAG::ERR_HACKSHIELD_VERSION:
SECURELOG(SECURELOG_USERINFO(pUser, eABUSE_LOGIC_VIOLATION, eABUSE_SUB_LOGIC_VIOLATION_HACKSHIELD_INVALID_STATUS_DISCONNECT), pErrMsg, dwTimeoutTick);
break;
case sSECURE_FLAG::ERR_FORCEDCLOSING:
break;
default:
SECURELOG(SECURELOG_USERINFO(pUser, eABUSE_LOGIC_VIOLATION, eABUSE_SUB_LOGIC_VIOLATION_SECURITY_QUERY_DISCONNECT), pErrMsg, dwTimeoutTick);
break;
}
////////////////////////////////////////////////////////////////////////////////////
pWorkNode = RemoveCryptingUser(pWorkNode);
pWorkNode = UTIL.GetPrevNode(pWorkNode);
////////////////////////////////////////////////////////////////////////////////////
}
} while(GetCryptingUserListEntry() != pWorkNode->next);
}
//==================================================================================================
//==================================================================================================
//==================================================================================================
//==================================================================================================
// <RandomTimeUtil>
//
// <SHARED MACROs>
#define _RNDTMFN_F0(x,y,z) ((x & y) | (z & (x | y)))
#define _RNDTMFN_F1(x,y,z) (z ^ (x & (y ^ z)))
#define _RNDTMFN_F2(x,y,z) ((x) ^ (y) ^ (z))
// <<<32BIT OPERATORs>>>
#define _RNDTMFN32_SHR(x,n) ((x & 0xFFFFFFFF) >> n)
#define _RNDTMFN32_SHL(x,n) (x << (32 - n))
#define _RNDTMFN32_SWAP(x,n) (_RNDTMFN32_SHR(x,n) | _RNDTMFN32_SHL(x,n))
#define RNDTM_SHA32_T1(x) (_RNDTMFN32_SWAP(x, 7) ^ _RNDTMFN32_SWAP(x,18) ^ _RNDTMFN32_SHR(x, 3))
#define RNDTM_SHA32_T2(x) (_RNDTMFN32_SWAP(x,17) ^ _RNDTMFN32_SWAP(x,19) ^ _RNDTMFN32_SHR(x,10))
#define RNDTM_COMPLEX_CALC(a,b,c,d) \
(((a) + RNDTM_SHA32_T1(b) + RNDTM_SHA32_T2(c)) + (_RNDTMFN32_SWAP(d, 2) + b + c))
// <设置查询后的等待时间>
// 在LIVE模式下{基准Time out 180sec}
// USE : GetRandomTimeDelay_ByMinMaxBoundary
// RANGE: { 180sec +/- 30sec }
DWORD RandomTimeUtil::SECURE_KEYEXCHANGE_TIMEOUT_POLE = 80*RandomTimeUtil::SECOND;
DWORD RandomTimeUtil::SECURE_KEYEXCHANGE_TIMEOUT_MINMAX_BOUNDARY = 30*RandomTimeUtil::SECOND;
// <设置成为下一个查询对象的时间>
// USE : GetRandomTimeDelay
// RANGE: { MIN 5 ~ MAX 10 }概率在5~7分钟之间.
DWORD RandomTimeUtil::SECURE_NEXT_CHECK_INTERVAL_POLE = 6*RandomTimeUtil::MINUTE;
DWORD RandomTimeUtil::SECURE_NEXT_CHECK_INTERVAL_MINMAX_BOUNDARY = 1*RandomTimeUtil::MINUTE;
// <终止等待状态延迟>
// USE : GetRandomTimeDelay
// RANGE: { MIN 13 ~ MAX 26 }概率在13~20秒之间.
DWORD RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_POLE = 20*RandomTimeUtil::SECOND;
DWORD RandomTimeUtil::SECURE_FAIL_CLOSING_INTERVAL_MINMAX_BOUNDARY = 13*RandomTimeUtil::SECOND;
//
const DWORD cdwRndValue = 0x10337F32;
static DWORD s_dwRndValueBase = RNDTM_SHA32_T1(cdwRndValue);
static DWORD s_dwRndValueOut = RNDTM_SHA32_T2(s_dwRndValueBase);
static DWORD sdwRNDARRAY[4] = { GetTickCount(), 0x90442381, 0x01913384, 0x1F004097 };
DWORD RandomTimeUtil::GetPostQueryTimeout(DWORD dwFlagTick, DWORD dwMinMax /* {+/-} dword */)
{
//ITimeout sFlagTick;
if(!(dwFlagTick < dwMinMax))
{
s_dwRndValueBase = RNDTM_SHA32_T1(s_dwRndValueBase) + s_dwRndValueOut;
s_dwRndValueOut = RNDTM_SHA32_T2(s_dwRndValueOut) + s_dwRndValueBase;
INT iDiff = (INT)(s_dwRndValueOut%(dwMinMax<<1));
if(dwMinMax > (DWORD)iDiff)
dwFlagTick -= (DWORD)(dwMinMax-iDiff);
else
dwFlagTick += (DWORD)(iDiff-dwMinMax);
}
//sFlagTick.SetNextTimeoutInterval(dwFlagTick);
//return sFlagTick.GetTimeoutTicks();
return dwFlagTick;
}
// RANGE: { dwFlagTick ~ dwFlagTick+dwMax }
DWORD RandomTimeUtil::GetPostQueryTimeoutOver(DWORD dwFlagTick, DWORD dwMax /* {+} dword */)
{
//ITimeout sFlagTick;
s_dwRndValueBase = RNDTM_SHA32_T1(s_dwRndValueBase) + s_dwRndValueOut;
s_dwRndValueOut = RNDTM_SHA32_T2(s_dwRndValueOut) + s_dwRndValueBase;
DWORD dwRandom = s_dwRndValueOut%dwMax;
dwFlagTick += dwRandom;
//sFlagTick.SetNextTimeoutInterval(dwFlagTick);
//return sFlagTick.GetTimeoutTicks();
return dwFlagTick;
}
DWORD RandomTimeUtil::GetRandomNumber()
{
DWORD dwRndValueTick = RNDTM_SHA32_T1(GetTickCount());
sdwRNDARRAY[0] = RNDTM_COMPLEX_CALC(dwRndValueTick, sdwRNDARRAY[0], sdwRNDARRAY[1], sdwRNDARRAY[2]);
DWORD dwRndTmp = sdwRNDARRAY[0];
sdwRNDARRAY[0] = sdwRNDARRAY[1];
sdwRNDARRAY[1] = sdwRNDARRAY[2];
sdwRNDARRAY[2] = sdwRNDARRAY[3];
sdwRNDARRAY[3] = dwRndTmp;
//sdwRNDARRAY[1] = RNDTM_COMPLEX_CALC(sdwRNDARRAY[1], sdwRNDARRAY[2], dwRndValue2, sdwRNDARRAY[3]);
//sdwRNDARRAY[2] = RNDTM_COMPLEX_CALC(s_dwRndValueBase, sdwRNDARRAY[1], sdwRNDARRAY[3], sdwRNDARRAY[2]);
//sdwRNDARRAY[3] = RNDTM_COMPLEX_CALC(sdwRNDARRAY[3], sdwRNDARRAY[2], sdwRNDARRAY[1], sdwRNDARRAY[0]);
s_dwRndValueOut = RNDTM_COMPLEX_CALC(sdwRNDARRAY[2], sdwRNDARRAY[3], s_dwRndValueBase, dwRndValueTick);
return s_dwRndValueOut;
}
DWORD RandomTimeUtil::GetRandomNumber(DWORD dwMin, DWORD dwUpperBound)
{
//DWORD dwRandomValue = GetRandomNumber();
if(dwMin > dwUpperBound)
(dwMin) ^= (dwUpperBound) ^= (dwMin) ^= (dwUpperBound);
DWORD dwDiff = dwUpperBound - dwMin;
if(dwDiff)
dwDiff = s_dwRndValueBase % dwDiff;
return dwMin + dwDiff;
}
//==================================================================================================
// <Timeout Control for ServerMode>
// 密钥交换相关:必须适用...
//
enum eCRYPTOGRAPHY_KEY_CHANGE_TIMEOUT
{
//////////////////////////////////////////////////////////////////////////
//不同服务器模式的cUSER KEYCHANGE TIMEOUT重新设置值
CRYPTO_KEYCHANGE_TIMEOUT_MODE_DEV = 999*RandomTimeUtil::MINUTE,
CRYPTO_KEYCHANGE_TIMEOUT_MODE_INTRAOFFICE = 999*RandomTimeUtil::MINUTE,
CRYPTO_KEYCHANGE_TIMEOUT_MODE_LIVE = 120*RandomTimeUtil::SECOND,
CRYPTO_KEYCHANGE_TIMEOUT_MODE_TESTLIVE = 120*RandomTimeUtil::SECOND,
SECURE_MANAGER_UPDATE_INTERVAL_MODE_DEV = 999*RandomTimeUtil::MINUTE,
SECURE_MANAGER_UPDATE_INTERVAL_MODE_INTRAOFFICE = 999*RandomTimeUtil::MINUTE,
SECURE_MANAGER_UPDATE_INTERVAL_MODE_LIVE = 11*RandomTimeUtil::SECOND,
SECURE_MANAGER_UPDATE_INTERVAL_MODE_TESTLIVE = 11*RandomTimeUtil::SECOND,
};
DWORD RandomTimeUtil::cSECURE_MANAGER_UPDATE_INTERVAL = SECURE_MANAGER_UPDATE_INTERVAL_MODE_LIVE;
// <基本值>安全查询后等待响应时间
DWORD RandomTimeUtil::cUSER_KEYCHANGE_TIMEOUT = CRYPTO_KEYCHANGE_TIMEOUT_MODE_LIVE;
VOID RandomTimeUtil::Initialize(DWORD dwSERVER_MODE)
{
cUSER_KEYCHANGE_TIMEOUT
= (eSERVER_DEV == dwSERVER_MODE) ? CRYPTO_KEYCHANGE_TIMEOUT_MODE_DEV
: (eSERVER_INTRAOFFICE == dwSERVER_MODE) ? CRYPTO_KEYCHANGE_TIMEOUT_MODE_INTRAOFFICE
: (eSERVER_LIVE == dwSERVER_MODE) ? CRYPTO_KEYCHANGE_TIMEOUT_MODE_LIVE
: (eSERVER_TESTLIVE == dwSERVER_MODE) ? CRYPTO_KEYCHANGE_TIMEOUT_MODE_TESTLIVE
: CRYPTO_KEYCHANGE_TIMEOUT_MODE_LIVE
;
SECURE_KEYEXCHANGE_TIMEOUT_POLE = cUSER_KEYCHANGE_TIMEOUT;
SECURE_KEYEXCHANGE_TIMEOUT_MINMAX_BOUNDARY
= ((1*RandomTimeUtil::MINUTE) > SECURE_KEYEXCHANGE_TIMEOUT_POLE)
? 5*RandomTimeUtil::SECOND
: 20*RandomTimeUtil::SECOND
;
cSECURE_MANAGER_UPDATE_INTERVAL
= (eSERVER_DEV == dwSERVER_MODE) ? SECURE_MANAGER_UPDATE_INTERVAL_MODE_DEV
: (eSERVER_INTRAOFFICE == dwSERVER_MODE) ? SECURE_MANAGER_UPDATE_INTERVAL_MODE_INTRAOFFICE
: (eSERVER_LIVE == dwSERVER_MODE) ? SECURE_MANAGER_UPDATE_INTERVAL_MODE_LIVE
: (eSERVER_TESTLIVE == dwSERVER_MODE) ? SECURE_MANAGER_UPDATE_INTERVAL_MODE_TESTLIVE
: SECURE_MANAGER_UPDATE_INTERVAL_MODE_LIVE
;
#if USING_GAMEGUARD
SECURE_NEXT_CHECK_INTERVAL_POLE = 4 * RandomTimeUtil::MINUTE;
SECURE_NEXT_CHECK_INTERVAL_MINMAX_BOUNDARY = 30 * RandomTimeUtil::SECOND;
SECURE_FAIL_CLOSING_INTERVAL_POLE = 10 * RandomTimeUtil::SECOND;
SECURE_FAIL_CLOSING_INTERVAL_MINMAX_BOUNDARY = 1 * RandomTimeUtil::SECOND;
#else
SECURE_NEXT_CHECK_INTERVAL_POLE = 70*RandomTimeUtil::SECOND;
SECURE_NEXT_CHECK_INTERVAL_MINMAX_BOUNDARY = 20*RandomTimeUtil::SECOND;
SECURE_FAIL_CLOSING_INTERVAL_POLE = 20*RandomTimeUtil::SECOND;
SECURE_FAIL_CLOSING_INTERVAL_MINMAX_BOUNDARY = 15*RandomTimeUtil::SECOND;
#endif
}