| 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) |