From 7e22ea731daeb0d4999638ecdc96c373be39bfe2 Mon Sep 17 00:00:00 2001 From: Jaemin Ryu Date: Thu, 10 Aug 2017 13:25:00 +0900 Subject: [PATCH] Add security policy Change-Id: I6517713ef05f095877d0c9eced828be63cb209b7 Signed-off-by: Jaemin Ryu --- CMakeLists.txt | 85 +++++++++++++ api/CMakeLists.txt | 48 +++++++ api/dpm-security.pc.in | 12 ++ api/security.cpp | 115 +++++++++++++++++ api/security.h | 183 +++++++++++++++++++++++++++ dpm-security.manifest | 5 + packaging/dpm-security.spec | 79 ++++++++++++ plugin/CMakeLists.txt | 35 ++++++ plugin/security.cpp | 298 ++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 860 insertions(+) create mode 100755 CMakeLists.txt create mode 100755 api/CMakeLists.txt create mode 100644 api/dpm-security.pc.in create mode 100644 api/security.cpp create mode 100644 api/security.h create mode 100644 dpm-security.manifest create mode 100755 packaging/dpm-security.spec create mode 100755 plugin/CMakeLists.txt create mode 100755 plugin/security.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..b1c3c70 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,85 @@ +# +# 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. +# + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +PROJECT(dpm-security) + +IF(NOT DEFINED VERSION) + SET(VERSION "0.0.1") +ENDIF(NOT DEFINED VERSION) + +INCLUDE(FindPkgConfig) + +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE "DEBUG") +ENDIF(NOT CMAKE_BUILD_TYPE) + +SET(DPM_API ${PROJECT_SOURCE_DIR}/api) +SET(DPM_PLUGIN ${PROJECT_SOURCE_DIR}/plugin) + +IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7) + SET(CXX_STD "c++0x") +else() + SET(CXX_STD "c++11") +endif() + +SET(COMPILE_BASE_FLAGS "-g -fPIC -Werror -Wall -Wl,--as-needed -Wl,--no-whole-archive") +SET(CMAKE_C_FLAGS_PROFILING "${COMPILE_BASE_FLAGS} -O0 -pg") +SET(CMAKE_CXX_FLAGS_PROFILING "${COMPILE_BASE_FLAGS} -O0 -pg -std=${CXX_STD} -fno-rtti") +SET(CMAKE_C_FLAGS_DEBUG "${COMPILE_BASE_FLAGS} -O0 -ggdb") +SET(CMAKE_CXX_FLAGS_DEBUG "${COMPILE_BASE_FLAGS} -O0 -ggdb -std=${CXX_STD} -fno-rtti") +SET(CMAKE_C_FLAGS_RELEASE "${COMPILE_BASE_FLAGS} -O2 -DNDEBUG") +SET(CMAKE_CXX_FLAGS_RELEASE "${COMPILE_BASE_FLAGS} -O2 -DNDEBUG -std=${CXX_STD} -fno-rtti") +SET(CMAKE_C_FLAGS_CCOV "${COMPILE_BASE_FLAGS} -O0 --coverage") +SET(CMAKE_CXX_FLAGS_CCOV "${COMPILE_BASE_FLAGS} -O0 --coverage -std=${CXX_STD} -fno-rtti") + +IF(NOT DEFINED LIB_INSTALL_DIR) + SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}") +ENDIF(NOT DEFINED LIB_INSTALL_DIR) + +IF(NOT DEFINED INCLUDE_INSTALL_DIR) + SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") +ENDIF(NOT DEFINED INCLUDE_INSTALL_DIR) + +IF(NOT DEFINED CONF_INSTALL_DIR) + SET(CONF_INSTALL_DIR "${SYSCONF_INSTALL_DIR}/dpm") +ENDIF(NOT DEFINED CONF_INSTALL_DIR) + +IF(NOT DEFINED DATA_INSTALL_DIR) + SET(DATA_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/dpm") +ENDIF(NOT DEFINED DATA_INSTALL_DIR) + +IF(NOT DEFINED DB_INSTALL_DIR) + SET(DB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/dbspace") +ENDIF(NOT DEFINED DB_INSTALL_DIR) + +IF(NOT DEFINED RUN_INSTALL_DIR) + SET(RUN_INSTALL_DIR "/var/run") +ENDIF(NOT DEFINED RUN_INSTALL_DIR) + +IF(NOT DEFINED PAMD_INSTALL_DIR) + SET(PAMD_INSTALL_DIR "${SYSCONF_INSTALL_DIR}/pam.d") +ENDIF(NOT DEFINED PAMD_INSTALL_DIR) + +IF(NOT DEFINED SYSTEMD_UNIT_INSTALL_DIR) + SET(SYSTEMD_UNIT_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system") +ENDIF(NOT DEFINED SYSTEMD_UNIT_INSTALL_DIR) + +ADD_DEFINITIONS(-DUG_WAYLAND) + +ADD_SUBDIRECTORY(${DPM_PLUGIN}) +ADD_SUBDIRECTORY(${DPM_API}) diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt new file mode 100755 index 0000000..e0bb542 --- /dev/null +++ b/api/CMakeLists.txt @@ -0,0 +1,48 @@ +# +# Copyright (c) 2015 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. +# +SET(TARGET ${PROJECT_NAME}) +SET(PC_FILE "${TARGET}.pc") + +SET(LIB_VERSION "${VERSION}") +SET(LIB_SOVERSION "0") + +SET(API_SOURCES "security.cpp") +SET(API_HEADERS "security.h") + +SET(DEPENDENCY klay + dpm-pil + capi-base-common + capi-system-info +) + +PKG_CHECK_MODULES(API_DEPS REQUIRED ${DEPENDENCY}) + +SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack") + +ADD_LIBRARY(${TARGET} SHARED ${API_SOURCES}) + +SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS "-fvisibility=default") +SET_TARGET_PROPERTIES(${TARGET} PROPERTIES SOVERSION ${LIB_SOVERSION}) +SET_TARGET_PROPERTIES(${TARGET} PROPERTIES VERSION ${LIB_VERSION}) + +INCLUDE_DIRECTORIES(SYSTEM ${API_DEPS_INCLUDE_DIRS}) +TARGET_LINK_LIBRARIES(${TARGET} ${API_DEPS_LIBRARIES} pthread) + +CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY) + +INSTALL(FILES ${CMAKE_BINARY_DIR}/${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) +INSTALL(TARGETS ${TARGET} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) +INSTALL(FILES ${API_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/dpm) diff --git a/api/dpm-security.pc.in b/api/dpm-security.pc.in new file mode 100644 index 0000000..eda263d --- /dev/null +++ b/api/dpm-security.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@ + +Name: Security policy module +Description: Security policy module for device policy manager +Version: @VERSION@ +Libs: -L${libdir} -ldpm-security +Cflags: -I${includedir}/dpm diff --git a/api/security.cpp b/api/security.cpp new file mode 100644 index 0000000..24bdcce --- /dev/null +++ b/api/security.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015 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 +#include + +#include + +#include "security.h" + +EXPORT_API int dpm_security_lockout_screen(device_policy_manager_h handle) +{ + RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER); + + DevicePolicyClient &client = GetDevicePolicyClient(handle); + try { + Status status { -1 }; + status = client.methodCall("Security::lockoutScreen"); + return status.get(); + } catch (...) { + return -1; + } +} + +EXPORT_API int dpm_security_set_internal_storage_encryption(device_policy_manager_h handle, bool encrypt) +{ + RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER); + + DevicePolicyClient &client = GetDevicePolicyClient(handle); + try { + Status status { -1 }; + status = client.methodCall("Security::setInternalStorageEncryption", encrypt); + return status.get(); + } catch (...) { + return -1; + } +} + +EXPORT_API int dpm_security_is_internal_storage_encrypted(device_policy_manager_h handle, bool *is_encrypted) +{ + RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER); + RET_ON_FAILURE(is_encrypted, DPM_ERROR_INVALID_PARAMETER); + + DevicePolicyClient &client = GetDevicePolicyClient(handle); + try { + Status status { false }; + status = client.methodCall("Security::isInternalStorageEncrypted"); + *is_encrypted = status.get(); + } catch (...) { + return -1; + } + + return DPM_ERROR_NONE; +} + +EXPORT_API int dpm_security_set_external_storage_encryption(device_policy_manager_h handle, bool encrypt) +{ + RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER); + + DevicePolicyClient &client = GetDevicePolicyClient(handle); + try { + Status status { -1 }; + status = client.methodCall("Security::setExternalStorageEncryption", encrypt); + return status.get(); + } catch (...) { + return -1; + } +} + +EXPORT_API int dpm_security_is_external_storage_encrypted(device_policy_manager_h handle, bool *is_encrypted) +{ + RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER); + RET_ON_FAILURE(is_encrypted, DPM_ERROR_INVALID_PARAMETER); + + DevicePolicyClient &client = GetDevicePolicyClient(handle); + try { + Status status { false }; + status = client.methodCall("Security::isExternalStorageEncrypted"); + *is_encrypted = status.get(); + } catch (...) { + return -1; + } + + return DPM_ERROR_NONE; +} + +EXPORT_API int dpm_security_wipe_data(device_policy_manager_h handle, dpm_security_wipe_type_e type) +{ + int mask = type & (DPM_SECURITY_WIPE_INTERNAL_STORAGE | DPM_SECURITY_WIPE_EXTERNAL_STORAGE); + + RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER); + RET_ON_FAILURE(mask, DPM_ERROR_INVALID_PARAMETER); + + DevicePolicyClient &client = GetDevicePolicyClient(handle); + try { + Status status { -1 }; + status = client.methodCall("Security::wipeData", mask); + return status.get(); + } catch (...) { + return -1; + } +} diff --git a/api/security.h b/api/security.h new file mode 100644 index 0000000..6431c7e --- /dev/null +++ b/api/security.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2015 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 + */ + +#ifndef __CAPI_DPM_SECURITY_POLICY_H__ +#define __CAPI_DPM_SECURITY_POLICY_H__ + +#include + +typedef void * device_policy_manager_h; + +/** + * @file security.h + * @brief This file provides APIs to control security functionality such as + * device encryption and screen lock. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup CAPI_DPM_SECURITY_POLICY_MODULE + * @{ + */ + +/** + * @partner + * @brief Locks device screen immediately. + * @details An administrator can use this API to lock the device screen + * immediately + * @since_tizen 3.0 + * @privlevel partner + * @privilege %http://tizen.org/privilege/dpm.lock + * @param[in] handle Device policy manager handle + * @return #DPM_ERROR_NONE on success, otherwise a negative value + * @retval #DPM_ERROR_NONE Successful + * @retval #DPM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DPM_ERROR_PERMISSION_DENIED The application does not have + * the privilege to call this API + * @pre The handle must be created by dpm_manager_create(). + * @see dpm_manager_create() + */ +int dpm_security_lockout_screen(device_policy_manager_h handle); + +/** + * @partner + * @brief Encrypts or decrypts internal storage. + * @details An administrator can use this API to enable full device + * encryption, which includes device memory and internal SD card. + * Before calling this API, administrator must ensure that + * the device password is set to alphanumeric quality. + * The administrator can set an alphanumeric password by using + * dpm_set_password_quality() API + * @since_tizen 3.0 + * @privlevel partner + * @privilege %http://tizen.org/privilege/dpm.security + * @param[in] handle Device policy manager handle + * @param[in] encrypt true if encryption is required, false if decryption is + * required + * @return #DPM_ERROR_NONE on success, otherwise a negative value + * @retval #DPM_ERROR_NONE Successful + * @retval #DPM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DPM_ERROR_PERMISSION_DENIED The application does not have + * the privilege to call this API + * @pre The handle must be created by dpm_manager_create(). + * @see dpm_manager_create() + * @see dpm_security_is_internal_storage_encrypted() + */ +int dpm_security_set_internal_storage_encryption(device_policy_manager_h handle, bool encrypt); + +/** + * @brief Checks the internal storage encryption state. + * @details An administrator can use this API to check whether internal + * storage encryption is enabled. + * @since_tizen 3.0 + * @param[in] handle Device policy manager handle + * @param[out] is_encrypted true if internal storage is encrypted or being encrypted, + * else false. + * @return #DPM_ERROR_NONE on success, otherwise a negative value + * @retval #DPM_ERROR_NONE Successful + * @retval #DPM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DPM_ERROR_TIMED_OUT Time out + * @pre The handle must be created by dpm_manager_create(). + * @see dpm_manager_create() + * @see dpm_security_set_internal_storage_encryption() + */ +int dpm_security_is_internal_storage_encrypted(device_policy_manager_h handle, bool *is_encrypted); + +/** + * @partner + * @brief Encrypts or decrypts external storage. + * @details An administrator can use this API to enable external SD card + * encryption. Before calling this API, administrator must + * ensure that the device password is set to alphanumeric quality. + * The administrator can set an alphanumeric password by using + * dpm_set_password_quality() API + * @since_tizen 3.0 + * @privlevel partner + * @privilege %http://tizen.org/privilege/dpm.security + * @param[in] handle Device policy manager handle + * @param[in] encrypt true if encryption is required, false if decryption is + * required + * @return #DPM_ERROR_NONE on success, otherwise a negative value + * @retval #DPM_ERROR_NONE Successful + * @retval #DPM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DPM_ERROR_PERMISSION_DENIED The application does not have + * the privilege to call this API + * @pre The handle must be created by dpm_manager_create(). + * @see dpm_manager_create() + * @see dpm_security_is_external_storage_encryped() + */ +int dpm_security_set_external_storage_encryption(device_policy_manager_h handle, bool encrypt); + +/** + * @brief Checks the external storage encryption state. + * @details An administrator can use this API to check whether external + * storage encryption is enabled. + * @since_tizen 3.0 + * @param[in] handle Device policy manager handle + * @param[out] is_encrypted true if external storage is encrypted or being encrypted, + * else false + * @return #DPM_ERROR_NONE on success, otherwise a negative value + * @retval #DPM_ERROR_NONE Successful + * @retval #DPM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DPM_ERROR_TIMED_OUT Time out + * @pre The handle must be created by dpm_manager_create(). + * @see dpm_manager_create() + * @see dpm_security_set_external_storage_encryption() + */ +int dpm_security_is_external_storage_encrypted(device_policy_manager_h handle, bool *is_encrypted); + +/** + * @brief Enumeration for device wipe type. + * @since_tizen 3.0 + */ +typedef enum { + DPM_SECURITY_WIPE_INTERNAL_STORAGE = (1 << 0), /**< Wipe internal memory */ + DPM_SECURITY_WIPE_EXTERNAL_STORAGE = (1 << 1), /**< Wipe external memory */ +} dpm_security_wipe_type_e; + +/** + * @partner + * @brief Wipes external memory, internal memory, or both selectively. + * @details Device Admin can use this API to wipe both SD card data + * and application data. + * Calling this API may require rebooting the device. + * @since_tizen 3.0 + * @privlevel partner + * @privilege %http://tizen.org/privilege/dpm.wipe + * @param[in] handle Device policy manager handle + * @param[in] type The target storage for wipe + * @return #DPM_ERROR_NONE on success, otherwise a negative value + * @retval #DPM_ERROR_NONE Successful + * @retval #DPM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DPM_ERROR_PERMISSION_DENIED The application does not have + * the privilege to call this API + * @pre The handle must be created by dpm_manager_create(). + * @see dpm_manager_create() + */ +int dpm_security_wipe_data(device_policy_manager_h handle, dpm_security_wipe_type_e type); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif //! __CAPI_DPM_SECURITY_POLICY_H__ diff --git a/dpm-security.manifest b/dpm-security.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/dpm-security.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/dpm-security.spec b/packaging/dpm-security.spec new file mode 100755 index 0000000..dcb8f62 --- /dev/null +++ b/packaging/dpm-security.spec @@ -0,0 +1,79 @@ +Name: dpm-security +Version: 1.0.1 +Release: 0 +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Summary: Tizen Device Policy Manager Security Policy Module +Group: Security/Other +BuildRequires: gcc +BuildRequires: cmake +BuildRequires: gettext-tools +BuildRequires: pkgconfig(klay) +BuildRequires: pkgconfig(dpm-pil) +BuildRequires: pkgconfig(deviced) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(vconf-internal-keys) +BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(capi-base-common) + +%description +The dpm-security package provides security policy module for device policy manager + +%files +%manifest dpm-security.manifest +%defattr(644,root,root,755) +%attr(755,root,root) /opt/data/dpm/plugins/security +%attr(755,root,root) %{_libdir}/libdpm-security.so.%{version} +%{_libdir}/libdpm-security.so.0 + +%prep +%setup -q + +%build +%{!?build_type:%define build_type "RELEASE"} + +%if %{build_type} == "DEBUG" || %{build_type} == "PROFILING" || %{build_type} == "CCOV" + CFLAGS="$CFLAGS -Wp,-U_FORTIFY_SOURCE" + CXXFLAGS="$CXXFLAGS -Wp,-U_FORTIFY_SOURCE" +%endif + +%cmake . -DVERSION=%{version} \ + -DCMAKE_BUILD_TYPE=%{build_type} \ + -DSCRIPT_INSTALL_DIR=%{_scriptdir} \ + -DSYSTEMD_UNIT_INSTALL_DIR=%{_unitdir} \ + -DDATA_INSTALL_DIR=%{TZ_SYS_DATA}/dpm \ + -DDB_INSTALL_DIR=%{TZ_SYS_DB} \ + -DRUN_INSTALL_DIR=%{TZ_SYS_RUN} \ + -DAPP_INSTALL_PREFIX="%{TZ_SYS_RO_APP}" \ + -DAPP_SHARE_PACKAGES_DIR="%{TZ_SYS_RO_PACKAGES}" \ + +make %{?jobs:-j%jobs} + +%install +%make_install + +%clean +rm -rf %{buildroot} + +%post + +%preun + +%postun + +## Devel Package ############################################################## +%package -n libdpm-security-devel +Summary: Libraries and header files for device policy client development +Group: Development/Libraries +Requires: device-policy-manager = %{version}-%{release} + +%description -n libdpm-security-devel +The libdpm-security-devel package includes the libraries and header files necessary for +developing the DPM client program. + +%files -n libdpm-security-devel +%manifest dpm-security.manifest +%defattr(644,root,root,755) +%{_libdir}/libdpm-security.so +%{_libdir}/pkgconfig/dpm-security.pc +%{_includedir}/dpm diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt new file mode 100755 index 0000000..c23755d --- /dev/null +++ b/plugin/CMakeLists.txt @@ -0,0 +1,35 @@ +# +# Copyright (c) 2015 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. +# +SET(TARGET "dpm-plugin-security") + +SET(PLUGIN_SOURCES "security.cpp") + +SET(DEPENDENCY klay + dpm-pil + vconf + deviced +) + +PKG_CHECK_MODULES(PLUGIN_DEPS REQUIRED ${DEPENDENCY}) + +SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack") + +ADD_LIBRARY(${TARGET} SHARED ${PLUGIN_SOURCES}) +SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS "-fvisibility=default") +INCLUDE_DIRECTORIES(SYSTEM ${PLUGIN_DEPS_INCLUDE_DIRS}) +TARGET_LINK_LIBRARIES(${TARGET} ${PLUGIN_DEPS_LIBRARIES}) + +INSTALL(FILES libdpm-plugin-security.so RENAME security DESTINATION /opt/data/dpm/plugins) diff --git a/plugin/security.cpp b/plugin/security.cpp new file mode 100755 index 0000000..b0271cf --- /dev/null +++ b/plugin/security.cpp @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2015 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 +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace { + +const std::string APPID_DEVICE_ENCRYPTION = "org.tizen.ode"; +const std::string APPID_LOCKSCREEN = "org.tizen.lockscreen"; + +const std::string PROG_FACTORY_RESET = "/usr/bin/dbus-send"; +const std::vector wipeCommand = { + "/usr/bin/dbus-send", + "--system", + "--type=signal", + "--print-reply", + "--dest=com.samsung.factoryreset", + "/com/samsung/factoryreset", + "com.samsung.factoryreset.start.setting" +}; + +bool checkEncryptionState(const char* key, bool encrypt) +{ + char *value = ::vconf_get_str(key); + if (value == NULL) { + ERROR("Failed to read internal storage encryption state"); + return false; + } + + std::string state(value); + ::free(value); + if (encrypt) { + if (state != "unencrypted") { + ERROR("Storage might be already encrypted or it has error"); + return false; + } + } else { + if (state != "encrypted") { + ERROR("Storage might be already decrypted or it has error"); + return false; + } + } + + return true; +} + +bool getEncryptionState(const char* key) +{ + char *state = ::vconf_get_str(key); + if (state == NULL) { + throw runtime::Exception("Failed to read internal storage encryption state"); + } + + std::string expected("encrypted"); + if (expected == state) { + ::free(state); + return true; + } + + ::free(state); + return false; +} + +int launchApplication(const std::string& name, const Bundle& bundle) +{ + try { + Launchpad launchpad(rmi::Service::getPeerUid()); + if (launchpad.isRunning(name)) { + launchpad.resume(name); + return 0; + } + + launchpad.launch(name, bundle); + } catch (runtime::Exception& e) { + ERROR("Failed to start application: " << name); + return -1; + } + + return 0; +} + + +std::vector getStorageDeviceList(const std::string& type) +{ + int intparams[6]; + char* strparams[7]; + std::vector storages; + + dbus::Connection &systemDBus = dbus::Connection::getSystem(); + const dbus::Variant &var = systemDBus.methodcall("org.tizen.system.storage", + "/Org/Tizen/System/Storage/Block/Manager", + "org.tizen.system.storage.BlockManager", + "GetDeviceList", + -1, + "(a(issssssisibii))", + "(s)", + type.c_str()); + dbus::VariantIterator it; + var.get("(a(issssssisibii))", &it); + while (it.get("(issssssisibii)", + &intparams[0], // block type: 0 - scsi, 1 : mmc + &strparams[0], // devnode + &strparams[1], // syspath + &strparams[2], // usage + &strparams[3], // fs type + &strparams[4], // fs version + &strparams[5], // fs uuid enc + &intparams[1], // readonly: 0 - rw, 1 - ro + &strparams[6], // mount point + &intparams[2], // state: 0 - unmount, 1 - mount + &intparams[3], // primary: 0 - flase, 1 - true + &intparams[4], // flags: 1 - unmounted + // 2 - broken filesystem + // 4 - no filesystem + // 8 - not supported + // 16 - readonly + &intparams[5])) { // strage id + storages.push_back(strrchr(strparams[0], '/') + 1); + for (int i = 0; i < 7; i++) { + if (strparams[i]) { + ::free(strparams[i]); + } + } + } + + return storages; +} + +void requestDeviceFormat(const std::string& devnode, int option) +{ + int ret; + dbus::Connection &systemDBus = dbus::Connection::getSystem(); + systemDBus.methodcall("org.tizen.system.storage", + "/Org/Tizen/System/Storage/Block/Devices/" + devnode, + "org.tizen.system.storage.Block", + "Format", + G_MAXINT, + "(i)", + "(i)", + option).get("(i)", &ret); + if (ret != 0) { + throw runtime::Exception("Failed to format " + devnode); + } +} + +} // namespace + +class Security : public AbstractPolicyProvider { +public: + enum { + WIPE_INTERNAL_STORAGE = (1 << 0), /**< Wipe internal memory */ + WIPE_EXTERNAL_STORAGE = (1 << 1), /**< Wipe external memory */ + }; + + Security(); + ~Security(); + + int lockoutScreen(); + + int wipeData(int id); + + int setInternalStorageEncryption(bool encrypt); + bool isInternalStorageEncrypted(); + int setExternalStorageEncryption(bool encrypt); + bool isExternalStorageEncrypted(); +}; + +Security::Security() +{ +} + +Security::~Security() +{ +} + +int Security::lockoutScreen() +{ + return launchApplication(APPID_LOCKSCREEN, Bundle()); +} + +int Security::setInternalStorageEncryption(bool encrypt) +{ + if (!checkEncryptionState(VCONFKEY_ODE_CRYPTO_STATE, encrypt)) { + return -1; + } + + Bundle bundle; + bundle.add("viewtype", encrypt ? "ENCRYPT_DEVICE" : "DECRYPT_DEVICE"); + return launchApplication(APPID_DEVICE_ENCRYPTION, bundle); +} + +bool Security::isInternalStorageEncrypted() +{ + return getEncryptionState(VCONFKEY_ODE_CRYPTO_STATE); +} + +int Security::setExternalStorageEncryption(bool encrypt) +{ + if (!checkEncryptionState(VCONFKEY_SDE_CRYPTO_STATE, encrypt)) { + return -1; + } + + Bundle bundle; + bundle.add("viewtype", encrypt ? "ENCRYPT_SD_CARD" : "DECRYPT_SD_CARD"); + return launchApplication(APPID_DEVICE_ENCRYPTION, bundle); +} + +bool Security::isExternalStorageEncrypted() +{ + return getEncryptionState(VCONFKEY_SDE_CRYPTO_STATE); +} + +int Security::wipeData(int id) +{ + auto worker = [id, this]() { + if (id & WIPE_EXTERNAL_STORAGE) { + try { + std::vector devices = getStorageDeviceList("mmc"); + for (const std::string& devnode : devices) { + std::cout << "Erase device: " << devnode << std::endl; + requestDeviceFormat(devnode, 1); + std::cout << "Erase device: " << devnode << " completed" << std::endl; + } + } catch(runtime::Exception& e) { + ERROR("Failed to enforce external storage policy"); + return -1; + } + } + + if (id & WIPE_INTERNAL_STORAGE) { + runtime::Process proc(PROG_FACTORY_RESET, wipeCommand); + if (proc.execute() == -1) { + ERROR("Failed to launch factory-reset"); + return -1; + } + } + + return 0; + }; + + std::thread deviceWiper(worker); + deviceWiper.detach(); + + return 0; +} + +extern "C" { + +#define PRIVILEGE_SECURITY "http://tizen.org/privilege/dpm.security" +#define PRIVILEGE_WIPE "http://tizen.org/privilege/dpm.wipe" +#define PRIVILEGE_LOCK "http://tizen.org/privilege/dpm.lock" + +AbstractPolicyProvider *PolicyFactory(PolicyControlContext& context) +{ + Security *policy = new Security(); + + context.expose(policy, PRIVILEGE_SECURITY, (int)(Security::setInternalStorageEncryption)(bool)); + context.expose(policy, PRIVILEGE_SECURITY, (int)(Security::setExternalStorageEncryption)(bool)); + context.expose(policy, PRIVILEGE_WIPE, (int)(Security::wipeData)(int)); + context.expose(policy, PRIVILEGE_LOCK, (int)(Security::lockoutScreen)()); + + context.expose(policy, "", (bool)(Security::isInternalStorageEncrypted)()); + context.expose(policy, "", (bool)(Security::isExternalStorageEncrypted)()); + + return policy; +} + +} // extern "C" + + -- 2.7.4