void login2( Network::Client* client, PKTIN_91* msg ) // Gameserver login and character listing { client->encrypt_server_stream = true; if ( Network::is_banned_ip( client ) ) { send_login_error( client, LOGIN_ERROR_ACCOUNT_BLOCKED ); client->Disconnect(); return; } /* Hmm, might have to re-search for account. For now, we already have the account in client->acct. Might work different if real loginservers were used. */ Accounts::Account* acct = Accounts::find_account( msg->name ); if ( acct == nullptr ) { send_login_error( client, LOGIN_ERROR_NO_ACCOUNT ); client->Disconnect(); return; } // First check the password - if wrong, you can't find out anything else. bool correct_password = false; // dave changed 6/5/3, always authenticate with hashed user+pass std::string msgpass = msg->password; std::string acctname = acct->name(); std::string temp; Clib::MD5_Encrypt( acctname + msgpass, temp ); // MD5 correct_password = Clib::MD5_Compare( acct->passwordhash(), temp ); if ( !correct_password ) { send_login_error( client, LOGIN_ERROR_WRONG_PASSWORD ); client->Disconnect(); POLLOG.Format( "Incorrect password for account {} from {}\n" ) << acct->name() << client->ipaddrAsString(); return; } else { // write out cleartext if necessary if ( Plib::systemstate.config.retain_cleartext_passwords ) { if ( acct->password().empty() ) acct->set_password( msgpass ); } } if ( !acct->enabled() || acct->banned() ) { send_login_error( client, LOGIN_ERROR_ACCOUNT_BLOCKED ); client->Disconnect(); return; } // // Dave moved the max_clients check to pol.cpp so character cmdlevel could be checked. // POLLOG.Format( "Account {} logged in from {}\n" ) << acct->name() << client->ipaddrAsString(); // ENHANCEMENT: could authenticate with real loginservers. client->acct = acct; /* NOTE: acct->client is not set here. It is possible that another client is still connected, or a connection is stuck open, or similar. When a character is selected, if another client is connected, measures will be taken. */ // Tell the client about the starting locations and his characters (up to 5). // MuadDib Added new seed system. This is for transferring KR/6017/Normal client detection from // loginserver // to the gameserver. Allows keeping client flags from remote loginserver to gameserver for 6017 // and kr // packets. client->ClientType = cfBEu16( msg->unk3_4_ClientType ); send_start( client ); }
void loginserver_login( Network::Client* client, PKTIN_80* msg ) { unsigned idx; if ( Network::is_banned_ip( client ) ) { send_login_error( client, LOGIN_ERROR_ACCOUNT_BLOCKED ); client->Disconnect(); return; } Accounts::Account* acct = Accounts::find_account( msg->name ); if ( !acct ) { send_login_error( client, LOGIN_ERROR_NO_ACCOUNT ); client->Disconnect(); return; } else if ( Plib::systemstate.config.min_cmdlevel_to_login > acct->default_cmdlevel() ) { send_login_error( client, LOGIN_ERROR_MISC ); client->Disconnect(); return; } bool correct_password = false; std::string msgpass = msg->password; std::string acctname = acct->name(); std::string temp; Clib::MD5_Encrypt( acctname + msgpass, temp ); // MD5 correct_password = Clib::MD5_Compare( acct->passwordhash(), temp ); if ( !correct_password ) { send_login_error( client, LOGIN_ERROR_WRONG_PASSWORD ); client->Disconnect(); POLLOG.Format( "Incorrect password for account {} from {}\n" ) << acct->name() << client->ipaddrAsString(); return; } else { if ( Plib::systemstate.config.retain_cleartext_passwords ) { if ( acct->password().empty() ) acct->set_password( msgpass ); } } if ( !acct->enabled() || acct->banned() ) { send_login_error( client, LOGIN_ERROR_ACCOUNT_BLOCKED ); client->Disconnect(); return; } POLLOG_INFO.Format( "Account {} logged in from {}\n" ) << acct->name() << client->ipaddrAsString(); client->acct = acct; Network::PktHelper::PacketOut<Network::PktOut_A8> msgA8; msgA8->offset += 2; msgA8->Write<u8>( 0xFFu ); msgA8->offset += 2; // servcount unsigned short servcount = 0; for ( idx = 0; idx < networkManager.servers.size(); idx++ ) { ServerDescription* server = networkManager.servers[idx]; if ( !server->hostname.empty() ) { struct hostent* he = gethostbyname( server->hostname.c_str() ); // FIXME: here is a potential server lockup if ( he != nullptr && he->h_addr_list[0] ) { char* addr = he->h_addr_list[0]; server->ip[0] = addr[3]; server->ip[1] = addr[2]; server->ip[2] = addr[1]; server->ip[3] = addr[0]; } else { POLLOG.Format( "gethostbyname(\"{}\") failed for server {}\n" ) << server->hostname << server->name; continue; } } if ( server_applies( client, idx ) ) { ++servcount; msgA8->WriteFlipped<u16>( idx + 1u ); msgA8->Write( server->name.c_str(), 30 ); msgA8->WriteFlipped<u16>( idx + 1u ); msgA8->offset += 2; // u8 percentfull, s8 timezone msgA8->Write( server->ip, 4 ); } } u16 len = msgA8->offset; msgA8->offset = 1; msgA8->WriteFlipped<u16>( len ); msgA8->offset++; msgA8->WriteFlipped<u16>( servcount ); msgA8.Send( client, len ); if ( servcount == 0 ) { POLLOG.Format( "No applicable servers for client connecting from {}\n" ) << client->ipaddrAsString(); } }