diff --git a/mythtv/libs/libmythbase/mythcorecontext.cpp b/mythtv/libs/libmythbase/mythcorecontext.cpp index dc73495439d..d52618d2ead 100644 --- a/mythtv/libs/libmythbase/mythcorecontext.cpp +++ b/mythtv/libs/libmythbase/mythcorecontext.cpp @@ -1268,6 +1268,8 @@ QString MythCoreContext::resolveAddress(const QString &host, ResolveType type, * There is a setting called AllowConnFromAll. If it is * true, then no check needs to be done. If false, check that * the connection comes from a subnet to which I am connected. + * If again false, check if the connection comes from a subnet + * listed in the AllowConnFromSubnets setting. * * \param socket in Socket to check. * \return true if the connection is allowed, false if not. @@ -1285,6 +1287,8 @@ bool MythCoreContext::CheckSubnet(const QAbstractSocket *socket) * There is a setting called AllowConnFromAll. If it is * true, then no check needs to be done. If false, check that * the connection comes from a subnet to which I am connected. + * If again false, check if the connection comes from a subnet + * listed in the AllowConnFromSubnets setting. * * \param peer in Host Address to check. * \return true if the connection is allowed, false if not. @@ -1334,6 +1338,17 @@ bool MythCoreContext::CheckSubnet(const QHostAddress &peer) } } } + + // check AllowConnFromSubnets + for (const auto &subnet : allowedSubnets()) + { + if (peer.isInSubnet(subnet.first, subnet.second)) + { + d->m_approvedIps.append(peer); + return true; + } + } + d->m_deniedIps.append(peer); LOG(VB_GENERAL, LOG_WARNING, LOC + QString("Denied connection from ip address: %1") @@ -1341,6 +1356,22 @@ bool MythCoreContext::CheckSubnet(const QHostAddress &peer) return false; } +QList> MythCoreContext::allowedSubnets() +{ + QList> subnets{}; + + auto subnetList = GetSetting("AllowConnFromSubnets", ""); + if (subnetList == "") + return subnets; + + for (const auto &subnet : subnetList.split(";")) + { + const auto parsed = QHostAddress::parseSubnet(subnet); + subnets.append(parsed); + } + + return subnets; +} void MythCoreContext::OverrideSettingForSession(const QString &key, const QString &value) diff --git a/mythtv/libs/libmythbase/mythcorecontext.h b/mythtv/libs/libmythbase/mythcorecontext.h index 62e9c2a27aa..cc0e6f52736 100644 --- a/mythtv/libs/libmythbase/mythcorecontext.h +++ b/mythtv/libs/libmythbase/mythcorecontext.h @@ -316,6 +316,8 @@ class MBASE_PUBLIC MythCoreContext : public QObject, public MythObservable, publ void connectionClosed(MythSocket *sock) override; // MythSocketCBs void readyRead(MythSocket *sock) override; // MythSocketCBs + QList> allowedSubnets(); + QMap m_testOverrideInts {}; QMap m_testOverrideFloats {}; QMap m_testOverrideStrings {}; diff --git a/mythtv/programs/mythtv-setup/backendsettings.cpp b/mythtv/programs/mythtv-setup/backendsettings.cpp index ed8cc0c6ed5..58b7b52e20a 100644 --- a/mythtv/programs/mythtv-setup/backendsettings.cpp +++ b/mythtv/programs/mythtv-setup/backendsettings.cpp @@ -49,6 +49,19 @@ static HostCheckBoxSetting *AllowConnFromAll() return gc; }; +static HostTextEditSetting *AllowConnFromSubnets() +{ + auto *gc = new HostTextEditSetting("AllowConnFromSubnets"); + gc->setLabel(QObject::tr("Allow Connections from specific Subnets")); + gc->setValue(""); + gc->setHelpText(QObject::tr( + "Allow this backend to receive connections from subnets " + "other than the ones available directly on the host's " + "interfaces. Each subnet is in `network/prefix-length` " + "form separated by semi-colons.")); + return gc; +} + static HostComboBoxSetting *LocalServerIP() { auto *gc = new HostComboBoxSetting("BackendServerIP"); @@ -889,7 +902,12 @@ BackendSettings::BackendSettings() server->addChild(m_localServerPort); server->addChild(LocalStatusPort()); server->addChild(LocalSecurityPin()); - server->addChild(AllowConnFromAll()); + m_allowConnFromAll = AllowConnFromAll(); + server->addChild(m_allowConnFromAll); + m_allowConnFromSubnets = AllowConnFromSubnets(); + server->addChild(m_allowConnFromSubnets); + connect(m_allowConnFromAll, qOverload(&HostCheckBoxSetting::valueChanged), + this, &BackendSettings::allowConnFromAllChanged); //+++ IP Addresses +++ m_ipAddressSettings = new IpAddressSettings(); server->addChild(m_ipAddressSettings); @@ -1089,6 +1107,13 @@ void BackendSettings::listenChanged() m_backendServerAddr->setChanged(addrChanged); } +void BackendSettings::allowConnFromAllChanged(bool allowAll) + { + if (!m_isLoaded) + return; + // Field is enabled if allowFromAll is disabled + m_allowConnFromSubnets->setEnabled(!allowAll); + } void BackendSettings::Load(void) { diff --git a/mythtv/programs/mythtv-setup/backendsettings.h b/mythtv/programs/mythtv-setup/backendsettings.h index 52a2748627f..971323bc98b 100644 --- a/mythtv/programs/mythtv-setup/backendsettings.h +++ b/mythtv/programs/mythtv-setup/backendsettings.h @@ -19,6 +19,8 @@ class BackendSettings : public GroupSetting HostComboBoxSetting *m_backendServerAddr {nullptr}; GlobalTextEditSetting *m_masterServerName {nullptr}; IpAddressSettings *m_ipAddressSettings {nullptr}; + HostCheckBoxSetting *m_allowConnFromAll {nullptr}; + HostTextEditSetting *m_allowConnFromSubnets {nullptr}; bool m_isLoaded {false}; QString m_priorMasterName; @@ -29,6 +31,7 @@ class BackendSettings : public GroupSetting private slots: void masterBackendChanged(void); void listenChanged(void); + void allowConnFromAllChanged(bool); }; #endif