| | 374 | pkt << (uint8) AUTH_LOGON_CHALLENGE; |
| | 375 | pkt << (uint8) 0x00; |
| | 376 | |
| | 377 | ///- Verify that this IP is not in the ip_banned table |
| | 378 | // No SQL injection possible (paste the IP address as passed by the socket) |
| | 379 | dbRealmServer.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); |
| | 380 | |
| | 381 | std::string address = GetRemoteAddress(); |
| | 382 | dbRealmServer.escape_string(address); |
| | 383 | QueryResult *result = dbRealmServer.PQuery( "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str()); |
| | 384 | if(result) |
| | 385 | { |
| | 386 | pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED; |
| | 387 | sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ()); |
| | 388 | delete result; |
| | 389 | } |
| | 390 | else |
| | 391 | { |
| | 392 | ///- Get the account details from the account table |
| | 393 | // No SQL injection (escaped user name) |
| | 394 | |
| | 395 | result = dbRealmServer.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ()); |
| | 396 | if( result ) |
| | 397 | { |
| | 398 | ///- If the IP is 'locked', check that the player comes indeed from the correct IP address |
| | 399 | bool locked = false; |
| | 400 | if((*result)[2].GetUInt8() == 1) // if ip is locked |
| | 401 | { |
| | 402 | DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString()); |
| | 403 | DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str()); |
| | 404 | if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) ) |
| | 405 | { |
| | 406 | DEBUG_LOG("[AuthChallenge] Account IP differs"); |
| | 407 | pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; |
| | 408 | locked=true; |
| | 409 | } |
| | 410 | else |
| | 411 | { |
| | 412 | DEBUG_LOG("[AuthChallenge] Account IP matches"); |
| | 413 | } |
| | 414 | } |
| | 415 | else |
| | 416 | { |
| | 417 | DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); |
| | 418 | } |
| | 419 | |
| | 420 | if (!locked) |
| | 421 | { |
| | 422 | //set expired bans to inactive |
| | 423 | dbRealmServer.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); |
| | 424 | ///- If the account is banned, reject the logon attempt |
| | 425 | QueryResult *banresult = dbRealmServer.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32()); |
| | 426 | if(banresult) |
| | 427 | { |
| | 428 | if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) |
| | 429 | { |
| | 430 | pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED; |
| | 431 | sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ()); |
| | 432 | } |
| | 433 | else |
| | 434 | { |
| | 435 | pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; |
| | 436 | sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ()); |
| | 437 | } |
| | 438 | |
| | 439 | delete banresult; |
| | 440 | } |
| | 441 | else |
| | 442 | { |
| | 443 | ///- Get the password from the account table, upper it, and make the SRP6 calculation |
| | 444 | std::string rI = (*result)[0].GetCppString(); |
| | 445 | _SetVSFields(rI); |
| | 446 | |
| | 447 | b.SetRand(19 * 8); |
| | 448 | BigNumber gmod=g.ModExp(b, N); |
| | 449 | B = ((v * 3) + gmod) % N; |
| | 450 | |
| | 451 | ASSERT(gmod.GetNumBytes() <= 32); |
| | 452 | |
| | 453 | BigNumber unk3; |
| | 454 | unk3.SetRand(16*8); |
| | 455 | |
| | 456 | ///- Fill the response packet with the result |
| | 457 | pkt << (uint8)REALM_AUTH_SUCCESS; |
| | 458 | |
| | 459 | // B may be calculated < 32B so we force minnimal length to 32B |
| | 460 | pkt.append(B.AsByteArray(32), 32); // 32 bytes |
| | 461 | pkt << (uint8)1; |
| | 462 | pkt.append(g.AsByteArray(), 1); |
| | 463 | pkt << (uint8)32; |
| | 464 | pkt.append(N.AsByteArray(), 32); |
| | 465 | pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes |
| | 466 | pkt.append(unk3.AsByteArray(), 16); |
| | 467 | pkt << (uint8)0; // Added in 1.12.x client branch |
| | 468 | |
| | 469 | uint8 secLevel = (*result)[4].GetUInt8(); |
| | 470 | _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; |
| | 471 | |
| | 472 | _localizationName.resize(4); |
| | 473 | for(int i = 0; i <4; ++i) |
| | 474 | _localizationName[i] = ch->country[4-i-1]; |
| | 475 | |
| | 476 | sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], GetLocaleByName(_localizationName)); |
| | 477 | } |
| | 478 | } |
| | 479 | delete result; |
| | 480 | } |
| | 481 | else //no account |
| | 482 | { |
| | 483 | pkt<< (uint8) REALM_AUTH_NO_MATCH; |
| | 484 | } |
| | 485 | } |
| | 486 | SendBuf((char const*)pkt.contents(), pkt.size()); |
| | 487 | return true; |
| | 488 | } |
| | 489 | |
| | 490 | /// Logon Proof command handler |
| | 491 | bool AuthSocket::_HandleLogonProof() |
| | 492 | { |
| | 493 | DEBUG_LOG("Entering _HandleLogonProof"); |
| | 494 | ///- Read the packet |
| | 495 | if (ibuf.GetLength() < sizeof(sAuthLogonProof_C)) |
| | 496 | return false; |
| | 497 | sAuthLogonProof_C lp; |
| | 498 | ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C)); |
| | 499 | |
| 376 | | if(ch->build==accepted_versions[i]) |
| 377 | | { |
| 378 | | valid_version=true; |
| 379 | | break; |
| 380 | | } |
| 381 | | |
| 382 | | /// <ul><li> if this is a valid version |
| 383 | | if(valid_version) |
| 384 | | { |
| 385 | | pkt << (uint8) AUTH_LOGON_CHALLENGE; |
| 386 | | pkt << (uint8) 0x00; |
| 387 | | |
| 388 | | ///- Verify that this IP is not in the ip_banned table |
| 389 | | // No SQL injection possible (paste the IP address as passed by the socket) |
| 390 | | dbRealmServer.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); |
| 391 | | |
| 392 | | std::string address = GetRemoteAddress(); |
| 393 | | dbRealmServer.escape_string(address); |
| 394 | | QueryResult *result = dbRealmServer.PQuery( "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str()); |
| 395 | | if(result) |
| 396 | | { |
| 397 | | pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED; |
| 398 | | sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ()); |
| 399 | | delete result; |
| 400 | | } |
| 401 | | else |
| 402 | | { |
| 403 | | ///- Get the account details from the account table |
| 404 | | // No SQL injection (escaped user name) |
| 405 | | |
| 406 | | result = dbRealmServer.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ()); |
| 407 | | if( result ) |
| 408 | | { |
| 409 | | ///- If the IP is 'locked', check that the player comes indeed from the correct IP address |
| 410 | | bool locked = false; |
| 411 | | if((*result)[2].GetUInt8() == 1) // if ip is locked |
| 412 | | { |
| 413 | | DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString()); |
| 414 | | DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str()); |
| 415 | | if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) ) |
| 416 | | { |
| 417 | | DEBUG_LOG("[AuthChallenge] Account IP differs"); |
| 418 | | pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; |
| 419 | | locked=true; |
| 420 | | } |
| 421 | | else |
| 422 | | { |
| 423 | | DEBUG_LOG("[AuthChallenge] Account IP matches"); |
| 424 | | } |
| 425 | | } |
| 426 | | else |
| 427 | | { |
| 428 | | DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); |
| 429 | | } |
| 430 | | |
| 431 | | if (!locked) |
| 432 | | { |
| 433 | | //set expired bans to inactive |
| 434 | | dbRealmServer.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); |
| 435 | | ///- If the account is banned, reject the logon attempt |
| 436 | | QueryResult *banresult = dbRealmServer.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32()); |
| 437 | | if(banresult) |
| 438 | | { |
| 439 | | if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) |
| 440 | | { |
| 441 | | pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED; |
| 442 | | sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ()); |
| 443 | | } |
| 444 | | else |
| 445 | | { |
| 446 | | pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED; |
| 447 | | sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ()); |
| 448 | | } |
| 449 | | |
| 450 | | delete banresult; |
| 451 | | } |
| 452 | | else |
| 453 | | { |
| 454 | | ///- Get the password from the account table, upper it, and make the SRP6 calculation |
| 455 | | std::string rI = (*result)[0].GetCppString(); |
| 456 | | _SetVSFields(rI); |
| 457 | | |
| 458 | | b.SetRand(19 * 8); |
| 459 | | BigNumber gmod=g.ModExp(b, N); |
| 460 | | B = ((v * 3) + gmod) % N; |
| 461 | | |
| 462 | | ASSERT(gmod.GetNumBytes() <= 32); |
| 463 | | |
| 464 | | BigNumber unk3; |
| 465 | | unk3.SetRand(16*8); |
| 466 | | |
| 467 | | ///- Fill the response packet with the result |
| 468 | | pkt << (uint8)REALM_AUTH_SUCCESS; |
| 469 | | |
| 470 | | // B may be calculated < 32B so we force minnimal length to 32B |
| 471 | | pkt.append(B.AsByteArray(32), 32); // 32 bytes |
| 472 | | pkt << (uint8)1; |
| 473 | | pkt.append(g.AsByteArray(), 1); |
| 474 | | pkt << (uint8)32; |
| 475 | | pkt.append(N.AsByteArray(), 32); |
| 476 | | pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes |
| 477 | | pkt.append(unk3.AsByteArray(), 16); |
| 478 | | pkt << (uint8)0; // Added in 1.12.x client branch |
| 479 | | |
| 480 | | uint8 secLevel = (*result)[4].GetUInt8(); |
| 481 | | _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; |
| 482 | | |
| 483 | | std::string localeName; |
| 484 | | localeName.resize(4); |
| 485 | | for(int i = 0; i <4; ++i) |
| 486 | | localeName[i] = ch->country[4-i-1]; |
| 487 | | |
| 488 | | _localization = GetLocaleByName(localeName); |
| 489 | | |
| 490 | | sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], _localization); |
| 491 | | } |
| 492 | | } |
| 493 | | delete result; |
| 494 | | } |
| 495 | | else //no account |
| 496 | | { |
| 497 | | pkt<< (uint8) REALM_AUTH_NO_MATCH; |
| 498 | | } |
| 499 | | } |
| 500 | | } //valid version |
| 501 | | else |
| 502 | | ///<li> else |
| | 504 | { |
| | 505 | if(_build==accepted_versions[i]) |
| | 506 | { |
| | 507 | valid_version=true; |
| | 508 | break; |
| | 509 | } |
| | 510 | } |
| | 511 | |
| | 512 | /// <ul><li> If the client has no valid version |
| | 513 | if(!valid_version) |