diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2025-04-29 18:59:43 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-29 18:59:43 +0200 |
| commit | 5bd7ff884dc613ad22ecd227d41ce6ad7ee336df (patch) | |
| tree | 63696482d6ca82db0f123ed53ce798ba500b7c44 /src/debug/HyprCtl.cpp | |
| parent | 21184404885cf61f7c10d2eb749478ef6b035dd2 (diff) | |
permissions: add perms for plugin loading (#10184)
Adds permission management for loading plugins
---------
Co-authored-by: Jan Beich <jbeich@FreeBSD.org>
Diffstat (limited to 'src/debug/HyprCtl.cpp')
| -rw-r--r-- | src/debug/HyprCtl.cpp | 91 |
1 files changed, 75 insertions, 16 deletions
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index 762f5d84..49325887 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -17,6 +17,7 @@ #include <sys/poll.h> #include <filesystem> #include <ranges> +#include <sys/eventfd.h> #include <sstream> #include <string> @@ -24,6 +25,7 @@ #include <numeric> #include <hyprutils/string/String.hpp> +#include <hyprutils/os/FileDescriptor.hpp> using namespace Hyprutils::String; using namespace Hyprutils::OS; #include <aquamarine/input/Input.hpp> @@ -53,6 +55,28 @@ using namespace Hyprutils::OS; #include "../render/Renderer.hpp" #include "../render/OpenGL.hpp" +#if defined(__DragonFly__) || defined(__FreeBSD__) +#include <sys/ucred.h> +#define CRED_T xucred +#define CRED_LVL SOL_LOCAL +#define CRED_OPT LOCAL_PEERCRED +#define CRED_PID cr_pid +#elif defined(__NetBSD__) +#define CRED_T unpcbid +#define CRED_LVL SOL_LOCAL +#define CRED_OPT LOCAL_PEEREID +#define CRED_PID unp_pid +#else +#if defined(__OpenBSD__) +#define CRED_T sockpeercred +#else +#define CRED_T ucred +#endif +#define CRED_LVL SOL_SOCKET +#define CRED_OPT SO_PEERCRED +#define CRED_PID pid +#endif + static void trimTrailingComma(std::string& str) { if (!str.empty() && str.back() == ',') str.pop_back(); @@ -1480,10 +1504,18 @@ static std::string dispatchPlugin(eHyprCtlOutputFormat format, std::string reque if (vars.size() < 3) return "not enough args"; - const auto PLUGIN = g_pPluginSystem->loadPlugin(PATH); + g_pHyprCtl->m_currentRequestParams.pendingPromise = CPromise<std::string>::make([PATH](SP<CPromiseResolver<std::string>> resolver) { + g_pPluginSystem->loadPlugin(PATH)->then([resolver, PATH](SP<CPromiseResult<CPlugin*>> result) { + if (result->hasError()) { + resolver->reject(result->error()); + return; + } - if (!PLUGIN) - return "error in loading plugin, last error: " + g_pPluginSystem->m_szLastError; + resolver->resolve("ok"); + }); + }); + + return "ok"; } else if (OPERATION == "unload") { if (vars.size() < 3) return "not enough args"; @@ -1712,9 +1744,10 @@ void CHyprCtl::unregisterCommand(const SP<SHyprCtlCommand>& cmd) { } std::string CHyprCtl::getReply(std::string request) { - auto format = eHyprCtlOutputFormat::FORMAT_NORMAL; - bool reloadAll = false; - m_currentRequestParams = {}; + auto format = eHyprCtlOutputFormat::FORMAT_NORMAL; + bool reloadAll = false; + m_currentRequestParams.all = false; + m_currentRequestParams.sysInfoConfig = false; // process flags for non-batch requests if (!request.starts_with("[[BATCH]]") && request.contains("/")) { @@ -1867,6 +1900,16 @@ static int hyprCtlFDTick(int fd, uint32_t mask, void* data) { std::array<char, 1024> readBuffer; + // try to get creds + CRED_T creds; + uint32_t len = sizeof(creds); + if (getsockopt(ACCEPTEDCONNECTION, CRED_LVL, CRED_OPT, &creds, &len) == -1) + Debug::log(ERR, "Hyprctl: failed to get peer creds"); + else { + g_pHyprCtl->m_currentRequestParams.pid = creds.CRED_PID; + Debug::log(LOG, "Hyprctl: new connection from pid {}", creds.CRED_PID); + } + // pollfd pollfds[1] = { { @@ -1903,18 +1946,34 @@ static int hyprCtlFDTick(int fd, uint32_t mask, void* data) { reply = "Err: " + std::string(e.what()); } - successWrite(ACCEPTEDCONNECTION, reply); + if (g_pHyprCtl->m_currentRequestParams.pendingPromise) { + // we have a promise pending + g_pHyprCtl->m_currentRequestParams.pendingPromise->then([ACCEPTEDCONNECTION, request](SP<CPromiseResult<std::string>> result) { + const auto RES = result->hasError() ? result->error() : result->result(); + successWrite(ACCEPTEDCONNECTION, RES); - if (isFollowUpRollingLogRequest(request)) { - Debug::log(LOG, "Followup rollinglog request received. Starting thread to write to socket."); - Debug::SRollingLogFollow::get().startFor(ACCEPTEDCONNECTION); - runWritingDebugLogThread(ACCEPTEDCONNECTION); - Debug::log(LOG, Debug::SRollingLogFollow::get().debugInfo()); - } else - close(ACCEPTEDCONNECTION); + // No rollinglog or ensureMonitor here. These are only for plugins for now. + + close(ACCEPTEDCONNECTION); + }); - if (g_pConfigManager->m_wantsMonitorReload) - g_pConfigManager->ensureMonitorStatus(); + g_pHyprCtl->m_currentRequestParams.pendingPromise.reset(); + } else { + successWrite(ACCEPTEDCONNECTION, reply); + + if (isFollowUpRollingLogRequest(request)) { + Debug::log(LOG, "Followup rollinglog request received. Starting thread to write to socket."); + Debug::SRollingLogFollow::get().startFor(ACCEPTEDCONNECTION); + runWritingDebugLogThread(ACCEPTEDCONNECTION); + Debug::log(LOG, Debug::SRollingLogFollow::get().debugInfo()); + } else + close(ACCEPTEDCONNECTION); + + if (g_pConfigManager->m_wantsMonitorReload) + g_pConfigManager->ensureMonitorStatus(); + + g_pHyprCtl->m_currentRequestParams.pid = 0; + } return 0; } |
