diff --git a/Libraries/LibDesktop/Launcher.cpp b/Libraries/LibDesktop/Launcher.cpp index e2abbf0445..740756c9bf 100644 --- a/Libraries/LibDesktop/Launcher.cpp +++ b/Libraries/LibDesktop/Launcher.cpp @@ -72,10 +72,45 @@ private: virtual void handle(const Messages::LaunchClient::Dummy&) override { } }; +static LaunchServerConnection& connection() +{ + static auto connection = LaunchServerConnection::construct(); + return connection; +} + +bool Launcher::add_allowed_handler_with_any_url(const String& handler) +{ + auto response = connection().send_sync(handler); + if (!response) { + dbgln("Launcher::add_allowed_handler_with_any_url: Failed"); + return false; + } + return true; +} + +bool Launcher::add_allowed_handler_with_only_specific_urls(const String& handler, const Vector& urls) +{ + auto response = connection().send_sync(handler, urls); + if (!response) { + dbgln("Launcher::add_allowed_handler_with_only_specific_urls: Failed"); + return false; + } + return true; +} + +bool Launcher::seal_allowed_handler_list() +{ + auto response = connection().send_sync(); + if (!response) { + dbgln("Launcher::seal_allowed_handler_list: Failed"); + return false; + } + return true; +} + bool Launcher::open(const URL& url, const String& handler_name) { - auto connection = LaunchServerConnection::construct(); - return connection->send_sync(url, handler_name)->response(); + return connection().send_sync(url, handler_name)->response(); } bool Launcher::open(const URL& url, const Details& details) @@ -86,14 +121,12 @@ bool Launcher::open(const URL& url, const Details& details) Vector Launcher::get_handlers_for_url(const URL& url) { - auto connection = LaunchServerConnection::construct(); - return connection->send_sync(url.to_string())->handlers(); + return connection().send_sync(url.to_string())->handlers(); } auto Launcher::get_handlers_with_details_for_url(const URL& url) -> NonnullRefPtrVector
{ - auto connection = LaunchServerConnection::construct(); - auto details = connection->send_sync(url.to_string())->handlers_details(); + auto details = connection().send_sync(url.to_string())->handlers_details(); NonnullRefPtrVector
handlers_with_details; for (auto& value : details) { handlers_with_details.append(Details::from_details_str(value)); diff --git a/Libraries/LibDesktop/Launcher.h b/Libraries/LibDesktop/Launcher.h index 73a23a98f7..d8412f3ec7 100644 --- a/Libraries/LibDesktop/Launcher.h +++ b/Libraries/LibDesktop/Launcher.h @@ -51,6 +51,9 @@ public: static NonnullRefPtr
from_details_str(const String&); }; + [[nodiscard]] static bool add_allowed_handler_with_any_url(const String& handler); + [[nodiscard]] static bool add_allowed_handler_with_only_specific_urls(const String& handler, const Vector&); + [[nodiscard]] static bool seal_allowed_handler_list(); static bool open(const URL&, const String& handler_name = {}); static bool open(const URL&, const Details& details); static Vector get_handlers_for_url(const URL&); diff --git a/Services/LaunchServer/ClientConnection.cpp b/Services/LaunchServer/ClientConnection.cpp index 69d1523d2a..5c2fbe86be 100644 --- a/Services/LaunchServer/ClientConnection.cpp +++ b/Services/LaunchServer/ClientConnection.cpp @@ -55,6 +55,22 @@ OwnPtr ClientConnection::handle(const Mes OwnPtr ClientConnection::handle(const Messages::LaunchServer::OpenURL& request) { + if (!m_allowed_handlers.is_empty()) { + bool allowed = false; + for (auto& allowed_handler : m_allowed_handlers) { + if (allowed_handler.handler_name == request.handler_name() + && (allowed_handler.any_url || allowed_handler.urls.contains_slow(request.url()))) { + allowed = true; + break; + } + } + if (!allowed) { + // You are not on the list, go home! + did_misbehave(String::formatted("Client requested a combination of handler/URL that was not on the list: '{}' with '{}'", request.handler_name(), request.url()).characters()); + return nullptr; + } + } + URL url(request.url()); auto result = Launcher::the().open_url(url, request.handler_name()); return make(result); @@ -74,4 +90,53 @@ OwnPtr ClientConne return make(result); } +OwnPtr ClientConnection::handle(const Messages::LaunchServer::AddAllowedHandlerWithAnyURL& request) +{ + if (m_allowed_handler_list_is_sealed) { + did_misbehave("Got request to add more allowed handlers after list was sealed"); + return nullptr; + } + + if (request.handler_name().is_empty()) { + did_misbehave("Got request to allow empty handler name"); + return nullptr; + } + + m_allowed_handlers.empend(request.handler_name(), true, Vector()); + + return make(); +} + +OwnPtr ClientConnection::handle(const Messages::LaunchServer::AddAllowedHandlerWithOnlySpecificURLs& request) +{ + if (m_allowed_handler_list_is_sealed) { + did_misbehave("Got request to add more allowed handlers after list was sealed"); + return nullptr; + } + + if (request.handler_name().is_empty()) { + did_misbehave("Got request to allow empty handler name"); + return nullptr; + } + + if (request.urls().is_empty()) { + did_misbehave("Got request to allow empty URL list"); + return nullptr; + } + + m_allowed_handlers.empend(request.handler_name(), false, request.urls()); + + return make(); +} + +OwnPtr ClientConnection::handle(const Messages::LaunchServer::SealAllowedHandlersList&) +{ + if (m_allowed_handler_list_is_sealed) { + did_misbehave("Got more than one request to seal the allowed handlers list"); + return nullptr; + } + + return make(); +} + } diff --git a/Services/LaunchServer/ClientConnection.h b/Services/LaunchServer/ClientConnection.h index ab3d31bdad..9f7c7d2bb5 100644 --- a/Services/LaunchServer/ClientConnection.h +++ b/Services/LaunchServer/ClientConnection.h @@ -47,5 +47,17 @@ private: virtual OwnPtr handle(const Messages::LaunchServer::OpenURL&) override; virtual OwnPtr handle(const Messages::LaunchServer::GetHandlersForURL&) override; virtual OwnPtr handle(const Messages::LaunchServer::GetHandlersWithDetailsForURL&) override; + virtual OwnPtr handle(const Messages::LaunchServer::AddAllowedHandlerWithAnyURL&) override; + virtual OwnPtr handle(const Messages::LaunchServer::AddAllowedHandlerWithOnlySpecificURLs&) override; + virtual OwnPtr handle(const Messages::LaunchServer::SealAllowedHandlersList&) override; + + struct AllowedHandler { + String handler_name; + bool any_url { false }; + Vector urls; + }; + + Vector m_allowed_handlers; + bool m_allowed_handler_list_is_sealed { false }; }; } diff --git a/Services/LaunchServer/LaunchServer.ipc b/Services/LaunchServer/LaunchServer.ipc index f6871ef0a8..154198f1d2 100644 --- a/Services/LaunchServer/LaunchServer.ipc +++ b/Services/LaunchServer/LaunchServer.ipc @@ -4,4 +4,8 @@ endpoint LaunchServer = 101 OpenURL(URL url, String handler_name) => (bool response) GetHandlersForURL(URL url) => (Vector handlers) GetHandlersWithDetailsForURL(URL url) => (Vector handlers_details) + + AddAllowedHandlerWithAnyURL(String handler_name) => () + AddAllowedHandlerWithOnlySpecificURLs(String handler_name, Vector urls) => () + SealAllowedHandlersList() => () }