Merge pull request #201 from PresJoeBiden/Keeping-People-Out-With-an-IP-Subnet-Ban,-man!

Executive Order 14042 : Implement IPRange Ban
This commit is contained in:
Rosemary Witchaven 2021-12-13 19:30:42 -06:00 committed by GitHub
commit 48dc849b32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 100 additions and 0 deletions

View File

@ -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

View File

@ -30,6 +30,7 @@
#include <QUrl>
#include <QMetaEnum>
#include <QElapsedTimer>
#include <QHostAddress>
//JSON loading requirements
#include <QJsonDocument>
@ -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.
*

View File

@ -179,6 +179,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.
*/
@ -225,6 +230,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.
*/
@ -243,6 +253,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.
*/

View File

@ -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");
}

View File

@ -236,6 +236,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();

View File

@ -398,6 +398,20 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack
qDebug() << "ws ip set to" << argv[0];
#endif
m_remote_ip = QHostAddress(argv[0]);
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());
m_socket->close();
return;
}
calculateIpid();
auto l_ban = server->db_manager->isIPBanned(m_ipid);
if (l_ban.first) {

View File

@ -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,20 @@ void Server::clientConnected()
return;
}
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());
client->deleteLater();
socket->close();
return;
}
m_clients.append(client);
connect(socket, &QTcpSocket::disconnected, client,
&AOClient::clientDisconnected);
@ -200,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)) {
@ -357,6 +385,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)) {