From d68fb667599f2fd2bcee745dc0704d06058b4a72 Mon Sep 17 00:00:00 2001 From: Salanto <90538293+PresJoeBiden@users.noreply.github.com> Date: Mon, 13 Sep 2021 10:32:05 +0200 Subject: [PATCH 1/7] Executive Order 14042 : Implement IPRange Ban --- core/include/config_manager.h | 8 ++++++++ core/include/server.h | 10 ++++++++++ core/src/config_manager.cpp | 12 ++++++++++++ core/src/server.cpp | 24 ++++++++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/core/include/config_manager.h b/core/include/config_manager.h index 74e80bc..5f64645 100644 --- a/core/include/config_manager.h +++ b/core/include/config_manager.h @@ -30,6 +30,7 @@ #include #include #include +#include //JSON loading requirements #include @@ -112,6 +113,13 @@ class ConfigManager { */ static QStringList rawAreaNames(); + /** + * @brief Returns a list of the IPrange bans. + * + * @return See short description. + */ + static QStringList iprangeBans(); + /** * @brief Returns true if the server should advertise to the master server. * diff --git a/core/include/server.h b/core/include/server.h index d6c86f8..0d86edc 100644 --- a/core/include/server.h +++ b/core/include/server.h @@ -195,6 +195,11 @@ class Server : public QObject { */ QStringList m_backgrounds; + /** + * @brief Collection of all IPs that are banned. + */ + QStringList m_ipban_list; + /** * @brief The database manager on the server, used to store users' bans and authorisation details. */ @@ -297,6 +302,11 @@ class Server : public QObject { **/ void hookupLogger(AOClient* client); + /** + * @brief Checks if an IP is in a subnet of the IPBanlist. + **/ + bool isIPBanned(QHostAddress f_remote_IP); + /** * @brief The proxy used for WebSocket connections. * diff --git a/core/src/config_manager.cpp b/core/src/config_manager.cpp index 2a2b180..a383314 100644 --- a/core/src/config_manager.cpp +++ b/core/src/config_manager.cpp @@ -235,6 +235,18 @@ QStringList ConfigManager::rawAreaNames() return m_areas->childGroups(); } +QStringList ConfigManager::iprangeBans() +{ + QStringList l_iprange_bans; + QFile l_file("config/iprange_bans.txt"); + l_file.open(QIODevice::ReadOnly | QIODevice::Text); + while (!(l_file.atEnd())) { + l_iprange_bans.append(l_file.readLine().trimmed()); + } + l_file.close(); + return l_iprange_bans; +} + void ConfigManager::reloadSettings() { m_settings->sync(); diff --git a/core/src/server.cpp b/core/src/server.cpp index 46741bb..8f47b1f 100644 --- a/core/src/server.cpp +++ b/core/src/server.cpp @@ -99,6 +99,9 @@ void Server::start() //Loads the command help information. This is not stored inside the server. ConfigManager::loadCommandHelp(); + + //Get IP bans + m_ipban_list = ConfigManager::iprangeBans(); //Rate-Limiter for IC-Chat connect(&next_message_timer, SIGNAL(timeout()), this, SLOT(allowMessage())); @@ -145,6 +148,15 @@ void Server::clientConnected() return; } + if (isIPBanned(client->m_remote_ip)){ + QString l_reason = "Your IP has been banned by a moderator."; + AOPacket l_ban_reason("BD", {l_reason}); + socket->write(l_ban_reason.toUtf8()); + client->deleteLater(); + socket->close(); + return; + } + m_clients.append(client); connect(socket, &QTcpSocket::disconnected, client, &AOClient::clientDisconnected); @@ -319,6 +331,18 @@ void Server::hookupLogger(AOClient* client) logger, &ULogger::logModcall); } +bool Server::isIPBanned(QHostAddress f_remote_IP) +{ + bool l_match_found = false; + for(const QString &l_ipban : qAsConst(m_ipban_list)) { + if (f_remote_IP.isInSubnet(QHostAddress::parseSubnet(l_ipban))) { + l_match_found = true; + break; + } + } + return l_match_found; +} + Server::~Server() { for (AOClient* client : qAsConst(m_clients)) { From ae190311bd6532d44303ae8d039be8296cab1be6 Mon Sep 17 00:00:00 2001 From: Salanto <90538293+PresJoeBiden@users.noreply.github.com> Date: Mon, 13 Sep 2021 15:24:56 +0200 Subject: [PATCH 2/7] Reload the list so that vile people shall no longer enter --- core/src/commands/moderation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/commands/moderation.cpp b/core/src/commands/moderation.cpp index bbd4bb4..45c41d3 100644 --- a/core/src/commands/moderation.cpp +++ b/core/src/commands/moderation.cpp @@ -474,6 +474,7 @@ void AOClient::cmdReload(int argc, QStringList argv) server->updateHTTPAdvertiserConfig(); server->handleDiscordIntegration(); server->m_music_list = ConfigManager::musiclist(); + server->m_ipban_list = ConfigManager::iprangeBans(); sendServerMessage("Reloaded configurations"); } From 09df305de27bdd3b15597e898b7f3a553371df76 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 13 Oct 2021 22:36:45 +0200 Subject: [PATCH 3/7] add example ranges https://en.wikipedia.org/wiki/Reserved_IP_addresses --- bin/config_sample/iprange_bans.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 bin/config_sample/iprange_bans.txt diff --git a/bin/config_sample/iprange_bans.txt b/bin/config_sample/iprange_bans.txt new file mode 100644 index 0000000..c04f87f --- /dev/null +++ b/bin/config_sample/iprange_bans.txt @@ -0,0 +1,10 @@ +# Test nets +192.0.2.0/24 +198.51.100.0/24 +192.88.99.0/24 +203.0.113.0/24 + +# IPv6 +2001:0000:/32 +2001:db8::/32 +2002::/16 \ No newline at end of file From 3ac0bc62478309fd60532e29aba88b348c8108bd Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 13 Oct 2021 22:45:59 +0200 Subject: [PATCH 4/7] add web range bans --- core/src/packets.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/src/packets.cpp b/core/src/packets.cpp index 52c37c3..76a5e63 100644 --- a/core/src/packets.cpp +++ b/core/src/packets.cpp @@ -398,6 +398,16 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack qDebug() << "ws ip set to" << argv[0]; #endif m_remote_ip = QHostAddress(argv[0]); + + if (isIPBanned(m_remote_ip)){ + QString l_reason = "Your IP has been banned by a moderator."; + AOPacket l_ban_reason("BD", {l_reason}); + m_socket->write(l_ban_reason.toUtf8()); + client->deleteLater(); + m_socket->close(); + return; + } + calculateIpid(); auto l_ban = server->db_manager->isIPBanned(m_ipid); if (l_ban.first) { From 7acc70464e8a6bc5206e0c93197430f9ce6bad9b Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 13 Oct 2021 22:54:42 +0200 Subject: [PATCH 5/7] web clients get removed later by the proxy --- core/src/packets.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/src/packets.cpp b/core/src/packets.cpp index 76a5e63..cdad7c5 100644 --- a/core/src/packets.cpp +++ b/core/src/packets.cpp @@ -399,11 +399,10 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack #endif m_remote_ip = QHostAddress(argv[0]); - if (isIPBanned(m_remote_ip)){ + if (server->isIPBanned(m_remote_ip)){ QString l_reason = "Your IP has been banned by a moderator."; AOPacket l_ban_reason("BD", {l_reason}); m_socket->write(l_ban_reason.toUtf8()); - client->deleteLater(); m_socket->close(); return; } From 6c15aa2164c96846a5cc04d833af8ff33ca8b66a Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Wed, 13 Oct 2021 23:00:29 +0200 Subject: [PATCH 6/7] =?UTF-8?q?just=20make=20it=20public=20=F0=9F=A4=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/include/server.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/include/server.h b/core/include/server.h index 0d86edc..9de8c4b 100644 --- a/core/include/server.h +++ b/core/include/server.h @@ -149,6 +149,11 @@ class Server : public QObject { */ void updateHTTPAdvertiserConfig(); + /** + * @brief Checks if an IP is in a subnet of the IPBanlist. + **/ + bool isIPBanned(QHostAddress f_remote_IP); + /** * @brief Getter for an area specific buffer from the logger. */ @@ -302,11 +307,6 @@ class Server : public QObject { **/ void hookupLogger(AOClient* client); - /** - * @brief Checks if an IP is in a subnet of the IPBanlist. - **/ - bool isIPBanned(QHostAddress f_remote_IP); - /** * @brief The proxy used for WebSocket connections. * From d92ba88cb746a0e37cca9764c7b673d480623fb4 Mon Sep 17 00:00:00 2001 From: Salanto <62221668+Salanto@users.noreply.github.com> Date: Sun, 17 Oct 2021 15:47:18 +0200 Subject: [PATCH 7/7] Add mapped IPv4 address parser. --- core/include/server.h | 5 +++++ core/src/packets.cpp | 7 ++++++- core/src/server.cpp | 18 +++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/core/include/server.h b/core/include/server.h index 9de8c4b..1e0acd0 100644 --- a/core/include/server.h +++ b/core/include/server.h @@ -223,6 +223,11 @@ class Server : public QObject { */ QTimer next_message_timer; + /** + * @brief Attempts to parse a IPv6 mapped IPv4 to an IPv4. + */ + QHostAddress parseToIPv4(QHostAddress f_remote_ip); + /** * @brief If false, IC messages will be rejected. */ diff --git a/core/src/packets.cpp b/core/src/packets.cpp index cdad7c5..b668ff5 100644 --- a/core/src/packets.cpp +++ b/core/src/packets.cpp @@ -399,7 +399,12 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack #endif m_remote_ip = QHostAddress(argv[0]); - if (server->isIPBanned(m_remote_ip)){ + QHostAddress l_remote_ip = m_remote_ip; + if (l_remote_ip.protocol() == QAbstractSocket::IPv6Protocol) { + l_remote_ip = server->parseToIPv4(l_remote_ip); + } + + if (server->isIPBanned(l_remote_ip)){ QString l_reason = "Your IP has been banned by a moderator."; AOPacket l_ban_reason("BD", {l_reason}); m_socket->write(l_ban_reason.toUtf8()); diff --git a/core/src/server.cpp b/core/src/server.cpp index 8f47b1f..27af9ec 100644 --- a/core/src/server.cpp +++ b/core/src/server.cpp @@ -148,7 +148,12 @@ void Server::clientConnected() return; } - if (isIPBanned(client->m_remote_ip)){ + QHostAddress l_remote_ip = client->m_remote_ip; + if (l_remote_ip.protocol() == QAbstractSocket::IPv6Protocol) { + l_remote_ip = parseToIPv4(l_remote_ip); + } + + if (isIPBanned(l_remote_ip)){ QString l_reason = "Your IP has been banned by a moderator."; AOPacket l_ban_reason("BD", {l_reason}); socket->write(l_ban_reason.toUtf8()); @@ -212,6 +217,17 @@ QStringList Server::getCursedCharsTaken(AOClient* client, QStringList chars_take return chars_taken_cursed; } +QHostAddress Server::parseToIPv4(QHostAddress f_remote_ip) +{ + bool l_ok; + QHostAddress l_remote_ip = f_remote_ip; + QHostAddress l_temp_remote_ip = QHostAddress(f_remote_ip.toIPv4Address(&l_ok)); + if (l_ok) { + l_remote_ip = l_temp_remote_ip; + } + return l_remote_ip; +} + void Server::broadcast(AOPacket packet, int area_index) { for (AOClient* client : qAsConst(m_clients)) {