void ProtocolAdmin::onRecvFirstMessage(NetworkMessage& msg) { //is the remote admin protocol enabled? if(!g_adminConfig->isEnabled()) { getConnection()->closeConnection(); return; } m_state = NO_CONNECTED; //is allowed this ip? if(!g_adminConfig->allowIP(getIP())) { addLogLine(this, LOGTYPE_EVENT, 1, "ip not allowed"); getConnection()->closeConnection(); return; } //max connections limit if(!g_adminConfig->addConnection()) { addLogLine(this, LOGTYPE_EVENT, 1, "cannot add new connection"); getConnection()->closeConnection(); return; } addLogLine(this, LOGTYPE_EVENT, 1, "sending HELLO"); //send hello OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false); if(output) { TRACK_MESSAGE(output); output->AddByte(AP_MSG_HELLO); output->AddU32(1); //version output->AddString("OTADMIN"); output->AddU16(g_adminConfig->getProtocolPolicy()); //security policy output->AddU32(g_adminConfig->getProtocolOptions()); //protocol options(encryption, ...) OutputMessagePool::getInstance()->send(output); } m_lastCommand = time(NULL); m_state = ENCRYPTION_NO_SET; }
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg) { if( #ifndef _CONSOLE !GUI::getInstance()->m_connections || #endif g_game.getGameState() == GAME_STATE_SHUTDOWN) { getConnection()->closeConnection(); return false; } uint32_t clientip = getConnection()->getIP(); /*uint16_t clientos = */msg.GetU16(); uint16_t version = msg.GetU16(); msg.SkipBytes(12); if(version <= 760) { disconnectClient(0x0A, "Only clients with protocol " CLIENT_VERSION_STR " allowed!"); return false; } if(!RSA_decrypt(msg)) { getConnection()->closeConnection(); return false; } uint32_t key[4]; key[0] = msg.GetU32(); key[1] = msg.GetU32(); key[2] = msg.GetU32(); key[3] = msg.GetU32(); enableXTEAEncryption(); setXTEAKey(key); std::string accountName = msg.GetString(); std::string password = msg.GetString(); if(accountName.empty()) { if(g_config.getBoolean(ConfigManager::ACCOUNT_MANAGER)) { accountName = "1"; password = "******"; } else { disconnectClient(0x0A, "Invalid Account Name."); return false; } } if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) { disconnectClient(0x0A, "Only clients with protocol " CLIENT_VERSION_STR " allowed!"); return false; } if(g_game.getGameState() == GAME_STATE_STARTUP) { disconnectClient(0x0A, "Gameworld is starting up. Please wait."); return false; } if(g_game.getGameState() == GAME_STATE_MAINTAIN) { disconnectClient(0x0A, "Gameworld is under maintenance. Please re-connect in a while."); return false; } if(g_bans.isIpDisabled(clientip)) { disconnectClient(0x0A, "Too many connections attempts from this IP. Try again later."); return false; } if(IOBan::getInstance()->isIpBanished(clientip)) { disconnectClient(0x0A, "Your IP is banished!"); return false; } uint32_t serverip = serverIPs[0].first; for(uint32_t i = 0; i < serverIPs.size(); i++) { if((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second)) { serverip = serverIPs[i].first; break; } } Account account = IOLoginData::getInstance()->loadAccount(accountName); if(account.id == 0 || !passwordTest(password, account.password)) { g_bans.addLoginAttempt(clientip, false); disconnectClient(0x0A, "Account name or password is not correct."); return false; } g_bans.addLoginAttempt(clientip, true); OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false); if(output) { TRACK_MESSAGE(output); //Update premium days g_game.updatePremium(account); //Add MOTD output->AddByte(0x14); std::ostringstream ss; ss << g_game.getMotdNum() << "\n" << g_config.getString(ConfigManager::MOTD); output->AddString(ss.str()); //Add char list output->AddByte(0x64); if(g_config.getBoolean(ConfigManager::ACCOUNT_MANAGER) && account.id != 1) { output->AddByte((uint8_t)account.charList.size() + 1); output->AddString("Account Manager"); output->AddString(g_config.getString(ConfigManager::SERVER_NAME)); output->AddU32(serverip); output->AddU16(g_config.getNumber(ConfigManager::GAME_PORT)); } else output->AddByte((uint8_t)account.charList.size()); std::list<std::string>::iterator it, end; for(it = account.charList.begin(), end = account.charList.end(); it != end; ++it) { output->AddString(*it); if(g_config.getBoolean(ConfigManager::ON_OR_OFF_CHARLIST)) { if(g_game.getPlayerByName((*it))) output->AddString("Online"); else output->AddString("Offline"); } else output->AddString(g_config.getString(ConfigManager::SERVER_NAME)); output->AddU32(serverip); output->AddU16(g_config.getNumber(ConfigManager::GAME_PORT)); } //Add premium days if(g_config.getBoolean(ConfigManager::FREE_PREMIUM)) output->AddU16(0xFFFF); //client displays free premium else output->AddU16(account.premiumDays); OutputMessagePool::getInstance()->send(output); } getConnection()->closeConnection(); return true; }
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg) { if(g_game.getGameState() == GAME_STATE_SHUTDOWN){ getConnection()->closeConnection(); return false; } uint32_t clientip = getConnection()->getIP(); /*uint16_t clientos =*/ msg.GetU16(); uint16_t version = msg.GetU16(); msg.SkipBytes(12); if(version <= 760){ disconnectClient(0x0A, "This server requires client version " CLIENT_VERSION_STRING "."); } if(!RSA_decrypt(msg)){ getConnection()->closeConnection(); return false; } uint32_t key[4]; key[0] = msg.GetU32(); key[1] = msg.GetU32(); key[2] = msg.GetU32(); key[3] = msg.GetU32(); enableXTEAEncryption(); setXTEAKey(key); std::string accname = msg.GetString(); std::string password = msg.GetString(); if(!accname.length()){ //Tibia sends this message if the account name length is < 5 //We will send it only if account name is BLANK disconnectClient(0x0A, "Invalid Account Name."); return false; } if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX){ disconnectClient(0x0A, "This server requires client version " CLIENT_VERSION_STRING "."); return false; } if(g_game.getGameState() == GAME_STATE_STARTUP){ disconnectClient(0x0A, "Gameworld is starting up. Please wait."); return false; } if(g_bans.isIpDisabled(clientip)){ disconnectClient(0x0A, "Too many connections attempts from this IP. Try again later."); return false; } if(g_bans.isIpBanished(clientip)){ disconnectClient(0x0A, "Your IP is banished!"); return false; } /* uint32_t serverip = serverIPs[0].first; for(uint32_t i = 0; i < serverIPs.size(); i++){ if((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second)){ serverip = serverIPs[i].first; break; } } */ Account account = IOAccount::instance()->loadAccount(accname); if(!(asLowerCaseString(account.name) == asLowerCaseString(accname) && passwordTest(password, account.password))){ g_bans.addLoginAttempt(clientip, false); disconnectClient(0x0A, "Account name or password is not correct."); return false; } g_bans.addLoginAttempt(clientip, true); OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false); if(output){ TRACK_MESSAGE(output); //Add MOTD std::stringstream motd; output->AddByte(0x14); motd << g_config.getNumber(ConfigManager::MOTD_NUM) << "\n"; motd << g_config.getString(ConfigManager::MOTD); output->AddString(motd.str()); //Add char list output->AddByte(0x64); output->AddByte((uint8_t)account.charList.size()); std::list<AccountCharacter>::iterator it; for(it = account.charList.begin(); it != account.charList.end(); it++){ const AccountCharacter& character = *it; output->AddString(character.name); output->AddString(character.world_name); output->AddU32(character.ip); output->AddU16(character.port); } output->AddU16(IOAccount::getPremiumDaysLeft(account.premiumEnd)); OutputMessagePool::getInstance()->send(output); } getConnection()->closeConnection(); return true; }
bool ProtocolLogin::parseFirstPacket(NetworkMessage& msg) { if (g_game.getGameState() == GAME_STATE_SHUTDOWN) { getConnection()->closeConnection(); return false; } uint32_t clientip = getConnection()->getIP(); /*uint16_t clientos = */ msg.GetU16(); uint16_t version = msg.GetU16(); msg.SkipBytes(12); /* * Skipped bytes: * 12 bytes: dat, spr, pic signatures (4 bytes each) */ #ifdef __PROTOCOL_77__ if (!RSA_decrypt(msg)) { getConnection()->closeConnection(); return false; } uint32_t key[4]; key[0] = msg.GetU32(); key[1] = msg.GetU32(); key[2] = msg.GetU32(); key[3] = msg.GetU32(); enableXTEAEncryption(); setXTEAKey(key); #endif uint32_t accountName = msg.GetU32(); std::string password = msg.GetString(); if (version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX) { disconnectClient(0x0A, "Only clients with protocol " CLIENT_VERSION_STR " allowed!"); return false; } if (g_game.getGameState() == GAME_STATE_STARTUP) { disconnectClient(0x0A, "Gameworld is starting up. Please wait."); return false; } if (g_game.getGameState() == GAME_STATE_MAINTAIN) { disconnectClient(0x0A, "Gameworld is under maintenance. Please re-connect in a while."); return false; } BanInfo banInfo; if (IOBan::getInstance()->isIpBanned(clientip, banInfo)) { if (banInfo.reason.empty()) { banInfo.reason = "(none)"; } std::ostringstream ss; ss << "Your IP has been banned until " << formatDateShort(banInfo.expiresAt) << " by " << banInfo.bannedBy << ".\n\nReason specified:\n" << banInfo.reason; disconnectClient(0x0A, ss.str().c_str()); return false; } uint32_t serverip = serverIPs[0].first; for (uint32_t i = 0; i < serverIPs.size(); i++) { if ((serverIPs[i].first & serverIPs[i].second) == (clientip & serverIPs[i].second)) { serverip = serverIPs[i].first; break; } } if (!accountName) { disconnectClient(0x0A, "Invalid account id."); return false; } Account account; if (!IOLoginData::getInstance()->loginserverAuthentication(accountName, password, account)) { disconnectClient(0x0A, "Account id or password is not correct."); return false; } OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false); if (output) { //Update premium days g_game.updatePremium(account); //Add MOTD output->AddByte(0x14); std::ostringstream ss; ss << g_game.getMotdNum() << "\n" << g_config.getString(ConfigManager::MOTD); output->AddString(ss.str()); //Add char list output->AddByte(0x64); output->AddByte((uint8_t)account.charList.size()); for (const std::string& characterName : account.charList) { output->AddString(characterName); if (g_config.getBoolean(ConfigManager::ON_OR_OFF_CHARLIST)) { if (g_game.getPlayerByName(characterName)) { output->AddString("Online"); } else { output->AddString("Offline"); } } else { output->AddString(g_config.getString(ConfigManager::SERVER_NAME)); } output->AddU32(serverip); output->AddU16(g_config.getNumber(ConfigManager::GAME_PORT)); } //Add premium days if (g_config.getBoolean(ConfigManager::FREE_PREMIUM)) { output->AddU16(0xFFFF); //client displays free premium } else { output->AddU16(account.premiumDays); } OutputMessagePool::getInstance()->send(output); } getConnection()->closeConnection(); return true; }