From 4bf6e58511562ac699fdc8dc985916d0fcb17094 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 12 Mar 2023 03:45:49 +0100 Subject: [PATCH] Evaluate ACLs when calculating vias --- CMakeLists.txt | 2 +- io.github.NhekoReborn.Nheko.yaml | 2 +- src/Utils.cpp | 54 ++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 490136d3..dc5fe4fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -598,7 +598,7 @@ if(USE_BUNDLED_MTXCLIENT) FetchContent_Declare( MatrixClient GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git - GIT_TAG e1a24f3752543d4264cb012a20d84fc9d7229709 + GIT_TAG c8849cd033bb59bee39f3fb2eaca953853731eb2 ) set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_TESTS OFF CACHE INTERNAL "") diff --git a/io.github.NhekoReborn.Nheko.yaml b/io.github.NhekoReborn.Nheko.yaml index 4eefd87b..3bcfdf52 100644 --- a/io.github.NhekoReborn.Nheko.yaml +++ b/io.github.NhekoReborn.Nheko.yaml @@ -213,7 +213,7 @@ modules: buildsystem: cmake-ninja name: mtxclient sources: - - commit: e1a24f3752543d4264cb012a20d84fc9d7229709 + - commit: c8849cd033bb59bee39f3fb2eaca953853731eb2 #tag: v0.9.2 type: git url: https://github.com/Nheko-Reborn/mtxclient.git diff --git a/src/Utils.cpp b/src/Utils.cpp index 2a0c4673..54bd51ab 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -1273,6 +1273,51 @@ utils::roomVias(const std::string &roomid) auto powerlevels = cache::client()->getStateEvent(roomid).value_or( mtx::events::StateEvent{}); + auto acls = cache::client()->getStateEvent(roomid); + + std::vector allowedServers; + std::vector deniedServers; + + if (acls) { + auto globToRegexp = [](const std::string &globExp) { + auto rawReg = QRegularExpression::escape(QString::fromStdString(globExp)) + .replace("\\*", ".*") + .replace("\\?", "."); + return QRegularExpression(QRegularExpression::anchoredPattern(rawReg), + QRegularExpression::DotMatchesEverythingOption | + QRegularExpression::DontCaptureOption); + }; + + allowedServers.reserve(acls->content.allow.size()); + for (const auto &s : acls->content.allow) + allowedServers.push_back(globToRegexp(s)); + deniedServers.reserve(acls->content.deny.size()); + for (const auto &s : acls->content.deny) + allowedServers.push_back(globToRegexp(s)); + + nhlog::ui()->critical("ACL: {}", nlohmann::json(acls->content).dump(2)); + } + + auto isHostAllowed = [&acls, &allowedServers, &deniedServers](const std::string &host) { + if (!acls) + return true; + + auto url = QUrl::fromEncoded( + "https://" + QByteArray::fromRawData(host.data(), host.size()), QUrl::StrictMode); + if (url.hasQuery() || url.hasFragment()) + return false; + + auto hostname = url.host(); + + for (const auto &d : deniedServers) + if (d.match(hostname).hasMatch()) + return false; + for (const auto &a : allowedServers) + if (a.match(hostname).hasMatch()) + return true; + + return false; + }; std::unordered_set users_with_high_pl; std::set users_with_high_pl_in_room; @@ -1281,7 +1326,10 @@ utils::roomVias(const std::string &roomid) for (const auto &user : powerlevels.content.users) { if (user.second >= powerlevels.content.events_default && user.second >= powerlevels.content.state_default) { - users_with_high_pl.insert(user.first); + auto host = + mtx::identifiers::parse(user.first).hostname(); + if (isHostAllowed(host)) + users_with_high_pl.insert(user.first); } } @@ -1294,7 +1342,9 @@ utils::roomVias(const std::string &roomid) users_with_high_pl_in_room.insert(m); } - // TODO(Nico): remove acled servers + std::erase_if(usercount_by_server, [&isHostAllowed](const auto &item) { + return !isHostAllowed(item.first); + }); // add the highest powerlevel user auto max_pl_user = std::max_element(