diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0fceb85..9c3b096 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -127,6 +127,7 @@ set(common_SRCS test.cpp sha1.cpp base64.cpp + ban.cpp ) # This gives us the icon diff --git a/src/auth.cpp b/src/auth.cpp index 5d61243..dc74041 100644 --- a/src/auth.cpp +++ b/src/auth.cpp @@ -40,6 +40,8 @@ std::string privsToString(u64 privs) os<<"privs,"; if(privs & PRIV_SHOUT) os<<"shout,"; + if(privs & PRIV_BAN) + os<<"ban,"; if(os.tellp()) { // Drop the trailing comma. (Why on earth can't @@ -70,6 +72,8 @@ u64 stringToPrivs(std::string str) privs |= PRIV_PRIVS; else if(s == "shout") privs |= PRIV_SHOUT; + else if(s == "ban") + privs |= PRIV_BAN; else return PRIV_INVALID; } diff --git a/src/auth.h b/src/auth.h index 62dced2..5ea697a 100644 --- a/src/auth.h +++ b/src/auth.h @@ -38,6 +38,7 @@ const u64 PRIV_SERVER = 16; // Can manage the server (e.g. shutodwn // ,settings) const u64 PRIV_SHOUT = 32; // Can broadcast chat messages to all // players +const u64 PRIV_BAN = 64; // Can ban players // Default privileges - these can be overriden for new players using the // config option "default_privs" - however, this value still applies for diff --git a/src/ban.cpp b/src/ban.cpp new file mode 100644 index 0000000..0d66e80 --- /dev/null +++ b/src/ban.cpp @@ -0,0 +1,118 @@ +/* +Minetest-c55 +Copyright (C) 2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "ban.h" +#include +#include +#include +#include "strfnd.h" +#include "debug.h" + +BanManager::BanManager(const std::string &banfilepath): + m_banfilepath(banfilepath), + m_modified(false) +{ + m_mutex.Init(); + try{ + load(); + } + catch(SerializationError &e) + { + dstream<<"WARNING: BanManager: creating " + <::iterator + i = m_ips.begin(); + i != m_ips.end(); i++) + { + if(*i == "") + continue; + os<<*i<<"\n"; + } + m_modified = false; +} + +bool BanManager::isIpBanned(std::string ip) +{ + JMutexAutoLock lock(m_mutex); + return m_ips.find(ip) != m_ips.end(); +} + +void BanManager::add(std::string ip) +{ + JMutexAutoLock lock(m_mutex); + m_ips.insert(ip); + m_modified = true; +} + +void BanManager::remove(std::string ip) +{ + JMutexAutoLock lock(m_mutex); + m_ips.erase(m_ips.find(ip)); + m_modified = true; +} + + +bool BanManager::isModified() +{ + JMutexAutoLock lock(m_mutex); + return m_modified; +} + diff --git a/src/ban.h b/src/ban.h new file mode 100644 index 0000000..38b08b6 --- /dev/null +++ b/src/ban.h @@ -0,0 +1,49 @@ +/* +Minetest-c55 +Copyright (C) 2011 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef BAN_HEADER +#define BAN_HEADER + +#include +#include +#include +#include +#include "common_irrlicht.h" +#include "exceptions.h" + +class BanManager +{ +public: + BanManager(const std::string &bannfilepath); + ~BanManager(); + void load(); + void save(); + void add(std::string ip); + void remove(std::string ip); + bool isIpBanned(std::string ip); + bool isModified(); +private: + JMutex m_mutex; + std::string m_banfilepath; + std::set m_ips; + bool m_modified; + +}; + +#endif diff --git a/src/game.cpp b/src/game.cpp index 147a1fa..a3a5f42 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1062,6 +1062,14 @@ void the_game( { //std::cerr<<"frame"<disconnect_requested) { g_gamecallback->disconnect_requested = false; diff --git a/src/server.cpp b/src/server.cpp index 176a13e..65ea453 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1063,6 +1063,7 @@ Server::Server( m_env(new ServerMap(mapsavedir), this), m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this), m_authmanager(mapsavedir+"/auth.txt"), + m_banmanager(mapsavedir+"/ipban.txt"), m_thread(this), m_emergethread(this), m_time_counter(0), @@ -1834,6 +1835,10 @@ void Server::AsyncRunStep() // Auth stuff if(m_authmanager.isModified()) m_authmanager.save(); + + //Bann stuff + if(m_banmanager.isModified()) + m_banmanager.save(); // Map JMutexAutoLock lock(m_env_mutex); @@ -1923,6 +1928,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) <address.serializeString())){ + SendAccessDenied(m_con, peer_id, + L"Your ip is banned!"); + m_con.deletePeer(peer_id, false); + return; + } u8 peer_ser_ver = getClient(peer->id)->serialization_version; @@ -1959,7 +1972,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) //peer->serialization_version = deployed; getClient(peer->id)->pending_serialization_version = deployed; - + if(deployed == SER_FMT_VER_INVALID) { derr_server<privs && PRIV_BAN) == 0) + { + os<parms.size() != 2) + { + os<parms[0] == L"ipban") + { + Player *player = ctx->env->getPlayer(wide_to_narrow(ctx->parms[1]).c_str()); + + if(player == NULL) + { + os<server->getPeerNoEx(player->peer_id); + if(peer == NULL) + { + dstream<<"peer was not found!"<server->setIpBanned(peer->address.serializeString()); + os<address.serializeString())<server->unsetIpBanned(wide_to_narrow(ctx->parms[1])); + os<parms[1]<parms[0] == L"status") { @@ -233,6 +273,10 @@ std::wstring processServerCommand(ServerCommandContext *ctx) { cmd_teleport(os, ctx); } + else if(ctx->parms[0] == L"ipban" || ctx->parms[0] == L"ipunban") + { + cmd_ipbanunban(os, ctx); + } else { os<parms[0]; diff --git a/src/socket.cpp b/src/socket.cpp index ab3ca62..a7d2040 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -97,6 +97,16 @@ void Address::Resolve(const char *name) freeaddrinfo(resolved); } +std::string Address::serializeString() +{ + unsigned int a, b, c, d; + a = (m_address && 0xFF000000)>>24; + b = (m_address && 0x00FF0000)>>16; + c = (m_address && 0x0000FF00)>>8; + d = (m_address && 0x000000FF); + return itos(a)+"."+itos(b)+"."+itos(c)+"."+itos(d); +} + unsigned int Address::getAddress() const { return m_address; diff --git a/src/socket.h b/src/socket.h index c2b496e..f24947c 100644 --- a/src/socket.h +++ b/src/socket.h @@ -97,6 +97,7 @@ public: void setPort(unsigned short port); void print(std::ostream *s) const; void print() const; + std::string serializeString(); private: unsigned int m_address; unsigned short m_port;