Exemple #1
0
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;
}