bool AdminProtocolConfig::allowIP(uint32_t ip) { if(m_onlyLocalHost){ if(ip == 0x0100007F){ //127.0.0.1 return true; } else{ addLogLine(NULL, LOGTYPE_WARNING, 1, std::string("forbidden connection try from ") + convertIPToString(ip)); return false; } } else{ if(!g_bans.isIpDisabled(ip)){ return true; } else{ return false; } } }
void ServicePort::onAccept(boost::asio::ip::tcp::socket* socket, const boost::system::error_code& error) { if(!error){ if(m_services.empty()){ #ifdef __DEBUG_NET__ std::cout << "Error: [ServerPort::accept] No services running!" << std::endl; #endif return; } boost::system::error_code error; const boost::asio::ip::tcp::endpoint endpoint = socket->remote_endpoint(error); uint32_t remote_ip = 0; if(!error){ remote_ip = htonl(endpoint.address().to_v4().to_ulong()); } if(remote_ip != 0 && g_bans.acceptConnection(remote_ip)){ Connection_ptr connection = ConnectionManager::getInstance()->createConnection(socket, m_io_service, shared_from_this()); if(m_services.front()->is_single_socket()){ // Only one handler, and it will send first connection->acceptConnection(m_services.front()->make_protocol(connection)); } else{ connection->acceptConnection(); } } else{ //close the socket if(socket->is_open()){ boost::system::error_code error; socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, error); socket->close(error); delete socket; } } #ifdef __DEBUG_NET_DETAIL__ std::cout << "accept - OK" << std::endl; #endif accept(); } else{ if(error != boost::asio::error::operation_aborted){ close(); if(!m_pendingStart){ m_pendingStart = true; g_scheduler.addEvent(createSchedulerTask(5000, boost::bind(&ServicePort::openAcceptor, boost::weak_ptr<ServicePort>(shared_from_this()), m_serverPort))); } } else{ #ifdef __DEBUG_NET__ std::cout << "Error: [ServerPort::onAccept] Operation aborted." << std::endl; #endif } } }
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; }