Add policy-loader to policyd
authorSangwan Kwon <sangwan.kwon@samsung.com>
Tue, 24 Sep 2019 06:39:56 +0000 (15:39 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Thu, 10 Oct 2019 06:26:21 +0000 (15:26 +0900)
Disable whole features without policy-core and sdk.
* Restore the features before PR to master branch.

Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
16 files changed:
packaging/osquery.spec
plugins/bluetooth/CMakeLists.txt
plugins/bluetooth/bluetooth.cpp
src/CMakeLists.txt
src/policyd/CMakeLists.txt
src/policyd/core/CMakeLists.txt [new file with mode: 0644]
src/policyd/core/logger.cpp [new file with mode: 0644]
src/policyd/core/logger.h [new file with mode: 0644]
src/policyd/core/policy-loader.cpp [new file with mode: 0644]
src/policyd/core/policy-loader.h [new file with mode: 0644]
src/policyd/core/policy-manager.cpp [new file with mode: 0644]
src/policyd/core/policy-manager.h [new file with mode: 0644]
src/policyd/core/tests/core-tests.cpp [new file with mode: 0644]
src/policyd/sdk/global-policy.h
src/policyd/sdk/policy-provider.h
src/policyd/sdk/tests/sdk-tests.cpp [moved from src/policyd/sdk/tests/policy_tests.cpp with 93% similarity]

index 797df79..798fe48 100644 (file)
@@ -99,10 +99,10 @@ mkdir -p %{buildroot}%{dpm_event}
 mkdir -p %{buildroot}%{dpm_plugins}
 mkdir -p %{buildroot}/%{_unitdir}/multi-user.target.wants
 mkdir -p %{buildroot}/%{_unitdir}/sockets.target.wants
-ln -s ../src/policyd/device-policy-manager.service %{buildroot}/%{_unitdir}/multi-user.target.wants/device-policy-manager.service
-ln -s ../src/policyd/device-policy-manager.socket %{buildroot}/%{_unitdir}/sockets.target.wants/device-policy-manager.socket
+#ln -s ../src/policyd/device-policy-manager.service %{buildroot}/%{_unitdir}/multi-user.target.wants/device-policy-manager.service
+#ln -s ../src/policyd/device-policy-manager.socket %{buildroot}/%{_unitdir}/sockets.target.wants/device-policy-manager.socket
 
-%find_lang dpm-syspopup
+#%find_lang dpm-syspopup
 
 %clean
 rm -rf %{buildroot}
@@ -119,8 +119,8 @@ Testcases for osquery
 
 %files test
 %manifest %{name}.manifest
-%{_bindir}/osquery-test
-%{_bindir}/apix-test
+#%{_bindir}/osquery-test
+#%{_bindir}/apix-test
 
 
 ## DPM Policyd ###############################################################
@@ -157,20 +157,20 @@ managing device policies.
 %files policyd
 %manifest device-policy-manager.manifest
 %defattr(644,root,root,755)
-%attr(700,root,root) %{_bindir}/dpm-admin-cli
-%attr(755,root,root) %{_bindir}/dpm-syspopup
-%attr(755,root,root) %{_bindir}/dpm-storage-builder
-%attr(755,root,root) %{_bindir}/device-policy-syspopup
-%attr(-,%{user_name},%{group_name}) %{dpm_base}
-%attr(-,%{user_name},%{group_name}) %{dpm_event}
+#%attr(700,root,root) %{_bindir}/dpm-admin-cli
+#%attr(755,root,root) %{_bindir}/dpm-syspopup
+#%attr(755,root,root) %{_bindir}/dpm-storage-builder
+#%attr(755,root,root) %{_bindir}/device-policy-syspopup
+#%attr(-,%{user_name},%{group_name}) %{dpm_base}
+#%attr(-,%{user_name},%{group_name}) %{dpm_event}
 %attr(-,%{user_name},%{group_name}) %{dpm_plugins}
-%{_unitdir}/device-policy-manager.service
-%{_unitdir}/device-policy-manager.socket
-%{_unitdir}/sockets.target.wants/device-policy-manager.socket
-%{_unitdir}/multi-user.target.wants/device-policy-manager.service
-%{_unitdir}/device-policy-syspopup.service
-/etc/dbus-1/system.d/org.tizen.dpm.syspopup.conf
-/usr/share/dbus-1/system-services/org.tizen.dpm.syspopup.service
+#%{_unitdir}/device-policy-manager.service
+#%{_unitdir}/device-policy-manager.socket
+#%{_unitdir}/sockets.target.wants/device-policy-manager.socket
+#%{_unitdir}/multi-user.target.wants/device-policy-manager.service
+#%{_unitdir}/device-policy-syspopup.service
+#/etc/dbus-1/system.d/org.tizen.dpm.syspopup.conf
+#/usr/share/dbus-1/system-services/org.tizen.dpm.syspopup.service
 
 ## Devel Package ##############################################################
 %package policyd-devel
@@ -191,8 +191,8 @@ developing the device policy module.
 %files policyd-devel
 #%manifest device-policy-client.manifest
 %defattr(644,root,root,755)
-%{_includedir}/dpm
-%{_libdir}/pkgconfig/dpm-pil.pc
+#%{_includedir}/dpm
+#%{_libdir}/pkgconfig/dpm-pil.pc
 
 ## DPM Syspopup Package ######################################################
 %package -n org.tizen.dpm-syspopup
@@ -206,13 +206,14 @@ BuildRequires: pkgconfig(capi-system-info)
 %description -n org.tizen.dpm-syspopup
 Tizen DPM system popup interface package
 
-%files -n org.tizen.dpm-syspopup -f dpm-syspopup.lang
+%files -n org.tizen.dpm-syspopup
+# -f dpm-syspopup.lang
 %defattr(-,root,root,-)
-%manifest src/policyd/tools/syspopup/org.tizen.dpm-syspopup.manifest
-%{TZ_SYS_RO_APP}/org.tizen.dpm-syspopup/bin/*
-%{TZ_SYS_RO_PACKAGES}/org.tizen.dpm-syspopup.xml
-/usr/share/icons/default/small/org.tizen.dpm-syspopup.png
-%{TZ_SYS_RO_APP}/org.tizen.dpm-syspopup/res/images/*
+#%manifest src/policyd/tools/syspopup/org.tizen.dpm-syspopup.manifest
+#%{TZ_SYS_RO_APP}/org.tizen.dpm-syspopup/bin/*
+#%{TZ_SYS_RO_PACKAGES}/org.tizen.dpm-syspopup.xml
+#/usr/share/icons/default/small/org.tizen.dpm-syspopup.png
+#%{TZ_SYS_RO_APP}/org.tizen.dpm-syspopup/res/images/*
 
 ## Test Package ###############################################################
 %package policyd-test
index 2f21f4c..23a42fe 100644 (file)
@@ -16,9 +16,7 @@ SET(TARGET "dpm-plugin-bluetooth")
 
 SET(PLUGIN_SOURCES "bluetooth.cpp")
 
-SET(DEPENDENCY klay
-                          aul
-                          bluetooth-api
+SET(DEPENDENCY bluetooth-api
                           capi-network-bluetooth)
 
 PKG_CHECK_MODULES(PLUGIN_DEPS REQUIRED ${DEPENDENCY})
index f9df95c..3489d66 100644 (file)
@@ -18,9 +18,8 @@
 #include <bluetooth-api.h>
 #include <bluetooth_internal.h>
 
-#include <policyd/pil/global-policy.h>
-#include <policyd/pil/policy-storage.h>
-#include <policyd/pil/policy-event.h>
+#include <policyd/sdk/global-policy.h>
+#include <policyd/sdk/policy-provider.h>
 
 #include <memory>
 
        ((int)(enable) ? BLUETOOTH_DPM_BT_ALLOWED :              \
                                         BLUETOOTH_DPM_BT_RESTRICTED)
 
-namespace {
-
-inline int canonicalize(int value)
-{
-       return -value;
-}
-
-} // namespace
+using namespace policyd;
 
 class ModeChange : public GlobalPolicy {
 public:
-       ModeChange() : GlobalPolicy("bluetooth")
-       {
-               PolicyEventNotifier::create("bluetooth");
-       }
+       ModeChange() : GlobalPolicy("bluetooth", PolicyValue(1)) {}
 
-       bool apply(const DataSetInt& value, uid_t)
+       void onChanged(const PolicyValue& value) override
        {
-               int ret = bluetooth_dpm_set_allow_mode(STATE_CHANGE_IS_ALLOWED(value));
-               if (!BT_FAILED(ret)) {
-                       int enable = value;
-                       PolicyEventNotifier::emit("bluetooth", enable ? "allowed" : "disallowed");
-                       return true;
-               }
-               return false;
+               int ret = ::bluetooth_dpm_set_allow_mode(STATE_CHANGE_IS_ALLOWED(value));
+               if (BT_FAILED(ret))
+                       throw std::runtime_error("Failed to set bluetooth.");
        }
 };
 
 class DesktopConnectivity : public GlobalPolicy {
 public:
-       DesktopConnectivity() : GlobalPolicy("bluetooth-desktop-connectivity")
-       {
-               PolicyEventNotifier::create("bluetooth_desktop_connectivity");
-       }
+       DesktopConnectivity() :
+               GlobalPolicy("bluetooth-desktop-connectivity", PolicyValue(1)) {}
 
-       bool apply(const DataSetInt & value, uid_t)
+       void onChanged(const PolicyValue& value) override
        {
-               int ret = bluetooth_dpm_set_desktop_connectivity_state(POLICY_IS_ALLOWED(value));
-               if (!BT_FAILED(ret)) {
-                       int enable = value;
-                       PolicyEventNotifier::emit("bluetooth_desktop_connectivity",
-                                                                         enable ? "allowed" : "disallowed");
-                       return true;
-               }
-               return false;
+               int ret = ::bluetooth_dpm_set_desktop_connectivity_state(POLICY_IS_ALLOWED(value));
+               if (BT_FAILED(ret))
+                       throw std::runtime_error("Failed to set bt_desktop_connectivity.");
        }
 };
 
 class Pairing: public GlobalPolicy {
 public:
-       Pairing() : GlobalPolicy("bluetooth-pairing")
-       {
-               PolicyEventNotifier::create("bluetooth_pairing");
-       }
+       Pairing() : GlobalPolicy("bluetooth-pairing", PolicyValue(1)) {}
 
-       bool apply(const DataSetInt& value, uid_t)
+       void onChanged(const PolicyValue& value) override
        {
-               int ret = bluetooth_dpm_set_pairing_state(POLICY_IS_ALLOWED(value));
-               if (!BT_FAILED(ret)) {
-                       int enable = value;
-                       PolicyEventNotifier::emit("bluetooth_pairing",
-                                                                         enable ? "allowed" : "disallowed");
-                       return true;
-               }
-               return false;
+               int ret = ::bluetooth_dpm_set_pairing_state(POLICY_IS_ALLOWED(value));
+               if (BT_FAILED(ret))
+                       throw std::runtime_error("Failed to set bt_pairing.");
        }
 };
 
 class Tethering: public GlobalPolicy {
 public:
-       Tethering() : GlobalPolicy("bluetooth-tethering")
-       {
-               PolicyEventNotifier::create("bluetooth_tethering");
-       }
+       Tethering() : GlobalPolicy("bluetooth-tethering", PolicyValue(1)) {}
 
-       bool apply(const DataSetInt& value, uid_t)
-       {
-               int enable = value;
-               PolicyEventNotifier::emit("bluetooth_tethering",
-                                                                 enable ? "allowed" : "disallowed");
-               return true;
-       }
+       void onChanged(const PolicyValue&) {}
 };
 
-class Bluetooth : public AbstractPolicyProvider {
+class Bluetooth : public PolicyProvider {
 public:
-       Bluetooth();
-       ~Bluetooth();
-
-private:
-       static void onStateChanged(int result, bt_adapter_state_e state, void *user_data);
-};
-
-Bluetooth::Bluetooth()
-{
-       if (::bt_initialize() != BT_ERROR_NONE) {
-               ERROR(PLUGINS,"Bluetooth framework was not initilaized");
-               return;
+       Bluetooth(const std::string& name) : PolicyProvider(name)
+       {
+               if (::bt_initialize() != BT_ERROR_NONE)
+                       ERROR(PLUGINS,"Bluetooth framework was not initilaized");
        }
 
-       if (::bt_adapter_set_state_changed_cb(onStateChanged, this) != BT_ERROR_NONE) {
-               ERROR(PLUGINS,"Failed to register Bluetooth callback");
-               return;
+       ~Bluetooth()
+       {
+               ::bt_deinitialize();
        }
-}
+};
 
-Bluetooth::~Bluetooth()
-{
-       ::bt_deinitialize();
-}
+// TODO(Sangwan): Add privilege to provider
+#define PRIVILEGE "http://tizen.org/privilege/dpm.bluetooth"
 
-void Bluetooth::onStateChanged(int result, bt_adapter_state_e state, void *user_data)
+extern "C" PolicyProvider* PolicyFactory()
 {
-       Bluetooth *pimpl = reinterpret_cast<Bluetooth *>(user_data);
-       if (pimpl != nullptr && state == BT_ADAPTER_ENABLED) {
-//             pimpl->modeChange.apply();
-//             pimpl->desktopConnectivity.apply();
-//             pimpl->pairing.apply();
-//             pimpl->deviceRestriction.enforce();
-//             pimpl->uuidRestriction.enforce();
-       }
+       Bluetooth* provider = new Bluetooth("bluetooth");
+       provider->add(std::make_shared<ModeChange>());
+       provider->add(std::make_shared<DesktopConnectivity>());
+       provider->add(std::make_shared<Pairing>());
+       provider->add(std::make_shared<Tethering>());
+
+       return provider;
 }
index 82f4c86..67b6019 100644 (file)
@@ -16,6 +16,9 @@ SET(TARGET_APIX_LIB apix)
 SET(TARGET_OSQUERY_LIB osquery)
 SET(TARGET_POLICYD_LIB policyd)
 
-ADD_SUBDIRECTORY(apix)
-ADD_SUBDIRECTORY(osquery)
-ADD_SUBDIRECTORY(policyd)
+#ADD_SUBDIRECTORY(apix)
+#ADD_SUBDIRECTORY(osquery)
+
+IF(DEFINED GBS_BUILD)
+       ADD_SUBDIRECTORY(policyd)
+ENDIF(DEFINED GBS_BUILD)
index 5beb1f2..7764632 100644 (file)
@@ -18,60 +18,42 @@ SET(TARGET_POLICYD_TEST policyd-test)
 SET(${TARGET_POLICYD_LIB}_SRCS "")
 SET(${TARGET_POLICYD_LIB}_TESTS "")
 
-IF(DEFINED GBS_BUILD)
-       SET(DEPENDENCY appsvc
-                                  aul
-                                  bundle
-                                  capi-base-common
-                                  capi-system-info
-                                  capi-system-system-settings
-                                  cynara-client
-                                  cynara-session
-                                  deviced
-                                  gio-2.0
-                                  glib-2.0
-                                  klay
-                                  libtzplatform-config
-                                  notification
-                                  pkgmgr
-                                  pkgmgr-info
-                                  security-privilege-manager
-                                  sqlite3
-                                  syspopup-caller
-                                  vconf)
+SET(DEPENDENCY klay)
 
-       PKG_CHECK_MODULES(POLICYD_DEPS REQUIRED ${DEPENDENCY})
+PKG_CHECK_MODULES(POLICYD_DEPS REQUIRED ${DEPENDENCY})
 
-       INCLUDE_DIRECTORIES(SYSTEM . ${POLICYD_DEPS_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(SYSTEM . ${POLICYD_DEPS_INCLUDE_DIRS})
 
-       ADD_DEFINITIONS(-DDATA_PATH="${DATA_INSTALL_DIR}"
-                                       -DRUN_PATH="${RUN_INSTALL_DIR}"
-                                       -DDB_PATH="${DB_INSTALL_DIR}"
-                                       -DPLUGIN_INSTALL_DIR="${PLUGIN_INSTALL_DIR}"
-                                       -DEVENT_CONFIGURE_DIR="${EVENT_CONFIGURE_DIR}")
-       ADD_DEFINITIONS(-DUG_WAYLAND)
+ADD_DEFINITIONS(-DDATA_PATH="${DATA_INSTALL_DIR}"
+                               -DRUN_PATH="${RUN_INSTALL_DIR}"
+                               -DDB_PATH="${DB_INSTALL_DIR}"
+                               -DPLUGIN_INSTALL_DIR="${PLUGIN_INSTALL_DIR}"
+                               -DEVENT_CONFIGURE_DIR="${EVENT_CONFIGURE_DIR}")
+ADD_DEFINITIONS(-DUG_WAYLAND)
 
-       ADD_SUBDIRECTORY(client)
-       ADD_SUBDIRECTORY(conf)
-       ADD_SUBDIRECTORY(pil)
-       ADD_SUBDIRECTORY(server)
-       ADD_SUBDIRECTORY(tools)
-       ADD_SUBDIRECTORY(ui)
+ADD_SUBDIRECTORY(core)
+ADD_SUBDIRECTORY(sdk)
 
-       ADD_LIBRARY(${TARGET_POLICYD_LIB} STATIC ${${TARGET_POLICYD_LIB}_SRCS})
+#ADD_SUBDIRECTORY(client)
+#ADD_SUBDIRECTORY(conf)
+#ADD_SUBDIRECTORY(pil)
+#ADD_SUBDIRECTORY(server)
+#ADD_SUBDIRECTORY(tools)
+#ADD_SUBDIRECTORY(ui)
 
-       TARGET_LINK_LIBRARIES(${TARGET_POLICYD_LIB} ${POLICYD_DEPS_LIBRARIES} pthread dl)
+ADD_LIBRARY(${TARGET_POLICYD_LIB} STATIC ${${TARGET_POLICYD_LIB}_SRCS})
 
-       SET_TARGET_PROPERTIES(${TARGET_POLICYD_LIB} PROPERTIES COMPILE_FLAGS "-fPIE")
-       SET_TARGET_PROPERTIES(${TARGET_POLICYD_LIB} PROPERTIES LINK_FLAGS "-pie")
-ENDIF(DEFINED GBS_BUILD)
+TARGET_LINK_LIBRARIES(${TARGET_POLICYD_LIB} ${POLICYD_DEPS_LIBRARIES} pthread dl)
+
+SET_TARGET_PROPERTIES(${TARGET_POLICYD_LIB} PROPERTIES COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_POLICYD_LIB} PROPERTIES LINK_FLAGS "-pie")
 
-ADD_SUBDIRECTORY(sdk)
 
 ADD_EXECUTABLE(${TARGET_POLICYD_TEST} ../apix/main/tests.cpp
                                                                          ${${TARGET_POLICYD_LIB}_TESTS})
 
-TARGET_LINK_LIBRARIES(${TARGET_POLICYD_TEST} gtest
+TARGET_LINK_LIBRARIES(${TARGET_POLICYD_TEST} ${TARGET_POLICYD_LIB}
+                                                                                        gtest
                                                                                         pthread)
 ADD_TEST(${TARGET_POLICYD_TEST} ${TARGET_POLICYD_TEST})
 INSTALL(TARGETS ${TARGET_POLICYD_TEST}
diff --git a/src/policyd/core/CMakeLists.txt b/src/policyd/core/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d608072
--- /dev/null
@@ -0,0 +1,21 @@
+# Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ADD_POLICYD_LIBRARY(policyd_core policy-manager.cpp
+                                                                policy-loader.cpp
+                                                                logger.cpp)
+
+FILE(GLOB SDK_TESTS "tests/*.cpp")
+ADD_POLICYD_TEST(${SDK_TESTS})
diff --git a/src/policyd/core/logger.cpp b/src/policyd/core/logger.cpp
new file mode 100644 (file)
index 0000000..927d83c
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include "logger.h"
+
+#include <klay/audit/dlog-sink.h>
+
+namespace policyd {
+
+std::unique_ptr<audit::LogSink> Logger::logSink = nullptr;
+std::once_flag Logger::flag;
+
+audit::LogSink* Logger::GetLogSink(const std::string& tag)
+{
+       std::call_once(flag, [&]() {
+                       auto dlogSink = new audit::DlogLogSink(tag);
+                       logSink.reset(dynamic_cast<audit::LogSink*>(dlogSink));
+               });
+
+       return logSink.get();
+}
+
+} // namespace policyd
diff --git a/src/policyd/core/logger.h b/src/policyd/core/logger.h
new file mode 100644 (file)
index 0000000..c52433e
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include <klay/audit/logger.h>
+
+#include <memory>
+#include <mutex>
+
+#define DPM Logger::GetLogSink("DPM")
+
+namespace policyd {
+
+class Logger {
+public:
+       static audit::LogSink* GetLogSink(const std::string& tag);
+
+private:
+       static std::unique_ptr<audit::LogSink> logSink;
+       static std::once_flag flag;
+};
+
+} // namespace policyd
diff --git a/src/policyd/core/policy-loader.cpp b/src/policyd/core/policy-loader.cpp
new file mode 100644 (file)
index 0000000..173ddf8
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include "policy-loader.h"
+
+namespace policyd {
+
+std::shared_ptr<PolicyProvider> PolicyLoader::load(const std::string& path)
+{
+       PluginLoader loader(path);
+       PolicyProvider::FactoryType factory = nullptr;
+       loader.load(PolicyProvider::getFactoryName(), factory);
+       if (factory == nullptr)
+               std::runtime_error("Failed to load symbol. " + PolicyProvider::getFactoryName());
+
+       std::shared_ptr<PolicyProvider> provider((*factory)());
+       if (provider == nullptr)
+               std::runtime_error("Failed to make provider. " + PolicyProvider::getFactoryName());
+
+       return provider;
+}
+
+PluginLoader::PluginLoader(const std::string& path, int flag)
+       : handle(::dlopen(path.c_str(), flag), ::dlclose)
+{
+       if (handle == nullptr)
+               throw std::invalid_argument("Failed to open: " + path);
+}
+
+} // namespace policyd
diff --git a/src/policyd/core/policy-loader.h b/src/policyd/core/policy-loader.h
new file mode 100644 (file)
index 0000000..22ad283
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include <policyd/sdk/policy-provider.h>
+
+#include <stdexcept>
+#include <string>
+#include <memory>
+
+#include <dlfcn.h>
+
+namespace policyd {
+
+struct PolicyLoader final {
+       static std::shared_ptr<PolicyProvider> load(const std::string& path);
+};
+
+class PluginLoader final {
+public:
+       explicit PluginLoader(const std::string& path, int flag = RTLD_LAZY);
+
+       template<typename T>
+       void load(const std::string& name, T& symbol);
+
+private:
+       using Handle = std::unique_ptr<void, decltype(&::dlclose)>;
+       Handle handle;
+};
+
+template<typename T>
+void PluginLoader::load(const std::string& name, T& symbol)
+{
+       symbol = reinterpret_cast<T>(::dlsym(handle.get(), name.c_str()));
+       if (symbol == nullptr)
+               throw std::runtime_error("Failed to load: " + name);
+}
+
+} // namespace policyd
diff --git a/src/policyd/core/policy-manager.cpp b/src/policyd/core/policy-manager.cpp
new file mode 100644 (file)
index 0000000..7ab04d3
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include "policy-manager.h"
+#include "policy-loader.h"
+#include "logger.h"
+
+#include <klay/filesystem.h>
+
+namespace policyd {
+
+std::pair<int, int> PolicyManager::loadPolicy(const std::string& path) {
+       INFO(DPM, "Load policies from :" << path);
+       klay::File dir(path);
+       if (!dir.exists() || !dir.isDirectory())
+               throw std::invalid_argument("Plugin directory is wrong.: " + path);
+
+       int passed = 0, failed = 0;
+       klay::DirectoryIterator end;
+       for (klay::DirectoryIterator iter(path); iter != end; ++iter) {
+               if (!iter->isFile())
+                       continue;
+
+               try {
+                       auto provider = PolicyLoader::load(iter->getPath());
+                       DEBUG(DPM, "Loaded provider: " << provider->getName());
+                       this->providers.emplace_back(std::move(provider));
+               } catch (const std::exception&) {
+                       ++failed;
+                       ERROR(DPM, "Failed to load: " << iter->getPath());
+                       continue;
+               }
+
+               ++passed;
+       }
+
+       INFO(DPM, "Loaded result >> passed: " << passed << ", failed: " << failed);
+       return std::make_pair(passed, failed);
+}
+
+} // namespace policyd
diff --git a/src/policyd/core/policy-manager.h b/src/policyd/core/policy-manager.h
new file mode 100644 (file)
index 0000000..a3b31ca
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include <policyd/sdk/policy-provider.h>
+
+#include <string>
+#include <exception>
+#include <memory>
+#include <vector>
+
+namespace policyd {
+
+class PolicyManager final {
+public:
+       std::pair<int, int> loadPolicy(const std::string& path);
+
+       std::vector<std::shared_ptr<PolicyProvider>> providers;
+};
+
+} // namespace policyd
diff --git a/src/policyd/core/tests/core-tests.cpp b/src/policyd/core/tests/core-tests.cpp
new file mode 100644 (file)
index 0000000..6a56487
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include <gtest/gtest.h>
+
+#include "../policy-manager.h"
+
+using namespace policyd;
+
+class PolicyCoreTests : public testing::Test {};
+
+TEST_F(PolicyCoreTests, policy_loader) {
+       PolicyManager pm;
+       auto result = pm.loadPolicy(PLUGIN_INSTALL_DIR);
+
+       EXPECT_TRUE(result.first > 0);
+       EXPECT_TRUE(result.second == 0);
+}
index a83cf75..0217554 100644 (file)
@@ -18,7 +18,7 @@
 
 #include "policy-model.h"
 
-#include <exception>
+#include <stdexcept>
 #include <string>
 
 namespace policyd {
index 35f1658..0ebe5a3 100644 (file)
 #include "global-policy.h"
 
 #include <cstddef>
+#include <memory>
 #include <unordered_map>
 
 namespace policyd {
 
-class PolicyProvider final {
+class PolicyProvider {
 public:
+       using FactoryType = PolicyProvider* (*)();
+
        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));
@@ -37,6 +41,10 @@ public:
        }
 
        inline const std::string& getName() const noexcept { return name; }
+       static const std::string& getFactoryName() noexcept {
+               static std::string name = "PolicyFactory";
+               return name;
+       }
 
        std::size_t gsize() { return global.size(); }
        std::size_t dsize() { return domain.size(); }
@@ -47,6 +55,4 @@ private:
        std::unordered_map<std::string, std::shared_ptr<DomainPolicy>> domain;
 };
 
-using PolicyFactory = PolicyProvider* (*)();
-
 } // namespace policyd
similarity index 93%
rename from src/policyd/sdk/tests/policy_tests.cpp
rename to src/policyd/sdk/tests/sdk-tests.cpp
index 568d21c..afc476f 100644 (file)
@@ -30,7 +30,7 @@ namespace {
 
 using namespace policyd;
 
-class PolicyModelTests : public testing::Test {};
+class PolicySDKTests : public testing::Test {};
 
 class TestGlobalPolicy : public GlobalPolicy {
 public:
@@ -41,7 +41,7 @@ public:
        }
 };
 
-TEST_F(PolicyModelTests, global_policy) {
+TEST_F(PolicySDKTests, global_policy) {
        TestGlobalPolicy policy;
 
        EXPECT_EQ(policy.getName(), "test_policy");
@@ -72,7 +72,7 @@ public:
        }
 };
 
-TEST_F(PolicyModelTests, domain_policy) {
+TEST_F(PolicySDKTests, domain_policy) {
        TestDomainPolicy policy;
        uid_t domain = 5001;
 
@@ -94,7 +94,7 @@ TEST_F(PolicyModelTests, domain_policy) {
        EXPECT_EQ(3, policy.get(domain));
 }
 
-TEST_F(PolicyModelTests, policy_provider) {
+TEST_F(PolicySDKTests, policy_provider) {
        PolicyProvider provider("testProvider");
        provider.add(std::make_shared<TestGlobalPolicy>());
        provider.add(std::make_shared<TestDomainPolicy>());