Requires: boost-regex boost-system boost-thread boost-filesystem
Requires: procps-ng
Requires: libsystemd
+Requires: klay
%global user_name security_fw
%global group_name security_fw
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(capi-system-info)
BuildRequires: pkgconfig(capi-base-common)
+BuildRequires: pkgconfig(klay)
## Bluetooth
BuildRequires: pkgconfig(bluetooth-api)
## Wifi
BuildRequires: pkgconfig(capi-network-wifi-manager)
BuildRequires: pkgconfig(capi-network-connection)
+Requires: klay
%description policyd-plugins
Provides plugins for device policy manager
%files policyd-plugins
%manifest packaging/%{name}-plugins.manifest
%{vist_plugin_dir}/bluetooth
+%{vist_plugin_dir}/wifi
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
ADD_SUBDIRECTORY(bluetooth)
+ADD_SUBDIRECTORY(wifi)
#ADD_SUBDIRECTORY(usb)
-#ADD_SUBDIRECTORY(wifi)
# See the License for the specific language governing permissions and
# limitations under the License.
#
-SET(TARGET "dpm-plugin-bluetooth")
+SET(TARGET "vist-plugin-bluetooth")
SET(PLUGIN_SOURCES "bluetooth.cpp")
SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS "-fvisibility=default")
TARGET_LINK_LIBRARIES(${TARGET} ${PLUGIN_DEPS_LIBRARIES})
-INSTALL(FILES libdpm-plugin-bluetooth.so
+INSTALL(FILES libvist-plugin-bluetooth.so
RENAME bluetooth
DESTINATION ${PLUGIN_INSTALL_DIR})
extern "C" PolicyProvider* PolicyFactory()
{
+ INFO(PLUGINS, "Bluetooth plugin loaded.");
Bluetooth* provider = new Bluetooth("bluetooth");
provider->add(std::make_shared<ModeChange>());
provider->add(std::make_shared<DesktopConnectivity>());
private:
DLog()
{
- auto dlog = new audit::DlogLogSink("DPM_PLUGIN");
+ auto dlog = new audit::DlogLogSink("VIST_PLUGIN");
this->logSink.reset(dynamic_cast<audit::LogSink*>(dlog));
}
~DLog() noexcept = default;
# See the License for the specific language governing permissions and
# limitations under the License.
#
-SET(TARGET "dpm-plugin-wifi")
+SET(TARGET "vist-plugin-wifi")
SET(PLUGIN_SOURCES "wifi.cpp")
SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS "-fvisibility=default")
TARGET_LINK_LIBRARIES(${TARGET} ${PLUGIN_DEPS_LIBRARIES})
-INSTALL(FILES libdpm-plugin-wifi.so
+INSTALL(FILES libvist-plugin-wifi.so
RENAME wifi
DESTINATION ${PLUGIN_INSTALL_DIR})
*/
#include <arpa/inet.h>
-
-#include <cstdlib>
-#include <functional>
-#include <unordered_set>
-
#include <wifi-manager.h>
+#include <policyd/sdk/global-policy.h>
+#include <policyd/sdk/policy-provider.h>
+
#include <klay/dbus/connection.h>
-#include <policyd/pil/policy-context.h>
-#include <policyd/pil/policy-model.h>
-#include <policyd/pil/policy-storage.h>
-#include <policyd/pil/policy-event.h>
+#include <memory>
#include "../dlog.h"
"/net/netconfig/network", \
"net.netconfig.network"
-class ModeChange : public GlobalPolicy<DataSetInt> {
+using namespace policyd;
+
+class ModeChange : public GlobalPolicy {
public:
- ModeChange() : GlobalPolicy("wifi")
- {
- PolicyEventNotifier::create("wifi");
- }
+ ModeChange() : GlobalPolicy("wifi", PolicyValue(1)) {}
- bool apply(const DataType& value)
+ void onChanged(const PolicyValue& value) override
{
int enable = value;
- try {
- dbus::Connection &systemDBus = dbus::Connection::getSystem();
- systemDBus.methodcall(NETCONFIG_INTERFACE,
- "DevicePolicySetWifi",
- -1,
- "",
- "(i)",
- enable);
- } catch (runtime::Exception& e) {
- ERROR(PLUGINS, "Failed to chaneg Wi-Fi state");
- return false;
- }
-
- PolicyEventNotifier::emit("wifi", enable ? "allowed" : "disallowed");
- return true;
+ klay::dbus::Connection &systemDBus = klay::dbus::Connection::getSystem();
+ systemDBus.methodcall(NETCONFIG_INTERFACE,
+ "DevicePolicySetWifi",
+ -1,
+ "",
+ "(i)",
+ enable);
}
};
-class ProfileChange : public GlobalPolicy<DataSetInt> {
+class ProfileChange : public GlobalPolicy {
public:
- ProfileChange() : GlobalPolicy("wifi-profile-change")
- {
- PolicyEventNotifier::create("wifi_profile_change");
- }
+ ProfileChange() : GlobalPolicy("wifi-profile-change", PolicyValue(1)) {}
- bool apply(const DataType& value)
+ void onChanged(const PolicyValue& value) override
{
int enable = value;
- try {
- dbus::Connection &systemDBus = dbus::Connection::getSystem();
- systemDBus.methodcall(NETCONFIG_INTERFACE,
- "DevicePolicySetWifiProfile",
- -1,
- "",
- "(i)",
- enable);
- } catch (runtime::Exception& e) {
- ERROR(PLUGINS, "Failed to set Wi-Fi profile change restriction");
- return false;
- }
- PolicyEventNotifier::emit("wifi_profile_change", enable ? "allowed" : "disallowed");
- return true;
+ dbus::Connection &systemDBus = dbus::Connection::getSystem();
+ systemDBus.methodcall(NETCONFIG_INTERFACE,
+ "DevicePolicySetWifiProfile",
+ -1,
+ "",
+ "(i)",
+ enable);
}
};
-class Hotspot : public GlobalPolicy<DataSetInt> {
+class Hotspot : public GlobalPolicy {
public:
- Hotspot() : GlobalPolicy("wifi-hotspot")
- {
- PolicyEventNotifier::create("wifi_hotspot");
- }
+ Hotspot() : GlobalPolicy("wifi-hotspot", PolicyValue(1)) {}
- bool apply(const DataType& value)
+ void onChanged(const PolicyValue&) override
{
- int enable = value;
- PolicyEventNotifier::emit("wifi_hotspot", enable ? "allowed" : "disallowed");
- return true;
+ /// N/A
}
};
-class Wifi : public AbstractPolicyProvider {
+class SsidRestriction : public GlobalPolicy {
public:
- Wifi();
- ~Wifi();
-
- int setState(bool enable);
- bool getState();
- int setHotspotState(bool enable);
- bool getHotspotState();
- int setProfileChangeRestriction(bool enable);
- bool isProfileChangeRestricted();
+ SsidRestriction() : GlobalPolicy("wifi-ssid-restriction", PolicyValue(0)) {}
- static void onConnectionStateChanged(wifi_manager_connection_state_e state,
- wifi_manager_ap_h ap, void *user_data);
-
-private:
- wifi_manager_h handle;
-
- ModeChange modeChange;
- ProfileChange profileChange;
- Hotspot hotspot;
+ void onChanged(const PolicyValue&) override
+ {
+ /// N/A
+ }
};
+class Wifi : public PolicyProvider {
+public:
+ Wifi(const std::string& name) : PolicyProvider(name)
+ {
+ int ret = ::wifi_manager_initialize(&handle);
+ if (ret != WIFI_MANAGER_ERROR_NONE) {
+ if (ret == WIFI_MANAGER_ERROR_NOT_SUPPORTED)
+ return;
-Wifi::Wifi() : handle(nullptr)
-{
- int ret = 0;
-
- ret = ::wifi_manager_initialize(&handle);
- if (ret != WIFI_MANAGER_ERROR_NONE) {
- if (ret == WIFI_MANAGER_ERROR_NOT_SUPPORTED) {
- return;
+ throw std::runtime_error("WiFi Manager initialization failed.");
}
- throw runtime::Exception("WiFi Manager initialization failed");
}
- ret = ::wifi_manager_set_connection_state_changed_cb(handle, &onConnectionStateChanged, this);
- if (ret != WIFI_MANAGER_ERROR_NONE) {
- throw runtime::Exception("WiFi Manager set connection state changed callback failed");
- }
-}
+ ~Wifi()
+ {
+ if (handle == nullptr)
+ return;
-Wifi::~Wifi()
-{
- if (handle) {
- ::wifi_manager_unset_connection_state_changed_cb(handle);
::wifi_manager_deinitialize(handle);
}
-}
-void Wifi::onConnectionStateChanged(wifi_manager_connection_state_e state,
- wifi_manager_ap_h ap, void *user_data)
-{
- if (state == WIFI_MANAGER_CONNECTION_STATE_FAILURE ||
- state == WIFI_MANAGER_CONNECTION_STATE_DISCONNECTED) {
- return;
- }
-}
-
-int Wifi::setState(bool enable)
-{
- try {
- modeChange.set(enable);
- } catch (runtime::Exception& e) {
- ERROR(PLUGINS, e.what());
- return -1;
- }
-
- return 0;
-}
-
-bool Wifi::getState()
-{
- return modeChange.get();
-}
-
-int Wifi::setHotspotState(bool enable)
-{
- try {
- hotspot.set(enable);
- } catch (runtime::Exception& e) {
- ERROR(PLUGINS, e.what());
- return -1;
- }
-
- return 0;
-}
-
-bool Wifi::getHotspotState()
-{
- return hotspot.get();
-}
-
-int Wifi::setProfileChangeRestriction(bool enable)
-{
- try {
- profileChange.set(enable);
- } catch (runtime::Exception& e) {
- ERROR(PLUGINS, e.what());
- return -1;
- }
-
- return 0;
-}
-
-bool Wifi::isProfileChangeRestricted()
-{
- return profileChange.get();
-}
-
-extern "C" {
+private:
+ ::wifi_manager_h handle = nullptr;
+};
+// TODO(Sangwan): Add privilege to provider
#define PRIVILEGE "http://tizen.org/privilege/dpm.wifi"
-AbstractPolicyProvider *PolicyFactory(PolicyControlContext& context)
+extern "C" PolicyProvider* PolicyFactory()
{
- INFO(PLUGINS, "Wifi plugin loaded");
- Wifi *policy = new Wifi();
-
- context.expose(policy, PRIVILEGE, (int)(Wifi::setState)(bool));
- context.expose(policy, PRIVILEGE, (int)(Wifi::setHotspotState)(bool));
- context.expose(policy, PRIVILEGE, (int)(Wifi::setProfileChangeRestriction)(bool));
-
- context.expose(policy, "", (bool)(Wifi::getState)());
- context.expose(policy, "", (bool)(Wifi::getHotspotState)());
- context.expose(policy, "", (bool)(Wifi::isProfileChangeRestricted)());
-
- return policy;
+ INFO(PLUGINS, "Wifi plugin loaded.");
+ Wifi* provider = new Wifi("wifi");
+ provider->add(std::make_shared<ModeChange>());
+ provider->add(std::make_shared<ProfileChange>());
+ provider->add(std::make_shared<Hotspot>());
+ provider->add(std::make_shared<SsidRestriction>());
+
+ return provider;
}
-
-} // extern "C"
namespace policyd {
-std::shared_ptr<PolicyProvider> PolicyLoader::load(const std::string& path)
+PolicyProvider* PolicyLoader::load(const std::string& path)
{
PluginLoader loader(path);
PolicyProvider::FactoryType factory = nullptr;
if (factory == nullptr)
std::runtime_error("Failed to load symbol. " + PolicyProvider::getFactoryName());
- std::shared_ptr<PolicyProvider> provider((*factory)());
+ auto provider = (*factory)();
if (provider == nullptr)
std::runtime_error("Failed to make provider. " + PolicyProvider::getFactoryName());
}
PluginLoader::PluginLoader(const std::string& path, int flag)
- : handle(::dlopen(path.c_str(), flag), ::dlclose)
+ : handle(::dlopen(path.c_str(), flag), [](void*)->int{return 0;})
+// Cleaning object after dlclose() makes SEGFAULT.
+// TODO: Sync dynamic loading's life-cycle with program.(PluginManager)
+// : handle(::dlopen(path.c_str(), flag), ::dlclose)
{
if (handle == nullptr)
throw std::invalid_argument("Failed to open: " + path);
namespace policyd {
struct PolicyLoader final {
- static std::shared_ptr<PolicyProvider> load(const std::string& path);
+ static PolicyProvider* load(const std::string& path);
};
class PluginLoader final {
void load(const std::string& name, T& symbol);
private:
- using Handle = std::unique_ptr<void, decltype(&::dlclose)>;
+ using Handle = std::unique_ptr<void, int(*)(void*)>;
Handle handle;
};
try {
auto provider = PolicyLoader::load(iter->getPath());
DEBUG(VIST, "Loaded provider: " << provider->getName());
- this->providers.emplace_back(std::move(provider));
+
+ bool exist = false;
+ for (const auto& p : this->providers) {
+ if (p->getName() == provider->getName()) {
+ exist = true;
+ break;
+ }
+ }
+
+ if (!exist)
+ this->providers.emplace_back(std::move(provider));
} catch (const std::exception& e) {
++failed;
ERROR(VIST, "Failed to load: " << iter->getPath() << e.what());
int PolicyManager::loadPolicies()
{
- for (const auto& p : providers) {
- this->global.insert(p->global.cbegin(), p->global.cend());
- this->domain.insert(p->domain.cbegin(), p->domain.cend());
- }
-
bool changed = false;
- for (const auto& g : global) {
- if (!storage.exists(g.first)) {
- INFO(VIST, "Define global policy: " << g.first);
- storage.define(0, g.first, g.second->getInitial().value);
- changed = true;
+
+ /// Make policy-provider map for performance
+ for (const auto& provider : providers) {
+ for (const auto& pair : provider->global) {
+ policies[pair.first] = provider->getName();
+
+ /// Check the policy is defined on policy-storage
+ if (!storage.exists(pair.first)) {
+ INFO(VIST, "Define global policy: " << pair.first);
+ storage.define(0, pair.first, pair.second->getInitial().value);
+ changed = true;
+ }
}
- }
- for (const auto& d : domain) {
- if (!storage.exists(d.first)) {
- INFO(VIST, "Define domain policy: " << d.first);
- storage.define(1, d.first, d.second->getInitial().value);
- changed = true;
+ for (const auto& pair : provider->domain) {
+ policies[pair.first] = provider->getName();
+
+ if (!storage.exists(pair.first)) {
+ INFO(VIST, "Define domain policy: " << pair.first);
+ storage.define(1, pair.first, pair.second->getInitial().value);
+ changed = true;
+ }
}
}
if (changed)
storage.syncPolicyDefinition();
- return global.size() + domain.size();
+ return policies.size();
}
void PolicyManager::enroll(const std::string& admin, uid_t uid)
void PolicyManager::set(const std::string& policy, const PolicyValue& value,
const std::string& admin, uid_t uid)
{
+ if (policies.find(policy) == policies.end())
+ std::runtime_error("Not exist policy: " + policy);
+
storage.update(admin, uid, policy, value);
- if (global.find(policy) != global.end()) {
- global[policy]->set(value);
- return;
- }
+ for (auto& p : providers) {
+ if (p->getName() != policies[policy])
+ continue;
- if (domain.find(policy) != domain.end()) {
- domain[policy]->set(uid, value);
- return;
- }
+ if (p->global.find(policy) != p->global.end()) {
+ p->global[policy]->set(value);
+ return;
+ }
- throw std::runtime_error("Cannot set policy." + policy);
+ if (p->domain.find(policy) != p->domain.end()) {
+ p->domain[policy]->set(uid, value);
+ return;
+ }
+ }
}
PolicyValue PolicyManager::get(const std::string& policy, uid_t uid)
int loadPolicies();
PolicyStorage storage;
- std::vector<std::shared_ptr<PolicyProvider>> providers;
+ std::vector<std::unique_ptr<PolicyProvider>> providers;
- std::unordered_map<std::string, std::shared_ptr<GlobalPolicy>> global;
- std::unordered_map<std::string, std::shared_ptr<DomainPolicy>> domain;
+ /// Policy-Provider
+ std::unordered_map<std::string, std::string> policies;
FRIEND_TEST(PolicyCoreTests, policy_loader);
};
TEST_F(PolicyCoreTests, policy_loader) {
auto& manager = PolicyManager::Instance();
- /// Clearing for test
- manager.providers.clear();
- manager.global.clear();
- manager.domain.clear();
-
- auto result = manager.loadProviders(PLUGIN_INSTALL_DIR);
- EXPECT_TRUE(result.first > 0);
- EXPECT_TRUE(result.second == 0);
-
- auto size = manager.loadPolicies();
- EXPECT_TRUE(size > 0);
+ EXPECT_TRUE(manager.providers.size() > 0);
+ EXPECT_TRUE(manager.policies.size() > 0);
}
TEST_F(PolicyCoreTests, policy_set_get) {
explicit PolicyProvider(std::string name) noexcept : name(std::move(name)) {}
virtual ~PolicyProvider() = default;
- inline void add(std::shared_ptr<GlobalPolicy>&& policy) {
- global.emplace(policy->getName(), std::move(policy));
+ inline void add(const std::shared_ptr<GlobalPolicy>& policy) {
+ global[policy->getName()] = policy;
}
- inline void add(std::shared_ptr<DomainPolicy>&& policy) {
- domain.emplace(policy->getName(), std::move(policy));
+ inline void add(const std::shared_ptr<DomainPolicy>& policy) {
+ domain[policy->getName()] = policy;
}
inline const std::string& getName() const noexcept { return name; }