Files
Sun1602/Server/AuthSystem/AuthServer/Query_Auth.cpp
T
2022-10-26 12:25:11 +08:00

960 lines
31 KiB
C++

#include "stdafx.h"
#include "Query_Auth.h"
#include "AuthFrame.h"
#include "WZ_MD5.h"
#include "QueryManager.h"
#include "AlertRequestSender.h"
#include "AccountManager.h"
#include "ServerDataManager.h"
#include "AuthAgentServerSession.h"
#include "LoginFrontServerSession.h"
#include <AuthProtocol_FS.h>
#include <AuthProtocol_AS.h>
#include <AuthStepAuthToken.h>
#include "ReAuthInfo.h"
#ifdef _KR_0_20120207_CRYPT_SHA256
#include "../ProgramCommon/SHA256.h"
#endif
#if defined(_JP_0_20100723_GAMECHU_AUTHFLOW_) || defined(__CN_20100909_SECURITY_TOKEN__ ) || defined(_NA_20100307_BETAKEY_SYSTEM)
#include <atlconv.h>
#endif
extern TCHAR g_LoginErrorString[AUTHRESULT_MAX][MAX_AUTHRESULT_MESSAGE_LEN + 1];
#ifdef _CHANNELING_AUTH_FLOW
BOOST_STATIC_ASSERT(sizeof(MSG_CF_AUTH_TOKEN_PASS_SYN::Stream) > sizeof(DB_LOGIN_USER::AuthToken) &&
sizeof(DB_LOGIN_USER::AuthToken) == sizeof(wchar_t) * (36 + 1));
BOOST_STATIC_ASSERT(AuthStepAuthToken::DB_AuthToken_Length == DB_LOGIN_USER::DB_AuthToken_Length &&
sizeof(AuthStepAuthToken::AuthTokenStreamTimeout) == sizeof(DB_LOGIN_USER::AuthToken));
#endif //_CHANNELING_AUTH_FLOW
QueryAuth::QueryAuth()
: QueryObject(QUERYTYPE_LOGINUSER)
, m_TokenType(eAuthToken_None)
, m_front_user_id(0)
{
//Sts3는 중국에서만 실명 인증 식별용도로 쓰임(0 : 비실명 , 1 : 실명)
m_recordSet.RegisterVariable(&m_Record.UserGuid, "UserGuid");
m_recordSet.RegisterVariable(m_Record.PassWD, "PassWD");
m_recordSet.RegisterVariable(&m_Record.Sts[0], "Sts");
m_recordSet.RegisterVariable(&m_Record.Sts[1], "Sts2");
m_recordSet.RegisterVariable(&m_Record.Sts[2], "Sts3");
m_recordSet.RegisterVariable(m_Record.CharPassWD, "CharPassWD");
m_recordSet.RegisterVariable(&m_Record.Age, "Age");
m_recordSet.RegisterVariable(&m_Record.IpGuid, "IpGuid");
#ifdef _SECURE_AUTH
m_recordSet.RegisterVariable(&m_Record.pData, "CardNo");
#endif
m_recordSet.RegisterVariable(&m_Record.btAuthFailCount, "AuthFailCount");
#ifdef _AUTH_MATRIX_FAIL_COUNT
m_recordSet.RegisterVariable(&m_Record.btShapeAuthFailCount, "ShapeAuthFailCount");
m_recordSet.RegisterVariable(&m_Record.btMatrixAuthFailCount, "MatrixAuthFailCount");
#endif
#ifdef _NA_20100307_BETAKEY_SYSTEM
#endif
#ifdef _CHANNELING_AUTH_FLOW
// m_recordSet.RegisterVariable(&m_Record.auth_token_result, "AuthKey");
#endif
#ifdef _CHANNELING_AUTH_FLOW_HANGAME_USER_
// m_recordSet.RegisterVariable(&m_Record.userType, "UserType");
#endif
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
m_recordSet.RegisterVariable(m_Record.user_account, "UserID");
#endif
#ifdef __CN_20100909_SECURITY_TOKEN__
m_recordSet.RegisterVariable(&m_Record.is_token_use_, "is_token_auth");
m_recordSet.RegisterVariable(m_Record.token_base64_key_, "base64string");
#endif
m_recordSet.RegisterVariable(m_Record.Login_PassWD, "Login_PassWD"); //錦맣쵱쯤駱聯槨츠匡쵱쯤駱聯 by:枷쟁팃숲 2021-06-08
m_recordSet.RegisterParameter(&m_DbResult, "", adInteger, adParamReturnValue, sizeof(int), "");
}
void
QueryAuth::Configuration(eAuthToken token_type)
{
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
gamechu_usn_ = 0;
#endif
m_key = 0;
m_TokenType = token_type;
m_ReAuthKey = 0;
m_front_user_id = 0;
m_DbResult = eQueryResult_Undefined;
ZeroMemory(&m_Record, sizeof(m_Record));
ZeroMemory(&m_account, sizeof(m_account));
ZeroMemory(&m_password, sizeof(m_password));
ZeroMemory(&m_clientIp, sizeof(m_clientIp));
ZeroMemory(&m_localIp, sizeof(m_localIp));
ZeroMemory(&m_AuthToken, sizeof(m_AuthToken));
}
BOOLEAN
QueryAuth::ValidClientAuthInfo()
{
BOOLEAN is_matched = FALSE;
if (m_TokenType == eAuthToken_None)
{
is_matched = CheckPassword();
}
else if (m_TokenType == eAuthToken_AuthTokenKorea)
{
// DB_LOGIN_USER::DB_AuthToken_Length ==> hard-code value (DB AuthToken 32Byte)
BOOST_STATIC_ASSERT(sizeof(m_AuthToken) == sizeof(m_Record.auth_token_result) &&
sizeof(m_AuthToken) == _countof(m_AuthToken) * sizeof(wchar_t));
BOOLEAN is_null = memcmp(AuthStepAuthToken::AuthTokenStreamNull,
m_Record.auth_token_result,
sizeof(m_Record.auth_token_result)) == 0;
BOOLEAN is_timeout = TRUE;
if (is_null == FALSE)
{
// "00000000-0000-0000-0000-000000000000" timeout stream
is_timeout = memcmp(AuthStepAuthToken::AuthTokenStreamTimeout,
m_Record.auth_token_result,
sizeof(m_Record.auth_token_result)) == 0;
}
//////////////////////////////////////////////////////////////////////////
// current step status table
// isNull | is_timeout
// 0 0 - O (compare client auth_token)
// 0 1 - Timeout
// 1 0 - X
// 1 1 - Already Queried | Server Selecting Client
//////////////////////////////////////////////////////////////////////////
if (is_timeout == FALSE)
{
is_matched = memcmp(m_AuthToken, m_Record.auth_token_result,
sizeof(m_Record.auth_token_result)) == 0;
}
else
{
//////////////////////////////////////////////////////////////////////////
// if server selecting client?
// F: already queried client (irregular)
// T: compare 're-authentication token stream' with 'client auth token'
//////////////////////////////////////////////////////////////////////////
is_matched = ReauthTokenAuthentication();
if (is_matched == FALSE) {
SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] 路劤룀駱聯즈탬룀駱聯呵겨 [瑯뵀:%s]", this->m_account);
}
}
SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] [瑯뵀角뤠튈토:%d][꿴璂角뤠냥묘:%d][角뤠낚珂:%d] [瑯뵀:%s]", is_matched, is_null, is_timeout, this->m_account);
}
#ifdef __NA000000_NORTH_AMERICA_HANGAME_CHANNELING__
else if (m_TokenType == eAuthToken_AuthTokenNorthA)
{
BOOST_STATIC_WARNING(0);
is_matched = true;
//#define __WAVERIX_DEBUG_CODE__
#ifdef __WAVERIX_DEBUG_CODE__
BYTE tokenStream[128];
char outputMsg[1024];
int iWritten = 0;
//////////////////////////////////////////////////////////////////////////
SUNLOG(eCRITICAL_LOG, "ID: {%s} AuthToken DBStream", m_account);
BOOST_STATIC_ASSERT(sizeof(tokenStream) >= sizeof(m_Record.auth_token_result));
CopyMemory(tokenStream, &m_Record.auth_token_result, sizeof(m_Record.auth_token_result));
iWritten = 0;
for(int i = 0; i < sizeof(m_Record.auth_token_result); ++i)
iWritten += _snprintf(&outputMsg[iWritten], _countof(outputMsg) - iWritten,
"[%02X]", tokenStream[i]);
SUNLOG(eCRITICAL_LOG, outputMsg);
//////////////////////////////////////////////////////////////////////////
SUNLOG(eCRITICAL_LOG, "ID: {%s} AuthToken UserStream", m_account);
BOOST_STATIC_ASSERT(sizeof(tokenStream) >= sizeof(m_AuthToken));
CopyMemory(tokenStream, &m_AuthToken, sizeof(m_AuthToken));
iWritten = 0;
for(int i = 0; i < sizeof(m_AuthToken); ++i)
iWritten += _snprintf(&outputMsg[iWritten], _countof(outputMsg) - iWritten,
"[%02X]", tokenStream[i]);
SUNLOG(eCRITICAL_LOG, outputMsg);
//////////////////////////////////////////////////////////////////////////
#endif
}
#endif
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
else if(m_TokenType == eAuthToken_AuthTokenGameChu)
{
is_matched = true;
}
#endif
#ifdef _RU_INGAMBA_AUTH_PROCESS
else if(m_TokenType == eAuthToken_AuthIngamba)
{
is_matched = true;
}
#endif
#ifdef _CN_ZY_AUTH_PROCESS
else if (m_TokenType == eAuthToken_AuthChinaZY) {
#ifdef _CN_ZY_AUTH_PROCESS_DBAUTH
is_matched = true;
#else
is_matched = CheckPassword();
#endif //_CN_ZY_AUTH_PROCESS_DBAUTH
}
#endif //_CN_ZY_AUTH_PROCESS
return is_matched;
}
//#endif //_CHANNELING_AUTH_FLOW
BOOLEAN
QueryAuth::ReauthTokenAuthentication()
{
BOOLEAN is_matched = false;
#ifdef __NA001334_090420_SERVER_SELECT_FACILITY__
if(m_ReAuthKey != 0)
{
ReAuthManager* pReAuthManager = ReAuthManager::Instance();
const ReAuthInfo* pReAuthInfo = pReAuthManager->FindReAuthInfo(m_ReAuthKey);
if(pReAuthInfo != 0)
{
// 이미 m_ReAuthKey가 할당되는 시점 검증된 값임.
pReAuthManager->OnAcceptQueryLoginUser(pReAuthInfo);
is_matched = true;
}
}
#endif
return is_matched;
}
BOOLEAN
QueryAuth::CheckPassword()
{ //錦맣쵱쯤駱聯槨츠匡쵱쯤駱聯 by:枷쟁팃숲 2021-06-08
//wchar_t password_widen[32] = { 0, };
//wchar_t key_widen[32] = { 0, };
char* password = m_password;
char dbPassword[kCryptStringSize]={0};
::WideCharToMultiByte(CP_ACP, 0, m_Record.Login_PassWD, -1, dbPassword,
kCryptStringSize, 0, 0);
//int password_len = int(strlen(m_password));
//MultiByteToWideChar(CP_ACP, 0,
// password, password_len + 1,
// password_widen, _countof(password_widen));
//char* key = m_account;
//int key_len = int(strlen(m_account));
//MultiByteToWideChar(CP_ACP, 0,
// key, key_len + 1,
// key_widen, _countof(key_widen));
bool is_matched = false;
//#ifdef _KR_0_20120207_CRYPT_SHA256
// int mode = AuthFrame::Instance()->GetMode();
// switch (mode)
// {
// case eSERVER_DEV:
// {
// is_matched = !!MD5::Compare((BYTE*)password_widen, int(wcslen(password_widen) * sizeof(wchar_t)),
// (BYTE*)m_Record.PassWD, // digest[16]
// (BYTE*)key_widen, int(wcslen(key_widen) * sizeof(wchar_t)));
// }
// break;
// case eSERVER_INTRAOFFICE:
// case eSERVER_LIVE:
// case eSERVER_TESTLIVE:
// {
// Crypt::SHA256 sha256;
// is_matched = sha256.Compare(password, (const char*)m_account, m_Record.PassWD);
// if (is_matched == false && strlen(sha256.GetLastError()) != 0)
// SUNLOG(eCRITICAL_LOG, "[SHA256]Account FAIL : %s", sha256.GetLastError());
// }
// break;
// default:
// is_matched = false;
// break;
// }
//#else
is_matched = (strcmp(password,dbPassword)==0);
//!!MD5::Compare((BYTE*)password_widen, int(wcslen(password_widen) * sizeof(wchar_t)),
// (BYTE*)m_Record.Login_PassWD, // digest[16]
// (BYTE*)key_widen, int(wcslen(key_widen) * sizeof(wchar_t)));
//#endif
#ifdef __NA001334_090420_SERVER_SELECT_FACILITY__
if(is_matched == 0 && m_ReAuthKey != 0)
{
ReAuthManager* pReAuthManager = ReAuthManager::Instance();
const ReAuthInfo* pReAuthInfo = pReAuthManager->FindReAuthInfo(m_ReAuthKey);
if(pReAuthInfo != 0)
{ // 이미 m_ReAuthKey가 할당되는 시점 검증된 값임.
pReAuthManager->OnAcceptQueryLoginUser(pReAuthInfo);
is_matched = true;
}
}
#endif
return is_matched;
}
/*
BOOLEAN
QueryAuth::CheckPassword(LPTSTR key, LPTSTR password, LPTSTR recvPasswd)
{
WCHAR wszPasswd[32] = {0, };
WCHAR wszKey[32] = {0, };
::ZeroMemory(wszPasswd, 32);
::MultiByteToWideChar(CP_ACP, 0,
recvPasswd, (int)strlen(recvPasswd) + 1,
wszPasswd, (int)sizeof(wszPasswd) / 2);
::ZeroMemory(wszKey, 32);
::MultiByteToWideChar(CP_ACP, 0, key, (int)strlen(key) + 1, wszKey, (int)sizeof(wszKey) / 2);
if(MD5::Compare((BYTE*)wszPasswd, (int)strlen(recvPasswd) * 2,
(BYTE*)password, (BYTE*)wszKey, (int)strlen(key) * 2))
{
return TRUE;
}
return FALSE;
}
*/
AccountInfo*
QueryAuth::CheckOverlapLogin(DWORD user_guid,
LPTSTR account,
DWORD login_front_id,
DWORD front_user_id,
BYTE& result_value)
{
AuthFrame* const auth_frame = AuthFrame::Instance();
AccountManager* const account_manager = AccountManager::Instance();
LoginFrontServerSession* login_front = (LoginFrontServerSession*)auth_frame->FindSession(login_front_id);
// 이전 접속자가 있다면, 그 정보를 얻어온다.
AccountInfo* prev_account_info = NULL;
AccountInfo* current_account_info =
account_manager->CreateAccountInfo(account, &prev_account_info);
// 이전 접속자가 없으면 성공!
if (prev_account_info == NULL)
{
current_account_info->m_LoginFrontId = login_front_id;
current_account_info->m_LoginFrontUserId = front_user_id;
current_account_info->m_locationId = 0;
current_account_info->m_userGuid = user_guid;
return current_account_info;
}
if(prev_account_info->m_locationId == NULL)
{
// 현재 인증중인 계정이 존재(서버를 선택하지 않은 상황)
result_value = AUTHRESULT_PROCESSLOGIN;
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 瑯뵀 : %s, 寧늴되쩌駱聯榴檄 : %u",
prev_account_info->m_account,
prev_account_info->m_status
);
}
else
{
// 현재 접속중인 계정이 존재(서버를 선택한 상황)
result_value = AUTHRESULT_ALREADYLOGIN;
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 瑯뵀 : %s, 寧늴되쩌駱聯榴檄 : %u, 덜잿륩蛟똥젯쌈긍뵀 : %u",
prev_account_info->m_account,
prev_account_info->m_status,
prev_account_info->m_locationId
);
AuthAgentServerSession* auth_agent_server =
ServerDataManager::Instance()->FindAuthAgentServerSession(prev_account_info->m_locationId);
if (auth_agent_server)
{
// 이전 접속자 강제종료 요청
MSG_SA_AUTH_ASK_PC_LOGOUT_SYN logout_msg;
logout_msg.m_dwAuthUserID = prev_account_info->m_authKey;
logout_msg.m_GameAgentID = prev_account_info->m_locationId;
logout_msg.m_dwUserGUID = prev_account_info->m_userGuid;
CHECK_ID_LENGTH_BUFFER(logout_msg.m_szID);
CHECK_ID_LENGTH_BUFFER(prev_account_info->m_account);
::_tcsncpy(logout_msg.m_szID, prev_account_info->m_account, _countof(logout_msg.m_szID));
logout_msg.m_szID[_countof(logout_msg.m_szID) - 1] = '\0';
logout_msg.m_dwLogoutCode = eDRC_OVERLAPPEDCONN;
auth_agent_server->SendPacket(&logout_msg, sizeof(logout_msg));
}
else
{
account_manager->ClearInfo(prev_account_info->m_account);
}
}
return NULL;
}
VOID
QueryAuth::onResult()
{
QueryObject::onResult();
AuthFrame* const auth_frame = AuthFrame::Instance();
QueryManager* const query_manager = QueryManager::Instance();
LoginFrontServerSession* login_front =
static_cast<LoginFrontServerSession*>(auth_frame->FindSession(m_key));
if (login_front == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 灌冷돕되쩌쳔빵,젯쌈긍뵀 : %u", m_key
);
return;
}
MSG_SF_AUTH_ID_PASSWORD_CHECK_ACK ack_msg;
ack_msg.m_dwFrontUserID = m_front_user_id;
ack_msg.m_byFailCount = 0;
ack_msg.m_byResult = AUTHRESULT_OK;
#ifdef __CN_20100909_SECURITY_TOKEN__
ack_msg.m_Is_Token_Use = m_Record.is_token_use_;
#endif
// - eQueryResult_Undefined = -1, Impossible
// - eQueryResult_Success = 0, Query Successed
// - eQueryResult_Fail = 1, can't find user, 기존 일반 에러.
if (m_DbResult != eQueryResult_Success &&
m_DbResult != eQueryResult_Fail)
{
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
if(m_TokenType == eAuthToken_AuthTokenGameChu)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 鑒앴욋꿴璂써벎 : %d, 瑯뵀 : %u",
m_DbResult,
gamechu_usn_
);
}
else
{
#endif
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__ " : 鑒앴욋꿴璂써벎 : %d - 瑯뵀 : %s",
m_DbResult,
m_account
);
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
}
#endif
}
if(m_DbResult==eQueryResult_MaxLoginCount)
{// 낚법離댕젯쌈鑒 by:枷쟁팃숲 2021-06-28
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__ " : 낚법離댕젯쌈鑒 :瑯뵀 : %s IP=%s",
m_account,
m_clientIp
);
ack_msg.m_byResult = AUTHRESULT_MAXLOGINCOUNT;
goto ERROR_RESULT;
}
if (m_recordSet.GetRecordCount() == 0)
{
ack_msg.m_byResult = AUTHRESULT_INVALIDACCOUNT;
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
if(m_TokenType == eAuthToken_AuthTokenGameChu)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : doesn't exist in DB : GameChu USN : %u",
gamechu_usn_
);
}
else
{
#endif
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 灌꿴璂돕뚤壇瑯뵀斤口 : 瑯뵀 : %s",
m_account
);
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
}
#endif
goto ERROR_RESULT;
}
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
if (m_TokenType == eAuthToken_AuthTokenGameChu)
{
USES_CONVERSION;
::_tcsncpy(m_account, W2A(m_Record.user_account), _countof(m_account));
m_account[_countof(m_account) - 1] = '\0';
_strupr(m_account);
::_tcsncpy(ack_msg.m_szID, m_account , _countof(m_account));
ack_msg.m_szID[_countof(ack_msg.m_szID) - 1] = '\0';
}
#endif
if (auth_frame->IsAllowSts((USER_STS)m_Record.Sts[0]) == false)
{
ack_msg.m_byResult = AUTHRESULT_NOTALLOWEDACCOUNT;
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 꼇豚冀되쩌 : 瑯뵀: %s, 榴檄 : %u",
m_account,
m_Record.Sts[0]
);
goto ERROR_RESULT;
}
#ifdef _RESTRICT_ADULT
if (m_Record.Age < 18)
{
ack_msg.m_byResult = AUTHRESULT_RESTRICTADULT;
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 꼇豚冀되쩌 : 瑯뵀: %s, 쾨쥑 : %u",
m_account,
m_Record.Age
);
goto ERROR_RESULT;
}
#endif
const DWORD limit_block_count = auth_frame->GetBlockLimit();
if (m_Record.btAuthFailCount >= limit_block_count)
{
ack_msg.m_byResult = AUTHRESULT_ACCOUNT_BLOCK;
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 瑯뵀傑땍 : 瑯뵀: %s, 되쩌呵겨늴鑒 : %u",
m_account,
m_Record.btAuthFailCount
);
goto ERROR_RESULT;
}
//암호 검사
BOOLEAN is_valid_client = ValidClientAuthInfo();
if (is_valid_client == FALSE)
{
#ifdef _AUTH_CHINA
ack_msg.m_byResult = AUTHRESULT_INVALIDACCOUNT;
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__ " : Invalid password : Account : %s",
m_account
);
goto ERROR_RESULT;
#else
//DB에 연속 오류 횟수를 증가시킨 후 ACK를 보낸다.
query_manager->QueryUpdateAuthFailCount(m_account, m_clientIp, 0,
m_front_user_id, m_key,
ACCOUNT_AUTH);
return;
#endif
}
#if !defined(_SECURE_AUTH) && !defined(_AUTH_CHINA)
// 인증 성공 후엔 연속오류회수를 초기화
query_manager->QueryUpdateAuthFailCount(m_account,
m_clientIp,
1,
m_front_user_id,
m_key,
ACCOUNT_AUTH);
#endif
AccountInfo* account_info = CheckOverlapLogin(m_Record.UserGuid,
m_account,
m_key,
m_front_user_id,
ack_msg.m_byResult);
if (account_info == NULL)
{
goto ERROR_RESULT;
}
else
{
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
account_info->gamechu_usn_ = gamechu_usn_;
#endif//_JP_0_20100723_GAMECHU_AUTHFLOW_
#ifdef __CN_20100909_SECURITY_TOKEN__
account_info->is_token_use_ = m_Record.is_token_use_;
if (m_Record.is_token_use_)
{
USES_CONVERSION;
::_tcsncpy(account_info->token_base64_key_,
W2A(m_Record.token_base64_key_),
_countof(account_info->token_base64_key_));
account_info->token_base64_key_[_countof(account_info->token_base64_key_) - 1] = '\0';
}
#endif//__CN_20100909_SECURITY_TOKEN__
#ifdef _NA_20100307_BETAKEY_SYSTEM
account_info->betakey_ = ack_msg.m_betakey_ = 0;
#endif//_NA_20100307_BETAKEY_SYSTEM
BOOST_STATIC_ASSERT(_countof(account_info->m_userCode) == _countof(m_Record.Sts));
for (int i = 0; i < _countof(account_info->m_userCode); ++i)
{
account_info->m_userCode[i] =
static_cast<BYTE>(m_Record.Sts[i]);
}
account_info->m_LoginFrontId = m_key;
account_info->m_userGuid = m_Record.UserGuid;
account_info->m_age = static_cast<BYTE>(m_Record.Age);
account_info->m_pcBangId = m_Record.IpGuid;
::_tcsncpy(account_info->m_clientIp, m_clientIp, IP_MAX_LEN);
::_tcsncpy(account_info->m_localIp, m_localIp, IP_MAX_LEN);
#ifdef __PCBANG_IP_UPDATE
account_info->pc_room_ip_value_ =
::inet_addr(account_info->m_clientIp);
#endif//__PCBANG_IP_UPDATE
BOOST_STATIC_ASSERT(
sizeof(account_info->m_MD5) == sizeof(m_Record.CharPassWD)
);
::memcpy(account_info->m_MD5,
m_Record.CharPassWD,
sizeof(account_info->m_MD5));
account_info->m_AuthUserType = static_cast<BYTE>(m_Record.userType);
#if defined(_SECURE_AUTH)
//매트릭스 인증
if (m_Record.pData[0] != '\0')
{
//매트릭스 카드 사용자일 경우
auth_frame->SendMatrixCardAuth(login_front,
account_info,
m_front_user_id,
m_Record.btMatrixAuthFailCount,
1);
}
else
{
//아니면 그냥 성공
ack_msg.m_byResult = AUTHRESULT_OK;
::_tcsncpy(ack_msg.m_szInfo,
g_LoginErrorString[ack_msg.m_byResult],
_countof(ack_msg.m_szInfo));
login_front->SendPacket(&ack_msg, sizeof(ack_msg));
account_info->m_status = ACCOUNTSTATUS_AUTH;
}
#else//_SECURE_AUTH
//계정 인증만 사용
#ifdef _NET_CAFE
account_info->m_pcBangId = 0; // 일본 넷카페의 경우 DB에서 고유번호를 넘겨준다
#ifdef _JP_0_20100723_GAMECHU_AUTHFLOW_
eNetCafeLoginType token_type;
token_type = (m_TokenType == eAuthToken_AuthTokenGameChu) ? NETCAFE_GAMECHU_LOGIN :
NETCAFE_ONTIME_LOGIN;
query_manager->QueryNetCafeLogInsert(m_key, m_front_user_id, m_account, m_clientIp,
token_type, m_ReAuthKey);
#else
query_manager->QueryNetCafeLogInsert(m_key, m_front_user_id, m_account, m_clientIp,
true, m_ReAuthKey);
#endif
#else//_NET_CAFE
//중국,일본,글로벌을 제외한 다른 버전들은 이곳에서 최종 인증 성공
ack_msg.m_byResult = AUTHRESULT_OK;
::_tcsncpy(ack_msg.m_szInfo, g_LoginErrorString[ack_msg.m_byResult],
_countof(ack_msg.m_szInfo));
login_front->SendPacket(&ack_msg, sizeof(ack_msg));
account_info->m_status = ACCOUNTSTATUS_AUTH;
#endif//_NET_CAFE
#endif//_SECURE_AUTH
#ifdef _TIRED_CHECK
account_info->m_ucRealNameAuth = m_Record.Sts[2]; // 실명 인증자 인지 식별
#endif
#ifdef _SECURE_AUTH
if (m_Record.pData[0] != '\0')
{
// 매트릭스 카드 사용자일 경우
char szSeedValue[(SEED_SIZE * 2) + 1] = { 0, };
wchar_t* wszSCValue = (wchar_t*)m_Record.pData;
::WideCharToMultiByte(CP_ACP, 0, wszSCValue, -1, szSeedValue,
SEED_SIZE * 2, 0, 0);
// 카드번호를 가지고 시드값을 만든다
genseed(szSeedValue, account_info->m_seedValue);
account_info->m_bSucceedShape = true;
SUNLOG(
eFULL_LOG,
__FUNCTION__" : 鑒앴욋踏깃令 : %s",
szSeedValue
);
}
#endif
account_info->m_tickConnectTime = ::GetTickCount();
::GetLocalTime(&account_info->m_loginTime);
}
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 되쩌駱聯냥묘 : 瑯뵀 : %s, ip : %s",
account_info->m_account,
account_info->m_clientIp
);
return;
ERROR_RESULT:
query_manager->UpdateIPCount(m_clientIp);
::_tcsncpy(ack_msg.m_szInfo,
g_LoginErrorString[ack_msg.m_byResult],
_countof(ack_msg.m_szInfo));
login_front->SendPacket(&ack_msg, sizeof(ack_msg));
}
VOID
QueryRecoverLocation::onResult()
{
QueryObject::onResult();
TCHAR temp_account_id[ID_MAX_LEN + 1];
int count = 0;
AccountManager* const account_manager = AccountManager::Instance();
ServerDataManager* const server_data_manager = ServerDataManager::Instance();
AccountInfo* account_info = NULL;
AccountInfo* temp_account_info = NULL;
// 복구작업을 시작한다.
// SET NOCOUNT 를 사용하는 procedure이므로 GetRecordCount를 사용할 수 없다.
while (m_recordSet.IsEndRecord() == false)
{
CHECK_ID_LENGTH_BUFFER(temp_account_id);
ZeroMemory(temp_account_id, sizeof(temp_account_id));
// (WAVERIX) (090331) UserID 하드코딩 값 수정
::WideCharToMultiByte(CP_ACP, 0, m_Record.UserID, -1, temp_account_id, ID_MAX_LEN, 0, 0);
account_info = account_manager->CreateAccountInfo(temp_account_id, &temp_account_info);
if (account_info != NULL)
{
ServerData* server_data =
server_data_manager->FindServerData((AGENTID)m_Record.ServerGuid);
if (server_data == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 灌꿴璂돕뚤壇륩蛟 : 瑯뵀ID : %s, 륩蛟ID : %u",
temp_account_id,
m_Record.ServerGuid
);
m_recordSet.Next();
continue;
}
short status_type = (m_Record.ConnectSts == USERSTATUS_PLAY ? ACCOUNTSTATUS_PLAY : 0);
account_info->m_status = static_cast<ACCOUNTSTATUS_TYPE>(status_type);
account_info->m_userGuid = m_Record.UserGuid;
account_info->m_locationId = server_data->GetGameAgentID();
account_info->m_tickBillingTime = ::GetTickCount();
account_info->m_pcBangId = m_Record.CompGuid;
::WideCharToMultiByte(CP_ACP, 0, m_Record.IpPublicAddr, -1,
account_info->m_clientIp, 15, 0, 0);
::WideCharToMultiByte(CP_ACP, 0, m_Record.IpLocalAddr, -1,
account_info->m_localIp, 15, 0, 0);
::WideCharToMultiByte(CP_ACP, 0, m_Record.AuthUserGuid, -1,
account_info->m_glogKey, 8, 0, 0);
account_info->m_authKey = m_Record.AuthKey;
account_info->m_tickConnectTime = account_info->m_tickBillingTime;
SYSTEMTIME login_time;
VariantTimeToSystemTime(static_cast<double>(m_Record.ConnectTime), &login_time);
account_info->m_loginTime = login_time;
++count;
// location Id는 1부터 시작한다.
server_data->IncLoginUserCount();
}
m_recordSet.Next();
}
if(account_info&&strlen(account_info->m_clientIp)>0)
{
QueryManager* const query_manager = QueryManager::Instance();
query_manager->UpdateIPCount(account_info->m_clientIp);
}
#if !defined(__NA000000_GLOBAL_AUTH_PROCESS__)
// (WAVERIX) (NOTE) 글로벌 인증서버는 해당 쿼리를 사용하지 않는다. 코드를 막는 이유는
// ReadyState에 의해 listen정책이 정해지기 때문
AuthFrame::Instance()->GetReadyState().SetReadyState(AUTH_READY_RECOVER_STS, TRUE);
#endif
SUNLOG(eCRITICAL_LOG, "[QueryRecoverLocation::onResult] Recover Count[%d]", count);
}
VOID
QueryAuthFailCount::onResult()
{
QueryObject::onResult();
if(m_btFlag)
{
return;
}
QueryManager* const query_manager = QueryManager::Instance();
query_manager->UpdateIPCount(m_clientIP);
// 인증 실패에 대한 처리를 한다.
MSG_SF_AUTH_ID_PASSWORD_CHECK_ACK ack_msg;
ack_msg.m_dwFrontUserID = m_front_user_id;
ack_msg.m_byFailCount = 0;
ack_msg.m_byResult = AUTHRESULT_OK;
AuthFrame* const auth_frame = AuthFrame::Instance();
LoginFrontServerSession* login_front =
static_cast<LoginFrontServerSession*>(auth_frame->FindSession(m_key));
if (login_front == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 灌꿴璂돕되쩌駱聯품똥: %u",
m_key
);
return;
}
AccountInfo* account_info =
AccountManager::Instance()->FindWithLoginFrontUserID(m_front_user_id);
// 누적 오류 횟수 제한에 걸려 계정 블록
if (m_btAuthFailCount >= auth_frame->GetBlockLimit())
{
if(account_info)
{
#ifdef _SECURE_AUTH
account_info->m_bSucceedShape = false;
#endif
}
ack_msg.m_byResult = AUTHRESULT_ACCOUNT_BLOCK;
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 瑯뵀傑땍 : 瑯뵀 : %s, 呵겨늴鑒 : %u",
m_account,
m_btAuthFailCount
);
goto ERROR_RESULT;
}
switch(m_btAuthType)
{
case ACCOUNT_AUTH:
{
ack_msg.m_byResult = AUTHRESULT_INVALIDACCOUNT;
ack_msg.m_byFailCount = static_cast<BYTE>(m_btAuthFailCount);
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 쵱쯤轟槻 : 瑯뵀 : %s",
m_account
);
goto ERROR_RESULT;
}
break;
#ifdef _SECURE_AUTH
case MATRIX_CARD_AUTH:
{
auth_frame->SendMatrixCardAuth(login_front, account_info, m_front_user_id, 0, 0);
return;
}
break;
#endif
default:
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 駱聯잚謹轟槻 : %u",
m_btAuthType
);
}
break;
}
return;
ERROR_RESULT:
::_tcsncpy(ack_msg.m_szInfo, g_LoginErrorString[ack_msg.m_byResult],
_countof(ack_msg.m_szInfo));
login_front->SendPacket(&ack_msg, sizeof(ack_msg));
}
QueryCheckPassword::QueryCheckPassword()
: QueryObject(QUERYTYPE_CHECK_PASSWORD)
{
memset(m_account, 0, sizeof(m_account));
memset(m_password, 0, sizeof(m_password));
m_front_user_id = 0;
m_recordSet.RegisterParameter(&m_DbResult, "", adInteger, adParamReturnValue, sizeof(int), "");
}
VOID QueryCheckPassword::onResult()
{
QueryObject::onResult();
AuthFrame* const auth_frame = AuthFrame::Instance();
QueryManager* const query_manager = QueryManager::Instance();
LoginFrontServerSession* login_front =
static_cast<LoginFrontServerSession*>(auth_frame->FindSession(m_key));
if (login_front == NULL)
{
SUNLOG(
eCRITICAL_LOG,
__FUNCTION__" : 灌꿴璂돕되쩌駱聯품똥 : %u", m_key
);
return;
}
if (m_DbResult == 0) // success
{
#ifdef _CN_ZY_AUTH_PROCESS_DBAUTH
query_manager->QueryLoginUserByChinaZY( \
m_key/*login_front_id*/, m_account, NULL/*password*/, \
m_front_user_id, m_ReAuthKey, m_clientIp, m_localIp);
#endif //_CN_ZY_AUTH_PROCESS_DBAUTH
}
else
{
MSG_SF_AUTH_ID_PASSWORD_CHECK_ACK ack_msg;
ack_msg.m_dwFrontUserID = m_front_user_id;
ack_msg.m_byFailCount = 0;
ack_msg.m_byResult = AUTHRESULT_INVALIDACCOUNT;
login_front->SendPacket(&ack_msg, sizeof(ack_msg));
}
}