Enable wifi plugin
authorSangwan Kwon <sangwan.kwon@samsung.com>
Fri, 18 Oct 2019 06:45:04 +0000 (15:45 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Mon, 21 Oct 2019 05:41:24 +0000 (14:41 +0900)
Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
13 files changed:
packaging/osquery.spec
plugins/CMakeLists.txt
plugins/bluetooth/CMakeLists.txt
plugins/bluetooth/bluetooth.cpp
plugins/dlog.h
plugins/wifi/CMakeLists.txt
plugins/wifi/wifi.cpp
src/policyd/core/policy-loader.cpp
src/policyd/core/policy-loader.h
src/policyd/core/policy-manager.cpp
src/policyd/core/policy-manager.h
src/policyd/core/tests/core-tests.cpp
src/policyd/sdk/policy-provider.h

index 1db3e2176d84045eb9c431559c769c24a77bc100..870edd15235ba3717daa4458685d284d727e50bf 100644 (file)
@@ -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
index 8ec261990359ef982802508e7576342e63411706..405589122489ef9cb7c7e39ff4b3f82637537e61 100644 (file)
@@ -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)
index 23a42fefe7774d34f782319125b765af772cedbd..10c866ef7c7241b2336563b0f5d75e51bd2ce2f6 100644 (file)
@@ -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})
index 3489d66dd8751c4fe0f6de457742a8c12445ee2b..eb41e97b9da28ca659a9d0248704517f73dc0237 100644 (file)
@@ -102,6 +102,7 @@ public:
 
 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>());
index 701c6d5b8febe60244b4eba64d790d34554b3934..7d851706ef7a983cd9e9245d97b0eac82ee157dc 100644 (file)
@@ -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<audit::LogSink*>(dlog));
        }
        ~DLog() noexcept = default;
index e97bb67fd1c541d823afa62f68f7de0e1d30957c..d236772af0b781a3872f0dfa4b444ac0effd93b5 100644 (file)
@@ -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})
index 4317498febdf8076ef1c2a924316a313ac65962d..e490ac975e9e24925d7d2ab012463c14c04dd09e 100644 (file)
  */
 
 #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"
index 173ddf8f4a2e6350de44dd690fa3f6eac3d3309e..042e9154c832ec00eaca9b9a310012bf5e481bda 100644 (file)
@@ -18,7 +18,7 @@
 
 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;
@@ -26,7 +26,7 @@ std::shared_ptr<PolicyProvider> PolicyLoader::load(const std::string& path)
        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());
 
@@ -34,7 +34,10 @@ std::shared_ptr<PolicyProvider> 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);
index 22ad28373b4614a32faacac3de261067ea4684d9..14c32a2cf6969d5296cebd17740e3006d8994985 100644 (file)
@@ -27,7 +27,7 @@
 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 {
@@ -38,7 +38,7 @@ public:
        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;
 };
 
index dba0d522ccbc33aa45791ccd23d77f75cb71766a..1b2b035538ef68d5c0d5d6d0ea910a8f2d005040 100644 (file)
@@ -45,7 +45,17 @@ std::pair<int, int> 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<int, int> 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)
index 9e8577992f98c3c2a7ade0f21e8448523fdd3472..57eae0ee552ccd1deb032aa87992edd8afe7b420 100644 (file)
@@ -61,10 +61,10 @@ private:
        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);
 };
index 49fc46323ead1f841ed2e2ca14eff44b56e00bdd..83e5cb6ad4c4d23ada2439dc3629d921125de93a 100644 (file)
@@ -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) {
index 8dd319bc6422c8bb958ee02ba5cd5fc990cfce88..27bb0ae56b16b43ce782c66dcb64881ddd1778c9 100644 (file)
@@ -32,12 +32,12 @@ public:
        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; }