79 lines
2.1 KiB
C++
79 lines
2.1 KiB
C++
// SPDX-FileCopyrightText: Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
#include "user_policy.hh"
|
|
|
|
#include "logger.hh"
|
|
#include "resolver.hh"
|
|
|
|
#include "parentalcontrol-dns.h"
|
|
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <unistd.h>
|
|
|
|
namespace /* anonymous */ {
|
|
|
|
struct GObjectDeletor {
|
|
auto operator() (void *gobj) const noexcept -> void {
|
|
g_object_unref(gobj);
|
|
}
|
|
};
|
|
|
|
} // ~ namespace anonymous
|
|
|
|
|
|
using ProxyPtr = std::unique_ptr<ParentalControlsDns, GObjectDeletor>;
|
|
|
|
auto malcontent::UserPolicy::resolver(std::optional<uid_t> maybe_uid) const -> std::shared_ptr<Resolver> {
|
|
auto uid = maybe_uid.value_or(getuid());
|
|
if (uid == 0) {
|
|
return nullptr; // no restrictions for root!
|
|
}
|
|
|
|
// If cached, let's return this immediately
|
|
{
|
|
std::shared_lock lock { _cache_mutex };
|
|
auto it = _resolver_cache.find(uid);
|
|
if (it != _resolver_cache.cend()) {
|
|
return it->second;
|
|
}
|
|
}
|
|
|
|
// Missing from cache, insert if still needed
|
|
std::unique_lock lock { _cache_mutex };
|
|
auto it = _resolver_cache.find(uid);
|
|
if (it != _resolver_cache.cend()) {
|
|
return it->second;
|
|
}
|
|
|
|
GError *error = nullptr;
|
|
auto dbus_proxy = ProxyPtr {
|
|
parental_controls_dns_proxy_new_for_bus_sync(
|
|
G_BUS_TYPE_SYSTEM,
|
|
// right now we check the property value at start
|
|
// and we never update during runtime.
|
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
|
"com.endlessm.ParentalControls.Dns",
|
|
"/com/endlessm/ParentalControls/Dns",
|
|
nullptr,
|
|
&error
|
|
)
|
|
};
|
|
|
|
if (error != nullptr) {
|
|
malcontent::Logger::warn(error->message);
|
|
return nullptr;
|
|
}
|
|
|
|
std::vector<std::string> dns;
|
|
for (auto it = parental_controls_dns_get_dns(dbus_proxy.get()); it != nullptr; ++it) {
|
|
dns.push_back(*it);
|
|
}
|
|
|
|
it = _resolver_cache.insert(it, { uid, std::make_shared<Resolver>(std::move(dns)) });
|
|
return it->second;
|
|
}
|