From eeddaa988a252d1fdb8aeb5a259c457c393a279e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 25 Aug 2021 20:02:10 +0200 Subject: ConfigServer+LibConfig: Add pledge_domains() API This API lets applications specify which configuration domains they will be accessing throughout their lifetime. It works similarly in spirit to the kernel's pledge(). You cannot pledge_domains() more than once, and once you have used it, it's no longer possible to access any other configuration domain. This is obviously just a first cut of this mechanism, and we may need to tweak it further as we go. --- .../Services/ConfigServer/ClientConnection.cpp | 39 ++++++++++++++++++++++ Userland/Services/ConfigServer/ClientConnection.h | 6 ++++ Userland/Services/ConfigServer/ConfigServer.ipc | 2 ++ 3 files changed, 47 insertions(+) (limited to 'Userland/Services/ConfigServer') diff --git a/Userland/Services/ConfigServer/ClientConnection.cpp b/Userland/Services/ConfigServer/ClientConnection.cpp index e55879c74c..3551a1af5b 100644 --- a/Userland/Services/ConfigServer/ClientConnection.cpp +++ b/Userland/Services/ConfigServer/ClientConnection.cpp @@ -27,8 +27,32 @@ void ClientConnection::die() s_connections.remove(client_id()); } +void ClientConnection::pledge_domains(Vector const& domains) +{ + if (m_has_pledged) { + did_misbehave("Tried to pledge domains twice."); + return; + } + m_has_pledged = true; + for (auto& domain : domains) + m_pledged_domains.set(domain); +} + +bool ClientConnection::validate_access(String const& domain, String const& group, String const& key) +{ + if (!m_has_pledged) + return true; + if (m_pledged_domains.contains(domain)) + return true; + did_misbehave(String::formatted("Blocked attempt to access domain '{}', group={}, key={}", domain, group, key).characters()); + return false; +} + Messages::ConfigServer::ReadStringValueResponse ClientConnection::read_string_value(String const& domain, String const& group, String const& key) { + if (!validate_access(domain, group, key)) + return nullptr; + auto config = Core::ConfigFile::open_for_app(domain); if (!config->has_key(group, key)) return Optional {}; @@ -37,6 +61,9 @@ Messages::ConfigServer::ReadStringValueResponse ClientConnection::read_string_va Messages::ConfigServer::ReadI32ValueResponse ClientConnection::read_i32_value(String const& domain, String const& group, String const& key) { + if (!validate_access(domain, group, key)) + return nullptr; + auto config = Core::ConfigFile::open_for_app(domain); if (!config->has_key(group, key)) return Optional {}; @@ -45,6 +72,9 @@ Messages::ConfigServer::ReadI32ValueResponse ClientConnection::read_i32_value(St Messages::ConfigServer::ReadBoolValueResponse ClientConnection::read_bool_value(String const& domain, String const& group, String const& key) { + if (!validate_access(domain, group, key)) + return nullptr; + auto config = Core::ConfigFile::open_for_app(domain); if (!config->has_key(group, key)) return Optional {}; @@ -53,18 +83,27 @@ Messages::ConfigServer::ReadBoolValueResponse ClientConnection::read_bool_value( void ClientConnection::write_string_value(String const& domain, String const& group, String const& key, String const& value) { + if (!validate_access(domain, group, key)) + return; + auto config = Core::ConfigFile::open_for_app(domain, Core::ConfigFile::AllowWriting::Yes); config->write_entry(group, key, value); } void ClientConnection::write_i32_value(String const& domain, String const& group, String const& key, i32 value) { + if (!validate_access(domain, group, key)) + return; + auto config = Core::ConfigFile::open_for_app(domain, Core::ConfigFile::AllowWriting::Yes); config->write_num_entry(group, key, value); } void ClientConnection::write_bool_value(String const& domain, String const& group, String const& key, bool value) { + if (!validate_access(domain, group, key)) + return; + auto config = Core::ConfigFile::open_for_app(domain, Core::ConfigFile::AllowWriting::Yes); config->write_bool_entry(group, key, value); } diff --git a/Userland/Services/ConfigServer/ClientConnection.h b/Userland/Services/ConfigServer/ClientConnection.h index df41d9647e..cdbc53ab64 100644 --- a/Userland/Services/ConfigServer/ClientConnection.h +++ b/Userland/Services/ConfigServer/ClientConnection.h @@ -23,12 +23,18 @@ public: private: explicit ClientConnection(NonnullRefPtr, int client_id); + virtual void pledge_domains(Vector const&) override; virtual Messages::ConfigServer::ReadStringValueResponse read_string_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key) override; virtual Messages::ConfigServer::ReadI32ValueResponse read_i32_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key) override; virtual Messages::ConfigServer::ReadBoolValueResponse read_bool_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key) override; virtual void write_string_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key, [[maybe_unused]] String const& value) override; virtual void write_i32_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key, [[maybe_unused]] i32 value) override; virtual void write_bool_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key, [[maybe_unused]] bool value) override; + + bool validate_access(String const& domain, String const& group, String const& key); + + bool m_has_pledged { false }; + HashTable m_pledged_domains; }; } diff --git a/Userland/Services/ConfigServer/ConfigServer.ipc b/Userland/Services/ConfigServer/ConfigServer.ipc index 7c0b725870..9ce1bbc70a 100644 --- a/Userland/Services/ConfigServer/ConfigServer.ipc +++ b/Userland/Services/ConfigServer/ConfigServer.ipc @@ -1,5 +1,7 @@ endpoint ConfigServer { + pledge_domains(Vector domains) =| + read_string_value(String domain, String group, String key) => (Optional value) read_i32_value(String domain, String group, String key) => (Optional value) read_bool_value(String domain, String group, String key) => (Optional value) -- cgit v1.2.3