예제 #1
0
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 );
}
예제 #2
0
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();
  }
}