mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2025-12-30 20:28:05 -06:00
Add ip subnet whitelist for bypassing webui auth
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
* Contact : hammered999@gmail.com
|
||||
*/
|
||||
|
||||
#include "preferences.h"
|
||||
|
||||
#include <QCryptographicHash>
|
||||
#include <QDir>
|
||||
#include <QLocale>
|
||||
@@ -51,11 +53,10 @@
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
#include "logger.h"
|
||||
#include "settingsstorage.h"
|
||||
#include "utils/fs.h"
|
||||
#include "utils/misc.h"
|
||||
#include "settingsstorage.h"
|
||||
#include "logger.h"
|
||||
#include "preferences.h"
|
||||
|
||||
Preferences *Preferences::m_instance = 0;
|
||||
|
||||
@@ -463,6 +464,38 @@ void Preferences::setWebUiLocalAuthEnabled(bool enabled)
|
||||
setValue("Preferences/WebUI/LocalHostAuth", enabled);
|
||||
}
|
||||
|
||||
bool Preferences::isWebUiAuthSubnetWhitelistEnabled() const
|
||||
{
|
||||
return value("Preferences/WebUI/AuthSubnetWhitelistEnabled", false).toBool();
|
||||
}
|
||||
|
||||
void Preferences::setWebUiAuthSubnetWhitelistEnabled(bool enabled)
|
||||
{
|
||||
setValue("Preferences/WebUI/AuthSubnetWhitelistEnabled", enabled);
|
||||
}
|
||||
|
||||
QList<Utils::Net::Subnet> Preferences::getWebUiAuthSubnetWhitelist() const
|
||||
{
|
||||
QList<Utils::Net::Subnet> subnets;
|
||||
foreach (const QString &rawSubnet, value("Preferences/WebUI/AuthSubnetWhitelist").toStringList()) {
|
||||
bool ok = false;
|
||||
const Utils::Net::Subnet subnet = Utils::Net::parseSubnet(rawSubnet.trimmed(), &ok);
|
||||
if (ok)
|
||||
subnets.append(subnet);
|
||||
}
|
||||
|
||||
return subnets;
|
||||
}
|
||||
|
||||
void Preferences::setWebUiAuthSubnetWhitelist(const QList<Utils::Net::Subnet> &subnets)
|
||||
{
|
||||
QStringList subnetsStringList;
|
||||
for (const Utils::Net::Subnet &subnet : subnets)
|
||||
subnetsStringList.append(Utils::Net::subnetToString(subnet));
|
||||
|
||||
setValue("Preferences/WebUI/AuthSubnetWhitelist", subnetsStringList);
|
||||
}
|
||||
|
||||
QString Preferences::getServerDomains() const
|
||||
{
|
||||
return value("Preferences/WebUI/ServerDomains", "*").toString();
|
||||
|
||||
@@ -33,15 +33,18 @@
|
||||
#ifndef PREFERENCES_H
|
||||
#define PREFERENCES_H
|
||||
|
||||
#include <QTime>
|
||||
#include <QDateTime>
|
||||
#include <QHostAddress>
|
||||
#include <QList>
|
||||
#include <QSize>
|
||||
#include <QTimer>
|
||||
#include <QReadWriteLock>
|
||||
#include <QNetworkCookie>
|
||||
#include <QReadWriteLock>
|
||||
#include <QSize>
|
||||
#include <QStringList>
|
||||
#include <QTime>
|
||||
#include <QTimer>
|
||||
#include <QVariant>
|
||||
|
||||
#include "base/utils/net.h"
|
||||
#include "types.h"
|
||||
|
||||
enum scheduler_days
|
||||
@@ -170,10 +173,9 @@ public:
|
||||
bool isSearchEnabled() const;
|
||||
void setSearchEnabled(bool enabled);
|
||||
|
||||
// HTTP Server
|
||||
bool isWebUiEnabled() const;
|
||||
void setWebUiEnabled(bool enabled);
|
||||
bool isWebUiLocalAuthEnabled() const;
|
||||
void setWebUiLocalAuthEnabled(bool enabled);
|
||||
QString getServerDomains() const;
|
||||
void setServerDomains(const QString &str);
|
||||
QString getWebUiAddress() const;
|
||||
@@ -182,16 +184,28 @@ public:
|
||||
void setWebUiPort(quint16 port);
|
||||
bool useUPnPForWebUIPort() const;
|
||||
void setUPnPForWebUIPort(bool enabled);
|
||||
|
||||
// Authentication
|
||||
bool isWebUiLocalAuthEnabled() const;
|
||||
void setWebUiLocalAuthEnabled(bool enabled);
|
||||
bool isWebUiAuthSubnetWhitelistEnabled() const;
|
||||
void setWebUiAuthSubnetWhitelistEnabled(bool enabled);
|
||||
QList<Utils::Net::Subnet> getWebUiAuthSubnetWhitelist() const;
|
||||
void setWebUiAuthSubnetWhitelist(const QList<Utils::Net::Subnet> &subnets);
|
||||
QString getWebUiUsername() const;
|
||||
void setWebUiUsername(const QString &username);
|
||||
QString getWebUiPassword() const;
|
||||
void setWebUiPassword(const QString &new_password);
|
||||
|
||||
// HTTPS
|
||||
bool isWebUiHttpsEnabled() const;
|
||||
void setWebUiHttpsEnabled(bool enabled);
|
||||
QByteArray getWebUiHttpsCertificate() const;
|
||||
void setWebUiHttpsCertificate(const QByteArray &data);
|
||||
QByteArray getWebUiHttpsKey() const;
|
||||
void setWebUiHttpsKey(const QByteArray &data);
|
||||
|
||||
// Dynamic DNS
|
||||
bool isDynDNSEnabled() const;
|
||||
void setDynDNSEnabled(bool enabled);
|
||||
DNS::Service getDynDNSService() const;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "net.h"
|
||||
#include <QHostAddress>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
@@ -38,5 +39,55 @@ namespace Utils
|
||||
{
|
||||
return !QHostAddress(ip).isNull();
|
||||
}
|
||||
|
||||
Subnet parseSubnet(const QString &subnetStr, bool *ok)
|
||||
{
|
||||
const Subnet invalid = qMakePair(QHostAddress(), -1);
|
||||
const Subnet subnet = QHostAddress::parseSubnet(subnetStr);
|
||||
if (ok)
|
||||
*ok = (subnet != invalid);
|
||||
return subnet;
|
||||
}
|
||||
|
||||
bool canParseSubnet(const QString &subnetStr)
|
||||
{
|
||||
bool ok = false;
|
||||
parseSubnet(subnetStr, &ok);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool isLoopbackAddress(const QHostAddress &addr)
|
||||
{
|
||||
return (addr == QHostAddress::LocalHost)
|
||||
|| (addr == QHostAddress::LocalHostIPv6)
|
||||
|| (addr == QHostAddress(QLatin1String("::ffff:127.0.0.1")));
|
||||
}
|
||||
|
||||
bool isIPInRange(const QHostAddress &addr, const QList<Subnet> &subnets)
|
||||
{
|
||||
QHostAddress protocolEquivalentAddress;
|
||||
bool addrConversionOk = false;
|
||||
|
||||
if (addr.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||
// always succeeds
|
||||
protocolEquivalentAddress = QHostAddress(addr.toIPv6Address());
|
||||
addrConversionOk = true;
|
||||
}
|
||||
else {
|
||||
// only succeeds when addr is an ipv4-mapped ipv6 address
|
||||
protocolEquivalentAddress = QHostAddress(addr.toIPv4Address(&addrConversionOk));
|
||||
}
|
||||
|
||||
for (const Subnet &subnet : subnets)
|
||||
if (addr.isInSubnet(subnet) || (addrConversionOk && protocolEquivalentAddress.isInSubnet(subnet)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString subnetToString(const Subnet &subnet)
|
||||
{
|
||||
return subnet.first.toString() + '/' + QString::number(subnet.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,13 +28,26 @@
|
||||
|
||||
#ifndef BASE_UTILS_NET_H
|
||||
#define BASE_UTILS_NET_H
|
||||
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
|
||||
class QHostAddress;
|
||||
class QString;
|
||||
class QStringList;
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
namespace Net
|
||||
{
|
||||
using Subnet = QPair<QHostAddress, int>;
|
||||
|
||||
bool isValidIP(const QString &ip);
|
||||
Subnet parseSubnet(const QString &subnetStr, bool *ok = nullptr);
|
||||
bool canParseSubnet(const QString &subnetStr);
|
||||
bool isLoopbackAddress(const QHostAddress &addr);
|
||||
bool isIPInRange(const QHostAddress &addr, const QList<Subnet> &subnets);
|
||||
QString subnetToString(const Subnet &subnet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user