Add ip subnet whitelist for bypassing webui auth

This commit is contained in:
Thomas Piccirello
2017-09-27 13:55:20 -04:00
parent 04cec39277
commit 95bf63330e
15 changed files with 504 additions and 20 deletions

View File

@@ -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();

View File

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

View File

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

View File

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