From: Sangwan Kwon Date: Fri, 18 Oct 2019 06:45:04 +0000 (+0900) Subject: Enable wifi plugin X-Git-Tag: submit/tizen/20200810.073515~180 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4669df89153fda8653b29fbdf5d76e55d6fab0ce;p=platform%2Fcore%2Fsecurity%2Fvist.git Enable wifi plugin Signed-off-by: Sangwan Kwon --- diff --git a/packaging/osquery.spec b/packaging/osquery.spec index 1db3e21..870edd1 100644 --- a/packaging/osquery.spec +++ b/packaging/osquery.spec @@ -27,6 +27,7 @@ Requires: gflag 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 @@ -115,6 +116,7 @@ BuildRequires: pkgconfig(buxton2) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(klay) ## Bluetooth BuildRequires: pkgconfig(bluetooth-api) @@ -123,6 +125,7 @@ BuildRequires: pkgconfig(capi-network-bluetooth) ## Wifi BuildRequires: pkgconfig(capi-network-wifi-manager) BuildRequires: pkgconfig(capi-network-connection) +Requires: klay %description policyd-plugins Provides plugins for device policy manager @@ -130,3 +133,4 @@ Provides plugins for device policy manager %files policyd-plugins %manifest packaging/%{name}-plugins.manifest %{vist_plugin_dir}/bluetooth +%{vist_plugin_dir}/wifi diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 8ec2619..4055891 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -18,5 +18,5 @@ INCLUDE(FindPkgConfig) SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack") ADD_SUBDIRECTORY(bluetooth) +ADD_SUBDIRECTORY(wifi) #ADD_SUBDIRECTORY(usb) -#ADD_SUBDIRECTORY(wifi) diff --git a/plugins/bluetooth/CMakeLists.txt b/plugins/bluetooth/CMakeLists.txt index 23a42fe..10c866e 100644 --- a/plugins/bluetooth/CMakeLists.txt +++ b/plugins/bluetooth/CMakeLists.txt @@ -12,7 +12,7 @@ # 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") @@ -27,6 +27,6 @@ ADD_LIBRARY(${TARGET} SHARED ${PLUGIN_SOURCES}) 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}) diff --git a/plugins/bluetooth/bluetooth.cpp b/plugins/bluetooth/bluetooth.cpp index 3489d66..eb41e97 100644 --- a/plugins/bluetooth/bluetooth.cpp +++ b/plugins/bluetooth/bluetooth.cpp @@ -102,6 +102,7 @@ public: extern "C" PolicyProvider* PolicyFactory() { + INFO(PLUGINS, "Bluetooth plugin loaded."); Bluetooth* provider = new Bluetooth("bluetooth"); provider->add(std::make_shared()); provider->add(std::make_shared()); diff --git a/plugins/dlog.h b/plugins/dlog.h index 701c6d5..7d85170 100644 --- a/plugins/dlog.h +++ b/plugins/dlog.h @@ -45,7 +45,7 @@ public: private: DLog() { - auto dlog = new audit::DlogLogSink("DPM_PLUGIN"); + auto dlog = new audit::DlogLogSink("VIST_PLUGIN"); this->logSink.reset(dynamic_cast(dlog)); } ~DLog() noexcept = default; diff --git a/plugins/wifi/CMakeLists.txt b/plugins/wifi/CMakeLists.txt index e97bb67..d236772 100644 --- a/plugins/wifi/CMakeLists.txt +++ b/plugins/wifi/CMakeLists.txt @@ -12,7 +12,7 @@ # 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") @@ -28,6 +28,6 @@ ADD_LIBRARY(${TARGET} SHARED ${PLUGIN_SOURCES}) 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}) diff --git a/plugins/wifi/wifi.cpp b/plugins/wifi/wifi.cpp index 4317498..e490ac9 100644 --- a/plugins/wifi/wifi.cpp +++ b/plugins/wifi/wifi.cpp @@ -15,19 +15,14 @@ */ #include - -#include -#include -#include - #include +#include +#include + #include -#include -#include -#include -#include +#include #include "../dlog.h" @@ -36,204 +31,98 @@ "/net/netconfig/network", \ "net.netconfig.network" -class ModeChange : public GlobalPolicy { +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 { +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 { +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()); + provider->add(std::make_shared()); + provider->add(std::make_shared()); + provider->add(std::make_shared()); + + return provider; } - -} // extern "C" diff --git a/src/policyd/core/policy-loader.cpp b/src/policyd/core/policy-loader.cpp index 173ddf8..042e915 100644 --- a/src/policyd/core/policy-loader.cpp +++ b/src/policyd/core/policy-loader.cpp @@ -18,7 +18,7 @@ namespace policyd { -std::shared_ptr PolicyLoader::load(const std::string& path) +PolicyProvider* PolicyLoader::load(const std::string& path) { PluginLoader loader(path); PolicyProvider::FactoryType factory = nullptr; @@ -26,7 +26,7 @@ std::shared_ptr PolicyLoader::load(const std::string& path) if (factory == nullptr) std::runtime_error("Failed to load symbol. " + PolicyProvider::getFactoryName()); - std::shared_ptr provider((*factory)()); + auto provider = (*factory)(); if (provider == nullptr) std::runtime_error("Failed to make provider. " + PolicyProvider::getFactoryName()); @@ -34,7 +34,10 @@ std::shared_ptr PolicyLoader::load(const std::string& path) } 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); diff --git a/src/policyd/core/policy-loader.h b/src/policyd/core/policy-loader.h index 22ad283..14c32a2 100644 --- a/src/policyd/core/policy-loader.h +++ b/src/policyd/core/policy-loader.h @@ -27,7 +27,7 @@ namespace policyd { struct PolicyLoader final { - static std::shared_ptr load(const std::string& path); + static PolicyProvider* load(const std::string& path); }; class PluginLoader final { @@ -38,7 +38,7 @@ public: void load(const std::string& name, T& symbol); private: - using Handle = std::unique_ptr; + using Handle = std::unique_ptr; Handle handle; }; diff --git a/src/policyd/core/policy-manager.cpp b/src/policyd/core/policy-manager.cpp index dba0d52..1b2b035 100644 --- a/src/policyd/core/policy-manager.cpp +++ b/src/policyd/core/policy-manager.cpp @@ -45,7 +45,17 @@ std::pair PolicyManager::loadProviders(const std::string& path) 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()); @@ -61,32 +71,36 @@ std::pair PolicyManager::loadProviders(const std::string& path) 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) @@ -102,19 +116,25 @@ void PolicyManager::disenroll(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) diff --git a/src/policyd/core/policy-manager.h b/src/policyd/core/policy-manager.h index 9e85779..57eae0e 100644 --- a/src/policyd/core/policy-manager.h +++ b/src/policyd/core/policy-manager.h @@ -61,10 +61,10 @@ private: int loadPolicies(); PolicyStorage storage; - std::vector> providers; + std::vector> providers; - std::unordered_map> global; - std::unordered_map> domain; + /// Policy-Provider + std::unordered_map policies; FRIEND_TEST(PolicyCoreTests, policy_loader); }; diff --git a/src/policyd/core/tests/core-tests.cpp b/src/policyd/core/tests/core-tests.cpp index 49fc463..83e5cb6 100644 --- a/src/policyd/core/tests/core-tests.cpp +++ b/src/policyd/core/tests/core-tests.cpp @@ -25,17 +25,8 @@ class PolicyCoreTests : public testing::Test {}; 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) { diff --git a/src/policyd/sdk/policy-provider.h b/src/policyd/sdk/policy-provider.h index 8dd319b..27bb0ae 100644 --- a/src/policyd/sdk/policy-provider.h +++ b/src/policyd/sdk/policy-provider.h @@ -32,12 +32,12 @@ public: explicit PolicyProvider(std::string name) noexcept : name(std::move(name)) {} virtual ~PolicyProvider() = default; - inline void add(std::shared_ptr&& policy) { - global.emplace(policy->getName(), std::move(policy)); + inline void add(const std::shared_ptr& policy) { + global[policy->getName()] = policy; } - inline void add(std::shared_ptr&& policy) { - domain.emplace(policy->getName(), std::move(policy)); + inline void add(const std::shared_ptr& policy) { + domain[policy->getName()] = policy; } inline const std::string& getName() const noexcept { return name; }