mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 19:55:07 +02:00
Merge pull request #9053 from huffman/feat/whitelist-ac-ip
Add AC ip address whitelist to domain server
This commit is contained in:
commit
e38da75115
5 changed files with 79 additions and 3 deletions
|
@ -388,6 +388,23 @@
|
|||
"default": "",
|
||||
"advanced": false
|
||||
},
|
||||
{
|
||||
"name": "ac_subnet_whitelist",
|
||||
"label": "Assignment Client IP address Whitelist",
|
||||
"type": "table",
|
||||
"can_add_new_rows": true,
|
||||
"help": "The IP addresses or subnets of ACs that can connect to this server. You can specify an IP address or a subnet in CIDR notation ('A.B.C.D/E', Example: '10.0.0.0/24'). Local ACs (localhost) are always permitted and do not need to be added here.",
|
||||
"numbered": false,
|
||||
"advanced": true,
|
||||
"columns": [
|
||||
{
|
||||
"name": "ip",
|
||||
"label": "IP Address",
|
||||
"type": "ip",
|
||||
"can_set": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "standard_permissions",
|
||||
"type": "table",
|
||||
|
|
|
@ -158,6 +158,42 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
|
||||
|
||||
qDebug() << "domain-server is running";
|
||||
static const QString AC_SUBNET_WHITELIST_SETTING_PATH = "security.ac_subnet_whitelist";
|
||||
|
||||
static const Subnet LOCALHOST { QHostAddress("127.0.0.1"), 32 };
|
||||
_acSubnetWhitelist = { LOCALHOST };
|
||||
|
||||
auto whitelist = _settingsManager.valueOrDefaultValueForKeyPath(AC_SUBNET_WHITELIST_SETTING_PATH).toStringList();
|
||||
for (auto& subnet : whitelist) {
|
||||
auto netmaskParts = subnet.trimmed().split("/");
|
||||
|
||||
if (netmaskParts.size() > 2) {
|
||||
qDebug() << "Ignoring subnet in whitelist, malformed: " << subnet;
|
||||
continue;
|
||||
}
|
||||
|
||||
// The default netmask is 32 if one has not been specified, which will
|
||||
// match only the ip provided.
|
||||
int netmask = 32;
|
||||
|
||||
if (netmaskParts.size() == 2) {
|
||||
bool ok;
|
||||
netmask = netmaskParts[1].toInt(&ok);
|
||||
if (!ok) {
|
||||
qDebug() << "Ignoring subnet in whitelist, bad netmask: " << subnet;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto ip = QHostAddress(netmaskParts[0]);
|
||||
|
||||
if (!ip.isNull()) {
|
||||
qDebug() << "Adding AC whitelist subnet: " << subnet << " -> " << (ip.toString() + "/" + QString::number(netmask));
|
||||
_acSubnetWhitelist.push_back({ ip , netmask });
|
||||
} else {
|
||||
qDebug() << "Ignoring subnet in whitelist, invalid ip portion: " << subnet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DomainServer::parseCommandLine() {
|
||||
|
@ -1001,6 +1037,21 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointer<ReceivedMessage
|
|||
// construct the requested assignment from the packet data
|
||||
Assignment requestAssignment(*message);
|
||||
|
||||
auto senderAddr = message->getSenderSockAddr().getAddress();
|
||||
|
||||
auto isHostAddressInSubnet = [&senderAddr](const Subnet& mask) -> bool {
|
||||
return senderAddr.isInSubnet(mask);
|
||||
};
|
||||
|
||||
auto it = find_if(_acSubnetWhitelist.begin(), _acSubnetWhitelist.end(), isHostAddressInSubnet);
|
||||
if (it == _acSubnetWhitelist.end()) {
|
||||
static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex(
|
||||
"Received an assignment connect request from a disallowed ip address: [^ ]+");
|
||||
qDebug() << "Received an assignment connect request from a disallowed ip address:"
|
||||
<< senderAddr.toString();
|
||||
return;
|
||||
}
|
||||
|
||||
// Suppress these for Assignment::AgentType to once per 5 seconds
|
||||
static QElapsedTimer noisyMessageTimer;
|
||||
static bool wasNoisyTimerStarted = false;
|
||||
|
|
|
@ -36,6 +36,9 @@
|
|||
typedef QSharedPointer<Assignment> SharedAssignmentPointer;
|
||||
typedef QMultiHash<QUuid, WalletTransaction*> TransactionHash;
|
||||
|
||||
using Subnet = QPair<QHostAddress, int>;
|
||||
using SubnetList = std::vector<Subnet>;
|
||||
|
||||
class DomainServer : public QCoreApplication, public HTTPSRequestHandler {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -156,6 +159,8 @@ private:
|
|||
|
||||
void setupGroupCacheRefresh();
|
||||
|
||||
SubnetList _acSubnetWhitelist;
|
||||
|
||||
DomainGatekeeper _gatekeeper;
|
||||
|
||||
HTTPManager _httpManager;
|
||||
|
|
|
@ -1077,6 +1077,9 @@ QJsonObject DomainServerSettingsManager::settingDescriptionFromGroup(const QJson
|
|||
}
|
||||
|
||||
bool DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject) {
|
||||
static const QString SECURITY_ROOT_KEY = "security";
|
||||
static const QString AC_SUBNET_WHITELIST_KEY = "ac_subnet_whitelist";
|
||||
|
||||
auto& settingsVariant = _configMap.getConfig();
|
||||
bool needRestart = false;
|
||||
|
||||
|
@ -1127,7 +1130,7 @@ bool DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJ
|
|||
|
||||
if (!matchingDescriptionObject.isEmpty()) {
|
||||
updateSetting(rootKey, rootValue, *thisMap, matchingDescriptionObject);
|
||||
if (rootKey != "security") {
|
||||
if (rootKey != SECURITY_ROOT_KEY) {
|
||||
needRestart = true;
|
||||
}
|
||||
} else {
|
||||
|
@ -1143,7 +1146,7 @@ bool DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJ
|
|||
if (!matchingDescriptionObject.isEmpty()) {
|
||||
QJsonValue settingValue = rootValue.toObject()[settingKey];
|
||||
updateSetting(settingKey, settingValue, *thisMap, matchingDescriptionObject);
|
||||
if (rootKey != "security") {
|
||||
if (rootKey != SECURITY_ROOT_KEY || settingKey == AC_SUBNET_WHITELIST_KEY) {
|
||||
needRestart = true;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -226,5 +226,5 @@ QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath, bool
|
|||
shouldCreateIfMissing);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue