示例#1
0
void Battlenet::Session::Start()
{
    std::string ip_address = GetRemoteIpAddress().to_string();
    TC_LOG_TRACE("session", "Accepted connection from %s", ip_address.c_str());

    PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO);
    stmt->setString(0, ip_address);
    stmt->setUInt32(1, inet_addr(ip_address.c_str()));

    _queryCallback = std::bind(&Battlenet::Session::CheckIpCallback, this, std::placeholders::_1);
    _queryFuture = LoginDatabase.AsyncQuery(stmt);
}
示例#2
0
void Battlenet::Session::Start()
{
    std::string ip_address = GetRemoteIpAddress().to_string();
    TC_LOG_TRACE("session", "%s Accepted connection", GetClientInfo().c_str());

    // Verify that this IP is not in the ip_banned table
    LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));

    PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO);
    stmt->setString(0, ip_address);
    stmt->setUInt32(1, inet_addr(ip_address.c_str()));

    _queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithPreparedCallback(std::bind(&Battlenet::Session::CheckIpCallback, this, std::placeholders::_1)));
}
示例#3
0
std::string Battlenet::Session::GetClientInfo() const
{
    std::ostringstream stream;
    stream << '[' << GetRemoteIpAddress() << ':' << GetRemotePort();
    if (_accountInfo && !_accountInfo->Login.empty())
        stream << ", Account: " << _accountInfo->Login;

    if (_gameAccountInfo)
        stream << ", Game account: " << _gameAccountInfo->Name;

    stream << ']';

    return stream.str();
}
示例#4
0
uint32 Battlenet::Session::GetRealmListTicket(std::unordered_map<std::string, Variant const*> const& params, game_utilities::v1::ClientResponse* response)
{
    if (Variant const* identity = GetParam(params, "Param_Identity"))
    {
        ::JSON::RealmList::RealmListTicketIdentity data;
        std::size_t jsonStart = identity->blob_value().find(':');
        if (jsonStart != std::string::npos && ::JSON::Deserialize(identity->blob_value().substr(jsonStart + 1), &data))
        {
            auto itr = _accountInfo->GameAccounts.find(data.gameaccountid());
            if (itr != _accountInfo->GameAccounts.end())
                _gameAccountInfo = &itr->second;
        }
    }

    if (!_gameAccountInfo)
        return ERROR_UTIL_SERVER_INVALID_IDENTITY_ARGS;

    bool clientInfoOk = false;
    if (Variant const* clientInfo = GetParam(params, "Param_ClientInfo"))
    {
        ::JSON::RealmList::RealmListTicketClientInformation data;
        std::size_t jsonStart = clientInfo->blob_value().find(':');
        if (jsonStart != std::string::npos && ::JSON::Deserialize(clientInfo->blob_value().substr(jsonStart + 1), &data))
        {
            if (_clientSecret.size() == data.info().secret().size())
            {
                clientInfoOk = true;
                memcpy(_clientSecret.data(), data.info().secret().data(), _clientSecret.size());
            }
        }
    }

    if (!clientInfoOk)
        return ERROR_WOW_SERVICES_DENIED_REALM_LIST_TICKET;

    PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO);
    stmt->setString(0, GetRemoteIpAddress().to_string());
    stmt->setUInt8(1, GetLocaleByName(_locale));
    stmt->setString(2, _os);
    stmt->setUInt32(3, _accountInfo->Id);

    LoginDatabase.Execute(stmt);

    Attribute* attribute = response->add_attribute();
    attribute->set_name("Param_RealmListTicket");
    attribute->mutable_value()->set_blob_value("AuthRealmListTicket");

    return ERROR_OK;
}
示例#5
0
void Socket::CloseSocket()
{
    if (_closed.exchange(true))
        return;

    boost::system::error_code shutdownError;
    _socket.shutdown(boost::asio::socket_base::shutdown_send, shutdownError);
    if (shutdownError)
        std::cout << "Socket::CloseSocket: " << GetRemoteIpAddress().to_string().c_str() << " errored when shutting down socket: " << shutdownError.value() << " (" << shutdownError.message().c_str() << ")";

    {
        std::lock_guard<std::mutex> sessionGuard(_sessionLock);
        _session = nullptr;
    }
}
示例#6
0
bool Socket::ReadHeaderHandler()
{
    ClientHeader* header = reinterpret_cast<ClientHeader*>(_headerBuffer.GetReadPointer());
    uint32 opcode = header->Command;
    uint32 size = header->Size;

    if (!ClientHeader::IsValidSize(size) || !ClientHeader::IsValidOpcode(opcode))
    {
        std::cout << "Socket::ReadHeaderHandler(): client " << GetRemoteIpAddress().to_string().c_str() << " sent malformed packet (size: " << size << ", cmd: " << opcode << ")" << std::endl;
        return false;
    }

    _packetBuffer.Resize(size);
    return true;
}
示例#7
0
bool Battlenet::Session::HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response)
{
    Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
    if (dataStream->Read<uint8>(8) == 1)
    {
        logonResponse->AccountId = _accountId;
        logonResponse->GameAccountName = _gameAccountName;
        logonResponse->GameAccountFlags = GAMEACCOUNT_FLAG_PROPASS_LOCK;
        PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_FAILED_LOGINS);
        stmt->setUInt32(0, _accountId);
        if (PreparedQueryResult failedLoginsResult = LoginDatabase.Query(stmt))
            logonResponse->FailedLogins = (*failedLoginsResult)[0].GetUInt32();

        SQLTransaction trans = LoginDatabase.BeginTransaction();

        stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO);
        stmt->setString(0, GetRemoteIpAddress().to_string());
        stmt->setUInt8(1, GetLocaleByName(_locale));
        stmt->setString(2, _os);
        stmt->setUInt32(3, _accountId);
        trans->Append(stmt);

        stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY);
        stmt->setString(0, K.AsHexStr());
        stmt->setBool(1, true);
        stmt->setUInt32(2, _accountId);
        trans->Append(stmt);

        LoginDatabase.CommitTransaction(trans);

        _authed = true;
        sSessionMgr.AddSession(this);
    }
    else
        logonResponse->SetAuthResult(AUTH_BAD_VERSION_HASH);

    ReplaceResponse(response, logonResponse);
    return true;
}
示例#8
0
void Battlenet::Session::HandleJoinRequestV2(WoWRealm::JoinRequestV2 const& joinRequest)
{
    WoWRealm::JoinResponseV2* joinResponse = new WoWRealm::JoinResponseV2();
    Realm const* realm = sRealmList->GetRealm(joinRequest.Realm);
    if (!realm || realm->Flags & (REALM_FLAG_VERSION_MISMATCH | REALM_FLAG_OFFLINE))
    {
        joinResponse->Response = WoWRealm::JoinResponseV2::FAILURE;
        AsyncWrite(joinResponse);
        return;
    }

    joinResponse->ServerSeed = rand32();

    uint8 sessionKey[40];
    HmacSha1 hmac(K.GetNumBytes(), K.AsByteArray().get());
    hmac.UpdateData((uint8*)"WoW\0", 4);
    hmac.UpdateData((uint8*)&joinRequest.ClientSeed, 4);
    hmac.UpdateData((uint8*)&joinResponse->ServerSeed, 4);
    hmac.Finalize();

    memcpy(sessionKey, hmac.GetDigest(), hmac.GetLength());

    HmacSha1 hmac2(K.GetNumBytes(), K.AsByteArray().get());
    hmac2.UpdateData((uint8*)"WoW\0", 4);
    hmac2.UpdateData((uint8*)&joinResponse->ServerSeed, 4);
    hmac2.UpdateData((uint8*)&joinRequest.ClientSeed, 4);
    hmac2.Finalize();

    memcpy(sessionKey + hmac.GetLength(), hmac2.GetDigest(), hmac2.GetLength());

    LoginDatabase.DirectPExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = %u, failed_logins = 0, os = '%s' WHERE id = %u",
        ByteArrayToHexStr(sessionKey, 40, true).c_str(), GetRemoteIpAddress().to_string().c_str(), GetLocaleByName(_locale), _os.c_str(), _gameAccountInfo->Id);

    joinResponse->IPv4.emplace_back(realm->ExternalAddress, realm->Port);
    if (realm->ExternalAddress != realm->LocalAddress)
        joinResponse->IPv4.emplace_back(realm->LocalAddress, realm->Port);

    AsyncWrite(joinResponse);
}
示例#9
0
void Battlenet::Session::Start()
{
    std::string ip_address = GetRemoteIpAddress().to_string();
    TC_LOG_TRACE("session", "Accepted connection from %s", ip_address.c_str());

    if (_queryCallback)
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_LOGON_TOO_FAST);
        AsyncWrite(logonResponse);
        TC_LOG_DEBUG("session", "[Session::Start] %s attempted to log too quick after previous attempt!", GetClientInfo().c_str());
        return;
    }

    // Verify that this IP is not in the ip_banned table
    LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));

    PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_INFO);
    stmt->setString(0, ip_address);
    stmt->setUInt32(1, inet_addr(ip_address.c_str()));

    _queryCallback = std::bind(&Battlenet::Session::CheckIpCallback, this, std::placeholders::_1);
    _queryFuture = LoginDatabase.AsyncQuery(stmt);
}
示例#10
0
uint32 Battlenet::Session::HandleLogon(authentication::v1::LogonRequest const* logonRequest, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation)
{
    if (logonRequest->program() != "WoW")
    {
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with game other than WoW (using %s)!", GetClientInfo().c_str(), logonRequest->program().c_str());
        return ERROR_BAD_PROGRAM;
    }

    if (logonRequest->platform() != "Win" && logonRequest->platform() != "Wn64" && logonRequest->platform() != "Mc64")
    {
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in from an unsupported platform (using %s)!", GetClientInfo().c_str(), logonRequest->platform().c_str());
        return ERROR_BAD_PLATFORM;
    }

    if (GetLocaleByName(logonRequest->locale()) == LOCALE_enUS && logonRequest->locale() != "enUS")
    {
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with unsupported locale (using %s)!", GetClientInfo().c_str(), logonRequest->locale().c_str());
        return ERROR_BAD_LOCALE;
    }

    _locale = logonRequest->locale();
    _os = logonRequest->platform();
    _build = logonRequest->application_version();

    if (logonRequest->has_cached_web_credentials())
        return VerifyWebCredentials(logonRequest->cached_web_credentials(), continuation);

    boost::asio::ip::tcp::endpoint const& endpoint = sLoginService.GetAddressForClient(GetRemoteIpAddress());

    challenge::v1::ChallengeExternalRequest externalChallenge;
    externalChallenge.set_payload_type("web_auth_url");
    externalChallenge.set_payload(Trinity::StringFormat("https://%s:%u/bnetserver/login/", endpoint.address().to_string().c_str(), endpoint.port()));
    Service<challenge::v1::ChallengeListener>(this).OnExternalChallenge(&externalChallenge);
    return ERROR_OK;
}
示例#11
0
uint32 Battlenet::Session::HandleVerifyWebCredentials(authentication::v1::VerifyWebCredentialsRequest const* verifyWebCredentialsRequest)
{
    authentication::v1::LogonResult logonResult;
    logonResult.set_error_code(0);
    _accountInfo = sLoginService.VerifyLoginTicket(verifyWebCredentialsRequest->web_credentials());
    if (!_accountInfo)
        return ERROR_DENIED;

    std::string ip_address = GetRemoteIpAddress().to_string();

    // If the IP is 'locked', check that the player comes indeed from the correct IP address
    if (_accountInfo->IsLockedToIP)
    {
        TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to IP - '%s' is logging in from '%s'",
            _accountInfo->Login.c_str(), _accountInfo->LastIP.c_str(), ip_address.c_str());

        if (_accountInfo->LastIP != ip_address)
            return ERROR_RISK_ACCOUNT_LOCKED;
    }
    else
    {
        TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to ip", _accountInfo->Login.c_str());
        if (_accountInfo->LockCountry.empty() || _accountInfo->LockCountry == "00")
            TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to country", _accountInfo->Login.c_str());
        else if (!_accountInfo->LockCountry.empty() && !_ipCountry.empty())
        {
            TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to country: '%s' Player country is '%s'",
                _accountInfo->Login.c_str(), _accountInfo->LockCountry.c_str(), _ipCountry.c_str());

            if (_ipCountry != _accountInfo->LockCountry)
                return ERROR_RISK_ACCOUNT_LOCKED;
        }
    }

    // If the account is banned, reject the logon attempt
    if (_accountInfo->IsBanned)
    {
        if (_accountInfo->IsPermanenetlyBanned)
        {
            TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str());
            return ERROR_GAME_ACCOUNT_BANNED;
        }
        else
        {
            TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Temporarily banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str());
            return ERROR_GAME_ACCOUNT_SUSPENDED;
        }
    }

    logonResult.mutable_account_id()->set_low(_accountInfo->Id);
    logonResult.mutable_account_id()->set_high(UI64LIT(0x100000000000000));
    for (auto itr = _accountInfo->GameAccounts.begin(); itr != _accountInfo->GameAccounts.end(); ++itr)
    {
        if (!itr->second.IsBanned)
        {
            EntityId* gameAccountId = logonResult.add_game_account_id();
            gameAccountId->set_low(itr->second.Id);
            gameAccountId->set_high(UI64LIT(0x200000200576F57));
        }
    }

    if (!_ipCountry.empty())
        logonResult.set_geoip_country(_ipCountry);

    BigNumber k;
    k.SetRand(8 * 64);
    logonResult.set_session_key(k.AsByteArray(64).get(), 64);

    _authed = true;

    Service<authentication::v1::AuthenticationListener>(this).OnLogonComplete(&logonResult);
    return ERROR_OK;
}
示例#12
0
bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response)
{
    if (dataStream->Read<uint8>(8) != 1)
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
        ReplaceResponse(response, logonResponse);
        return false;
    }

    dataStream->Read<uint8>(8);
    std::string account = dataStream->ReadString(8);
    if (account.empty())
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
        ReplaceResponse(response, logonResponse);
        return false;
    }

    for (std::size_t i = 0; i < _gameAccounts.size(); ++i)
    {
        if (_gameAccounts[i].DisplayName == account)
        {
            _gameAccountInfo = &_gameAccounts[i];
            break;
        }
    }

    if (!_gameAccountInfo)
    {
        Authentication::LogonResponse* complete = new Authentication::LogonResponse();
        complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
        ReplaceResponse(response, complete);
        TC_LOG_DEBUG("session", "[Battlenet::SelectGameAccount] %s attempted to log in with invalid game account name %s!", GetClientInfo().c_str(), account.c_str());
        return false;
    }

    if (_gameAccountInfo->IsBanned)
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        if (_gameAccountInfo->IsPermanentlyBanned)
        {
            logonResponse->SetAuthResult(LOGIN_BANNED);
            TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str());
        }
        else
        {
            logonResponse->SetAuthResult(LOGIN_SUSPENDED);
            TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str());
        }

        ReplaceResponse(response, logonResponse);
        return false;
    }

    Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
    proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint"));
    ReplaceResponse(response, proofRequest);

    _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT);
    return true;
}
示例#13
0
bool Battlenet::Session::HandlePasswordModule(BitStream* dataStream, ServerPacket** response)
{
    if (dataStream->GetSize() != 1 + 128 + 32 + 128)
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
        ReplaceResponse(response, logonResponse);
        return false;
    }

    if (dataStream->Read<uint8>(8) != 2)                // State
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
        ReplaceResponse(response, logonResponse);
        return false;
    }

    BigNumber A, clientM1, clientChallenge;
    A.SetBinary(dataStream->ReadBytes(128).get(), 128);
    clientM1.SetBinary(dataStream->ReadBytes(32).get(), 32);
    clientChallenge.SetBinary(dataStream->ReadBytes(128).get(), 128);

    if (A.isZero())
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
        ReplaceResponse(response, logonResponse);
        return false;
    }

    SHA256Hash sha;
    sha.UpdateBigNumbers(&A, &B, NULL);
    sha.Finalize();

    BigNumber u;
    u.SetBinary(sha.GetDigest(), sha.GetLength());

    BigNumber S = ((A * v.ModExp(u, N)) % N).ModExp(b, N);

    uint8 S_bytes[128];
    memcpy(S_bytes, S.AsByteArray(128).get(), 128);

    uint8 part1[64];
    uint8 part2[64];

    for (int i = 0; i < 64; ++i)
    {
        part1[i] = S_bytes[i * 2];
        part2[i] = S_bytes[i * 2 + 1];
    }

    SHA256Hash part1sha, part2sha;
    part1sha.UpdateData(part1, 64);
    part1sha.Finalize();
    part2sha.UpdateData(part2, 64);
    part2sha.Finalize();

    uint8 sessionKey[SHA256_DIGEST_LENGTH * 2];
    for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i)
    {
        sessionKey[i * 2] = part1sha.GetDigest()[i];
        sessionKey[i * 2 + 1] = part2sha.GetDigest()[i];
    }

    K.SetBinary(sessionKey, SHA256_DIGEST_LENGTH * 2);

    BigNumber M1;

    uint8 hash[SHA256_DIGEST_LENGTH];
    sha.Initialize();
    sha.UpdateBigNumbers(&N, NULL);
    sha.Finalize();
    memcpy(hash, sha.GetDigest(), sha.GetLength());

    sha.Initialize();
    sha.UpdateBigNumbers(&g, NULL);
    sha.Finalize();

    for (int i = 0; i < sha.GetLength(); ++i)
        hash[i] ^= sha.GetDigest()[i];

    SHA256Hash shaI;
    shaI.UpdateData(ByteArrayToHexStr(I.AsByteArray().get(), 32));
    shaI.Finalize();

    // Concat all variables for M1 hash
    sha.Initialize();
    sha.UpdateData(hash, SHA256_DIGEST_LENGTH);
    sha.UpdateData(shaI.GetDigest(), shaI.GetLength());
    sha.UpdateBigNumbers(&s, &A, &B, &K, NULL);
    sha.Finalize();

    M1.SetBinary(sha.GetDigest(), sha.GetLength());

    if (memcmp(M1.AsByteArray().get(), clientM1.AsByteArray().get(), 32))
    {
        PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_FAILED_LOGINS);
        stmt->setString(0, _accountInfo->Login);
        LoginDatabase.Execute(stmt);

        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
        ReplaceResponse(response, logonResponse);
        TC_LOG_DEBUG("session", "[Battlenet::Password] %s attempted to log in with invalid password!", GetClientInfo().c_str());
        return false;
    }

    if (_gameAccounts.empty())
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
        ReplaceResponse(response, logonResponse);
        TC_LOG_DEBUG("session", "[Battlenet::Password] %s does not have any linked game accounts!", GetClientInfo().c_str());
        return false;
    }

    BigNumber M;
    sha.Initialize();
    sha.UpdateBigNumbers(&A, &M1, &K, NULL);
    sha.Finalize();
    M.SetBinary(sha.GetDigest(), sha.GetLength());

    BigNumber serverProof;
    serverProof.SetRand(128 * 8); // just send garbage, server signature check is patched out in client

    BitStream stream;
    ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password");
    uint8 state = 3;

    stream.WriteBytes(&state, 1);
    stream.WriteBytes(M.AsByteArray(32).get(), 32);
    stream.WriteBytes(serverProof.AsByteArray(128).get(), 128);

    password->DataSize = stream.GetSize();
    password->Data = new uint8[password->DataSize];
    memcpy(password->Data, stream.GetBuffer(), password->DataSize);

    Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
    proofRequest->Modules.push_back(password);
    if (_gameAccounts.size() > 1)
    {
        BitStream accounts;
        state = 0;
        accounts.WriteBytes(&state, 1);
        accounts.Write(_gameAccounts.size(), 8);
        for (GameAccountInfo const& gameAccount : _gameAccounts)
        {
            accounts.Write(2, 8);
            accounts.WriteString(gameAccount.DisplayName, 8);
        }

        ModuleInfo* selectGameAccount = sModuleMgr->CreateModule(_os, "SelectGameAccount");
        selectGameAccount->DataSize = accounts.GetSize();
        selectGameAccount->Data = new uint8[selectGameAccount->DataSize];
        memcpy(selectGameAccount->Data, accounts.GetBuffer(), selectGameAccount->DataSize);
        proofRequest->Modules.push_back(selectGameAccount);
        _modulesWaitingForData.push(MODULE_SELECT_GAME_ACCOUNT);
    }
    else
    {
        _gameAccountInfo = &_gameAccounts[0];

        if (_gameAccountInfo->IsBanned)
        {
            delete proofRequest;

            Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
            if (_gameAccountInfo->IsPermanentlyBanned)
            {
                logonResponse->SetAuthResult(LOGIN_BANNED);
                TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str());
            }
            else
            {
                logonResponse->SetAuthResult(LOGIN_SUSPENDED);
                TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::Password] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountInfo->Login.c_str());
            }

            ReplaceResponse(response, logonResponse);
            return false;
        }

        proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint"));
        _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT);
    }

    ReplaceResponse(response, proofRequest);
    return true;
}
示例#14
0
void Battlenet::Session::CheckIpCallback(PreparedQueryResult result)
{
    if (result)
    {
        bool banned = false;
        do
        {
            Field* fields = result->Fetch();
            if (fields[0].GetUInt64() != 0)
                banned = true;

            if (!fields[1].GetString().empty())
                _ipCountry = fields[1].GetString();

        } while (result->NextRow());

        if (banned)
        {
            Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
            logonResponse->SetAuthResult(AUTH_INTERNAL_ERROR);
            AsyncWrite(logonResponse);
            TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort());
            return;
        }
    }

    AsyncRead();
}
示例#15
0
void Battlenet::Session::HandleLogonRequestCallback(PreparedQueryResult result)
{
    if (!result)
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
        AsyncWrite(logonResponse);
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is trying to log in from unknown account!", GetClientInfo().c_str());
        return;
    }

    Field* fields = result->Fetch();
    _accountInfo->LoadResult(fields);

    std::string pStr = fields[8].GetString();
    std::string databaseV = fields[9].GetString();
    std::string databaseS = fields[10].GetString();

    _gameAccounts.resize(result->GetRowCount());
    uint32 i = 0;
    do
    {
        _gameAccounts[i++].LoadResult(result->Fetch() + 11);

    } while (result->NextRow());

    std::string ip_address = GetRemoteIpAddress().to_string();
    // If the IP is 'locked', check that the player comes indeed from the correct IP address
    if (_accountInfo->IsLockedToIP)
    {
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountInfo->Login.c_str(), _accountInfo->LastIP.c_str(), ip_address.c_str());

        if (_accountInfo->LastIP != ip_address)
        {
            Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
            logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
            AsyncWrite(logonResponse);
            return;
        }
    }
    else
    {
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountInfo->Login.c_str());
        if (_accountInfo->LockCountry.empty() || _accountInfo->LockCountry == "00")
            TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountInfo->Login.c_str());
        else if (!_accountInfo->LockCountry.empty() && !_ipCountry.empty())
        {
            TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to country: '%s' Player country is '%s'", _accountInfo->Login.c_str(), _accountInfo->LockCountry.c_str(), _ipCountry.c_str());
            if (_ipCountry != _accountInfo->LockCountry)
            {
                Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
                logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
                AsyncWrite(logonResponse);
                return;
            }
        }
    }

    // If the account is banned, reject the logon attempt
    if (_accountInfo->IsBanned)
    {
        if (_accountInfo->IsPermanentlyBanned)
        {
            Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
            logonResponse->SetAuthResult(LOGIN_BANNED);
            AsyncWrite(logonResponse);
            TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountInfo->Login.c_str());
            return;
        }
        else
        {
            Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
            logonResponse->SetAuthResult(LOGIN_SUSPENDED);
            AsyncWrite(logonResponse);
            TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountInfo->Login.c_str());
            return;
        }
    }

    SHA256Hash sha;
    sha.UpdateData(_accountInfo->Login);
    sha.Finalize();

    I.SetBinary(sha.GetDigest(), sha.GetLength());

    ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password");
    ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint");

    if (databaseV.size() != size_t(BufferSizes::SRP_6_V) * 2 || databaseS.size() != size_t(BufferSizes::SRP_6_S) * 2)
        _SetVSFields(pStr);
    else
    {
        s.SetHexStr(databaseS.c_str());
        v.SetHexStr(databaseV.c_str());
    }

    b.SetRand(128 * 8);
    B = ((v * k) + g.ModExp(b, N)) % N;
    BigNumber unk;
    unk.SetRand(128 * 8);

    BitStream passwordData;
    uint8 state = 0;
    passwordData.WriteBytes(&state, 1);
    passwordData.WriteBytes(I.AsByteArray(32).get(), 32);
    passwordData.WriteBytes(s.AsByteArray(32).get(), 32);
    passwordData.WriteBytes(B.AsByteArray(128).get(), 128);
    passwordData.WriteBytes(unk.AsByteArray(128).get(), 128);

    password->DataSize = passwordData.GetSize();
    password->Data = new uint8[password->DataSize];
    memcpy(password->Data, passwordData.GetBuffer(), password->DataSize);

    _modulesWaitingForData.push(MODULE_PASSWORD);

    Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
    proofRequest->Modules.push_back(password);
    // if has authenticator, send Token module
    proofRequest->Modules.push_back(thumbprint);
    AsyncWrite(proofRequest);
}
示例#16
0
void Battlenet::Session::HandleLogonRequest(Authentication::LogonRequest3 const& logonRequest)
{
    // Verify that this IP is not in the ip_banned table
    LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));

    std::string ip_address = GetRemoteIpAddress().to_string();
    PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED);
    stmt->setString(0, ip_address);
    if (PreparedQueryResult result = LoginDatabase.Query(stmt))
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(LOGIN_BANNED);
        AsyncWrite(logonResponse);
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Banned ip '%s:%d' tries to login!", ip_address.c_str(), GetRemotePort());
        return;
    }

    if (logonRequest.Program != "WoW")
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM);
        AsyncWrite(logonResponse);
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with game other than WoW (using %s)!", GetClientInfo().c_str(), logonRequest.Program.c_str());
        return;
    }

    if (!sComponentMgr->HasPlatform(logonRequest.Platform))
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_INVALID_OS);
        AsyncWrite(logonResponse);
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in from an unsupported platform (using %s)!", GetClientInfo().c_str(), logonRequest.Platform.c_str());
        return;
    }

    if (!sComponentMgr->HasPlatform(logonRequest.Locale))
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_UNSUPPORTED_LANGUAGE);
        AsyncWrite(logonResponse);
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s attempted to log in with unsupported locale (using %s)!", GetClientInfo().c_str(), logonRequest.Locale.c_str());
        return;
    }

    for (Component const& component : logonRequest.Components)
    {
        if (!sComponentMgr->HasComponent(&component))
        {
            Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
            if (!sComponentMgr->HasProgram(component.Program))
            {
                logonResponse->SetAuthResult(AUTH_INVALID_PROGRAM);
                TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component program %s!", GetClientInfo().c_str(), component.Program.c_str());
            }
            else if (!sComponentMgr->HasPlatform(component.Platform))
            {
                logonResponse->SetAuthResult(AUTH_INVALID_OS);
                TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component platform %s!", GetClientInfo().c_str(), component.Platform.c_str());
            }
            else
            {
                if (component.Program != "WoW" || AuthHelper::IsBuildSupportingBattlenet(component.Build))
                    logonResponse->SetAuthResult(AUTH_REGION_BAD_VERSION);
                else
                    logonResponse->SetAuthResult(AUTH_USE_GRUNT_LOGON);

                TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is using unsupported component version %u!", GetClientInfo().c_str(), component.Build);
            }

            AsyncWrite(logonResponse);
            return;
        }

        if (component.Platform == "base")
            _build = component.Build;
    }

    _accountName = logonRequest.Login;
    _locale = logonRequest.Locale;
    _os = logonRequest.Platform;

    Utf8ToUpperOnlyLatin(_accountName);
    stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO);
    stmt->setString(0, _accountName);

    PreparedQueryResult result = LoginDatabase.Query(stmt);
    if (!result)
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_UNKNOWN_ACCOUNT);
        AsyncWrite(logonResponse);
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] %s is trying to log in from unknown account!", GetClientInfo().c_str());
        return;
    }

    Field* fields = result->Fetch();

    _accountId = fields[1].GetUInt32();

    // If the IP is 'locked', check that the player comes indeed from the correct IP address
    if (fields[2].GetUInt8() == 1)                  // if ip is locked
    {
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to IP - '%s' is logging in from '%s'", _accountName.c_str(), fields[4].GetCString(), ip_address.c_str());

        if (strcmp(fields[4].GetCString(), ip_address.c_str()) != 0)
        {
            Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
            logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
            AsyncWrite(logonResponse);
            return;
        }
    }
    else
    {
        TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to ip", _accountName.c_str());
        std::string accountCountry = fields[3].GetString();
        if (accountCountry.empty() || accountCountry == "00")
            TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is not locked to country", _accountName.c_str());
        else if (!accountCountry.empty())
        {
            uint32 ip = inet_addr(ip_address.c_str());
            EndianConvertReverse(ip);

            stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY);
            stmt->setUInt32(0, ip);
            if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt))
            {
                std::string loginCountry = (*sessionCountryQuery)[0].GetString();
                TC_LOG_DEBUG("session", "[Battlenet::LogonRequest] Account '%s' is locked to country: '%s' Player country is '%s'", _accountName.c_str(), accountCountry.c_str(), loginCountry.c_str());
                if (loginCountry != accountCountry)
                {
                    Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
                    logonResponse->SetAuthResult(AUTH_ACCOUNT_LOCKED);
                    AsyncWrite(logonResponse);
                    return;
                }
            }
        }
    }

    //set expired bans to inactive
    LoginDatabase.DirectExecute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_EXPIRED_BANS));

    // If the account is banned, reject the logon attempt
    stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN);
    stmt->setUInt32(0, _accountId);
    PreparedQueryResult banresult = LoginDatabase.Query(stmt);
    if (banresult)
    {
        Field* fields = banresult->Fetch();
        if (fields[0].GetUInt32() == fields[1].GetUInt32())
        {
            Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
            logonResponse->SetAuthResult(LOGIN_BANNED);
            AsyncWrite(logonResponse);
            TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
            return;
        }
        else
        {
            Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
            logonResponse->SetAuthResult(LOGIN_SUSPENDED);
            AsyncWrite(logonResponse);
            TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::LogonRequest] Temporarily banned account %s tried to login!", ip_address.c_str(), GetRemotePort(), _accountName.c_str());
            return;
        }
    }

    SHA256Hash sha;
    sha.UpdateData(_accountName);
    sha.Finalize();

    I.SetBinary(sha.GetDigest(), sha.GetLength());

    ModuleInfo* password = sModuleMgr->CreateModule(_os, "Password");
    ModuleInfo* thumbprint = sModuleMgr->CreateModule(_os, "Thumbprint");

    std::string pStr = fields[0].GetString();

    std::string databaseV = fields[5].GetString();
    std::string databaseS = fields[6].GetString();

    if (databaseV.size() != size_t(BufferSizes::SRP_6_V) * 2 || databaseS.size() != size_t(BufferSizes::SRP_6_S) * 2)
        _SetVSFields(pStr);
    else
    {
        s.SetHexStr(databaseS.c_str());
        v.SetHexStr(databaseV.c_str());
    }

    b.SetRand(128 * 8);
    B = ((v * k) + g.ModExp(b, N)) % N;
    BigNumber unk;
    unk.SetRand(128 * 8);

    BitStream passwordData;
    uint8 state = 0;
    passwordData.WriteBytes(&state, 1);
    passwordData.WriteBytes(I.AsByteArray(32).get(), 32);
    passwordData.WriteBytes(s.AsByteArray(32).get(), 32);
    passwordData.WriteBytes(B.AsByteArray(128).get(), 128);
    passwordData.WriteBytes(unk.AsByteArray(128).get(), 128);

    password->DataSize = passwordData.GetSize();
    password->Data = new uint8[password->DataSize];
    memcpy(password->Data, passwordData.GetBuffer(), password->DataSize);

    _modulesWaitingForData.push(MODULE_PASSWORD);

    Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
    proofRequest->Modules.push_back(password);
    // if has authenticator, send Token module
    proofRequest->Modules.push_back(thumbprint);
    AsyncWrite(proofRequest);
}
示例#17
0
uint32 Battlenet::Session::VerifyWebCredentials(std::string const& webCredentials, std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)>& continuation)
{
    PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_INFO);
    stmt->setString(0, webCredentials);

    std::function<void(ServiceBase*, uint32, ::google::protobuf::Message const*)> asyncContinuation = std::move(continuation);
    std::shared_ptr<AccountInfo> accountInfo = std::make_shared<AccountInfo>();
    _queryProcessor.AddQuery(LoginDatabase.AsyncQuery(stmt).WithChainingPreparedCallback([this, accountInfo, asyncContinuation](QueryCallback& callback, PreparedQueryResult result)
    {
        Battlenet::Services::Authentication asyncContinuationService(this);
        NoData response;
        if (!result)
        {
            asyncContinuation(&asyncContinuationService, ERROR_DENIED, &response);
            return;
        }

        accountInfo->LoadResult(result);

        if (accountInfo->LoginTicketExpiry < time(nullptr))
        {
            asyncContinuation(&asyncContinuationService, ERROR_TIMED_OUT, &response);
            return;
        }

        PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_BNET_ID);
        stmt->setUInt32(0, accountInfo->Id);
        callback.SetNextQuery(LoginDatabase.AsyncQuery(stmt));
    })
        .WithChainingPreparedCallback([accountInfo](QueryCallback& callback, PreparedQueryResult characterCountsResult)
    {
        if (characterCountsResult)
        {
            do
            {
                Field* fields = characterCountsResult->Fetch();
                accountInfo->GameAccounts[fields[0].GetUInt32()]
                    .CharacterCounts[Battlenet::RealmHandle{ fields[3].GetUInt8(), fields[4].GetUInt8(), fields[2].GetUInt32() }.GetAddress()] = fields[1].GetUInt8();

            } while (characterCountsResult->NextRow());
        }

        PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_LAST_PLAYER_CHARACTERS);
        stmt->setUInt32(0, accountInfo->Id);
        callback.SetNextQuery(LoginDatabase.AsyncQuery(stmt));
    })
        .WithPreparedCallback([this, accountInfo, asyncContinuation](PreparedQueryResult lastPlayerCharactersResult)
    {
        if (lastPlayerCharactersResult)
        {
            do
            {
                Field* fields = lastPlayerCharactersResult->Fetch();
                Battlenet::RealmHandle realmId{ fields[1].GetUInt8(), fields[2].GetUInt8(), fields[3].GetUInt32() };
                Battlenet::Session::LastPlayedCharacterInfo& lastPlayedCharacter = accountInfo->GameAccounts[fields[0].GetUInt32()]
                    .LastPlayedCharacters[realmId.GetSubRegionAddress()];

                lastPlayedCharacter.RealmId = realmId;
                lastPlayedCharacter.CharacterName = fields[4].GetString();
                lastPlayedCharacter.CharacterGUID = fields[5].GetUInt64();
                lastPlayedCharacter.LastPlayedTime = fields[6].GetUInt32();

            } while (lastPlayerCharactersResult->NextRow());
        }

        _accountInfo = accountInfo;
        Battlenet::Services::Authentication asyncContinuationService(this);
        NoData response;

        std::string ip_address = GetRemoteIpAddress().to_string();

        // If the IP is 'locked', check that the player comes indeed from the correct IP address
        if (_accountInfo->IsLockedToIP)
        {
            TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to IP - '%s' is logging in from '%s'",
                _accountInfo->Login.c_str(), _accountInfo->LastIP.c_str(), ip_address.c_str());

            if (_accountInfo->LastIP != ip_address)
            {
                asyncContinuation(&asyncContinuationService, ERROR_RISK_ACCOUNT_LOCKED, &response);
                return;
            }
        }
        else
        {
            TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to ip", _accountInfo->Login.c_str());
            if (_accountInfo->LockCountry.empty() || _accountInfo->LockCountry == "00")
                TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is not locked to country", _accountInfo->Login.c_str());
            else if (!_accountInfo->LockCountry.empty() && !_ipCountry.empty())
            {
                TC_LOG_DEBUG("session", "[Session::HandleVerifyWebCredentials] Account '%s' is locked to country: '%s' Player country is '%s'",
                    _accountInfo->Login.c_str(), _accountInfo->LockCountry.c_str(), _ipCountry.c_str());

                if (_ipCountry != _accountInfo->LockCountry)
                {
                    asyncContinuation(&asyncContinuationService, ERROR_RISK_ACCOUNT_LOCKED, &response);
                    return;
                }
            }
        }

        // If the account is banned, reject the logon attempt
        if (_accountInfo->IsBanned)
        {
            if (_accountInfo->IsPermanenetlyBanned)
            {
                TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str());
                asyncContinuation(&asyncContinuationService, ERROR_GAME_ACCOUNT_BANNED, &response);
                return;
            }
            else
            {
                TC_LOG_DEBUG("session", "%s [Session::HandleVerifyWebCredentials] Temporarily banned account %s tried to login!", GetClientInfo().c_str(), _accountInfo->Login.c_str());
                asyncContinuation(&asyncContinuationService, ERROR_GAME_ACCOUNT_SUSPENDED, &response);
                return;
            }
        }

        authentication::v1::LogonResult logonResult;
        logonResult.set_error_code(0);
        logonResult.mutable_account_id()->set_low(_accountInfo->Id);
        logonResult.mutable_account_id()->set_high(UI64LIT(0x100000000000000));
        for (auto itr = _accountInfo->GameAccounts.begin(); itr != _accountInfo->GameAccounts.end(); ++itr)
        {
            if (!itr->second.IsBanned)
            {
                EntityId* gameAccountId = logonResult.add_game_account_id();
                gameAccountId->set_low(itr->second.Id);
                gameAccountId->set_high(UI64LIT(0x200000200576F57));
            }
        }

        if (!_ipCountry.empty())
            logonResult.set_geoip_country(_ipCountry);

        BigNumber k;
        k.SetRand(8 * 64);
        logonResult.set_session_key(k.AsByteArray(64).get(), 64);

        _authed = true;

        asyncContinuation(&asyncContinuationService, ERROR_OK, &response);
        Service<authentication::v1::AuthenticationListener>(this).OnLogonComplete(&logonResult);
    }));

    return ERROR_OK;
}
示例#18
0
bool Battlenet::Session::HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response)
{
    if (dataStream->Read<uint8>(8) != 1)
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(AUTH_CORRUPTED_MODULE);
        ReplaceResponse(response, logonResponse);
        return false;
    }

    dataStream->Read<uint8>(8);
    std::string account = dataStream->ReadString(8);
    if (account.empty())
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        logonResponse->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
        ReplaceResponse(response, logonResponse);
        return false;
    }

    PreparedStatement* stmt;
    if (account.substr(0, 3) != "WoW")
    {
        stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT);
        stmt->setString(0, account);
    }
    else
    {
        stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_GAME_ACCOUNT_UNNAMED);
        stmt->setUInt8(0, atol(account.substr(3).c_str()));
    }

    stmt->setUInt32(1, _accountId);
    PreparedQueryResult result = LoginDatabase.Query(stmt);
    if (!result)
    {
        Authentication::LogonResponse* complete = new Authentication::LogonResponse();
        complete->SetAuthResult(LOGIN_NO_GAME_ACCOUNT);
        ReplaceResponse(response, complete);
        TC_LOG_DEBUG("session", "[Battlenet::SelectGameAccount] %s attempted to log in with invalid game account name %s!", GetClientInfo().c_str(), account.c_str());
        return false;
    }

    Field* fields = result->Fetch();
    if (fields[4].GetBool())
    {
        Authentication::LogonResponse* logonResponse = new Authentication::LogonResponse();
        if (fields[2].GetUInt32() == fields[3].GetUInt32())
        {
            logonResponse->SetAuthResult(LOGIN_BANNED);
            TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
        }
        else
        {
            logonResponse->SetAuthResult(LOGIN_SUSPENDED);
            TC_LOG_DEBUG("session", "'%s:%d' [Battlenet::SelectGameAccount] Temporarily banned account %s tried to login!", GetRemoteIpAddress().to_string().c_str(), GetRemotePort(), _accountName.c_str());
        }

        ReplaceResponse(response, logonResponse);
        return false;
    }

    _gameAccountId = fields[0].GetUInt32();
    _gameAccountName = fields[1].GetString();

    Authentication::ProofRequest* proofRequest = new Authentication::ProofRequest();
    proofRequest->Modules.push_back(sModuleMgr->CreateModule(_os, "RiskFingerprint"));
    ReplaceResponse(response, proofRequest);

    _modulesWaitingForData.push(MODULE_RISK_FINGERPRINT);
    return true;
}
示例#19
0
void Battlenet::Session::Start()
{
    TC_LOG_TRACE("session", "Accepted connection from %s", GetRemoteIpAddress().to_string().c_str());
    AsyncRead();
}