Browse Source

BUGFIX: Set Web UI ban period to 1 hour

adaptive-webui-19844
Christophe Dumez 15 years ago
parent
commit
057cf3648e
  1. 1
      Changelog
  2. 13
      src/httpconnection.cpp
  3. 42
      src/httpserver.cpp
  4. 42
      src/httpserver.h

1
Changelog

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
- BUGFIX: Optimized RSS module memory usage
- BUGFIX: Consider HTTP downloads >1MB as invalid .torrent files and abort
- BUGFIX: Fix Web UI authentication with some browsers
- BUGFIX: Set Web UI ban period to 1 hour
- COSMETIC: Improved style management
* Mon Jan 18 2010 - Christophe Dumez <chris@qbittorrent.org> - v2.1.0

13
src/httpconnection.cpp

@ -47,7 +47,7 @@ @@ -47,7 +47,7 @@
#include <QTemporaryFile>
HttpConnection::HttpConnection(QTcpSocket *socket, Bittorrent *BTSession, HttpServer *parent)
: QObject(parent), socket(socket), parent(parent), BTSession(BTSession)
: QObject(parent), socket(socket), parent(parent), BTSession(BTSession)
{
socket->setParent(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(read()));
@ -131,8 +131,9 @@ QString HttpConnection::translateDocument(QString data) { @@ -131,8 +131,9 @@ QString HttpConnection::translateDocument(QString data) {
void HttpConnection::respond() {
//qDebug("Respond called");
int nb_fail = parent->client_failed_attempts.value(socket->peerAddress().toString(), 0);
if(nb_fail > 4) {
const QString &peer_ip = socket->peerAddress().toString();
const int nb_fail = parent->NbFailedAttemptsForIp(peer_ip);
if(nb_fail >= MAX_AUTH_FAILED_ATTEMPTS) {
generator.setStatusLine(403, "Forbidden");
generator.setMessage(tr("Your IP address has been banned after too many failed authentication attempts."));
write();
@ -142,8 +143,8 @@ void HttpConnection::respond() { @@ -142,8 +143,8 @@ void HttpConnection::respond() {
qDebug("Auth: %s", qPrintable(auth.split(" ").first()));
if (QString::compare(auth.split(" ").first(), "Digest", Qt::CaseInsensitive) != 0 || !parent->isAuthorized(auth.toLocal8Bit(), parser.method())) {
// Update failed attempt counter
parent->client_failed_attempts.insert(socket->peerAddress().toString(), nb_fail+1);
qDebug("client IP: %s (%d failed attempts)", qPrintable(socket->peerAddress().toString()), nb_fail);
parent->increaseNbFailedAttemptsForIp(peer_ip);
qDebug("client IP: %s (%d failed attempts)", qPrintable(peer_ip), nb_fail+1);
// Return unauthorized header
generator.setStatusLine(401, "Unauthorized");
generator.setValue("WWW-Authenticate", "Digest realm=\""+QString(QBT_REALM)+"\", nonce=\""+parent->generateNonce()+"\", algorithm=\"MD5\", qop=\"auth\"");
@ -151,7 +152,7 @@ void HttpConnection::respond() { @@ -151,7 +152,7 @@ void HttpConnection::respond() {
return;
}
// Client sucessfuly authenticated, reset number of failed attempts
parent->client_failed_attempts.remove(socket->peerAddress().toString());
parent->resetNbFailedAttemptsForIp(peer_ip);
QString url = parser.url();
// Favicon
if(url.endsWith("favicon.ico")) {

42
src/httpserver.cpp

@ -37,6 +37,48 @@ @@ -37,6 +37,48 @@
#include <QCryptographicHash>
#include <QTime>
#include <QRegExp>
#include <QTimer>
const int BAN_TIME = 3600000; // 1 hour
class UnbanTimer: public QTimer {
public:
UnbanTimer(QObject *parent, QString peer_ip): QTimer(parent), peer_ip(peer_ip){
setSingleShot(true);
setInterval(BAN_TIME);
}
~UnbanTimer() {
qDebug("||||||||||||Deleting ban timer|||||||||||||||");
}
QString peer_ip;
};
void HttpServer::UnbanTimerEvent() {
UnbanTimer* ubantimer = static_cast<UnbanTimer*>(sender());
qDebug("Ban period has expired for %s", qPrintable(ubantimer->peer_ip));
client_failed_attempts.remove(ubantimer->peer_ip);
ubantimer->deleteLater();
}
int HttpServer::NbFailedAttemptsForIp(QString ip) const {
return client_failed_attempts.value(ip, 0);
}
void HttpServer::increaseNbFailedAttemptsForIp(QString ip) {
const int nb_fail = client_failed_attempts.value(ip, 0);
client_failed_attempts.insert(ip, nb_fail+1);
if(nb_fail == MAX_AUTH_FAILED_ATTEMPTS-1) {
// Max number of failed attempts reached
// Start ban period
UnbanTimer* ubantimer = new UnbanTimer(this, ip);
connect(ubantimer, SIGNAL(timeout()), this, SLOT(UnbanTimerEvent()));
ubantimer->start();
}
}
void HttpServer::resetNbFailedAttemptsForIp(QString ip) {
client_failed_attempts.remove(ip);
}
HttpServer::HttpServer(Bittorrent *_BTSession, int msec, QObject* parent) : QTcpServer(parent) {
username = Preferences::getWebUiUsername().toLocal8Bit();

42
src/httpserver.h

@ -42,28 +42,34 @@ class Bittorrent; @@ -42,28 +42,34 @@ class Bittorrent;
class QTimer;
class EventManager;
const int MAX_AUTH_FAILED_ATTEMPTS = 5;
class HttpServer : public QTcpServer {
Q_OBJECT
Q_OBJECT
private:
QByteArray username;
QByteArray password_ha1;
Bittorrent *BTSession;
EventManager *manager;
QTimer *timer;
public:
HttpServer(Bittorrent *BTSession, int msec, QObject* parent = 0);
~HttpServer();
void setAuthorization(QString username, QString password_ha1);
bool isAuthorized(QByteArray auth, QString method) const;
EventManager *eventManager() const;
QString generateNonce() const;
int NbFailedAttemptsForIp(QString ip) const;
void increaseNbFailedAttemptsForIp(QString ip);
void resetNbFailedAttemptsForIp(QString ip);
public:
HttpServer(Bittorrent *BTSession, int msec, QObject* parent = 0);
~HttpServer();
void setAuthorization(QString username, QString password_ha1);
bool isAuthorized(QByteArray auth, QString method) const;
EventManager *eventManager() const;
QString generateNonce() const;
QHash<QString, int> client_failed_attempts;
private slots:
void newHttpConnection();
void onTimer();
void UnbanTimerEvent();
private slots:
void newHttpConnection();
void onTimer();
private:
QByteArray username;
QByteArray password_ha1;
Bittorrent *BTSession;
EventManager *manager;
QTimer *timer;
QHash<QString, int> client_failed_attempts;
};
#endif

Loading…
Cancel
Save