Merge pull request #138 from AttorneyOnline/remote-bans

Allow banning clients not connected to the server
This commit is contained in:
scatterflower 2021-06-21 22:25:27 -05:00 committed by GitHub
commit a90dfd2005
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 122 deletions

View File

@ -696,7 +696,7 @@ class AreaData : public QObject {
* * First, a `QStringList` that is the packet of the statement that was advanced to. * * First, a `QStringList` that is the packet of the statement that was advanced to.
* * Then, a `TestimonyProgress` value that describes how the advancement happened. * * Then, a `TestimonyProgress` value that describes how the advancement happened.
*/ */
std::pair<QStringList, AreaData::TestimonyProgress> jumpToStatement(int f_position); QPair<QStringList, AreaData::TestimonyProgress> jumpToStatement(int f_position);
/** /**
* @brief Returns a copy of the judgelog in the area. * @brief Returns a copy of the judgelog in the area.

View File

@ -56,52 +56,26 @@ public:
~DBManager(); ~DBManager();
/** /**
* @brief Checks if there is a record in the Bans table with the given IP address. * @brief Checks if there is a record in the Bans table with the given IPID.
* *
* @param ip The IP address to check if it is banned. * @param ipid The IPID to check if it is banned.
* *
* @return True if the query could return at least one such record. * @return A pair of values:
* * First, a `bool` that is true if the query could return at least one such record.
* * Then, a `QString` that is the reason for the ban.
*/ */
bool isIPBanned(QHostAddress ip); QPair<bool, QString> isIPBanned(QString ipid);
/** /**
* @brief Checks if there is a record in the Bans table with the given hardware ID. * @brief Checks if there is a record in the Bans table with the given hardware ID.
* *
* @param hdid The hardware ID to check if it is banned. * @param hdid The hardware ID to check if it is banned.
* *
* @return True if the query could return at least one such record. * @return A pair of values:
* * First, a `bool` that is true if the query could return at least one such record.
* * Then, a `QString` that is the reason for the ban.
*/ */
bool isHDIDBanned(QString hdid); QPair<bool, QString> isHDIDBanned(QString hdid);
/**
* @brief Returns the reason the given IP address was banned with.
*
* @param ip The IP address whose ban reason needs to be returned.
*
* @return The ban reason if the IP address is actually banned,
* or `"Ban reason not found."` if the IP address is not actually banned.
*/
QString getBanReason(QHostAddress ip);
/**
* @overload
*/
QString getBanReason(QString hdid);
/**
* @brief Returns the reason the given IP address was banned with.
*
* @param ip The IP address whose ban duration to get.
*
* @return The ban duration if the IP address is actually banned,
* or `-1` if the IP address is not actually banned.
*/
long long getBanDuration(QHostAddress ip);
/**
* @overload
*/
long long getBanDuration(QString hdid);
/** /**
* @brief Gets the ID number of a given ban. * @brief Gets the ID number of a given ban.

View File

@ -403,7 +403,7 @@ void AreaData::removeStatement(int f_position)
--m_statement; --m_statement;
} }
std::pair<QStringList, AreaData::TestimonyProgress> AreaData::jumpToStatement(int f_position) QPair<QStringList, AreaData::TestimonyProgress> AreaData::jumpToStatement(int f_position)
{ {
m_statement = f_position; m_statement = f_position;

View File

@ -79,8 +79,12 @@ void AOClient::cmdBan(int argc, QStringList argv)
if (kick_counter > 1) if (kick_counter > 1)
sendServerMessage("Kicked " + QString::number(kick_counter) + " clients with matching ipids."); sendServerMessage("Kicked " + QString::number(kick_counter) + " clients with matching ipids.");
if (!ban_logged)
sendServerMessage("User with ipid not found!"); // We're banning someone not connected.
if (!ban_logged) {
server->db_manager->addBan(ban);
sendServerMessage("Banned " + ban.ipid + " for reason: " + ban.reason);
}
} }
void AOClient::cmdKick(int argc, QStringList argv) void AOClient::cmdKick(int argc, QStringList argv)

View File

@ -31,101 +31,46 @@ DBManager::DBManager() :
updateDB(db_version); updateDB(db_version);
} }
bool DBManager::isIPBanned(QHostAddress ip) QPair<bool, QString> DBManager::isIPBanned(QString ipid)
{ {
QSqlQuery query; QSqlQuery query;
query.prepare("SELECT TIME FROM BANS WHERE IP = ? ORDER BY TIME DESC"); query.prepare("SELECT TIME,REASON,DURATION FROM BANS WHERE IPID = ? ORDER BY TIME DESC");
query.addBindValue(ip.toString()); query.addBindValue(ipid);
query.exec(); query.exec();
if (query.first()) { if (query.first()) {
long long duration = getBanDuration(ip);
long long ban_time = query.value(0).toLongLong(); long long ban_time = query.value(0).toLongLong();
QString reason = query.value(1).toString();
long long duration = query.value(2).toLongLong();
if (duration == -2) if (duration == -2)
return true; return {true, reason};
long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch();
if (ban_time + duration > current_time) if (ban_time + duration > current_time)
return true; return {true, reason};
else return false; else return {false, nullptr};
} }
else return false; else return {false, nullptr};
} }
bool DBManager::isHDIDBanned(QString hdid) QPair<bool, QString> DBManager::isHDIDBanned(QString hdid)
{ {
QSqlQuery query; QSqlQuery query;
query.prepare("SELECT TIME FROM BANS WHERE HDID = ? ORDER BY TIME DESC"); query.prepare("SELECT TIME,REASON,DURATION FROM BANS WHERE HDID = ? ORDER BY TIME DESC");
query.addBindValue(hdid); query.addBindValue(hdid);
query.exec(); query.exec();
if (query.first()) { if (query.first()) {
long long duration = getBanDuration(hdid);
long long ban_time = query.value(0).toLongLong(); long long ban_time = query.value(0).toLongLong();
QString reason = query.value(1).toString();
long long duration = query.value(2).toLongLong();
if (duration == -2) if (duration == -2)
return true; return {true, reason};
long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch(); long long current_time = QDateTime::currentDateTime().toSecsSinceEpoch();
if (ban_time + duration > current_time) if (ban_time + duration > current_time)
return true; return {true, reason};
else return false; else return {false, nullptr};
} }
else return false; else return {false, nullptr};
} }
QString DBManager::getBanReason(QHostAddress ip)
{
QSqlQuery query;
query.prepare("SELECT REASON FROM BANS WHERE IP = ? ORDER BY TIME DESC");
query.addBindValue(ip.toString());
query.exec();
if (query.first()) {
return query.value(0).toString();
}
else {
return "Ban reason not found.";
}
}
QString DBManager::getBanReason(QString hdid)
{
QSqlQuery query;
query.prepare("SELECT REASON FROM BANS WHERE HDID = ? ORDER BY TIME DESC");
query.addBindValue(hdid);
query.exec();
if (query.first()) {
return query.value(0).toString();
}
else {
return "Ban reason not found.";
}
}
long long DBManager::getBanDuration(QString hdid)
{
QSqlQuery query;
query.prepare("SELECT DURATION FROM BANS WHERE HDID = ? ORDER BY TIME DESC");
query.addBindValue(hdid);
query.exec();
if (query.first()) {
return query.value(0).toLongLong();
}
else {
return -1;
}
}
long long DBManager::getBanDuration(QHostAddress ip)
{
QSqlQuery query;
query.prepare("SELECT DURATION FROM BANS WHERE IP = ? ORDER BY TIME DESC");
query.addBindValue(ip.toString());
query.exec();
if (query.first()) {
return query.value(0).toLongLong();
}
else {
return -1;
}
}
int DBManager::getBanID(QString hdid) int DBManager::getBanID(QString hdid)
{ {
QSqlQuery query; QSqlQuery query;

View File

@ -27,8 +27,9 @@ void AOClient::pktDefault(AreaData* area, int argc, QStringList argv, AOPacket p
void AOClient::pktHardwareId(AreaData* area, int argc, QStringList argv, AOPacket packet) void AOClient::pktHardwareId(AreaData* area, int argc, QStringList argv, AOPacket packet)
{ {
hwid = argv[0]; hwid = argv[0];
if(server->db_manager->isHDIDBanned(hwid)) { auto ban = server->db_manager->isHDIDBanned(hwid);
sendPacket("BD", {server->db_manager->getBanReason(hwid) + "\nBan ID: " + QString::number(server->db_manager->getBanID(hwid))}); if (ban.first) {
sendPacket("BD", {ban.second + "\nBan ID: " + QString::number(server->db_manager->getBanID(hwid))});
socket->close(); socket->close();
return; return;
} }
@ -318,16 +319,17 @@ void AOClient::pktWebSocketIp(AreaData* area, int argc, QStringList argv, AOPack
// Special packet to set remote IP from the webao proxy // Special packet to set remote IP from the webao proxy
// Only valid if from a local ip // Only valid if from a local ip
if (remote_ip.isLoopback()) { if (remote_ip.isLoopback()) {
if(server->db_manager->isIPBanned(QHostAddress(argv[0]))) {
sendPacket("BD", {server->db_manager->getBanReason(QHostAddress(argv[0]))});
socket->close();
return;
}
#ifdef NET_DEBUG #ifdef NET_DEBUG
qDebug() << "ws ip set to" << argv[0]; qDebug() << "ws ip set to" << argv[0];
#endif #endif
remote_ip = QHostAddress(argv[0]); remote_ip = QHostAddress(argv[0]);
calculateIpid(); calculateIpid();
auto ban = server->db_manager->isIPBanned(ipid);
if (ban.first) {
sendPacket("BD", {ban.second});
socket->close();
return;
}
int multiclient_count = 0; int multiclient_count = 0;
for (AOClient* joined_client : server->clients) { for (AOClient* joined_client : server->clients) {

View File

@ -121,7 +121,9 @@ void Server::clientConnected()
int multiclient_count = 1; int multiclient_count = 1;
bool is_at_multiclient_limit = false; bool is_at_multiclient_limit = false;
bool is_banned = db_manager->isIPBanned(socket->peerAddress()); client->calculateIpid();
auto ban = db_manager->isIPBanned(client->getIpid());
bool is_banned = ban.first;
for (AOClient* joined_client : clients) { for (AOClient* joined_client : clients) {
if (client->remote_ip.isEqual(joined_client->remote_ip)) if (client->remote_ip.isEqual(joined_client->remote_ip))
multiclient_count++; multiclient_count++;
@ -131,7 +133,8 @@ void Server::clientConnected()
is_at_multiclient_limit = true; is_at_multiclient_limit = true;
if (is_banned) { if (is_banned) {
AOPacket ban_reason("BD", {db_manager->getBanReason(socket->peerAddress())}); QString reason = ban.second;
AOPacket ban_reason("BD", {reason});
socket->write(ban_reason.toUtf8()); socket->write(ban_reason.toUtf8());
} }
if (is_banned || is_at_multiclient_limit) { if (is_banned || is_at_multiclient_limit) {
@ -154,7 +157,6 @@ void Server::clientConnected()
// tsuserver4. It should disable fantacrypt // tsuserver4. It should disable fantacrypt
// completely in any client 2.4.3 or newer // completely in any client 2.4.3 or newer
client->sendPacket(decryptor); client->sendPacket(decryptor);
client->calculateIpid();
#ifdef NET_DEBUG #ifdef NET_DEBUG
qDebug() << client->remote_ip.toString() << "connected"; qDebug() << client->remote_ip.toString() << "connected";
#endif #endif