diff options
author | jk7744.park <jk7744.park@samsung.com> | 2015-09-08 22:36:05 +0900 |
---|---|---|
committer | jk7744.park <jk7744.park@samsung.com> | 2015-09-08 22:36:05 +0900 |
commit | 359f9ea27a0eb32390ef84fee3047cb873328db7 (patch) | |
tree | b6c7b72a060a04d29f40e250a3314f7c9060c3b7 | |
parent | 17521b8522b4648315cc4c47a61b7be1f49ed487 (diff) | |
download | privacy-manager-tizen_2.3.1.tar.gz privacy-manager-tizen_2.3.1.tar.bz2 privacy-manager-tizen_2.3.1.zip |
tizen 2.3.1 releasetizen_2.3.1_releasesubmit/tizen_2.3.1/20150915.081913tizen_2.3.1
62 files changed, 6062 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5c20d87 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +MESSAGE("build privacy-manager") + +SET(CMAKE_VERBOSE_MAKEFILE OFF) + +IF("${USE_AUTOSTART}" STREQUAL "1") + ADD_DEFINITIONS("-DUSE_AUTOSTART") +ENDIF() + +ADD_DEFINITIONS("-DCLIENT_IPC_THREAD") +ADD_DEFINITIONS("-DUSE_IPC_EPOLL") + +STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}") +ADD_DEFINITIONS("-DAPI_VERSION=\"$(API_VERSION)\"") + +ADD_SUBDIRECTORY(server) +ADD_SUBDIRECTORY(client) +ADD_SUBDIRECTORY(pkgmgr_plugin) diff --git a/LICENSE.Apache-2.0 b/LICENSE.Apache-2.0 new file mode 100644 index 0000000..a795f06 --- /dev/null +++ b/LICENSE.Apache-2.0 @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2011 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. + diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100644 index 0000000..3d545bc --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,100 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(this_target privacy-manager-client) +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") + +INCLUDE(FindPkgConfig) +pkg_check_modules(${this_target} REQUIRED dlog sqlite3 dbus-1 dbus-glib-1 db-util pkgmgr-info capi-system-info vconf capi-appfw-app-manager capi-appfw-package-manager) + +FOREACH(flag ${${this_target}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS_PROFILING " -g -pg") +SET(CMAKE_CXX_FLAGS_PROFILING " -std=c++0x -g -pg") +SET(CMAKE_C_FLAGS_DEBUG " -g") +SET(CMAKE_CXX_FLAGS_DEBUG " -std=c++0x -g") +SET(CMAKE_C_FLAGS_RELEASE " -g") +SET(CMAKE_CXX_FLAGS_RELEASE " -std=c++0x -g") +SET(CMAKE_C_FLAGS_CCOV " -g --coverage") +SET(CMAKE_CXX_FLAGS_CCOV " -std=c++0x -g --coverage") + +SET(client_src_dir "${CMAKE_SOURCE_DIR}/client/src") +SET(client_include_dir "${CMAKE_SOURCE_DIR}/client/inc/") +SET(common_src_dir "${CMAKE_SOURCE_DIR}/common/src/") +SET(common_include_dir "${CMAKE_SOURCE_DIR}/common/inc/") +#SET(lib_include_dir +# "/usr/include/dbus-1.0" +# "/usr/include/aul" +#) + +## Additional flag +ADD_DEFINITIONS("-fvisibility=hidden") +ADD_DEFINITIONS("-Wall -Werror") +ADD_DEFINITIONS("-DDLOG_ERROR_ENABLED") +#OPTION (FILTER_LISTED_PKG "FILTER PKG BY LIST" ON) +#IF(FILTER_LISTED_PKG) +# MESSAGE("FILTER PKGs BY FILTERING LIST") +# ADD_DEFINITIONS("-D__FILTER_LISTED_PKG") +#ENDIF(FILTER_LISTED_PKG) +OPTION (FILTER_PRELOADED_PKG "FILTER PRELOADEDPKG BY LIST" ON) +IF(FILTER_PRELOADED_PKG) + MESSAGE("FILTER PKGs BY PRELOADED PKG") + ADD_DEFINITIONS("-D__FILTER_PRELOADED_PKG") +ENDIF(FILTER_PRELOADED_PKG) + +OPTION (LOCATION_FILTER_LISTED_PKG "LOCATION FILTER PKG BY LIST" ON) +IF(LOCATION_FILTER_LISTED_PKG) + MESSAGE("LOCATION FILTER PKGs BY FILTERING LIST") + ADD_DEFINITIONS("-D__LOCATION_FILTER_LISTED_PKG") +ENDIF(LOCATION_FILTER_LISTED_PKG) + +################################################################################################### +## for lib${this_target} (executable) +INCLUDE_DIRECTORIES(${${this_target}_INCLUDE_DIRS} ${client_include_dir} ${common_include_dir} ${lib_include_dir}) +SET(PRIVACY_MANAGER_CLIENT_SOURCES + ${common_src_dir}/SocketConnection.cpp + ${common_src_dir}/SocketStream.cpp + ${common_src_dir}/PrivacyIdInfo.cpp + ${common_src_dir}/PrivacyDb.cpp + ${client_src_dir}/SocketClient.cpp + ${client_src_dir}/PrivacyManagerClient.cpp + ${client_src_dir}/PrivacyChecker.cpp + ${client_src_dir}/privacy_checker_client.cpp + ${client_src_dir}/privacy_info_client.cpp + ${client_src_dir}/privacy_manager_client.cpp + ) +SET(PRIVACY_MANAGER_CLIENT_HEADERS + ${client_include_dir}/PrivacyManagerClient.h + ${client_include_dir}/PrivacyChecker.h + ${client_include_dir}/privacy_info_client.h + ${client_include_dir}/privacy_manager_client.h + ${client_include_dir}/privacy_checker_client.h + ${common_include_dir}/privacy_manager_client_types.h +) +SET(PRIVACY_MANAGER_CLIENT_LDFLAGS " -module -avoid-version ") +SET(PRIVACY_MANAGER_CLIENT_CFLAGS " ${CFLAGS} -fPIC ") +#SET(PRIVACY_MANAGER_CLIENT_LIBADD " ") + +ADD_DEFINITIONS("-DLOG_TAG=\"PRIVACY-MANAGER-CLIENT\"") +ADD_LIBRARY(${this_target} SHARED ${PRIVACY_MANAGER_CLIENT_SOURCES}) +TARGET_LINK_LIBRARIES(${this_target} ${${this_target}_LDFLAGS} ${${this_target}_LIBRARIES}) +SET_TARGET_PROPERTIES(${this_target} PROPERTIES COMPILE_FLAGS "${PRIVACY_MANAGER_CLIENT_CFLAGS}") +SET_TARGET_PROPERTIES(${this_target} PROPERTIES SOVERSION ${API_VERSION}) +SET_TARGET_PROPERTIES(${this_target} PROPERTIES VERSION ${VERSION}) +################################################################################################### + +SET(PC_NAME ${this_target}) +SET(PC_DESCRIPTION "Privacy Manager Client API") +SET(PC_LDFLAGS "-l${this_target}") +SET(PC_CFLAGS -I\${includedir}/privacy_manager) + +CONFIGURE_FILE(../${this_target}.pc.in ${this_target}.pc @ONLY) + +INSTALL(TARGETS ${this_target} DESTINATION ../lib COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${this_target}.pc DESTINATION ../lib/pkgconfig) +INSTALL(FILES ${PRIVACY_MANAGER_CLIENT_HEADERS} DESTINATION ../include/privacy_manager) diff --git a/client/inc/PrivacyChecker.h b/client/inc/PrivacyChecker.h new file mode 100644 index 0000000..96ab93d --- /dev/null +++ b/client/inc/PrivacyChecker.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2012 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 _PRIVACY_CHECKER_H_ +#define _PRIVACY_CHECKER_H_ + +#include <string> +#include <mutex> +#include <list> +#include <vector> +#include <memory> +#include <map> +#include <condition_variable> +#include <PrivacyManagerTypes.h> +#include <dbus/dbus.h> +#include <glib.h> + +struct sqlite3; + +class EXTERN_API PrivacyChecker +{ +private: + static std::map < std::string, std::pair<bool,bool> > m_privacyCache; + static std::map < std::string, std::map < std::string, std::pair<bool,bool> > > m_privacyInfoCache; + static std::string m_pkgId; + static bool m_isInitialized; + static std::mutex m_cacheMutex; + static DBusConnection* m_pDBusConnection; + static GMainLoop* m_pLoop; + static GMainContext* m_pHandlerGMainContext; + static pthread_t m_signalThread; + static std::mutex m_dbusMutex; + static std::condition_variable m_condition; + static std::mutex m_initializeMutex; + static bool m_isPreloaded; + static bool m_isServiceProcess; + +private: + static int initializeDbus(void); + static int finalizeDbus(void); + static int updateCache(const std::string pkgId, std::string privacyId, std::map < std::string, std::pair<bool,bool> >& pkgCacheMap); + static int updateCache(const std::string pkgId, std::map < std::string, std::pair<bool,bool> >& pkgCacheMap); + static void printCache(void); + static void* runSignalListenerThread(void* pData); + static int getCurrentPkgId(std::string& pkgId); + static int check(const std::string privacyId, std::map < std::string, std::pair<bool,bool> >& privacyMap); + static void notify(const std::string& pkgId, const std::string privacyId); + static void removeWhiteSpace(std::string& packageNameString); + static bool isExceptionalCase(const std::string&); + +public: + // for Checking in Server Process + static int initialize(const std::string pkgId); + static int check(const std::string pkgId, const std::string privacyId); + static int checkWithPrivilege(const std::string pkgId, const std::string privilegeId); + static int checkWithDeviceCap(const std::string pkgId, const std::string deviceCap); + + // for Checking in App Process + static int initialize(void); + static int check(const std::string privacyId); + static int checkWithPrivilege(const std::string privilegeId); + static int checkWithDeviceCap(const std::string deviceCap); + static int checkExceptionalCase(std::string& pkgId, const std::string &privacyId); + + // common + static int finalize(void); + static int finalizeWihtoutCache(void); + static DBusHandlerResult handleNotification(DBusConnection* connection, DBusMessage* message, void* user_data); + + // utility + static int getPackageId(std::string& pkgId); + static int isPreloadedPackage(const std::string& pkdId); +}; + +#endif // _PRIVACY_CHECKER_H_ diff --git a/client/inc/PrivacyManagerClient.h b/client/inc/PrivacyManagerClient.h new file mode 100644 index 0000000..cfd34ca --- /dev/null +++ b/client/inc/PrivacyManagerClient.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2012 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 _PRIVACY_MANAGER_H_ +#define _PRIVACY_MANAGER_H_ + +#include <string> +#include <mutex> +#include <list> +#include <vector> +#include <memory> +#include <PrivacyManagerTypes.h> + +class SocketClient; + +class EXTERN_API PrivacyManagerClient +{ +private: + static PrivacyManagerClient* m_pInstance; + static const std::string INTERFACE_NAME; + + std::unique_ptr< SocketClient > m_pSocketClient; + + static std::mutex m_singletonMutex; + + PrivacyManagerClient(); + ~PrivacyManagerClient(); + +public: + static PrivacyManagerClient* getInstance(void); + + int addAppPackagePrivacyInfo(const std::string pkgId, const std::list < std::string >& list, bool privacyPopupRequired, bool isServerOperation = true); + + int removeAppPackagePrivacyInfo(const std::string pkgId, bool isServerOperation = true); + + int setPrivacySetting(const std::string pkgId, const std::string privacyId, bool isEnabled); + + int getPrivacyAppPackages(std::list < std::string >& list) const; + + int getAppPackagePrivacyInfo(const std::string pkgId, std::list < std::pair <std::string, bool > > & list) const; + + int isUserPrompted(const std::string pkgId, bool& isPrompted) const; + + int setUserPrompted(const std::string pkgId, bool prompted); + + int getAppPackagesbyPrivacyId(const std::string privacyId, std::list < std::pair < std::string, bool > >& list) const; + + int getPrivaycDisplayName(const std::string privacyId, std::string& displayName) const; + + int getPrivaycDisplayNameStringId(const std::string privacyId, std::string& displayNameStringId) const; + + int getPrivaycDescription(const std::string privacyId, std::string& description) const; + + int getPrivaycDescriptionStringId(const std::string privacyId, std::string& descriptionStringId) const; + + int notifyUserNotConsented(const std::string pkgId, const std::string privacyId) const; +}; + +#endif // _PRIVACY_MANAGER_H_ diff --git a/client/inc/SocketClient.h b/client/inc/SocketClient.h new file mode 100644 index 0000000..d2713b1 --- /dev/null +++ b/client/inc/SocketClient.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2012 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 SECURITYSOCKETCLIENT_H_ +#define SECURITYSOCKETCLIENT_H_ + +#include <memory> +#include <string> +#include <dlog.h> +#include "SocketConnection.h" + +/* IMPORTANT: + * Methods connect(), call() and disconnected() should be called one by one. + * Between connect() and disconnect() you can use call() only once. + * It is because of timeout on call, e.g. to avoid waiting for corrupted data. + */ + +/* USAGE: + * Class should be used according to this scheme: + * SocketClient client("Interface Name"); + * (...) + * client.connect(); + * client.call("Method name", in_arg1, in_arg2, ..., in_argN, + * out_arg1, out_arg2, ..., out_argM); + * client.disconnect(); + * (...) + * + * input parameters of the call are passed with reference, + * output ones are passed as pointers - parameters MUST be passed this way. + * + * Currently client supports serialization and deserialization of simple types + * (int, char, float, unsigned), strings (std::string and char*) and + * some STL containers (std::vector, std::list, std::map, std::pair). + * Structures and classes are not (yet) supported. + */ + +#include <string> +#include <PrivacyManagerTypes.h> + +class EXTERN_API SocketClient +{ +public: + + SocketClient(const std::string &interfaceName); + int connect(); + int disconnect(); + + int call(std::string methodName) + { + int res = make_call(m_interfaceName); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + + res = make_call(methodName); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename ...Args> + int call(std::string methodName, const Args&... args) + { + int res = make_call(m_interfaceName); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + res = make_call(methodName); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + res = make_call(args...); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename T> + int read(T* outvalue) + { + return m_socketConnector->read(outvalue); + } +private: + template<typename T, typename ...Args> + int make_call(const T& invalue, const Args&... args) + { + int res = make_call(invalue); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + res = make_call(args...); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename T> + int make_call(const T& invalue) + { + return m_socketConnector->write(invalue); + } + + template<typename T, typename ...Args> + int make_call(const T* invalue, const Args&... args) + { + int res = make_call(invalue); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + res = make_call(args...); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename T> + int make_call(const T* invalue) + { + return m_socketConnector->write(invalue); + } + + template<typename T, typename ...Args> + int make_call(T * outvalue, const Args&... args) + { + int res = make_call(outvalue); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + res = make_call(args...); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "make_call : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename T> + int make_call(T* outvalue) + { + return m_socketConnector->read(outvalue); + } + + +private: + std::string m_serverAddress; + std::string m_interfaceName; + std::unique_ptr<SocketConnection> m_socketConnector; + int m_socketFd; +}; + +#endif /* SECURITYSOCKETCLIENT_H_ */
\ No newline at end of file diff --git a/client/inc/privacy_checker_client.h b/client/inc/privacy_checker_client.h new file mode 100644 index 0000000..63fff77 --- /dev/null +++ b/client/inc/privacy_checker_client.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013 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 _PRIVACY_CHECKER_CLIENT_H +#define _PRIVACY_CHECKER_CLIENT_H + +#include <privacy_manager_client_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup CAPI_PRIVACY_MANAGER_MODULE + * @{ + */ + +/** + * @brief Initialize privacy checker + * @param [in] package_id The ID of the pacakge to check + * @return PRIV_MGR_ERROR_SUCCESS on success, otherwise a negative error value + * @retval #PRIV_MGR_ERROR_SUCCESS Successful + * @retval #PRIV_MGR_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PRIV_MGR_ERROR_SYSTEM_ERROR Failed to initialize + * @post privacy_checker_finalize must be called to finalize + */ +EXTERN_API int privacy_checker_initialize(const char *package_id); + +/** + * @brief Checks privacy is enabled or not by privacy id + * @param [in] privacy_ud The ID of privacy + * @return PRIV_MGR_ERROR_SUCCESS if the privacy is enabled else PRIV_MGR_ERROR_USER_NOT_CONSENTED, otherwise a negative error value + * @retval #PRIV_MGR_ERROR_SUCCESS Successful + * @retval #PRIV_MGR_ERROR_NOT_INITIALIZED Privacy chcker is not initialized + * @retval #PRIV_MGR_ERROR_DB_ERROR DB operation failed + * @retval #PRIV_MGR_ERROR_USER_NOT_CONSENTED The privacy of the package disabled + * @pre privacy_checker_initialize must be called to initialize + * @post privacy_checker_finalize must be called to finalize + * @see privacy_checker_initialize + * @see privacy_checker_finalize + */ +EXTERN_API int privacy_checker_check_by_privacy(const char *privacy_id); + +/** + * @brief Checks privacy is enabled or not by privilege id + * @param [in] privilege_id The ID of the privilege + * @return PRIV_MGR_ERROR_SUCCESS if the privacy is enabled else PRIV_MGR_ERROR_USER_NOT_CONSENTED, otherwise a negative error value + * @retval #PRIV_MGR_ERROR_SUCCESS Successful + * @retval #PRIV_MGR_ERROR_NOT_INITIALIZED Privacy chcker is not initialized + * @retval #PRIV_MGR_ERROR_DB_FAILED DB operation failed + * @retval #PRIV_MGR_ERROR_INVALID_PARAMETER invalid parameter + * @retval #PRIV_MGR_ERROR_USER_NOT_CONSENTED The privacy of the package disabled + * @remark Caller can free resource by calling privacy_checker_finalize() after calling this API otherwise, finalize while library unloading\n + * This API initialize privacy checker for the first time + * @see privacy_checker_finalize + */ +EXTERN_API int privacy_checker_check_by_privilege(const char *privilege_id); + +/** + * @brief Finalize privacy checker + * @return 0 on success. + * @retval #PRIV_MGR_ERROR_SUCCESS Successful + */ +EXTERN_API int privacy_checker_finalize(void); + +/** + * @brief Check privacy is enabled or not by privilege id of the package + * @param [in] package_id The ID of the pacakge + * @param [in] privacy_id The ID of the privacy + * @return PRIV_MGR_ERROR_SUCCESS if the privacy is enabled else PRIV_MGR_ERROR_USER_NOT_CONSENTED, otherwise a negative error value + * @retval #PRIV_MGR_ERROR_SUCCESS Successful + * @retval #PRIV_MGR_ERROR_DB_FAILED DB operation failed + * @retval #PRIV_MGR_ERROR_INVALID_PARAMETER invalid parameter + * @retval #PRIV_MGR_ERROR_USER_NOT_CONSENTED The privacy of the package disabled + * @post privacy_checker_finalize must be called to finalize + * @see privacy_checker_finalize + */ +EXTERN_API int privacy_checker_check_package_by_privilege(const char* package_id, const char *privilege_id); + +#ifdef __cplusplus +} +#endif + + +#endif //_PRIVACY_CHECKER_CLIENT_H diff --git a/client/inc/privacy_info_client.h b/client/inc/privacy_info_client.h new file mode 100644 index 0000000..afb9c1c --- /dev/null +++ b/client/inc/privacy_info_client.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 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 _PRIVACY_INFO_CLIENT_H +#define _PRIVACY_INFO_CLIENT_H + +#include <privacy_manager_client_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _privacy_info_client_s { + char *privacy_id; + bool is_enabled; +} privacy_info_client_s; + +EXTERN_API int create_privacy_info_client_s(const char* package_id, bool enabled, privacy_info_client_s **privacy_info); +EXTERN_API int privacy_info_client_s_destroy(privacy_info_client_s* privacy_info); +EXTERN_API int privacy_info_client_get_privacy_id(privacy_info_client_s* privacy_info, char **privacy_id); +EXTERN_API int privacy_info_client_get_privacy_display_name(privacy_info_client_s* privacy_info, char **name); +EXTERN_API int privacy_info_client_get_privacy_display_name_string_id(privacy_info_client_s* privacy_info, char **name_string_id); +EXTERN_API int privacy_info_client_get_privacy_description(privacy_info_client_s* privacy_info, char **description); +EXTERN_API int privacy_info_client_get_privacy_description_string_id(privacy_info_client_s* privacy_info, char **description_string_id); +EXTERN_API int privacy_info_client_is_enabled(privacy_info_client_s* privacy_info, bool *enabled); + +#ifdef __cplusplus +} +#endif + + +#endif //_PRIVACY_INFO_CLIENT_H diff --git a/client/inc/privacy_manager_client.h b/client/inc/privacy_manager_client.h new file mode 100644 index 0000000..eabdd22 --- /dev/null +++ b/client/inc/privacy_manager_client.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2013 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 _PRIVACY_MANAGER_CLIENT_H +#define _PRIVACY_MANAGER_CLIENT_H + +#include <privacy_info_client.h> +#include <privacy_manager_client_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef bool (*privacy_manager_client_privacy_packages_cb) (const char *package_id, void* user_data); +typedef bool (*privacy_manager_client_privacy_info_cb) (privacy_info_client_s* privacy_info, void* user_data); +typedef bool (*privacy_manager_client_all_privacy_info_cb) (privacy_info_client_s* privacy_info, void* user_data); +typedef bool (*privacy_manager_client_packages_by_privacy_cb) (const char *package_id, bool is_enabled, void* user_data); + +EXTERN_API int privacy_manager_client_install_privacy(const char *package_id, const char** privacy_list, bool privacy_popup_required); +EXTERN_API int privacy_manager_client_install_privacy_by_client(const char *package_id, const char** privacy_list, bool privacy_popup_required); +EXTERN_API int privacy_manager_client_uninstall_privacy(const char *package_id); +EXTERN_API int privacy_manager_client_uninstall_privacy_by_server(const char *package_id); +EXTERN_API int privacy_manager_client_foreach_privacy_packages(privacy_manager_client_privacy_packages_cb callback, void *user_data); +EXTERN_API int privacy_manager_client_foreach_get_privacy_info(const char *package_id, privacy_manager_client_privacy_info_cb callback, void* user_data); +EXTERN_API int privacy_manager_client_set_package_privacy(const char *package_id, const char *privacy_id, bool enable); + +EXTERN_API int privacy_manager_client_check_user_consented(const char *package_id, bool *consented); +EXTERN_API int privacy_manager_client_set_user_consented(const char *package_id, bool consented); + +EXTERN_API int privacy_manager_client_foreach_all_privacy(privacy_manager_client_all_privacy_info_cb callback, void* user_data); +EXTERN_API int privacy_manager_client_foreach_package_list_by_privacy(const char *privacy_id, privacy_manager_client_packages_by_privacy_cb callback, void* user_data); + +#ifdef __cplusplus +} +#endif + + +#endif //__TIZEN_PRIVACYMGR_PRIVACY_MANAGER_CLIENT_H + diff --git a/client/src/PrivacyChecker.cpp b/client/src/PrivacyChecker.cpp new file mode 100644 index 0000000..3afa25e --- /dev/null +++ b/client/src/PrivacyChecker.cpp @@ -0,0 +1,606 @@ +/* + * Copyright (c) 2012 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 <PrivacyChecker.h> +#include <PrivacyIdInfo.h> +#include <PrivacyManagerClient.h> +#include <SocketClient.h> +#include <algorithm> +#include <memory> +#include <Utils.h> +#include <dlog.h> +#include <sqlite3.h> +#include <dbus/dbus-glib-lowlevel.h> +#include <sys/types.h> +#include <unistd.h> +#include <vconf.h> +#include <pkgmgr-info.h> +#include <app_manager.h> +#include <package_manager.h> + +bool PrivacyChecker::m_isInitialized = false; +std::map < std::string, std::pair<bool,bool> >PrivacyChecker::m_privacyCache; +std::map < std::string, std::map < std::string, std::pair<bool,bool> > > PrivacyChecker::m_privacyInfoCache; +std::mutex PrivacyChecker::m_cacheMutex; +std::mutex PrivacyChecker::m_dbusMutex; +std::mutex PrivacyChecker::m_initializeMutex; +std::condition_variable PrivacyChecker::m_condition; +std::string PrivacyChecker::m_pkgId; +DBusConnection* PrivacyChecker::m_pDBusConnection; +GMainLoop* PrivacyChecker::m_pLoop = NULL; +GMainContext* PrivacyChecker::m_pHandlerGMainContext = NULL; +pthread_t PrivacyChecker::m_signalThread; +bool PrivacyChecker::m_isPreloaded = false; +bool PrivacyChecker::m_isServiceProcess = false; + +const int MAX_LOCAL_BUF_SIZE = 128; +static bool conditionFlag = false; +static const char* LOCATION_PRIVACY = "http://tizen.org/privacy/location"; + +void __attribute__((destructor)) finalize_privacy_checker(void) +{ + PrivacyChecker::finalizeWihtoutCache(); +} + +bool +PrivacyChecker::isExceptionalCase(const std::string& privacyId) +{ + if(m_isServiceProcess || (privacyId.compare(LOCATION_PRIVACY) != 0 && m_isPreloaded)) + { + //SECURE_LOGD("Exceptional case. Return Success"); + return true; + } + + return false; + +} + +int +PrivacyChecker::checkExceptionalCase(std::string& pkgId, const std::string &privacyId) +{ + // except location privacy, preloaded package is exceptional case + int ret = getPackageId(pkgId); + if(ret != PRIV_MGR_ERROR_SUCCESS) + { + LOGD("Handle as service process"); + m_isServiceProcess= true; + return true; + } + ret = isPreloadedPackage(pkgId); + if(ret > 0) + { + SECURE_LOGD("Preloaded package %d", ret); + m_isPreloaded= true; + return true; + } + return false; // check privacy +} + +int +PrivacyChecker::isPreloadedPackage(const std::string& pkgId) +{ + int ret = 0; + bool preload; + pkgmgrinfo_pkginfo_h handle; + ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle); + if (ret != PMINFO_R_OK) + return -1; + ret = pkgmgrinfo_pkginfo_is_preload(handle, &preload); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return -1; + } + + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return preload; +} + +int +PrivacyChecker::getPackageId(std::string& pkgId) +{ + int pid = getpid(); + char* app_id = NULL; + char* package_id = NULL; + + int ret = app_manager_get_app_id(pid, &app_id); + + if (ret != APP_MANAGER_ERROR_NONE || !app_id) + { + free(app_id); + return PRIV_MGR_ERROR_SYSTEM_ERROR; + } + + ret = package_manager_get_package_id_by_app_id(app_id, &package_id); + if (ret != PACKAGE_MANAGER_ERROR_NONE) + { + free(app_id); + free(package_id); + return PRIV_MGR_ERROR_SYSTEM_ERROR; + } + + pkgId = package_id; + free(app_id); + free(package_id); + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyChecker::initialize(const std::string pkgId) +{ + if (m_isInitialized) { + return PRIV_MGR_ERROR_SUCCESS; + } + + m_pkgId = pkgId; + LOGD("Initialize privacy : %s %s", m_pkgId.c_str(), pkgId.c_str()); + + std::lock_guard < std::mutex > guard(m_cacheMutex); + + int res = updateCache(m_pkgId, m_privacyCache); + TryReturn(res == 0, res, m_pkgId.clear(), "Failed to update cache : %d", res); + + res = initialize(); + TryReturn(res == 0, res, m_pkgId.clear(), "Failed to initialize() : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyChecker::initialize(void) +{ + std::unique_lock<std::mutex> initlock(m_initializeMutex); + TryReturn(!m_isInitialized, PRIV_MGR_ERROR_SUCCESS, , "Already Initalized"); + LOGI("Got lock. Starting initialize"); + + m_pHandlerGMainContext = g_main_context_new(); + TryReturn(m_pHandlerGMainContext != NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, m_pkgId.clear(), "cannot create m_pHandlerGMainContext"); + + m_pLoop = g_main_loop_new(m_pHandlerGMainContext, FALSE); + TryReturn(m_pLoop != NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, m_pkgId.clear(), "cannot create m_pLoop"); + + std::unique_lock<std::mutex> lock(m_dbusMutex); + int res = pthread_create(&m_signalThread, NULL, &runSignalListenerThread, NULL); + TryReturn(res >= 0, PRIV_MGR_ERROR_SYSTEM_ERROR, errno = res, "Failed to create listener thread :%s", strerror(res)); + while (conditionFlag == false) + { + m_condition.wait(lock); + } + + m_isInitialized = true; + + LOGI("Initialized"); + return PRIV_MGR_ERROR_SUCCESS; +} + +void* +PrivacyChecker::runSignalListenerThread(void* pData) +{ + if(pthread_detach(pthread_self())!=0) + { + LOGE("Failed to detach thread"); + } + + LOGI("Running g main loop for signal"); + + initializeDbus(); + + { + std::unique_lock<std::mutex> lock(m_dbusMutex); + conditionFlag = true; + m_condition.notify_all(); + } + + g_main_loop_run(m_pLoop); + + finalizeDbus(); + + LOGI("Thread Exit"); + pthread_exit(NULL); + + return (void*) 0; +} + +int +PrivacyChecker::initializeDbus(void) +{ + DBusError error; + dbus_error_init(&error); + + LOGI("Starting initialize"); + + m_pDBusConnection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error); + TryReturn(m_pDBusConnection != NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, dbus_error_free(&error), "dbus_bus_get_private [%s] : %d", error.message, PRIV_MGR_ERROR_SYSTEM_ERROR); + + dbus_connection_setup_with_g_main(m_pDBusConnection, m_pHandlerGMainContext); + std::unique_ptr < char[] > pRule(new char[MAX_LOCAL_BUF_SIZE]); + + snprintf(pRule.get(), MAX_LOCAL_BUF_SIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH.c_str(), DBUS_SIGNAL_INTERFACE.c_str()); + dbus_bus_add_match(m_pDBusConnection, pRule.get(), &error); + TryReturn(!dbus_error_is_set(&error), PRIV_MGR_ERROR_SYSTEM_ERROR, dbus_error_free(&error), "dbus_bus_add_match[%s] : %d", error.message, PRIV_MGR_ERROR_SYSTEM_ERROR); + + dbus_bool_t r = dbus_connection_add_filter(m_pDBusConnection, handleNotification, NULL, NULL); + TryReturn(r, PRIV_MGR_ERROR_SYSTEM_ERROR, , "dbus_connection_add_filter: %d", PRIV_MGR_ERROR_SYSTEM_ERROR); + + LOGI("Initialized"); + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyChecker::finalizeDbus(void) +{ + dbus_connection_remove_filter(m_pDBusConnection, handleNotification, NULL); + dbus_connection_close(m_pDBusConnection); + m_pDBusConnection = NULL; + + return PRIV_MGR_ERROR_SUCCESS; +} + + +DBusHandlerResult +PrivacyChecker::handleNotification(DBusConnection* connection, DBusMessage* message, void* user_data) +{ + DBusError error; + dbus_bool_t r; + dbus_error_init(&error); + + char* pPkgId; + char* pPrivacyId; + + if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE.c_str(), DBUS_SIGNAL_SETTING_CHANGED.c_str())) + { + r = dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &pPkgId, + DBUS_TYPE_STRING, &pPrivacyId, + DBUS_TYPE_INVALID); + TryReturn(r, DBUS_HANDLER_RESULT_NOT_YET_HANDLED, , "Fail to get data : %s", error.message); + + std::lock_guard < std::mutex > guard(m_cacheMutex); + + if (std::string(pPkgId) == m_pkgId) + { + LOGI("Current app pkg privacy information updated"); + updateCache(m_pkgId, pPrivacyId, m_privacyCache); + //printCache(); + } + + std::map < std::string, std::map < std::string, std::pair<bool,bool> > > :: iterator iter = m_privacyInfoCache.find(std::string(pPkgId)); + if (iter != m_privacyInfoCache.end()) + { + LOGI("Current pkg privacy is in cache"); + updateCache(std::string(pPkgId), pPrivacyId, iter->second); + } + + } + else if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE.c_str(), DBUS_SIGNAL_PKG_REMOVED.c_str())) + { + r = dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &pPkgId, + DBUS_TYPE_INVALID); + TryReturn(r, DBUS_HANDLER_RESULT_NOT_YET_HANDLED, , "Fail to get data : %s", error.message); + + std::lock_guard < std::mutex > guard(m_cacheMutex); + + std::map < std::string, std::map < std::string, std::pair<bool,bool> > > :: iterator iter = m_privacyInfoCache.find(std::string(pPkgId)); + if (iter != m_privacyInfoCache.end()) + { + m_privacyInfoCache.erase(iter); + } + } +// else +// { +// return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +// } + + + // This event is not only for specific handler. All handlers of daemons should be check it and handle it. + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +int +PrivacyChecker::check(const std::string privacyId, std::map < std::string, std::pair<bool,bool> >& privacyMap) +{ + TryReturn(m_isInitialized, PRIV_MGR_ERROR_NOT_INITIALIZED, , "Not initialized"); + + std::map < std::string, std::pair<bool,bool> >::iterator iter; + + iter = privacyMap.find(privacyId); + if (iter == privacyMap.end() ) + { + LOGD("The application cannot access the privacy inforamtion."); + notify(m_pkgId, privacyId); + + // add privacy information to pkg cache for toast once + privacyMap.insert(std::map < std::string, std::pair<bool,bool> >::value_type(privacyId, std::make_pair(false, true))); + LOGD("Added notify cache"); + + return PRIV_MGR_ERROR_USER_NOT_CONSENTED; + } + else if (!iter->second.first) + { + LOGD("User does not consented to access the privacy information"); + if(!iter->second.second) + { + notify(m_pkgId, privacyId); + LOGD("Set notify cache"); + iter->second.second = true; + } + return PRIV_MGR_ERROR_USER_NOT_CONSENTED; + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyChecker::check(const std::string privacyId) +{ + int res = PRIV_MGR_ERROR_SUCCESS; + + if(isExceptionalCase(privacyId)) + return PRIV_MGR_ERROR_SUCCESS; + + if (!m_isInitialized) + { + std::string pkgId; + if(checkExceptionalCase(pkgId, privacyId)) + return PRIV_MGR_ERROR_SUCCESS; + + m_pkgId = pkgId; + LOGD("privacy checker is not initialized. initialize : %s", m_pkgId.c_str()); + initialize(); + } + + std::lock_guard < std::mutex > guard(m_cacheMutex); + + std::map < std::string, std::map < std::string, std::pair<bool,bool> > >::iterator iter = m_privacyInfoCache.find(m_pkgId); + if (iter == m_privacyInfoCache.end() ) + { + std::map < std::string, std::pair<bool, bool> > pkgCacheMap; + res = updateCache(m_pkgId, pkgCacheMap); + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, PRIV_MGR_ERROR_DB_ERROR, , "Failed to update cache : %d", res); + + m_privacyInfoCache.insert( std::map < std::string, std::map < std::string, std::pair<bool,bool> > >::value_type(std::string(m_pkgId), pkgCacheMap)); + iter = m_privacyInfoCache.find(m_pkgId); + } + + if (iter->second.size() == 0) + { + LOGD("Can not find privacy info from cache"); + notify(m_pkgId, privacyId); + + // add pkg-privacy information to iter->second for toast once + std::map < std::string, std::pair<bool, bool> > pkgCacheMap; + pkgCacheMap.insert(std::map < std::string, std::pair<bool,bool> >::value_type(privacyId, std::make_pair(false, true))); + m_privacyInfoCache.insert( std::map < std::string, std::map < std::string, std::pair<bool,bool> > >::value_type(std::string(m_pkgId), pkgCacheMap)); + LOGD("Added pkg privacy notify cache"); + return PRIV_MGR_ERROR_USER_NOT_CONSENTED; + } + + res = check(privacyId, iter->second); +// if (res == PRIV_MGR_ERROR_USER_NOT_CONSENTED) +// { +// notify(m_pkgId, privacyId); +// } + return res; +} + +int +PrivacyChecker::check(const std::string pkgId, const std::string privacyId) +{ + if (!m_isInitialized) + initialize(); + + m_pkgId = pkgId; // copy package id for core API + OSP API call privacy check together + std::lock_guard < std::mutex > guard(m_cacheMutex); + int res; + + std::map < std::string, std::map < std::string, std::pair<bool,bool> > >::iterator iter = m_privacyInfoCache.find(pkgId); + if (iter == m_privacyInfoCache.end() ) + { + std::map < std::string, std::pair<bool,bool> > pkgCacheMap; + res = updateCache(pkgId, pkgCacheMap); + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, PRIV_MGR_ERROR_DB_ERROR, , "Failed to update cache : %d", res); + + m_privacyInfoCache.insert( std::map < std::string, std::map < std::string, std::pair<bool,bool> > >::value_type(std::string(pkgId), pkgCacheMap)); + iter = m_privacyInfoCache.find(pkgId); + } + + if (iter->second.size() == 0) + { + // add pkg-privacy information to iter->second for toast once + std::map < std::string, std::pair<bool, bool> > pkgCacheMap; + pkgCacheMap.insert(std::map < std::string, std::pair<bool,bool> >::value_type(privacyId, std::make_pair(false, true))); + m_privacyInfoCache.insert( std::map < std::string, std::map < std::string, std::pair<bool,bool> > >::value_type(std::string(m_pkgId), pkgCacheMap)); + LOGD("Added pkg privacy notify cache"); + return PRIV_MGR_ERROR_USER_NOT_CONSENTED; + } + + res = check(privacyId, iter->second); +// if (res == PRIV_MGR_ERROR_USER_NOT_CONSENTED) +// { +// notify(m_pkgId, privacyId); +// } + + return res; +} + +int +PrivacyChecker::checkWithPrivilege(const std::string pkgId, const std::string privilege) +{ + std::string privacyId; + int res = PrivacyIdInfo::getPrivacyIdFromPrivilege(privilege, privacyId); + if (res == PRIV_MGR_ERROR_NO_DATA) { + return PRIV_MGR_ERROR_SUCCESS; + } + + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "getPrivacyIdFromPrivilege : %d", res); + + return check(pkgId, privacyId); +} + +int +PrivacyChecker::checkWithPrivilege(const std::string privilege) +{ + std::string privacyId; + int res = PrivacyIdInfo::getPrivacyIdFromPrivilege(privilege, privacyId); + if (res == PRIV_MGR_ERROR_NO_DATA) { + return PRIV_MGR_ERROR_SUCCESS; + } + + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "getPrivacyIdFromPrivilege : %d", res); + + return check(privacyId); +} + +int +PrivacyChecker::finalize(void) +{ + if(m_isInitialized) + { + LOGD("Finalize privacy checker : %s", m_pkgId.c_str()); + std::lock_guard <std::mutex> guard (m_cacheMutex); + m_privacyCache.clear(); + m_privacyInfoCache.clear(); + + if (m_pLoop != NULL) + { + LOGI("Quit signal to dbus thread"); + g_main_loop_quit(m_pLoop); + m_pLoop = NULL; + } + + if (m_pHandlerGMainContext != NULL) + { + g_main_context_unref(m_pHandlerGMainContext); + m_pHandlerGMainContext = NULL; + } + + m_isInitialized = false; + conditionFlag = false; + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyChecker::finalizeWihtoutCache(void) +{ + if(m_isInitialized) + { + LOGD("finalize privacy checker : %s", m_pkgId.c_str()); + if (m_pLoop != NULL) + { + LOGI("Quit signal to dbus thread"); + g_main_loop_quit(m_pLoop); + m_pLoop = NULL; + } + + if (m_pHandlerGMainContext != NULL) + { + g_main_context_unref(m_pHandlerGMainContext); + m_pHandlerGMainContext = NULL; + } + m_isInitialized = false; + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +void +PrivacyChecker::printCache(void) +{ + std::map < std::string, std::pair<bool,bool> >::const_iterator iter = m_privacyCache.begin(); + for (; iter != m_privacyCache.end(); ++iter) + { + LOGD(" %s : %d %d", iter->first.c_str(), iter->second.first, iter->second.second); + } +} + +int +PrivacyChecker::updateCache(const std::string pkgId, std::string privacyId, std::map < std::string, std::pair<bool,bool> >& pkgCacheMap) +{ + static const std::string PrivacyQuery = "SELECT IS_ENABLED from PrivacyInfo where PKG_ID=? and PRIVACY_ID=?"; + + openDb(PRIVACY_DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY); + prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt); + int res = sqlite3_bind_text(pPrivacyStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == 0, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + res = sqlite3_bind_text(pPrivacyStmt.get(), 2, privacyId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == 0, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + while ( sqlite3_step(pPrivacyStmt.get()) == SQLITE_ROW ) + { + bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 0) > 0 ? true : false; + + SECURE_LOGD("Set result : %s : %d", privacyId.c_str(), privacyEnabled ); + pkgCacheMap.erase(privacyId); + pkgCacheMap.insert(std::map < std::string, std::pair<bool,bool> >::value_type(privacyId, std::make_pair(privacyEnabled, false))); + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyChecker::updateCache(std::string pkgId, std::map < std::string, std::pair<bool,bool> >& pkgCacheMap) +{ + static const std::string PrivacyQuery = "SELECT PRIVACY_ID, IS_ENABLED from PrivacyInfo where PKG_ID=?"; + + pkgCacheMap.clear(); + + openDb(PRIVACY_DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY); + prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt); + int res = sqlite3_bind_text(pPrivacyStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + while ( (res = sqlite3_step(pPrivacyStmt.get())) == SQLITE_ROW ) + { + const char* privacyId = reinterpret_cast < const char* > (sqlite3_column_text(pPrivacyStmt.get(), 0)); + bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 1) > 0 ? true : false; + + pkgCacheMap.insert(std::map < std::string, std::pair<bool,bool> >::value_type(std::string(privacyId), std::make_pair(privacyEnabled, false))); + + SECURE_LOGD("Privacy found : %s %d", privacyId, privacyEnabled); + } + return PRIV_MGR_ERROR_SUCCESS; +} + +void +PrivacyChecker::notify(const std::string& pkgId, const std::string privacyId) +{ + int result = PrivacyManagerClient::getInstance()->notifyUserNotConsented(pkgId, privacyId); + if(result == PRIV_MGR_ERROR_SUCCESS) + LOGD("Succeed to notify"); + else + LOGD("Failed to notify"); + + return; +} + +void +PrivacyChecker::removeWhiteSpace(std::string& packageNameString) +{ + const char* from = " "; + const char* to = "Â "; + + size_t position = packageNameString.find(from); + size_t strLength = strlen(from); + + while(position < std::string::npos) + { + packageNameString.replace(position, strLength, to); + position = packageNameString.find(from, position); + } +} diff --git a/client/src/PrivacyManagerClient.cpp b/client/src/PrivacyManagerClient.cpp new file mode 100644 index 0000000..9057684 --- /dev/null +++ b/client/src/PrivacyManagerClient.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2012 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 <PrivacyManagerClient.h> +#include <PrivacyDb.h> +#include <SocketClient.h> +#include <PrivacyIdInfo.h> +#include <algorithm> +#include <memory> +#include <Utils.h> + +#undef __READ_DB_IPC__ + + +std::mutex PrivacyManagerClient::m_singletonMutex; +PrivacyManagerClient* PrivacyManagerClient::m_pInstance = NULL; +const std::string PrivacyManagerClient::INTERFACE_NAME("PrivacyInfoService"); + +PrivacyManagerClient::PrivacyManagerClient(void) +{ + std::unique_ptr<SocketClient> pSocketClient(new SocketClient(INTERFACE_NAME)); + m_pSocketClient = std::move(pSocketClient); +} + +PrivacyManagerClient* +PrivacyManagerClient::getInstance(void) +{ + std::lock_guard<std::mutex> guard(m_singletonMutex); + if (m_pInstance == NULL) + m_pInstance = new PrivacyManagerClient(); + return m_pInstance; +} + +int +PrivacyManagerClient::addAppPackagePrivacyInfo(const std::string pkgId, const std::list < std::string >& list, bool privacyPopupRequired, bool isServerOperation) +{ + + std::list < std::string > privacyList; + + int res = PrivacyIdInfo::getPrivacyIdListFromPrivilegeList(list, privacyList); + if (res != PRIV_MGR_ERROR_SUCCESS ) + return res; + + if (privacyList.size() == 0) + return PRIV_MGR_ERROR_SUCCESS; + + if (isServerOperation == true) + { + int result = PRIV_MGR_ERROR_SUCCESS; + res = m_pSocketClient->connect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + res = m_pSocketClient->call("addPrivacyInfo", pkgId, privacyList, privacyPopupRequired, &result); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, m_pSocketClient->disconnect(), "call : %d", res); + res = m_pSocketClient->disconnect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "disconnect : %d", res); + + return result; + } + else + { + return PrivacyDb::getInstance()->addAppPackagePrivacyInfo(pkgId, privacyList, privacyPopupRequired); + } +} + +int +PrivacyManagerClient::removeAppPackagePrivacyInfo(const std::string pkgId, bool isServerOperation) +{ + if (isServerOperation == true) + { + int result = PRIV_MGR_ERROR_SUCCESS; + int res = m_pSocketClient->connect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + result = m_pSocketClient->call("removePrivacyInfo", pkgId, &result); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, m_pSocketClient->disconnect(), "call : %d", res); + result = m_pSocketClient->disconnect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "disconnect : %d", res); + + return result; + } + else + return PrivacyDb::getInstance()->removeAppPackagePrivacyInfo(pkgId); +} + +int +PrivacyManagerClient::setPrivacySetting(const std::string pkgId, const std::string privacyId, bool isEnabled) +{ + int result = PRIV_MGR_ERROR_SUCCESS; + int res = m_pSocketClient->connect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + res = m_pSocketClient->call("setPrivacySetting", pkgId, privacyId, isEnabled, &result); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, m_pSocketClient->disconnect(), "call : %d", res); + res = m_pSocketClient->disconnect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + + return result; +} + +int +PrivacyManagerClient::getPrivacyAppPackages(std::list < std::string >& list) const +{ +#ifdef __READ_DB_IPC__ + + std::unique_ptr <SocketClient> pSocketClient (new SocketClient(INTERFACE_NAME)); + + int result = PRIV_MGR_ERROR_SUCCESS + int size = 0; + + int res = pSocketClient->connect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + res = pSocketClient->call("getPrivacyAppPackages", &result, &size, &list); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, m_pSocketClient->disconnect(), "call : %d", res); + res = pSocketClient->disconnect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + + return result; +#endif + + return PrivacyDb::getInstance()->getPrivacyAppPackages(list); +} + +int +PrivacyManagerClient::getAppPackagePrivacyInfo(const std::string pkgId, std::list < std::pair <std::string, bool > > & list) const +{ +#ifdef __READ_DB_IPC__ + std::unique_ptr <SocketClient> pSocketClient (new SocketClient(INTERFACE_NAME)); + + int result = PRIV_MGR_ERROR_SUCCESS; + int res = pSocketClient->connect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + pSocketClient->call("getAppPackagePrivacyInfo", pkgId, &result, &list); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, m_pSocketClient->disconnect(), "call : %d", res); + pSocketClient->disconnect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "disconnect : %d", res); + + return result; +#endif + + return PrivacyDb::getInstance()->getAppPackagePrivacyInfo(pkgId, list); +} + +int +PrivacyManagerClient::isUserPrompted(const std::string pkgId, bool& isPrompted) const +{ +#ifdef __READ_DB_IPC__ + std::unique_ptr <SocketClient> pSocketClient (new SocketClient(INTERFACE_NAME)); + + int result = PRIV_MGR_ERROR_SUCCESS; + int res = pSocketClient->connect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + res = pSocketClient->call("isUserPrompted", pkgId, &result, &isPrompted); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, m_pSocketClient->disconnect(), "call : %d", res); + res = pSocketClient->disconnect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "disconnect : %d", res); + + return result; +#endif + return PrivacyDb::getInstance()->isUserPrompted(pkgId, isPrompted); +} + +int +PrivacyManagerClient::setUserPrompted(const std::string pkgId, bool prompted) +{ + std::unique_ptr <SocketClient> pSocketClient (new SocketClient(INTERFACE_NAME)); + + int result = PRIV_MGR_ERROR_SUCCESS; + int res = pSocketClient->connect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + res = pSocketClient->call("setUserPrompted", pkgId, prompted, &result); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, m_pSocketClient->disconnect(), "call : %d", res); + res = pSocketClient->disconnect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "disconnect : %d", res); + + return result; +} + +int +PrivacyManagerClient::getAppPackagesbyPrivacyId(const std::string privacyId, std::list < std::pair < std::string, bool > >& list) const +{ + return PrivacyDb::getInstance()->getAppPackagesbyPrivacyId(privacyId, list); +} + +int +PrivacyManagerClient::getPrivaycDisplayName(const std::string privacyId, std::string& displayName) const +{ + return PrivacyIdInfo::getPrivaycDisplayName(privacyId, displayName); +} + +int +PrivacyManagerClient::getPrivaycDisplayNameStringId(const std::string privacyId, std::string& displayNameStringId) const +{ + return PrivacyIdInfo::getPrivaycDisplayNameStringId(privacyId, displayNameStringId); +} + +int +PrivacyManagerClient::getPrivaycDescription(const std::string privacyId, std::string& description) const +{ + return PrivacyIdInfo::getPrivaycDescription(privacyId, description); +} + +int +PrivacyManagerClient::getPrivaycDescriptionStringId(const std::string privacyId, std::string& descriptionStringId) const +{ + return PrivacyIdInfo::getPrivaycDescriptionStringId(privacyId, descriptionStringId); +} + +int +PrivacyManagerClient::notifyUserNotConsented(const std::string pkgId, const std::string privacyId) const +{ + int result = PRIV_MGR_ERROR_SUCCESS; + int res = m_pSocketClient->connect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + res = m_pSocketClient->call("notifyUserNotConsented", pkgId, privacyId, &result); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, m_pSocketClient->disconnect(), "call : %d", res); + res = m_pSocketClient->disconnect(); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "connect : %d", res); + + return result; +} diff --git a/client/src/SocketClient.cpp b/client/src/SocketClient.cpp new file mode 100644 index 0000000..bad62dd --- /dev/null +++ b/client/src/SocketClient.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2012 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 <sys/socket.h> +#include <string.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/un.h> +#include <errno.h> +#include <unistd.h> +#include <PrivacyManagerTypes.h> +#include "SocketClient.h" +#include <Utils.h> + +#define throwWithErrnoMessage(specificInfo) do {\ + LOGE("%s : %s", specificInfo, strerror(errno)); \ + return -1; \ + } while(0) + +SocketClient::SocketClient(const std::string& interfaceName) +{ + m_interfaceName = interfaceName; + m_serverAddress = SERVER_ADDRESS; + LOGI("Client created"); +} + +int SocketClient::connect() +{ + struct sockaddr_un remote; + m_socketFd = socket(AF_UNIX, SOCK_STREAM,0); + TryReturn( m_socketFd != -1, PRIV_MGR_ERROR_IPC_ERROR, , "socket : %s", strerror(errno)); + + int res; + //socket needs to be nonblocking, because read can block after select + int flags; + if ( (flags = fcntl(m_socketFd, F_GETFL, 0)) == -1 ) + flags = 0; + res = fcntl(m_socketFd, F_SETFL, flags | O_NONBLOCK); + TryReturn( m_socketFd != -1, PRIV_MGR_ERROR_IPC_ERROR, , "fcntl : %s", strerror(errno)); + + bzero(&remote, sizeof(remote)); + remote.sun_family = AF_UNIX; + if(strlen(m_serverAddress.c_str()) <= strlen(remote.sun_path)) + strcpy(remote.sun_path, m_serverAddress.c_str()); + else + return PRIV_MGR_ERROR_SYSTEM_ERROR; + res = ::connect(m_socketFd, (struct sockaddr *)&remote, SUN_LEN(&remote)); + TryReturn( res != -1, PRIV_MGR_ERROR_IPC_ERROR, , "connect : %s", strerror(errno)); + + m_socketConnector.reset(new SocketConnection(m_socketFd)); + + LOGI("Client connected"); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int SocketClient::disconnect() +{ + //Socket should be already closed by server side, + //even though we should close it in case of any errors + close(m_socketFd); + LOGI("Client disconnected"); + + return PRIV_MGR_ERROR_SUCCESS; +} diff --git a/client/src/privacy_checker_client.cpp b/client/src/privacy_checker_client.cpp new file mode 100644 index 0000000..ca21643 --- /dev/null +++ b/client/src/privacy_checker_client.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013 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 <string.h> +#include <string> +#include <memory> +#include <PrivacyManagerClient.h> +#include <privacy_manager_client.h> +#include <privacy_manager_client_types.h> +#include "privacy_manager_client_internal_types.h" +#include <PrivacyChecker.h> +#include <privacy_checker_client.h> +#include <privacy_info_client.h> +#include <PrivacyIdInfo.h> + +int privacy_checker_initialize(const char *package_id) +{ + if(!package_id) + { + return PRIV_MGR_ERROR_INVALID_PARAMETER; + } + return PrivacyChecker::initialize(std::string(package_id)); +} + +int privacy_checker_check_by_privacy(const char *privacy_id) +{ + if(!privacy_id) + { + return PRIV_MGR_ERROR_INVALID_PARAMETER; + } + return PrivacyChecker::check(std::string(privacy_id)); +} + +int privacy_checker_check_by_privilege(const char *privilege_id) +{ + if(!privilege_id) + { + return PRIV_MGR_ERROR_INVALID_PARAMETER; + } + return PrivacyChecker::checkWithPrivilege(privilege_id); +} + +int privacy_checker_finalize(void) +{ + return PrivacyChecker::finalize(); +} + +int privacy_checker_check_package_by_privilege(const char* package_id, const char *privilege_id) +{ + if(!package_id || !privilege_id) + { + return PRIV_MGR_ERROR_INVALID_PARAMETER; + } + return PrivacyChecker::checkWithPrivilege(package_id,privilege_id); +} diff --git a/client/src/privacy_info_client.cpp b/client/src/privacy_info_client.cpp new file mode 100644 index 0000000..9da2bd1 --- /dev/null +++ b/client/src/privacy_info_client.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2013 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 <string.h> +#include <string> +#include <memory> +#include <PrivacyManagerClient.h> +#include <privacy_manager_client.h> +#include <privacy_manager_client_types.h> +#include "privacy_manager_client_internal_types.h" + +int privacy_info_client_s_destroy(privacy_info_client_s* privacy_info) +{ + if (privacy_info != NULL) + { + if (privacy_info->privacy_id) + free(privacy_info->privacy_id); + free (privacy_info); + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int privacy_info_client_get_privacy_id(privacy_info_client_s* privacy_info, char **privacy_id) +{ + int size = strlen(privacy_info->privacy_id); + *privacy_id = (char*) calloc(1, size + 1); + + memcpy (*privacy_id, privacy_info->privacy_id, size); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int privacy_info_client_get_privacy_display_name(privacy_info_client_s* privacy_info, char **name) +{ + std::string displayName; + + int res = PrivacyManagerClient::getInstance()->getPrivaycDisplayName(std::string(privacy_info->privacy_id), displayName); + if (res != PRIV_MGR_ERROR_SUCCESS) + return res; + + int size = strlen(displayName.c_str()); + *name = (char*) calloc(1, size + 1); + memcpy (*name, displayName.c_str(), size); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int privacy_info_client_get_privacy_display_name_string_id(privacy_info_client_s* privacy_info, char **name_string_id) +{ + std::string displayNameStringId; + int res = PrivacyManagerClient::getInstance()->getPrivaycDisplayNameStringId(std::string(privacy_info->privacy_id), displayNameStringId); + if (res != PRIV_MGR_ERROR_SUCCESS) + return res; + + int size = strlen(displayNameStringId.c_str()); + *name_string_id = (char*) calloc(1, size + 1); + memcpy (*name_string_id, displayNameStringId.c_str(), size); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int privacy_info_client_get_privacy_description(privacy_info_client_s* privacy_info, char **description) +{ + std::string desc; + int res = PrivacyManagerClient::getInstance()->getPrivaycDisplayName(std::string(privacy_info->privacy_id), desc); + if (res != PRIV_MGR_ERROR_SUCCESS) + return res; + + int size = strlen(desc.c_str()); + *description = (char*) calloc(1, size + 1); + memcpy (*description, desc.c_str(), size); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int privacy_info_client_get_privacy_description_string_id(privacy_info_client_s* privacy_info, char **description_string_id) +{ + std::string descStringId; + int res = PrivacyManagerClient::getInstance()->getPrivaycDisplayName(std::string(privacy_info->privacy_id), descStringId); + if (res != PRIV_MGR_ERROR_SUCCESS) + return res; + + int size = strlen(descStringId.c_str()); + *description_string_id = (char*) calloc(1, size + 1); + memcpy (*description_string_id, descStringId.c_str(), size); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int privacy_info_client_is_enabled(privacy_info_client_s* privacy_info, bool *enabled) +{ + *enabled = privacy_info->is_enabled; + return PRIV_MGR_ERROR_SUCCESS; +} diff --git a/client/src/privacy_manager_client.cpp b/client/src/privacy_manager_client.cpp new file mode 100644 index 0000000..9c901db --- /dev/null +++ b/client/src/privacy_manager_client.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2013 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 <string.h> +#include <string> +#include <memory> +#include <dlog.h> +#include <PrivacyManagerClient.h> +#include <PrivacyIdInfo.h> +#include <privacy_manager_client.h> +#include "privacy_manager_client_internal_types.h" + +int create_privacy_info_client_s(const char* privacy_id, bool enabled, privacy_info_client_s **privacy_info) +{ + privacy_info_client_s* temp = (privacy_info_client_s*) calloc(1, sizeof(privacy_info_client_s)); + if (temp == NULL) + return PRIV_MGR_ERROR_OUT_OF_MEMORY; + + int size = strlen(privacy_id); + temp->privacy_id = (char*) calloc(1, size + 1); + if (temp->privacy_id == NULL) + { + free(temp); + return PRIV_MGR_ERROR_OUT_OF_MEMORY; + } + memcpy(temp->privacy_id, privacy_id, size + 1); + + temp->is_enabled = enabled; + + *privacy_info = temp; + + return PRIV_MGR_ERROR_SUCCESS; +} + +int privacy_manager_client_install_privacy(const char *package_id, const char** privacy_list, bool privacy_popup_required) +{ + PrivacyManagerClient* pInst = PrivacyManagerClient::getInstance(); + std::list < std::string > privacyList; + + while (*privacy_list[0] != '\0') + { + privacyList.push_back(std::string(*privacy_list++)); + } + + int retval = pInst->addAppPackagePrivacyInfo(std::string(package_id), privacyList, privacy_popup_required, true); + + return retval; +} + +int privacy_manager_client_install_privacy_by_client(const char *package_id, const char** privacy_list, bool privacy_popup_required) +{ + PrivacyManagerClient* pInst = PrivacyManagerClient::getInstance(); + std::list < std::string > privacyList; + + while (*privacy_list[0] != '\0') + { + privacyList.push_back(std::string(*privacy_list++)); + } + + int retval = pInst->addAppPackagePrivacyInfo(std::string(package_id), privacyList, privacy_popup_required, false); + + return retval; +} + +int privacy_manager_client_uninstall_privacy(const char *package_id) +{ + if (package_id == NULL) + return PRIV_MGR_ERROR_INVALID_PARAMETER; + return PrivacyManagerClient::getInstance()->removeAppPackagePrivacyInfo(std::string(package_id), false); +} + +int privacy_manager_client_uninstall_privacy_by_server(const char *package_id) +{ + if (package_id == NULL) + return PRIV_MGR_ERROR_INVALID_PARAMETER; + return PrivacyManagerClient::getInstance()->removeAppPackagePrivacyInfo(std::string(package_id), true); +} + +int privacy_manager_client_foreach_privacy_packages(privacy_manager_client_privacy_packages_cb callback, void *user_data) +{ + int retval; + PrivacyManagerClient* pInst = PrivacyManagerClient::getInstance(); + + std::list < std::string > list; + retval = pInst->getPrivacyAppPackages(list); + if (retval != PRIV_MGR_ERROR_SUCCESS) + return retval; + if (list.size() == 0) + return PRIV_MGR_ERROR_NO_DATA; + + for (std::list < std::string >::iterator iter = list.begin(); iter != list.end(); ++iter) + { + if ( ! callback(iter->c_str(), user_data) ) + break; + } + + return PRIV_MGR_ERROR_SUCCESS; +} +int privacy_manager_client_foreach_get_privacy_info(const char *package_id, privacy_manager_client_privacy_info_cb callback, void* user_data) +{ + int retval; + bool res; + PrivacyManagerClient* pInst = PrivacyManagerClient::getInstance(); + + std::list < std::pair <std::string, bool > > list; + + retval = pInst->getAppPackagePrivacyInfo(std::string(package_id), list); + if (retval != PRIV_MGR_ERROR_SUCCESS) + return retval; + if (list.size() == 0) + return PRIV_MGR_ERROR_NO_DATA; + + for (std::list < std::pair <std::string, bool > >::iterator iter = list.begin(); iter != list.end(); ++iter) + { + privacy_info_client_s *privacy_info_client_s = NULL; + retval = create_privacy_info_client_s(iter->first.c_str(), iter->second, &privacy_info_client_s); + res = callback(privacy_info_client_s, user_data); + privacy_info_client_s_destroy(privacy_info_client_s); + if (!res) + break; + } + return PRIV_MGR_ERROR_SUCCESS; + +} +int privacy_manager_client_set_package_privacy(const char *package_id, const char *privacy_id, bool enable) +{ + PrivacyManagerClient* pInst = PrivacyManagerClient::getInstance(); + + return pInst->setPrivacySetting(package_id, privacy_id, enable); +} + +int privacy_manager_client_check_user_consented(const char *package_id, bool *consented) +{ + PrivacyManagerClient* pInst = PrivacyManagerClient::getInstance(); + + return pInst->isUserPrompted(std::string(package_id), *consented); +} + +int privacy_manager_client_set_user_consented(const char *package_id, bool consented) +{ + PrivacyManagerClient* pInst = PrivacyManagerClient::getInstance(); + + return pInst->setUserPrompted(std::string(package_id), consented); +} + +int privacy_manager_client_foreach_all_privacy(privacy_manager_client_all_privacy_info_cb callback, void* user_data) +{ + int retval; + bool res; + + std::list < std::string > privacyList; + retval = PrivacyIdInfo::getAllPrivacyId(privacyList); + if (retval != PRIV_MGR_ERROR_SUCCESS) + return retval; + if (privacyList.size() == 0) + return PRIV_MGR_ERROR_NO_DATA; + + for (std::list < std::string >::iterator iter = privacyList.begin(); iter != privacyList.end(); ++iter) + { + privacy_info_client_s *privacy_info_client_s = NULL; + retval = create_privacy_info_client_s(iter->c_str(), false, &privacy_info_client_s); + res = callback(privacy_info_client_s, user_data); + privacy_info_client_s_destroy(privacy_info_client_s); + if (!res) + break; + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int privacy_manager_client_foreach_package_list_by_privacy(const char *privacy_id, privacy_manager_client_packages_by_privacy_cb callback, void* user_data) +{ + int retval; + bool res; + PrivacyManagerClient* pInst = PrivacyManagerClient::getInstance(); + + std::list < std::pair < std::string, bool > > packageList; + retval = pInst->getAppPackagesbyPrivacyId(std::string(privacy_id), packageList); + + if (retval != PRIV_MGR_ERROR_SUCCESS) + return retval; + if (packageList.size() == 0) + return PRIV_MGR_ERROR_NO_DATA; + + for (std::list < std::pair < std::string, bool > >::iterator iter = packageList.begin(); iter != packageList.end(); ++iter) + { + res = callback(iter->first.c_str(), iter->second, user_data); + if (!res) + break; + } + + return PRIV_MGR_ERROR_SUCCESS; +} diff --git a/client/src/privacy_manager_client_internal_types.h b/client/src/privacy_manager_client_internal_types.h new file mode 100644 index 0000000..ca9f907 --- /dev/null +++ b/client/src/privacy_manager_client_internal_types.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2013 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 __TIZEN_PRIVACYMGR_PRIVACY_INFO_CLIENT_INTERNAL_TYPES_H +#define __TIZEN_PRIVACYMGR_PRIVACY_INFO_CLIENT_INTERNAL_TYPES_H + +#include <tizen.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + + +#endif //__TIZEN_PRIVACYMGR_PRIVACY_INFO_CLIENT_INTERNAL_TYPES_H
\ No newline at end of file diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt new file mode 100644 index 0000000..e9137e4 --- /dev/null +++ b/common/CMakeLists.txt @@ -0,0 +1,14 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(common_src_dir "${CMAKE_SOURCE_DIR}/common/src/") +SET(common_include_dir "${CMAKE_SOURCE_DIR}/common/inc/") + +SET(PRIVACY_MANAGER_COMMON_SOURCES + ${common_src_dir}/SocketConnection.cpp + ${common_src_dir}/SocketStream.cpp + ) + +SET(PRIVACY_MANAGER_COMMON_HEADERS + ${common_include_dir}/SocketConnection.h + ${common_include_dir}/SocketConnection.h +)
\ No newline at end of file diff --git a/common/inc/IPrivacyManager.h b/common/inc/IPrivacyManager.h new file mode 100644 index 0000000..055bbbf --- /dev/null +++ b/common/inc/IPrivacyManager.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012 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 _IPRIVACY_MANAGER_H_ +#define _IPRIVACY_MANAGER_H_ + +#include <string> +#include <mutex> +#include <list> +#include <vector> +#include <memory> +#include <PrivacyManagerTypes.h> + +class SocketClient; + +class EXTERN_API IPrivacyManager +{ +public: + int addAppPackagePrivacyInfo(const std::string pkgId, const std::list < std::string >& pList, bool privacyPopupRequired); + + int removeAppPackagePrivacyInfo(const std::string pkgId); + + int setPrivacySetting(const std::string pkgId, const std::string privacyId, bool isEnabled); + + int getPrivacyAppPackages(std::list < std::string >& pList); + + int getAppPackagePrivacyInfo(const std::string pkgId, std::list < std::pair <std::string, bool > > & pList); +}; + +#endif // _IPRIVACY_MANAGER_H_
\ No newline at end of file diff --git a/common/inc/PrivacyDb.h b/common/inc/PrivacyDb.h new file mode 100644 index 0000000..f9129f9 --- /dev/null +++ b/common/inc/PrivacyDb.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013 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 _PRIVACY_DB_H_ +#define _PRIVACY_DB_H_ + +#include <string> +#include <memory> +#include <list> +#include <mutex> +#if defined(__FILTER_LISTED_PKG) || defined(__LOCATION_FILTER_LISTED_PKG) +#include <map> +#endif + +class PrivacyDb +{ +private: + static std::mutex m_singletonMutex; + static PrivacyDb* m_pInstance; +#if defined(__FILTER_LISTED_PKG) || defined(__LOCATION_FILTER_LISTED_PKG) + const static std::string PRIVACY_FILTER_LIST_FILE; + const static std::string PRIVACY_LOCATION_FILTER_LIST_FILE; + const static std::string FILTER_KEY; + static std::map < std::string, bool > m_filteredPkgList; + static std::map < std::string, bool > m_locationFilteredPkgList; +#endif + +private: + void createDB(void); + + bool isFilteredPackage(const std::string pkgId) const; + + bool isLocationFilteredPackage(const std::string pkgId) const; + + PrivacyDb(void); + + ~PrivacyDb(void); + +public: + static PrivacyDb* getInstance(void); + + int getPrivacyAppPackages(std::list <std::string>& list) const; + + int getAppPackagePrivacyInfo(const std::string pkgId, std::list < std::pair < std::string, bool > > & list) const; + + int setPrivacySetting(const std::string pkgId, const std::string privacyId, bool enabled); + + int addAppPackagePrivacyInfo(const std::string pkgcId, const std::list < std::string > privilegeList, bool privacyPopupRequired); + + int removeAppPackagePrivacyInfo(const std::string pkgId); + + int isUserPrompted(const std::string pkgId, bool& isPrompted) const; + + int setUserPrompted(const std::string pkgId, bool prompted); + + int getAppPackagesbyPrivacyId(std::string privacyId, std::list < std::pair < std::string, bool > >& list) const; +}; + + +#endif // _PRIVACY_DB_H_ diff --git a/common/inc/PrivacyIdInfo.h b/common/inc/PrivacyIdInfo.h new file mode 100644 index 0000000..ce2ec8f --- /dev/null +++ b/common/inc/PrivacyIdInfo.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013 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 _PRIVACY_ID_INFO_H_ +#define _PRIVACY_ID_INFO_H_ + +#include <string> +#include <map> +#include <list> +#include <mutex> + +class PrivacyIdInfo +{ +private: + static std::mutex m_initializeMutex; + static std::map <std::string, std::string> m_privilegeToPrivacyMap; + static bool m_isInitialized; + +public: + static int initialize(void); + static int getPrivacyIdFromPrivilege(const std::string privilege, std::string& privacyId); + static int getPrivilegeListFromPrivacyId(const std::string privacyId, std::list < std::string> & privilegeList); + static int getPrivacyIdListFromPrivilegeList(const std::list < std::string> privilegeList, std::list < std::string> & privacyIdList); + static int getAllPrivacyId(std::list < std::string >& privacyIdList); + + static int getPrivaycDisplayName(const std::string privacyId, std::string& displayName); + static int getPrivaycDisplayNameStringId(const std::string privacyId, std::string& displayNameStringId); + static int getPrivaycDescription(const std::string privacyId, std::string& description); + static int getPrivaycDescriptionStringId(const std::string privacyId, std::string& descriptionStringId); + + static int isFeatureEnabled(const std::string feature, bool& enabled); +}; + +#endif //_PRIVACY_ID_INFO_H_ diff --git a/common/inc/PrivacyManagerTypes.h b/common/inc/PrivacyManagerTypes.h new file mode 100644 index 0000000..becb451 --- /dev/null +++ b/common/inc/PrivacyManagerTypes.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013 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 _PRIVACY_MANAGER_TYPES_H_ +#define _PRIVACY_MANAGER_TYPES_H_ + +#include <string> +#include <privacy_manager_client_types.h> + +static const std::string PRIVACY_DB_PATH("/opt/dbspace/.privacy.db"); +static const std::string PRIVACY_INFO_DB_PATH("/opt/dbspace/.privacylist.db"); +static const std::string SERVER_ADDRESS ("/tmp/privacy_manager_server"); +static const std::string DBUS_PATH("/privacy_manager/dbus_notification"); +static const std::string DBUS_SIGNAL_INTERFACE("org.tizen.privacy_manager.signal"); +static const std::string DBUS_SIGNAL_SETTING_CHANGED("privacy_setting_changed"); +static const std::string DBUS_SIGNAL_PKG_REMOVED("privacy_pkg_removed"); + +#endif diff --git a/common/inc/SocketConnection.h b/common/inc/SocketConnection.h new file mode 100644 index 0000000..d255ed7 --- /dev/null +++ b/common/inc/SocketConnection.h @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2013 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 _SOCKET_CONNECTION_H_ +#define _SOCKET_CONNECTION_H_ + +#include <dlog.h> +#include <new> +#include <list> +#include <utility> +#include <SocketStream.h> +#include <PrivacyManagerTypes.h> +#include <iostream> +#include <Utils.h> +/* + * This class implements interface for generic read and write from given socket. + * It does not maintain socket descriptor, so any connecting and disconnecting should be + */ + +/* + * Throws SocketConnectionException when read/write will not succeed or if any bad allocation + * exception occurs during read. + */ + +class EXTERN_API SocketConnection +{ + +public: + + explicit SocketConnection(int socket_fd) : m_socketStream(socket_fd){ +// LOGI("Created"); + } + + template<typename T, typename ...Args> + int read(T* out, const Args&... args ) + { + int res = read(out); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "read : %d", res); + res = read(args...); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "read : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename T> + int read(T* out) + { + int length = 0; + int res = m_socketStream.readStream(sizeof(length), &length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "readStream : %d", res); + char* pBuf = new (std::nothrow) char[length + 1]; + TryReturn(pBuf != NULL, PRIV_MGR_ERROR_OUT_OF_MEMORY, , "new : %d", PRIV_MGR_ERROR_OUT_OF_MEMORY); + + res = m_socketStream.readStream(length, pBuf); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, delete[] pBuf, "readStream : %d", res); + + pBuf[length] = 0; + + out = T(pBuf); + + delete[] pBuf; + + return PRIV_MGR_ERROR_SUCCESS; + } + + int read(bool* pB) + { + int length = 0; + int res = m_socketStream.readStream(sizeof(length), &length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "readStream : %d", res); + + char* pBuf = new (std::nothrow) char[length + 1]; + TryReturn(pBuf != NULL, PRIV_MGR_ERROR_OUT_OF_MEMORY, , "new : %d", PRIV_MGR_ERROR_OUT_OF_MEMORY); + + res = m_socketStream.readStream(length, pBuf); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, delete[] pBuf, "readStream : %d", res); + + pBuf[length] = 0; + + *pB = * reinterpret_cast <bool* > (pBuf); + + delete[] pBuf; + + return PRIV_MGR_ERROR_SUCCESS; + } + + int read(bool& b) + { + return read(&b); + } + + int read(int& i) + { + return read(&i); + } + + int read(int* pI) + { + int length = 0; + int res = m_socketStream.readStream(sizeof(length), &length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "readStream : %d", res); + + char* pBuf = new (std::nothrow) char[length + 1]; + TryReturn(pBuf != NULL, PRIV_MGR_ERROR_OUT_OF_MEMORY, , "new : %d", PRIV_MGR_ERROR_OUT_OF_MEMORY); + + res = m_socketStream.readStream(length, pBuf); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, delete[] pBuf, "readStream : %d", res); + + pBuf[length] = 0; + + *pI = * reinterpret_cast <int* > (pBuf); + + delete[] pBuf; + + return PRIV_MGR_ERROR_SUCCESS; + } + + int read(std::string* pStr) + { + int length = 0; + int res = m_socketStream.readStream(sizeof(length), &length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "readStream : %d", res); + + char* pBuf = new (std::nothrow) char[length + 1]; + TryReturn(pBuf != NULL, PRIV_MGR_ERROR_OUT_OF_MEMORY, , "new : %d", PRIV_MGR_ERROR_OUT_OF_MEMORY); + + m_socketStream.readStream(length, pBuf); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, delete[] pBuf, "readStream : %d", res); + + pBuf[length] = 0; + + *pStr = std::string(pBuf); + delete[] pBuf; + + return PRIV_MGR_ERROR_SUCCESS; + } + + int read(std::string& str) + { + return read(&str); + } + + template < typename T > + int read (std::list<T>& list) + { + int length; + int res = read(length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "read : %d", res); + + for (int i = 0; i < length; ++i) + { + T obj; + res = read (obj); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "read : %d", res); + list.push_back(obj); + } + + return PRIV_MGR_ERROR_SUCCESS; + } + + template < typename T > + int read (std::list<T>* pList) + { + return read(*pList); + } + + template < typename K, typename P > + void read (std::pair<K, P>& pair) + { + int res = read( pair.first); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "read : %d", res); + res = read( pair.second); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "read : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template < typename K, typename P > + int read (std::pair<K, P>* pPair) + { + return read( *pPair); + } + + template<typename T, typename ...Args> + int write(const T& in, const Args&... args) + { + int res = write(in); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + res = write(args...); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + int write(const std::string& in) + { + int length = in.size(); + int res = m_socketStream.writeStream(sizeof(length), &length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + res = m_socketStream.writeStream(length, in.c_str()); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + int write(const unsigned int& in) + { + int length = sizeof(in); + int res = m_socketStream.writeStream(sizeof(length), &length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + res = m_socketStream.writeStream(length, &in); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + int write(const int& in) + { + int length = sizeof(in); + int res = m_socketStream.writeStream(sizeof(length), &length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + res = m_socketStream.writeStream(length, &in); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + int write(const bool& in) + { + int length = sizeof(in); + int res = m_socketStream.writeStream(sizeof(length), &length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + res = m_socketStream.writeStream(length, &in); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + int write(const char*& in) + { + int length = strlen(in); + int res = m_socketStream.writeStream(sizeof(length), &length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + res = m_socketStream.writeStream(length, in); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "writeStream : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename T, typename ...Args> + int write(const T* in, const Args&... args) + { + int res = write(in); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + res = write(args...); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename K, typename T> + int write(const std::pair<K, T> p) + { + int res = write(p.first); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + res = write(p.second); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename K, typename T> + int write(const std::pair<K, T&> p) + { + int res = write(p.first); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + res = write(p.second); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename K, typename T> + int write(const std::pair<K, T&>* pPair) + { + return write(*pPair); + } + + template<typename T> + int write(const std::list <T> list) + { + int length = list.size(); + int res = write(length); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + for (typename std::list <T>::const_iterator iter = list.begin(); iter != list.end(); iter++) { + res = write(*iter); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, res, , "write : %d", res); + } + + return PRIV_MGR_ERROR_SUCCESS; + } + + template<typename T> + int write(const std::list <T>* pList) + { + return write(*pList); + } + + +private: + SocketStream m_socketStream; +}; + +#endif // _SOCKET_CONNECTION_H_ diff --git a/common/inc/SocketStream.h b/common/inc/SocketStream.h new file mode 100644 index 0000000..d1631f6 --- /dev/null +++ b/common/inc/SocketStream.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013 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 _SOCKET_STREAM_H_ +#define _SOCKET_STREAM_H_ + +#include <string> +#include <PrivacyManagerTypes.h> + +class EXTERN_API SocketStream +{ +public: + explicit SocketStream(int socket_fd) + : m_socketFd(socket_fd) + , m_bytesRead(0) + ,m_bytesWrote(0) + { +// LOGI("Created"); + } + + int readStream(size_t num, void * bytes); + int writeStream(size_t num, const void * bytes); +private: + int throwWithErrnoMessage(std::string specificInfo); + int m_socketFd; + int m_bytesRead; + int m_bytesWrote; +}; + +#endif //_SOCKET_STREAM_H_ diff --git a/common/inc/Utils.h b/common/inc/Utils.h new file mode 100644 index 0000000..2e70cb9 --- /dev/null +++ b/common/inc/Utils.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013 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 _UTILS_H_ +#define _UTILS_H_ + +#include <vector> +#include <iostream> +#include <algorithm> +#include <dlog.h> +#include <sqlite3.h> +#include <memory> +#include <string> +#include <unistd.h> +#include <db-util.h> + +#define TryCatchLogReturn(condition, expr, r, logFormat) if (!(condition)) { \ + LOGE(logFormat); \ + expr; \ + return r; \ + } else {;} + +#define TryCatchResLogReturn(condition, expr, r, logFormat, res) if (!(condition)) { \ + LOGE(logFormat, res); \ + expr; \ + return r; \ + } else {;} + + +#define TryReturn(condition, r, expr, ...) \ + if ( !(condition) ) { \ + LOGE(__VA_ARGS__); \ + expr; \ + return r; \ + } else {;} + +auto StmtDeleter = [&](sqlite3_stmt* pPtr) { sqlite3_reset (pPtr); sqlite3_finalize(pPtr); }; +auto DbDeleter = [&](sqlite3* pPtr) { /*sqlite3_close(pPtr);*/ db_util_close(pPtr); }; + +#define setStmtToUniquePtr(x, y) std::unique_ptr < sqlite3_stmt, decltype(StmtDeleter) > x (y, StmtDeleter); +#define setDbToUniquePtr(x, y) std::unique_ptr < sqlite3, decltype(DbDeleter) > x (y, DbDeleter); + +#define openDb(dbpath, pHandler, mode) sqlite3* pHandler##Temp = NULL;\ + {\ + /*int res = sqlite3_open_v2(dbpath, &pHandler##Temp, mode , NULL);*/\ + int res = db_util_open_with_options(dbpath, &pHandler##Temp, mode, NULL);\ + TryCatchResLogReturn( res == SQLITE_OK, , PRIV_MGR_ERROR_DB_ERROR, "db_util_open_with_options : %d", res);\ + }\ + setDbToUniquePtr(pHandler, pHandler##Temp);\ + +static const int MAX_DATABASE_RETRY_COUNT = 5; +#define prepareDb(pHandler, sql, pStmt) sqlite3_stmt* pStmt##Temp;\ + {\ + int res = SQLITE_OK;\ + for (int dbRetryCount = 0; dbRetryCount < MAX_DATABASE_RETRY_COUNT; dbRetryCount++)\ + {\ + res = sqlite3_prepare_v2(pHandler.get(), sql, -1, & pStmt##Temp, NULL);\ + if (res != SQLITE_BUSY)\ + {\ + break;\ + }\ + else\ + {\ + LOGE("[DbRetryCount][%d]: Database is busy!", dbRetryCount); \ + usleep(50000);\ + }\ + }\ + TryCatchResLogReturn( res == SQLITE_OK, , PRIV_MGR_ERROR_DB_ERROR, "sqlite3_prepare_v2 : %d", res);\ + }\ + setStmtToUniquePtr(pStmt, pStmt##Temp); + +class Utils +{ +public: + static std::string toHash (std::string src); +}; +#endif //_UTILS_H_ diff --git a/common/inc/privacy_manager_client_types.h b/common/inc/privacy_manager_client_types.h new file mode 100644 index 0000000..9555cc8 --- /dev/null +++ b/common/inc/privacy_manager_client_types.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013 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 __TIZEN_PRIVACYMGR_PRIVACY_MANAGER_CLIENT_TYPES_H +#define __TIZEN_PRIVACYMGR_PRIVACY_MANAGER_CLIENT_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef EXTERN_API +#define EXTERN_API __attribute__((visibility("default"))) +#endif + +enum { + PRIV_MGR_ERROR_SUCCESS = 0, + + PRIV_MGR_ERROR_NOT_INITIALIZED = -10, + PRIV_MGR_ERROR_INVALID_PARAMETER = -11, + PRIV_MGR_ERROR_OUT_OF_MEMORY = -12, + PRIV_MGR_ERROR_IO_ERROR = -13, + PRIV_MGR_ERROR_NO_DATA = -14, + PRIV_MGR_ERROR_DB_ERROR = -15, + PRIV_MGR_ERROR_IPC_ERROR = -16, + PRIV_MGR_ERROR_INVALID_STATE = -17, + PRIV_MGR_ERROR_SYSTEM_ERROR = -18, + PRIV_MGR_ERROR_USER_NOT_CONSENTED = -19, + + PRIV_MGR_ERROR_UNKNOWN = -(0x99), +}; + + +#ifdef __cplusplus +} +#endif + +#endif //__TIZEN_PRIVACYMGR_PRIVACY_MANAGER_CLIENT_TYPES_H diff --git a/common/src/PrivacyDb.cpp b/common/src/PrivacyDb.cpp new file mode 100644 index 0000000..00c7ac3 --- /dev/null +++ b/common/src/PrivacyDb.cpp @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2013 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 <sstream> +#include <fstream> +#include <dlog.h> +#include <Utils.h> +#include <PrivacyDb.h> +#include <PrivacyManagerTypes.h> +#include <sqlite3.h> +#include <pkgmgr-info.h> + +std::mutex PrivacyDb::m_singletonMutex; +PrivacyDb* PrivacyDb::m_pInstance = NULL; +#if defined(__FILTER_LISTED_PKG) || defined(__LOCATION_FILTER_LISTED_PKG) +const std::string PrivacyDb::PRIVACY_FILTER_LIST_FILE = std::string("/usr/share/privacy-manager/privacy-filter-list.ini"); +const std::string PrivacyDb::PRIVACY_LOCATION_FILTER_LIST_FILE = std::string("/usr/share/privacy-manager/privacy-location-filter-list.ini"); +const std::string PrivacyDb::FILTER_KEY = std::string("package_id"); +std::map < std::string, bool > PrivacyDb::m_filteredPkgList; +std::map < std::string, bool > PrivacyDb::m_locationFilteredPkgList; +static const char* locationPrivacyKey = "http://tizen.org/privacy/location"; +#endif + +void +PrivacyDb::createDB(void) +{ + +} + +bool PrivacyDb::isFilteredPackage(const std::string pkgId) const +{ +#ifdef __FILTER_PRELOADED_PKG + pkgmgrinfo_pkginfo_h handle; + + int res = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle); + + if (res != PMINFO_R_OK) + return false; + + bool preloaded = false; + res = pkgmgrinfo_pkginfo_is_preload(handle, &preloaded); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + + return preloaded; +#elif __FILTER_LISTED_PKG + if (m_filteredPkgList.empty()) + return false; + + std::map < std::string, bool >::iterator it; + if ( (it = m_filteredPkgList.find(pkgId)) != m_filteredPkgList.end()) + { + return true; + } + + return false; +#else + return false; +#endif +} + +bool PrivacyDb::isLocationFilteredPackage(const std::string pkgId) const +{ +#ifdef __LOCATION_FILTER_PRELOADED_PKG + pkgmgrinfo_pkginfo_h handle; + + int res = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle); + + if (res != PMINFO_R_OK) + return false; + + bool preloaded = false; + res = pkgmgrinfo_pkginfo_is_preload(handle, &preloaded); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + + return preloaded; +#elif __LOCATION_FILTER_LISTED_PKG + if (m_locationFilteredPkgList.empty()) + return false; + + std::map < std::string, bool >::iterator it; + if ( (it = m_locationFilteredPkgList.find(pkgId)) != m_locationFilteredPkgList.end()) + { + return true; + } + return false; +#else + return false; +#endif +} + + +int +PrivacyDb::setPrivacySetting(const std::string pkgId, const std::string privacyId, bool enabled) +{ + static const std::string query = std::string("UPDATE PrivacyInfo set IS_ENABLED =? where PKG_ID=? and PRIVACY_ID=?"); + + openDb(PRIVACY_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READWRITE); + prepareDb(pDbHandler, query.c_str(), pStmt); + + int res = sqlite3_bind_int(pStmt.get(), 1, enabled); + TryReturn(res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_int : %d", res); + + res = sqlite3_bind_text(pStmt.get(), 2, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn(res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_int : %d", res); + + res = sqlite3_bind_text(pStmt.get(), 3, privacyId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + res = sqlite3_step(pStmt.get()); + TryReturn( res == SQLITE_DONE, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_step : %d", res); + + return 0; +} + +int +PrivacyDb::getPrivacyAppPackages(std::list <std::string>& list) const +{ + std::string query = "SELECT DISTINCT PKG_ID FROM PrivacyInfo WHERE PRIVACY_ID != 'http://tizen.org/privacy/location'"; + + openDb(PRIVACY_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READONLY); + prepareDb(pDbHandler, query.c_str(), pStmt); + + while ( sqlite3_step(pStmt.get()) == SQLITE_ROW ) + { + const char* pValue = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 0)); + + SECURE_LOGD("PkgId found : %s ", pValue); + std::string pkgId = std::string(pValue); + + if (isFilteredPackage(pkgId)) + { + SECURE_LOGD("%s is Filtered by isFilteredPackage", pkgId.c_str()); + continue; + } + list.push_back(std::string(pValue)); + } + + std::string locationQuery = "SELECT DISTINCT PKG_ID FROM PrivacyInfo WHERE PRIVACY_ID = 'http://tizen.org/privacy/location'"; + prepareDb(pDbHandler, locationQuery.c_str(), pLocationStmt); + + while ( sqlite3_step(pLocationStmt.get()) == SQLITE_ROW ) + { + const char* pValue = reinterpret_cast < const char* > (sqlite3_column_text(pLocationStmt.get(), 0)); + + SECURE_LOGD("PkgId found [Location] : %s ", pValue); + std::string pkgId = std::string(pValue); + + if (isLocationFilteredPackage(pkgId)) + { + SECURE_LOGD("%s is Filtered by isLocationFilteredPackage", pkgId.c_str()); + continue; + } + list.push_back(std::string(pValue)); + } + + list.sort(); + list.unique(); + return 0; +} + +int +PrivacyDb::getAppPackagePrivacyInfo(const std::string pkgId, std::list < std::pair < std::string, bool > >& privacyInfoList) const +{ + static const std::string query = "SELECT PRIVACY_ID, IS_ENABLED from PrivacyInfo where PKG_ID=?"; + + openDb(PRIVACY_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READONLY); + prepareDb(pDbHandler, query.c_str(), pStmt); + + int res = sqlite3_bind_text(pStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_int : %d", res); + + while ( (res= sqlite3_step(pStmt.get())) == SQLITE_ROW ) + { + const char* privacyId = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 0)); + if (strncmp(privacyId, locationPrivacyKey, strlen(privacyId)) == 0) + { + if (isLocationFilteredPackage(pkgId)) + { + SECURE_LOGD("%s is Filtered by isLocationFilteredPackage", pkgId.c_str()); + continue; + } + } + else + { + if (isFilteredPackage(pkgId)) + { + SECURE_LOGD("%s is Filtered by isFilteredPackage", pkgId.c_str()); + continue; + } + } + + bool privacyEnabled = sqlite3_column_int(pStmt.get(), 1) > 0 ? true : false; + + privacyInfoList.push_back( std::pair <std::string, bool> (std::string(privacyId), privacyEnabled) ); + + SECURE_LOGD("Privacy found : %s %d", privacyId, privacyEnabled); + } + + return 0; +} + + +int +PrivacyDb::addAppPackagePrivacyInfo(const std::string pkgId, const std::list < std::string > privilegeList, bool privacyPopupRequired) +{ + static const std::string pkgInfoQuery("INSERT INTO PackageInfo(PKG_ID, IS_SET) VALUES(?, ?)"); + static const std::string privacyQuery("INSERT INTO PrivacyInfo(PKG_ID, PRIVACY_ID, IS_ENABLED) VALUES(?, ?, ?)"); + + openDb(PRIVACY_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READWRITE); + prepareDb(pDbHandler, pkgInfoQuery.c_str(), pPkgInfoStmt); + + int res = sqlite3_bind_text(pPkgInfoStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + res = sqlite3_bind_int(pPkgInfoStmt.get(), 2, privacyPopupRequired ? 0 : 1); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_int : %d", res); + + res = sqlite3_step(pPkgInfoStmt.get()); + TryReturn( res == SQLITE_DONE, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_step : %d", res); + + for ( std::list <std::string>::const_iterator iter = privilegeList.begin(); iter != privilegeList.end(); ++iter) + { + SECURE_LOGD("install privacy: %s", iter->c_str()); + prepareDb(pDbHandler, privacyQuery.c_str(), pPrivacyStmt); + + res = sqlite3_bind_text(pPrivacyStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_int : %d", res); + + res = sqlite3_bind_text(pPrivacyStmt.get(), 2, iter->c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + // Before setting app and popup is ready, default value is true + res = sqlite3_bind_int(pPrivacyStmt.get(), 3, 1); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_int : %d", res); + + res = sqlite3_step(pPrivacyStmt.get()); + TryReturn( res == SQLITE_DONE || res == SQLITE_CONSTRAINT, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_step : %d", res); + + sqlite3_reset(pPrivacyStmt.get()); + } + + return 0; +} + +int +PrivacyDb::removeAppPackagePrivacyInfo(const std::string pkgId) +{ + static const std::string pkgInfoQuery("DELETE FROM PackageInfo WHERE PKG_ID=?"); + static const std::string privacyQuery("DELETE FROM PrivacyInfo WHERE PKG_ID=?"); + + int res; + + openDb(PRIVACY_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READWRITE); + prepareDb(pDbHandler, pkgInfoQuery.c_str(), pPkgInfoStmt); + + res = sqlite3_bind_text(pPkgInfoStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + res = sqlite3_step(pPkgInfoStmt.get()); + TryReturn( res == SQLITE_DONE, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_step : %d", res); + + prepareDb(pDbHandler, privacyQuery.c_str(), pPrivacyStmt); + + res = sqlite3_bind_text(pPrivacyStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + res = sqlite3_step(pPrivacyStmt.get()); + TryReturn( res == SQLITE_DONE, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_step : %d", res); + + return 0; +} + +int +PrivacyDb::isUserPrompted(const std::string pkgId, bool& isPrompted) const +{ + static const std::string query = "SELECT IS_SET from PackageInfo where PKG_ID=?"; + + isPrompted = true; + + if (isFilteredPackage(pkgId) && isLocationFilteredPackage(pkgId)) + { + SECURE_LOGD("%s is Filtered", pkgId.c_str()); + return 0; + } + + openDb(PRIVACY_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READONLY); + prepareDb(pDbHandler, query.c_str(), pStmt); + + int res = sqlite3_bind_text(pStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + std::unique_ptr < std::list < std::pair < std:: string, bool > > > pList ( new std::list < std::pair < std:: string, bool > >); + + if ((res = sqlite3_step(pStmt.get())) == SQLITE_ROW) + { + isPrompted = sqlite3_column_int(pStmt.get(), 0) > 0 ? true : false; + } + else + { + SECURE_LOGE("The package[%s] can not access privacy", pkgId.c_str()); + return PRIV_MGR_ERROR_SUCCESS; + } + + return 0; +} + +int +PrivacyDb::setUserPrompted(const std::string pkgId, bool prompted) +{ + std::string query = std::string("UPDATE PackageInfo set IS_SET =? where PKG_ID=?"); + + int res; + + openDb(PRIVACY_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READWRITE); + prepareDb(pDbHandler, query.c_str(), pStmt); + + res = sqlite3_bind_int(pStmt.get(), 1, prompted? 1 : 0); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_int : %d", res); + + res = sqlite3_bind_text(pStmt.get(), 2, pkgId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + res = sqlite3_step(pStmt.get()); + TryReturn( res == SQLITE_DONE, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_step : %d", res); + + return 0; +} + +int +PrivacyDb::getAppPackagesbyPrivacyId(std::string privacyId, std::list < std::pair < std::string, bool > >& list) const +{ + std::string sql = std::string("SELECT PKG_ID, IS_ENABLED from PrivacyInfo where PRIVACY_ID=?"); + + openDb(PRIVACY_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READWRITE); + prepareDb(pDbHandler, sql.c_str(), pStmt); + + SECURE_LOGD("privacy id : %s", privacyId.c_str()); + int res = sqlite3_bind_text(pStmt.get(), 1, privacyId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + while ( sqlite3_step(pStmt.get()) == SQLITE_ROW ) + { + const char* pPkgId = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 0)); + bool isEnabled = sqlite3_column_int(pStmt.get(), 1) > 0 ? true : false; + std::string pkgId = std::string(pPkgId); + if (privacyId == locationPrivacyKey) + { + if (isLocationFilteredPackage(pkgId)) + { + SECURE_LOGD("%s is Filtered by isLocationFilteredPackage", pkgId.c_str()); + continue; + } + } + else + { + if (isFilteredPackage(pkgId)) + { + SECURE_LOGD("%s is Filtered by isFilteredPackage", pkgId.c_str()); + continue; + } + } + + list.push_back( std::pair <std::string, bool >(pkgId, isEnabled) ); + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +PrivacyDb::PrivacyDb(void) +{ + +#if defined(__FILTER_LISTED_PKG) || defined(__LOCATION_FILTER_LISTED_PKG) + SECURE_LOGD("Construct with filter list"); + std::ifstream inFile; + inFile.open(PRIVACY_FILTER_LIST_FILE); + TryReturn(inFile.is_open(), , , "Cannot find %s file.", PRIVACY_FILTER_LIST_FILE.c_str()); + + char inputLine[256] = {0,}; + while(inFile.getline(inputLine, 256)) + { + if (inputLine[0] == '#') + continue; + if (strncmp(FILTER_KEY.c_str(), inputLine, FILTER_KEY.length()) != 0) + { + SECURE_LOGD("Invalid Key[%s]", inputLine); + continue; + } + std::string pkgId = std::string(inputLine).substr(FILTER_KEY.length() + 1); + if (!pkgId.empty()) + m_filteredPkgList.insert ( std::pair < std::string, bool > (pkgId, true) ); + SECURE_LOGD("Filter PKG: %s", pkgId.c_str()); + } + + SECURE_LOGD("Construct with filter list of location"); + std::ifstream inFileLocation; + inFileLocation.open(PRIVACY_LOCATION_FILTER_LIST_FILE); + TryReturn(inFileLocation.is_open(), , , "Cannot find %s file.", PRIVACY_LOCATION_FILTER_LIST_FILE.c_str()); + while(inFileLocation.getline(inputLine, 256)) + { + if (inputLine[0] == '#') + continue; + if (strncmp(FILTER_KEY.c_str(), inputLine, FILTER_KEY.length()) != 0) + { + SECURE_LOGD("Invalid Key[%s]", inputLine); + continue; + } + std::string pkgId = std::string(inputLine).substr(FILTER_KEY.length() + 1); + if (!pkgId.empty()) + m_locationFilteredPkgList.insert ( std::pair < std::string, bool > (pkgId, true) ); + SECURE_LOGD("Location filter PKG: %s", pkgId.c_str()); + } +#endif + +} + +PrivacyDb::~PrivacyDb(void) +{ + +} + +PrivacyDb* +PrivacyDb::getInstance(void) +{ + std::lock_guard < std::mutex > guard(m_singletonMutex); + + if (m_pInstance == NULL) + { + m_pInstance = new PrivacyDb(); + } + + return m_pInstance; +} diff --git a/common/src/PrivacyIdInfo.cpp b/common/src/PrivacyIdInfo.cpp new file mode 100644 index 0000000..5b18fd8 --- /dev/null +++ b/common/src/PrivacyIdInfo.cpp @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2013 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 <PrivacyIdInfo.h> +#include <privacy_manager_client_types.h> +#include <PrivacyManagerTypes.h> +#include <dlog.h> +#include <set> +#include <Utils.h> +#include <libintl.h> +#include <system_info.h> + +std::mutex PrivacyIdInfo::m_initializeMutex; +std::map <std::string, std::string> PrivacyIdInfo::m_privilegeToPrivacyMap; +bool PrivacyIdInfo:: m_isInitialized; + +int +PrivacyIdInfo::initialize(void) +{ + std::lock_guard < std::mutex > guard(m_initializeMutex); + if(m_isInitialized) + return PRIV_MGR_ERROR_SUCCESS; + + static const std::string sqlPrivilege("SELECT PRIVILEGE_ID, PRIVACY_ID from PrivilegeToPrivacyTable"); + static const std::string sqlPrivacyInfo("SELECT FEATURE FROM PrivacyInfo where PRIVACY_ID=?"); + + openDb(PRIVACY_INFO_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READONLY); + prepareDb(pDbHandler, sqlPrivilege.c_str(), pStmtPrivilege); + + int res; + while ( (res = sqlite3_step(pStmtPrivilege.get())) == SQLITE_ROW ) + { + const char* privilegeId = reinterpret_cast < const char* > (sqlite3_column_text(pStmtPrivilege.get(), 0)); + const char* privacyId = reinterpret_cast < const char* > (sqlite3_column_text(pStmtPrivilege.get(), 1)); + + prepareDb(pDbHandler, sqlPrivacyInfo.c_str(), pStmtPrivacyInfo); + res = sqlite3_bind_text(pStmtPrivacyInfo.get(), 1, privacyId, -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + res = sqlite3_step(pStmtPrivacyInfo.get()); + //LOGD("privacy id : %s", privacyId); + TryReturn( res == SQLITE_DONE || res == SQLITE_ROW, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_step : %d", res); + + const char* feature = reinterpret_cast < const char* > (sqlite3_column_text(pStmtPrivacyInfo.get(), 0)); + if (feature != NULL) + { + bool isSupported = false; + + res = isFeatureEnabled(std::string(feature), isSupported); + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "isFeatureEnabled : %d", res); + + if (!isSupported) + continue; + } + + m_privilegeToPrivacyMap.insert(std::map < std::string, std::string >::value_type(std::string(privilegeId), std::string(privacyId))); + } + + m_isInitialized = true; + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyIdInfo::getPrivacyIdFromPrivilege(const std::string privilege, std::string& privacyId) +{ + if (!m_isInitialized) + initialize(); + std::map < std::string, std::string >::iterator iter = m_privilegeToPrivacyMap.find(privilege); + if (iter == m_privilegeToPrivacyMap.end()) + return PRIV_MGR_ERROR_NO_DATA; + privacyId = iter->second; + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyIdInfo::getPrivilegeListFromPrivacyId(const std::string privacyId, std::list < std::string> & privilegeList) +{ + if (!m_isInitialized) + initialize(); + + privilegeList.clear(); + for (std::map < std::string, std::string >::iterator iter = m_privilegeToPrivacyMap.begin(); iter != m_privilegeToPrivacyMap.end(); ++iter) + { + if (privacyId.compare((iter->second)) == 0) + { + privilegeList.push_back(iter->first); + } + } + + if (privilegeList.size() == 0) + { + LOGE("PrivilegeList of %s privacy is empty!", privacyId.c_str()); + return PRIV_MGR_ERROR_NO_DATA; + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyIdInfo::getPrivacyIdListFromPrivilegeList(const std::list < std::string> privilegeList, std::list < std::string> & privacyIdList) +{ + if (!m_isInitialized) + initialize(); + + privacyIdList.clear(); + + std::set <std::string> privacyIdSet; + + for (std::list < std::string > ::const_iterator iter = privilegeList.begin(); iter != privilegeList.end(); ++iter) + { + std::string privacyId; + int res = getPrivacyIdFromPrivilege(*iter, privacyId); + if (res == PRIV_MGR_ERROR_SUCCESS) + privacyIdSet.insert(privacyId); + } + + for (std::set < std::string >::iterator iter = privacyIdSet.begin(); iter != privacyIdSet.end(); ++iter) + { + privacyIdList.push_back(*iter); + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyIdInfo::getAllPrivacyId(std::list < std::string >& privacyIdList) +{ + static const std::string sql("SELECT PRIVACY_ID, FEATURE from PrivacyInfo"); + + if (!m_isInitialized) + initialize(); + + openDb(PRIVACY_INFO_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READONLY); + prepareDb(pDbHandler, sql.c_str(), pStmt); + + int res; + while ( (res = sqlite3_step(pStmt.get())) == SQLITE_ROW ) + { + const char* privacyId = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 0)); + const char* feature = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 1)); + //LOGD("privacy: %s, feature: %s", privacyId, feature); + + if (feature != NULL) + { + bool isSupported = false; + res = isFeatureEnabled(std::string(feature), isSupported); + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "isFeatureEnabled : %d", res); + if (!isSupported) + continue; + } + + privacyIdList.push_back(std::string(privacyId)); + //SECURE_LOGD(" privacy Id : %s", privacyId); + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyIdInfo::getPrivaycDisplayName(const std::string privacyId, std::string& displayName) +{ + if (!m_isInitialized) + initialize(); + + std::string sql = std::string("SELECT STR_MODULE_ID, STR_NAME_ID from PrivacyInfo where PRIVACY_ID=?"); + + openDb(PRIVACY_INFO_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READONLY); + prepareDb(pDbHandler, sql.c_str(), pStmt); + + int res = sqlite3_bind_text(pStmt.get(), 1, privacyId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + if ( sqlite3_step(pStmt.get()) == SQLITE_ROW ) + { + const char* pModuleId = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 0)); + const char* pNameId = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 1)); + + if (pNameId == NULL) + displayName = privacyId; + else + displayName = std::string(dgettext(pModuleId, pNameId)); + } + else + { + LOGI("Cannot find privacy string %s ", privacyId.c_str()); + return PRIV_MGR_ERROR_NO_DATA; + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyIdInfo::getPrivaycDisplayNameStringId(const std::string privacyId, std::string& displayNameStringId) +{ + if (!m_isInitialized) + initialize(); + + std::string sql = std::string("SELECT STR_MODULE_ID, STR_NAME_ID from PrivacyInfo where PRIVACY_ID=?"); + + openDb(PRIVACY_INFO_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READONLY); + prepareDb(pDbHandler, sql.c_str(), pStmt); + + int res = sqlite3_bind_text(pStmt.get(), 1, privacyId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + if ( sqlite3_step(pStmt.get()) == SQLITE_ROW ) + { + const char* pNameId = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 1)); + + if (pNameId == NULL) + displayNameStringId = privacyId; + else + displayNameStringId = pNameId; + } + else + { + LOGI("Cannot find privacy string %s ", privacyId.c_str()); + return PRIV_MGR_ERROR_NO_DATA; + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyIdInfo::getPrivaycDescription(const std::string privacyId, std::string& description) +{ + if (!m_isInitialized) + initialize(); + + std::string sql = std::string("SELECT STR_MODULE_ID, STR_NAME_ID from PrivacyInfo where PRIVACY_ID=?"); + + openDb(PRIVACY_INFO_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READONLY); + prepareDb(pDbHandler, sql.c_str(), pStmt); + + int res = sqlite3_bind_text(pStmt.get(), 1, privacyId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + if ( sqlite3_step(pStmt.get()) == SQLITE_ROW ) + { + const char* pModuleId = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 0)); + const char* pNameId = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 1)); + + description = std::string(dgettext(pModuleId, pNameId)); + } + else + { + LOGI("Cannot find privacy string %s ", privacyId.c_str()); + return PRIV_MGR_ERROR_NO_DATA; + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyIdInfo::getPrivaycDescriptionStringId(const std::string privacyId, std::string& descriptionStringId) +{ + if (!m_isInitialized) + initialize(); + + std::string sql = std::string("SELECT STR_MODULE_ID, STR_NAME_ID from PrivacyInfo where PRIVACY_ID=?"); + + openDb(PRIVACY_INFO_DB_PATH.c_str(), pDbHandler, SQLITE_OPEN_READONLY); + prepareDb(pDbHandler, sql.c_str(), pStmt); + + int res = sqlite3_bind_text(pStmt.get(), 1, privacyId.c_str(), -1, SQLITE_TRANSIENT); + TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res); + + if ( sqlite3_step(pStmt.get()) == SQLITE_ROW ) + { + const char* pNameId = reinterpret_cast < const char* > (sqlite3_column_text(pStmt.get(), 1)); + + descriptionStringId = pNameId; + } + else + { + LOGI("Cannot find privacy string %s ", privacyId.c_str()); + return PRIV_MGR_ERROR_NO_DATA; + } + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyIdInfo::isFeatureEnabled(const std::string feature, bool& enabled) +{ + int res = 0; + + if (feature.empty()) + { + enabled = true; + return res; + } + + if(feature.find("tizen.org/feature") != std::string::npos) + { + res = system_info_get_platform_bool(feature.c_str(), &enabled); + } + else + { + res = system_info_get_custom_bool(feature.c_str(), &enabled); + } + TryReturn(res == 0, PRIV_MGR_ERROR_SYSTEM_ERROR, , "system_info_get : %d", res); + + return PRIV_MGR_ERROR_SUCCESS; +} diff --git a/common/src/SocketConnection.cpp b/common/src/SocketConnection.cpp new file mode 100644 index 0000000..bb9101c --- /dev/null +++ b/common/src/SocketConnection.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013 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 "SocketConnection.h" + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/common/src/SocketStream.cpp b/common/src/SocketStream.cpp new file mode 100644 index 0000000..4337c3e --- /dev/null +++ b/common/src/SocketStream.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2013 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 <sys/socket.h> +#include <sys/select.h> +#include <errno.h> +#include <cstring> +#include <unistd.h> +#include <dlog.h> +#include <Utils.h> +#include "SocketStream.h" + +#define READ_TIEMOUT_SEC 1 +#define READ_TIMEUOT_NSEC 0 +#define WRITE_TIMEOUT_SEC 0 +#define WRITE_TIMEOUT_NSEC 100000000 +#define MAX_BUFFER 10240 + +int +SocketStream::throwWithErrnoMessage(std::string function_name) +{ + LOGE("%s : %s", function_name.c_str(), strerror(errno)); + return errno; +} + +int +SocketStream::readStream(size_t num, void* pBytes) +{ + TryReturn(pBytes != NULL, -1, , "Null pointer to buffer"); + + m_bytesRead += num; + + TryReturn(m_bytesRead <= MAX_BUFFER, -1, , "Too big buffer requested!"); + + char partBuffer[MAX_BUFFER]; + std::string wholeBuffer; + + fd_set rset, allset; + int maxFd; + ssize_t bytesRead = 0; + ssize_t bytesToRead = (ssize_t) num; + + timespec timeout; + + maxFd = m_socketFd; + ++maxFd; + + FD_ZERO(&allset); + FD_SET(m_socketFd, &allset); + + int ret = -1; + + while(bytesToRead != 0) + { + timeout.tv_sec = READ_TIEMOUT_SEC; + timeout.tv_nsec = READ_TIMEUOT_NSEC; + rset = allset; + + if ( (ret = pselect(maxFd, &rset, NULL, NULL, &timeout, NULL)) == -1 ) + { + if (errno == EINTR) + continue; + LOGD("pselect : %s", strerror(errno)); + return -1; + } + //This means pselect got timedout + //This is not a proper behavior in reading data from UDS + //And could mean we got corrupted connection + TryReturn(ret != 0, -1, , "Couldn't read whole data"); + + if ( FD_ISSET(m_socketFd, &rset) ) + { + bytesRead = read(m_socketFd, partBuffer, num); + if ( bytesRead <= 0 ) + { + if(errno == ECONNRESET || errno == ENOTCONN || errno == ETIMEDOUT) + { + LOGI("Connection closed : %s", strerror(errno)); + return -1; + } + else if (errno != EAGAIN && errno != EWOULDBLOCK){ + LOGI("read()"); + return -1; + } + } + + wholeBuffer.append(partBuffer, bytesRead); + bytesToRead -= bytesRead; + bytesRead = 0; + continue; + } + + } + memcpy(pBytes, wholeBuffer.c_str(), num); + + return 0; +} + +int +SocketStream::writeStream(size_t num, const void* pBytes) +{ + TryReturn(pBytes != NULL, -1, , "Null pointer to buffer"); + + m_bytesWrote += num; + + TryReturn(m_bytesRead <= MAX_BUFFER, -1, , "Too big buffer requested!"); + + fd_set wset, allset; + int maxFd; + + timespec timeout; + + maxFd = m_socketFd; + ++maxFd; + + FD_ZERO(&allset); + FD_SET(m_socketFd, &allset); + + int res; + int writeRes; + int bytesToWrite = num; + unsigned int currentOffset = 0; + + while(currentOffset != num) + { + timeout.tv_sec = WRITE_TIMEOUT_SEC; + timeout.tv_nsec = WRITE_TIMEOUT_NSEC; + wset = allset; + + if ( (res = pselect(maxFd, NULL, &wset, NULL, &timeout, NULL)) == -1 ) + { + if(errno == EINTR) + continue; + LOGD("pselect : %s", strerror(errno)); + return -1; + } + + if(FD_ISSET(m_socketFd, &wset)) + { + if ( (writeRes = write(m_socketFd, reinterpret_cast<const char *>(pBytes) + currentOffset, bytesToWrite)) == -1) + { + if(errno == ECONNRESET || errno == EPIPE) + { + LOGI("Connection closed : %s", strerror(errno)); + return -1; + + } + else if(errno != EAGAIN && errno != EWOULDBLOCK) + { + LOGE("write()"); + return -1; + } + } + currentOffset += writeRes; + bytesToWrite -= writeRes; + } + } + return 0; +}
\ No newline at end of file diff --git a/common/src/Utils.cpp b/common/src/Utils.cpp new file mode 100644 index 0000000..d7aa293 --- /dev/null +++ b/common/src/Utils.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2013 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 <Utils.h> + +std::string Utils::toHash(std::string src) +{ + return src; +}
\ No newline at end of file diff --git a/doc/privacy_manager_doc.h b/doc/privacy_manager_doc.h new file mode 100755 index 0000000..63ee26c --- /dev/null +++ b/doc/privacy_manager_doc.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2011 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 __TIZEN_CORE_LIB_PRIVACY_MANAGER_DOC_H__ +#define __TIZEN_CORE_LIB_PRIVACY_MANAGER_DOC_H__ + +/** + * @defgroup CAPI_PRIVACY_MANAGER_MODULE Privacy Manager + * @ingroup CAPI_SECURITY_FRAMEWORK + * @brief The Privacy Manager provides functions for getting package list which can access user's privacy information and getting privacy setting information of the system. + * If the user turned off a privacy setting to the specific package, the package can not access related user's privacy information. + * @section CAPI_PRIVACY_MANAGER_MODULE_HEADER Required Header + * #include <privacy_manager.h> + * + * @section CAPI_PRIVACY_MANAGER_MODULE_OVERVIEW Overview + * This module provides information about package id can access user's privacy information and it's privacy setting information(@see privacy_info). + */ + +/** + * @defgroup CAPI_PRIVACY_INFO_MODULE Privacy Information + * @ingroup CAPI_PRIVACY_MANAGER_MODULE + * @brief The Privacy Information provides functions for getting it's privacy setting information, privacy id, display name and so on. + * @section CAPI_PRIVACY_INFO_MODULE_HEADER Required Header + * #include <privacy_manager.h> + * + * @section CAPI_PRIVACY_INFO_MODULE_OVERVIEW Overview + * This module provides functions for: + * - releasing privacy information and all its resources (privacy_info_destroy()), + * - getting the privacy ID/display name of the given privacy info (privacy_info_get_privacy_id(), privacy_info_get_privacy_display_name(), privacy_info_get_privacy_display_name_string_id()), + * - getting the description of the given privacy info (privacy_info_get_privacy_description(), privacy_info_get_privacy_description_string_id()), + * - checking whether the privacy setting is enabled (privacy_info_is_enabled()), + * - creating a copy of the given privacy info (privacy_info_clone()). + */ + +#endif diff --git a/packaging/libprivacy-manager-client.manifest b/packaging/libprivacy-manager-client.manifest new file mode 100644 index 0000000..c00c25b --- /dev/null +++ b/packaging/libprivacy-manager-client.manifest @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_" /> + </request> +</manifest> diff --git a/packaging/privacy-manager-client.manifest b/packaging/privacy-manager-client.manifest new file mode 100644 index 0000000..c00c25b --- /dev/null +++ b/packaging/privacy-manager-client.manifest @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_" /> + </request> +</manifest> diff --git a/packaging/privacy-manager-server.changes b/packaging/privacy-manager-server.changes new file mode 100644 index 0000000..a8af1cc --- /dev/null +++ b/packaging/privacy-manager-server.changes @@ -0,0 +1,2 @@ +* Thu Jul 25 2013 Hyunwoo Kim <hwlove.kim@samsung.com> +- If a feature is not supported in devices, related privacy ID is ignored. diff --git a/packaging/privacy-manager-server.manifest b/packaging/privacy-manager-server.manifest new file mode 100644 index 0000000..51c3106 --- /dev/null +++ b/packaging/privacy-manager-server.manifest @@ -0,0 +1,18 @@ +<manifest> + <define> + <domain name="privacy-manager" /> + <provide> + <label name="privacy-manager::daemon" /> + <label name="privacy-manager::db" /> + </provide> + <request> + <smack request="security-server::api-app-permissions" type="w"/> + </request> + </define> + <request> + <domain name="_" /> + </request> + <assign> + <filesystem path="/opt/dbspace/.privacylist.db" label="privacy-manager::db" exec_label="none" /> + </assign> +</manifest> diff --git a/packaging/privacy-manager-server.service b/packaging/privacy-manager-server.service new file mode 100644 index 0000000..2e7a99c --- /dev/null +++ b/packaging/privacy-manager-server.service @@ -0,0 +1,9 @@ + +[Unit] +Description=privacy manager server + +[Service] +ExecStart=/usr/bin/privacy-manager-server + +[Install] +WantedBy=multi-user.target diff --git a/packaging/privacy-manager.spec b/packaging/privacy-manager.spec new file mode 100644 index 0000000..69c3234 --- /dev/null +++ b/packaging/privacy-manager.spec @@ -0,0 +1,155 @@ +Name: privacy-manager-server +Summary: Privacy Management +Version: 0.0.6 +Release: 0 +Group: System/Libraries +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source1: privacy-manager-server.service +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(db-util) +BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(libprivilege-control) +BuildRequires: pkgconfig(security-server) +BuildRequires: pkgconfig(capi-appfw-app-manager) +BuildRequires: pkgconfig(capi-appfw-package-manager) +BuildRequires: pkgconfig(libsmack) +BuildRequires: pkgconfig(vconf) +BuildRequires: gettext-tools + +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description +Privacy Management + +%package -n privacy-manager-server-devel +summary: privacy-manager server +Group: Development/Libraries +Requires: privacy-manager-server = %{version}-%{release} + +%description -n privacy-manager-server-devel +privacy-manager server devel + +%package -n privacy-manager-client +summary: privacy-manager client +Group: Development/Libraries +Requires: privacy-manager-server = %{version}-%{release} + +%description -n privacy-manager-client +privacy-manager client + +%package -n privacy-manager-client-devel +Summary: privacy-manager client devel +Group: Development/Libraries +BuildRequires: pkgconfig(libxml-2.0) +Requires: privacy-manager-client = %{version}-%{release} + +%description -n privacy-manager-client-devel +Privacy Management(development files) + +%prep +%setup -q + +%build +#%{!?build_type:%define build_type "Release"} + +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" + +export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_ENGINEER_MODE" +export FFLAGS="$FFLAGS -DTIZEN_ENGINEER_MODE" + +echo cmake . -DPREFIX=%{_prefix} \ + -DEXEC_PREFIX=%{_exec_prefix} \ + -DLIBDIR=%{_libdir} \ + -DINCLUDEDIR=%{_includedir} \ + -DCMAKE_BUILD_TYPE=%{build_type} \ + -DVERSION=%{version} \ + -DFILTER_LISTED_PKG=ON +cmake . -DPREFIX=%{_prefix} \ + -DEXEC_PREFIX=%{_exec_prefix} \ + -DLIBDIR=%{_libdir} \ + -DINCLUDEDIR=%{_includedir} \ + -DCMAKE_BUILD_TYPE=%{build_type} \ + -DVERSION=%{version} \ + -DFILTER_LISTED_PKG=ON +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +cp LICENSE.Apache-2.0 %{buildroot}/usr/share/license/privacy-manager-server +mkdir -p %{buildroot}/usr/share/license +cp LICENSE.Apache-2.0 %{buildroot}/usr/share/license/privacy-manager-client +mkdir -p %{buildroot}/usr/bin +cp res/usr/bin/* %{buildroot}/usr/bin/ +mkdir -p %{buildroot}/opt/dbspace +cp res/opt/dbspace/.privacylist.db /%{buildroot}/opt/dbspace/ +mkdir -p %{buildroot}/usr/share/privacy-manager/ +cp res/usr/share/privacy-manager/privacy-filter-list.ini %{buildroot}/usr/share/privacy-manager/ +cp res/usr/share/privacy-manager/privacy-location-filter-list.ini %{buildroot}/usr/share/privacy-manager/ + +%make_install + +mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants + +%clean +rm -rf %{buildroot} + +%post -n privacy-manager-server +/sbin/ldconfig + +echo "Check privacy DB" +if [ ! -f /opt/dbspace/.privacy.db ] +then + echo "Create privacy DB" + /usr/bin/privacy_manager_create_clean_db.sh +fi +rm /usr/bin/privacy_manager_create_clean_db.sh +rm /usr/bin/privacy_db.sql + +%postun +/sbin/ldconfig + +%files -n privacy-manager-server +%defattr(-,root,root,-) +%manifest packaging/privacy-manager-server.manifest +%{_libdir}/libprivacy-manager-server.so* +/usr/share/license/privacy-manager-server +/opt/dbspace/.privacylist.db +/usr/bin/* + +%files -n privacy-manager-server-devel +%{_includedir}/privacy_manager/privacy_manager_daemon.h +%{_libdir}/pkgconfig/privacy-manager-server.pc + +%files -n privacy-manager-client +%defattr(-,root,root,-) +%manifest packaging/privacy-manager-client.manifest +%{_libdir}/libprivacy-manager-client.so* +/usr/share/license/privacy-manager-client +/usr/share/privacy-manager/privacy-filter-list.ini +/usr/share/privacy-manager/privacy-location-filter-list.ini +/usr/etc/package-manager/parserlib/libprivileges.so + +%files -n privacy-manager-client-devel +%defattr(-,root,root,-) +%{_libdir}/pkgconfig/privacy-manager-client.pc + +%{_includedir}/privacy_manager/PrivacyManagerClient.h +%{_includedir}/privacy_manager/PrivacyChecker.h +%{_includedir}/privacy_manager/privacy_info_client.h +%{_includedir}/privacy_manager/privacy_manager_client.h +%{_includedir}/privacy_manager/privacy_checker_client.h +%{_includedir}/privacy_manager/privacy_manager_client_types.h + diff --git a/pkgmgr_plugin/CMakeLists.txt b/pkgmgr_plugin/CMakeLists.txt new file mode 100644 index 0000000..40162b8 --- /dev/null +++ b/pkgmgr_plugin/CMakeLists.txt @@ -0,0 +1,58 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET (this_target privileges) + +SET(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/cmake_build_tmp/output) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkg REQUIRED glib-2.0 dlog libxml-2.0 ) + +FOREACH(flag ${privileges_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +INCLUDE_DIRECTORIES( + /usr/include + /usr/include/glib-2.0 + /usr/include/libxml2 + /usr/include/package_manager + /usr/include/dlog + "${CMAKE_SOURCE_DIR}/client/inc/" + "${CMAKE_SOURCE_DIR}/common/inc/" + ) + +SET (${this_target}_SOURCE_FILES + privileges.cpp + ) + +ADD_DEFINITIONS("-DDLOG_ERROR_ENABLED") +ADD_DEFINITIONS("-DLOG_TAG=\"PRIVILEGE_PLUGIN\"") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall" ) + +SET(CMAKE_C_FLAGS_PROFILING " -g -pg") +SET(CMAKE_CXX_FLAGS_PROFILING " -std=c++0x -g -pg") +SET(CMAKE_C_FLAGS_DEBUG " -g") +SET(CMAKE_CXX_FLAGS_DEBUG " -std=c++0x -g") +SET(CMAKE_C_FLAGS_RELEASE " -g") +SET(CMAKE_CXX_FLAGS_RELEASE " -std=c++0x -g") +SET(CMAKE_C_FLAGS_CCOV " -g --coverage") +SET(CMAKE_CXX_FLAGS_CCOV " -std=c++0x -g --coverage") + +## Create Library +ADD_LIBRARY (${this_target} SHARED ${${this_target}_SOURCE_FILES} ) +ADD_DEPENDENCIES(${this_target} privacy-manager-client) +## SET LINKER FLAGS +SET(CMAKE_SHARED_LINKER_FLAGS -Wl,--no-undefined) + +TARGET_LINK_LIBRARIES(${this_target} ${pkg_LDFLAGS} ${pkg_LIBRARIES}) +TARGET_LINK_LIBRARIES(${this_target} "-lprivacy-manager-client" "-L../client" ) + +ADD_CUSTOM_COMMAND(TARGET ${this_target} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${LIBRARY_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX} ${LIBRARY_OUTPUT_PATH}/debug/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX} + COMMAND ${CMAKE_STRIP} --strip-unneeded ${LIBRARY_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}${this_target}${CMAKE_SHARED_LIBRARY_SUFFIX} + COMMENT "strip ${this_target}" + ) + +INSTALL(TARGETS ${this_target} DESTINATION "../etc/package-manager/parserlib") + diff --git a/pkgmgr_plugin/privileges.cpp b/pkgmgr_plugin/privileges.cpp new file mode 100644 index 0000000..027b993 --- /dev/null +++ b/pkgmgr_plugin/privileges.cpp @@ -0,0 +1,162 @@ +// +// Open Service Platform +// Copyright (c) 2013 Samsung Electronics Co., Ltd. +// +// 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 <errno.h> +#include <libxml/parser.h> +#include <libxml/tree.h> +#include <privacy_manager_client.h> +#include <dlog.h> +#include <list> +#include <string> + +static const xmlChar _NODE_PRIVILEGES[] = "privileges"; +static const xmlChar _NODE_PRIVILEGE[] = "privilege"; +static const char TEST_AUTOMATION_PRIVILEGE[] = "http://tizen.org/privilege/testautomation"; + +void destroy_char_list(char** ppList, int size) +{ + int i; + for (i = 0; i < size; ++i) + { + if (ppList[i]) + free(ppList[i]); + } + free(ppList); +} + +extern "C" +__attribute__ ((visibility("default"))) +int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr docPtr, const char* packageId) +{ + int ret; + bool privacyPopupRequired = true; + + // Node: <privileges> + xmlNodePtr curPtr = xmlFirstElementChild(xmlDocGetRootElement(docPtr)); + + if(curPtr == NULL) + { + LOGD("Failed to get first element child"); + return -EINVAL; + } + + curPtr = curPtr->xmlChildrenNode; + if (curPtr == NULL) + { + LOGD("No privileges"); + return 0; + } + + std::list <std::string> privilegeList; + while (curPtr != NULL) + { + if (xmlStrcmp(curPtr->name, _NODE_PRIVILEGE) == 0) + { + xmlChar* pPrivilege = xmlNodeListGetString(docPtr, curPtr->xmlChildrenNode, 1); + + if (pPrivilege == NULL) + { + LOGE("Failed to get value"); + return -EINVAL; + } + if (strncmp(reinterpret_cast<char*>(pPrivilege), TEST_AUTOMATION_PRIVILEGE, strlen(TEST_AUTOMATION_PRIVILEGE) ) == 0 ) + { + SECURE_LOGD("No privacy popup"); + privacyPopupRequired = false; + } + else + { + privilegeList.push_back(std::string( reinterpret_cast<char*> (pPrivilege))); + } + } + curPtr = curPtr->next; + } + + char** ppPrivilegeList = (char**) calloc(privilegeList.size() + 1, sizeof(char*)); + std::list <std::string>::iterator iter = privilegeList.begin(); + for (int i = 0; i < privilegeList.size(); ++i) + { + ppPrivilegeList[i] = (char*)calloc (strlen(iter->c_str()) + 1, sizeof(char)); + if (ppPrivilegeList[i] == NULL) + { + destroy_char_list(ppPrivilegeList, privilegeList.size() + 1); + return -ENOMEM; + } + memcpy(ppPrivilegeList[i], iter->c_str(), strlen(iter->c_str())); + ++iter; + } + + ppPrivilegeList[privilegeList.size()] = (char*)calloc (2, sizeof(char)); + if (ppPrivilegeList[privilegeList.size()] == NULL) + { + destroy_char_list(ppPrivilegeList, privilegeList.size() + 1); + return -ENOMEM; + } + memcpy(ppPrivilegeList[privilegeList.size()], "\0", 1); + + ret = privacy_manager_client_install_privacy_by_client(packageId, (const char**) ppPrivilegeList, privacyPopupRequired); + destroy_char_list(ppPrivilegeList, privilegeList.size() + 1); + if (ret != PRIV_MGR_ERROR_SUCCESS) + { + LOGD("Failed to install privacy info: %d", ret); + return -EINVAL; + } + + return 0; +} + +extern "C" +__attribute__ ((visibility("default"))) +int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr docPtr, const char* packageId) +{ + int res = privacy_manager_client_uninstall_privacy_by_server(packageId); + if (res != PRIV_MGR_ERROR_SUCCESS) + { + LOGD("Failed to uninstall privacy info in server: %d", res); + + res = privacy_manager_client_uninstall_privacy(packageId); + if (res != PRIV_MGR_ERROR_SUCCESS) + { + LOGD("Failed to uninstall privacy info: %d", res); + return -EINVAL; + } + } + + return 0; +} + +extern "C" +__attribute__ ((visibility("default"))) +int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr docPtr, const char* packageId) +{ + int res = 0; + + LOGD("Update privacy Info"); + + res = PKGMGR_PARSER_PLUGIN_UNINSTALL(docPtr, packageId); + if (res != 0) + { + LOGD("Privacy info can be already uninstalled"); + } + + res = PKGMGR_PARSER_PLUGIN_INSTALL(docPtr, packageId); + if (res != 0) + { + LOGD("Failed to install privacy Info: %d", res); + } + return res; +} diff --git a/privacy-manager-client.pc.in b/privacy-manager-client.pc.in new file mode 100644 index 0000000..6f117ea --- /dev/null +++ b/privacy-manager-client.pc.in @@ -0,0 +1,11 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=/usr/include + +Name: @PC_NAME@ +Description: @PC_DESCRIPTION@ +Version: @VERSION@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: @PC_CFLAGS@ +Requires: diff --git a/privacy-manager-server.pc.in b/privacy-manager-server.pc.in new file mode 100644 index 0000000..6f117ea --- /dev/null +++ b/privacy-manager-server.pc.in @@ -0,0 +1,11 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=/usr/include + +Name: @PC_NAME@ +Description: @PC_DESCRIPTION@ +Version: @VERSION@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: @PC_CFLAGS@ +Requires: diff --git a/res/etc/rc.d/init.d/privacy-manager-server.sh b/res/etc/rc.d/init.d/privacy-manager-server.sh new file mode 100644 index 0000000..89303a1 --- /dev/null +++ b/res/etc/rc.d/init.d/privacy-manager-server.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +/usr/bin/privacy-manager-server & +set_pmon -p privacy-manager-server diff --git a/res/opt/dbspace/.privacylist.db b/res/opt/dbspace/.privacylist.db Binary files differnew file mode 100755 index 0000000..626a1b1 --- /dev/null +++ b/res/opt/dbspace/.privacylist.db diff --git a/res/usr/bin/privacy_db.sql b/res/usr/bin/privacy_db.sql new file mode 100644 index 0000000..49a0557 --- /dev/null +++ b/res/usr/bin/privacy_db.sql @@ -0,0 +1,18 @@ +PRAGMA foreign_keys = ON; BEGIN TRANSACTION; + +CREATE TABLE PackageInfo( + PKG_ID TEXT not null PRIMARY KEY UNIQUE, + IS_SET BOOL not null, +CHECK(1) ); + +CREATE TABLE PrivacyInfo( + PKG_ID TEXT not null , + PRIVACY_ID TEXT not null, + IS_ENABLED INTEGER not null, + FOREIGN KEY(PKG_ID) REFERENCES PackageInfo(PKG_ID), + CONSTRAINT PKG_PRIVACY UNIQUE (PKG_ID, PRIVACY_ID) +CHECK(1) ); + +COMMIT; +BEGIN TRANSACTION; +CREATE TABLE DB_VERSION_0_1 (version INT); COMMIT; diff --git a/res/usr/bin/privacy_manager_create_clean_db.sh b/res/usr/bin/privacy_manager_create_clean_db.sh new file mode 100755 index 0000000..9931bf3 --- /dev/null +++ b/res/usr/bin/privacy_manager_create_clean_db.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# Copyright (c) 2011 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. +# +for name in privacy +do + rm -f /opt/dbspace/.$name.db + rm -f /opt/dbspace/.$name.db-journal + SQL="PRAGMA journal_mode = PERSIST;" + sqlite3 /opt/dbspace/.$name.db "$SQL" + SQL=".read /usr/bin/"$name"_db.sql" + sqlite3 /opt/dbspace/.$name.db "$SQL" + touch /opt/dbspace/.$name.db-journal + chown 0:0 /opt/dbspace/.$name.db + chown 0:0 /opt/dbspace/.$name.db-journal + chmod 664 /opt/dbspace/.$name.db + chmod 664 /opt/dbspace/.$name.db-journal + if [ -f /usr/lib/rpm-plugins/msm.so ] + then + chsmack -a "privacy-manager::db" /opt/dbspace/.$name.db + chsmack -a "privacy-manager::db" /opt/dbspace/.$name.db-journal + fi +done + + diff --git a/res/usr/share/privacy-manager/privacy-filter-list.ini b/res/usr/share/privacy-manager/privacy-filter-list.ini new file mode 100644 index 0000000..3d5a55e --- /dev/null +++ b/res/usr/share/privacy-manager/privacy-filter-list.ini @@ -0,0 +1 @@ +#package_id=org.tizen.gallery diff --git a/res/usr/share/privacy-manager/privacy-location-filter-list.ini b/res/usr/share/privacy-manager/privacy-location-filter-list.ini new file mode 100644 index 0000000..ebf5287 --- /dev/null +++ b/res/usr/share/privacy-manager/privacy-location-filter-list.ini @@ -0,0 +1,2 @@ +#Dynamic Box Provider(slave) +package_id=org.tizen.data-provider-slave diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt new file mode 100644 index 0000000..e2ad49a --- /dev/null +++ b/server/CMakeLists.txt @@ -0,0 +1,93 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(privacy-manager) + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED dlog sqlite3 dbus-1 dbus-glib-1 db-util pkgmgr-info capi-system-info security-server libsmack vconf) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS_PROFILING " -g -pg") +SET(CMAKE_CXX_FLAGS_PROFILING " -std=c++0x -g -pg") +SET(CMAKE_C_FLAGS_DEBUG " -g") +SET(CMAKE_CXX_FLAGS_DEBUG " -std=c++0x -g") +SET(CMAKE_C_FLAGS_RELEASE " -g") +SET(CMAKE_CXX_FLAGS_RELEASE " -std=c++0x -g") +SET(CMAKE_C_FLAGS_CCOV " -g --coverage") +SET(CMAKE_CXX_FLAGS_CCOV " -std=c++0x -g --coverage") + +SET(server_src_dir "${CMAKE_SOURCE_DIR}/server/src") +SET(server_include_dir "${CMAKE_SOURCE_DIR}/server/inc/") +SET(common_src_dir "${CMAKE_SOURCE_DIR}/common/src/") +SET(common_include_dir "${CMAKE_SOURCE_DIR}/common/inc/") +SET(dbus_include_dir "/usr/include/dbus-1.0") + +## Additional flag +ADD_DEFINITIONS("-fvisibility=hidden") +ADD_DEFINITIONS("-Wall -Werror") +ADD_DEFINITIONS("-DDLOG_ERROR_ENABLED") +OPTION (FILTER_LISTED_PKG "FILTER PKG BY LIST" ON) +IF(FILTER_LISTED_PKG) + MESSAGE("FILTER PKGs BY FILTERING LIST") + ADD_DEFINITIONS("-D__FILTER_LISTED_PKG") +ENDIF(FILTER_LISTED_PKG) + +################################################################################################### +## for privacy-manager-server (executable) +INCLUDE_DIRECTORIES( + ${pkgs_INCLUDE_DIRS} + ${server_include_dir} + ${common_include_dir} + ${dbus_include_dir} + /usr/include/security-server/ + ) + +SET(PRIVACY_MANAGER_SERVER_SOURCES + ${common_src_dir}/SocketConnection.cpp + ${common_src_dir}/SocketStream.cpp + ${common_src_dir}/PrivacyDb.cpp + ${common_src_dir}/PrivacyIdInfo.cpp + # ${server_src_dir}/main.cpp + ${server_src_dir}/SocketService.cpp + ${server_src_dir}/PrivacyManagerDaemon.cpp + ${server_src_dir}/service/PrivacyInfoService.cpp + ${server_src_dir}/PrivacyManagerServer.cpp + ${server_src_dir}/NotificationServer.cpp + ${server_src_dir}/privacy_manager_daemon.cpp + ) +SET(PRIVACY_MANAGER_SERVER_HEADERS + ${server_include_dir}/privacy_manager_daemon.h + # ${server_include_dir}/SocketService.h + # ${server_include_dir}/PrivacyManagerDaemon.h + # ${common_include_dir}/SocketConnection.h + # ${common_include_dir}/SocketConnection.h +) +SET(PRIVACY_MANAGER_SERVER_LDFLAGS " -module -avoid-version ") +SET(PRIVACY_MANAGER_SERVER_CFLAGS " ${CFLAGS} -fPIC ") +#SET(PRIVACY_MANAGER_SERVER_LIBADD " ") + +ADD_DEFINITIONS("-DLOG_TAG=\"PRIVACY-MANAGER-SERVER\"") +ADD_LIBRARY(privacy-manager-server SHARED ${PRIVACY_MANAGER_SERVER_SOURCES}) +TARGET_LINK_LIBRARIES(privacy-manager-server ${pkgs_LDFLAGS} ${pkgs_LIBRARIES}) +SET_TARGET_PROPERTIES(privacy-manager-server PROPERTIES COMPILE_FLAGS "${PRIVACY_MANAGER_SERVER_CFLAGS}") +SET_TARGET_PROPERTIES(privacy-manager-server PROPERTIES SOVERSION ${API_VERSION}) +SET_TARGET_PROPERTIES(privacy-manager-server PROPERTIES VERSION ${VERSION}) +################################################################################################### + +SET(PC_NAME privacy-manager-server) +SET(PC_DESCRIPTION "Privacy Manager Server API") +SET(PC_LDFLAGS -lprivacy-manager-server) +SET(PC_CFLAGS -I\${includedir}/privacy_manager) + +CONFIGURE_FILE(../privacy-manager-server.pc.in privacy-manager-server.pc @ONLY) + +INSTALL(TARGETS privacy-manager-server DESTINATION ../lib COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/privacy-manager-server.pc DESTINATION ../lib/pkgconfig) +INSTALL(FILES ${PRIVACY_MANAGER_SERVER_HEADERS} DESTINATION ../include/privacy_manager) diff --git a/server/inc/NotificationServer.h b/server/inc/NotificationServer.h new file mode 100644 index 0000000..bd91953 --- /dev/null +++ b/server/inc/NotificationServer.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013 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 _NOTIFICATION_SERVER_H_ +#define _NOTIFICATION_SERVER_H_ + +#include <string> +#include <memory> +#include <list> +#include <sqlite3.h> +#include <mutex> +#include <dbus/dbus.h> +#include <gio/gio.h> + +class NotificationServer +{ +private: + bool m_initialized; + GDBusConnection* m_pDBusConnection; +public: + + NotificationServer(void); + ~NotificationServer(void); + int initialize(void); + int notifySettingChanged(const std::string pkgId, const std::string privacyId); + int notifyPkgRemoved(const std::string pkgId); +}; + + +#endif // _NOTIFICATION_SERVER_H_ diff --git a/server/inc/PrivacyInfoService.h b/server/inc/PrivacyInfoService.h new file mode 100644 index 0000000..3fcbde9 --- /dev/null +++ b/server/inc/PrivacyInfoService.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013 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 _PRIVACY_INFO_SERVICE_H_ +#define _PRIVACY_INFO_SERVICE_H_ + +#include <SocketConnection.h> +#include <SocketService.h> + +class PrivacyInfoService { +private: + inline static std::string getInterfaceName(void) + { + return "PrivacyInfoService"; + } + +public: + static void registerCallbacks(SocketService* pSocketService) + { + pSocketService->registerServiceCallback(getInterfaceName(), std::string("addPrivacyInfo"), addPrivacyInfo); + pSocketService->registerServiceCallback(getInterfaceName(), std::string("removePrivacyInfo"), removePrivacyInfo); + pSocketService->registerServiceCallback(getInterfaceName(), std::string("setPrivacySetting"), setPrivacySetting); + pSocketService->registerServiceCallback(getInterfaceName(), std::string("getPrivacyAppPackages"), getPrivacyAppPackages); + pSocketService->registerServiceCallback(getInterfaceName(), std::string("getAppPackagePrivacyInfo"), getAppPackagePrivacyInfo); + pSocketService->registerServiceCallback(getInterfaceName(), std::string("isUserPrompted"), isUserPrompted); + pSocketService->registerServiceCallback(getInterfaceName(), std::string("setUserPrompted"), setUserPrompted); + pSocketService->registerServiceCallback(getInterfaceName(), std::string("notifyUserNotConsented"), notifyUserNotConsented); + } + + static void addPrivacyInfo(SocketConnection* pConnector); + + static void removePrivacyInfo(SocketConnection* pConnector); + + static void setPrivacySetting(SocketConnection* pConnector); + + // input message format + // interface_name(str) | method_name(str) + // output message format + // result (int) | list size (int) | serialized package list (using delimeter) + static void getPrivacyAppPackages(SocketConnection* pConnector); + + static void getAppPackagePrivacyInfo(SocketConnection* pConnector); + + static void isUserPrompted(SocketConnection* pConnector); + + static void setUserPrompted(SocketConnection* pConnector); + + static void notifyUserNotConsented(SocketConnection* pConnector); + +}; +#endif // _PRIVACY_INFO_SERVICE_H_ diff --git a/server/inc/PrivacyManagerDaemon.h b/server/inc/PrivacyManagerDaemon.h new file mode 100644 index 0000000..a646c8b --- /dev/null +++ b/server/inc/PrivacyManagerDaemon.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2013 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 _PRIVACY_MANAGER_DAEMON_H_ +#define _PRIVACY_MANAGER_DAEMON_H_ + +#include <privacy_manager_client_types.h> + +class SocketService; + +class EXTERN_API PrivacyManagerDaemon +{ +private: + static PrivacyManagerDaemon* pInstance; + SocketService* pSocketService; + +private: + PrivacyManagerDaemon(void); + ~PrivacyManagerDaemon(void); + + +public: + static PrivacyManagerDaemon* getInstance(void); + int initialize(void); + int start(void); + int stop(void); + int shutdown(void); +}; + +#endif // _PRIVACY_MANAGER_DAEMON_H_ diff --git a/server/inc/PrivacyManagerServer.h b/server/inc/PrivacyManagerServer.h new file mode 100644 index 0000000..a6534ac --- /dev/null +++ b/server/inc/PrivacyManagerServer.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013 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 _PRIVACY_MANAGER_SERVER_H_ +#define _PRIVACY_MANAGER_SERVER_H_ + +#include <string> +#include <memory> +#include <list> +#include <mutex> +#include <NotificationServer.h> + +class NotificationServer; + +class PrivacyManagerServer +{ +private: + static std::mutex m_singletonMutex; + static PrivacyManagerServer* m_pInstance; + NotificationServer m_notificationServer; + +private: + void createDB(void); + +public: + + explicit PrivacyManagerServer(void); + + virtual ~PrivacyManagerServer(void); + + static PrivacyManagerServer* getInstance(void); + + int getPrivacyAppPackages(std::list <std::string>& list); + + int getAppPackagePrivacyInfo(const std::string pkgId, std::list < std::pair < std::string, bool > > & list); + + int setPrivacySetting(const std::string pkgId, const std::string privacyId, bool enabled); + + int addAppPackagePrivacyInfo(const std::string pkgcId, const std::list < std::string > privilegeList, bool privacyPopupRequired); + + int removeAppPackagePrivacyInfo(const std::string pkgId); + + int isUserPrompted(const std::string pkgId, bool& isPrompted); + + int setUserPrompted(const std::string pkgId, bool prompted); + + int setPermissions(const std::string pkgId, const std::string privacyId, bool enabled); + + int notifyUserNotConsented(const std::string pkgId, const std::string privacyId); + +}; + + +#endif // _PRIVACY_MANAGER_SERVER_H_ diff --git a/server/inc/SocketService.h b/server/inc/SocketService.h new file mode 100644 index 0000000..50fc0e6 --- /dev/null +++ b/server/inc/SocketService.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2013 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 _SOCKET_SERVICE_H_ +#define _SOCKET_SERVICE_H_ + +#include <string> +#include <mutex> +#include <list> +#include <map> +#include <memory> +#include <pthread.h> +#include <SocketConnection.h> + +typedef void(*socketServiceCallback)(SocketConnection* pConnector); + +class SocketService +{ + struct ConnectionInfo{ + ConnectionInfo(int fd, void* pData) : connFd(fd), pData(pData) {} + int connFd; + void* pData; + }; + class ServiceCallback + { + public: + ServiceCallback(socketServiceCallback callback) + : serviceCallback(callback) + {} + socketServiceCallback serviceCallback; + }; + +private: + static const int MAX_LISTEN; + static const int TIMEOUT_SEC; + static const int TIMEOUT_NSEC; + int m_listenFd; + int m_signalToClose; + pthread_t m_mainThread; + + typedef std::shared_ptr<ServiceCallback> ServiceCallbackPtr; + //Map for callback methods, key is a method name and value is a callback to method + typedef std::map<std::string, ServiceCallbackPtr> ServiceMethodCallbackMap; + //Map for interface methods, key is an interface name and value is a map of available methods with callbacks + std::map <std::string, ServiceMethodCallbackMap > m_callbackMap; + + std::list < int > m_clientSocketList; + std::mutex m_clientSocketListMutex; + +private: + static void* serverThread(void* ); + static void* connectionThread(void* pData); + int connectionService(int fd); + int mainloop(void); + void closeConnections(void); + + void addClientSocket(int clientSocket); + void removeClientSocket(int clientSocket); + bool popClientSocket(int* pClientSocket); + +public: + SocketService(void); + ~SocketService(void); + int initialize(void); + int registerServiceCallback(const std::string &interfaceName, const std::string &methodName, socketServiceCallback callbackMethod); + int start(void); + int stop(void); + int shutdown(void); +}; + +#endif //_SOCKET_SERVICE_H_
\ No newline at end of file diff --git a/server/inc/privacy_manager_daemon.h b/server/inc/privacy_manager_daemon.h new file mode 100644 index 0000000..70e39da --- /dev/null +++ b/server/inc/privacy_manager_daemon.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013 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 __PRIVACY_MANAGER_DAEMON_H__ +#define __PRIVACY_MANAGER_DAEMON_H__ + +#include <privacy_manager_client_types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +int EXTERN_API privacy_manager_daemon_initialize(void); +int EXTERN_API privacy_manager_daemon_start(void); +int EXTERN_API privacy_manager_daemon_stop(void); +int EXTERN_API privacy_manager_daemon_shutdown(void); + +#ifdef __cplusplus +} +#endif + + +#endif //__PRIVACY_MANAGER_DAEMON_H__ + diff --git a/server/src/CMakeLists.txt b/server/src/CMakeLists.txt new file mode 100644 index 0000000..9aecc40 --- /dev/null +++ b/server/src/CMakeLists.txt @@ -0,0 +1,73 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +#PROJECT(privacy-manager-server) + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") +SET(VERSION 0.0) + +SET(VERSION_MAJOR 0) +SET(VERSION "${VERSION_MAJOR}.0.1") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED dlog pkgmgr-info) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS_PROFILING " -g -pg")
+SET(CMAKE_CXX_FLAGS_PROFILING " -std=c++0x -g -pg")
+SET(CMAKE_C_FLAGS_DEBUG " -g")
+SET(CMAKE_CXX_FLAGS_DEBUG " -std=c++0x -g")
+SET(CMAKE_C_FLAGS_RELEASE " -g")
+SET(CMAKE_CXX_FLAGS_RELEASE " -std=c++0x -g")
+SET(CMAKE_C_FLAGS_CCOV " -g --coverage")
+SET(CMAKE_CXX_FLAGS_CCOV " -std=c++0x -g --coverage")
+ +SET(src_dir "./") +SET(include_dir "./../inc/") +SET(common_src_dir "./../../common/src/") +SET(common_include_dir "./../../common/inc/") + +## Additional flag +ADD_DEFINITIONS("-fvisibility=hidden") +ADD_DEFINITIONS("-Wall -Werror") +ADD_DEFINITIONS("-DDLOG_ERROR_ENABLED") + +################################################################################################### +## for libprivacy-manager-server.so (library) +INCLUDE_DIRECTORIES(${pkgs_INCLUDE_DIRS}) +SET(PRIVACY_MANAGER_SERVER_SOURCES + ${src_dir}/main.cpp + ${src_dir}/SocketService.cpp + ${src_dir}/PrivacyManagerDaemon.cpp + ${common_src_dir}/SocketConnection.cpp + ${common_src_dir}/SocketStream.cpp + ) +SET(PRIVACY_MANAGER_SERVER_HEADERS + ${include_dir}/SocketService.h + ${include_dir}/PrivacyManagerDaemon.h + ${common_include_dir}/SocketConnection.h + ${common_include_dir}/SocketConnection.h +) +SET(PRIVACY_MANAGER_SERVER_LDFLAGS " -module -avoid-version ") +SET(PRIVACY_MANAGER_SERVER_CFLAGS " ${CFLAGS} -fPIC -I${include_dir}" -I${common_include_dir}) +#SET(PRIVACY_MANAGER_SERVER_LIBADD " ") + +ADD_EXECUTABLE(privacy-manager-server ${PRIVACY_MANAGER_SERVER_SOURCES}) +TARGET_LINK_LIBRARIES(privacy-manager-server ${pkgs_LDFLAGS} ${pkgs_LIBRARIES}) +SET_TARGET_PROPERTIES(privacy-manager-server PROPERTIES COMPILE_FLAGS "${PRIVACY_MANAGER_SERVER_CFLAGS}") +SET_TARGET_PROPERTIES(privacy-manager-server PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(privacy-manager-server PROPERTIES VERSION ${VERSION}) +################################################################################################### + +CONFIGURE_FILE(../../privacy-manager-server.pc.in privacy-manager-server.pc @ONLY) + +INSTALL(TARGETS privacy-manager-server DESTINATION ../lib COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/privacy-manager-server.pc DESTINATION ../lib/pkgconfig) +INSTALL(FILES ${PRIVACY_MANAGER_SERVER_HEADERS} DESTINATION ../include) diff --git a/server/src/NotificationServer.cpp b/server/src/NotificationServer.cpp new file mode 100644 index 0000000..780901c --- /dev/null +++ b/server/src/NotificationServer.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2012 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 <NotificationServer.h> +#include <dbus/dbus.h> +#include <dbus/dbus-glib-lowlevel.h> +#include <PrivacyManagerTypes.h> +#include <Utils.h> +#include <gio/gio.h> + +auto DBusConnectionDeleter = [&](DBusConnection* pPtr) { dbus_connection_close(pPtr); pPtr = NULL;}; +const int MAX_LOCAL_BUF_SIZE = 128; + +NotificationServer::NotificationServer(void) + : m_initialized(false) + , m_pDBusConnection(NULL) +{ + +} + +NotificationServer::~NotificationServer(void) +{ + if (m_pDBusConnection) + { + g_object_unref(m_pDBusConnection); + m_pDBusConnection = NULL; + } +} + +int +NotificationServer::initialize(void) +{ + if (m_initialized) + return PRIV_MGR_ERROR_SUCCESS; + + GError* pGerror = NULL; + g_type_init(); + + m_pDBusConnection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &pGerror); + TryReturn(pGerror == NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, g_error_free(pGerror), "g_dbus_get_sync : %s", pGerror->message); + + m_initialized = true; + return PRIV_MGR_ERROR_SUCCESS; +} + +int +NotificationServer::notifySettingChanged(const std::string pkgId, const std::string privacyId) +{ + if (!m_initialized) + return PRIV_MGR_ERROR_INVALID_STATE; + + GError* pGerror = NULL; + char* pPkgId = const_cast <char*> (pkgId.c_str()); + char* pPrivacyId = const_cast <char*> (privacyId.c_str()); + + g_dbus_connection_emit_signal(m_pDBusConnection, + NULL, + DBUS_PATH.c_str(), + DBUS_SIGNAL_INTERFACE.c_str(), + DBUS_SIGNAL_SETTING_CHANGED.c_str(), + g_variant_new("(ss)", pPkgId, pPrivacyId), + &pGerror + ); + TryReturn(pGerror == NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, g_error_free(pGerror), "g_dbus_connection_emit_signal : %s", pGerror->message); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +NotificationServer::notifyPkgRemoved(const std::string pkgId) +{ + if (!m_initialized) + return PRIV_MGR_ERROR_INVALID_STATE; + + GError* pGerror = NULL; + char* pPkgId = const_cast <char*> (pkgId.c_str()); + + g_dbus_connection_emit_signal(m_pDBusConnection, + NULL, + DBUS_PATH.c_str(), + DBUS_SIGNAL_INTERFACE.c_str(), + DBUS_SIGNAL_PKG_REMOVED.c_str(), + g_variant_new("(s)", pPkgId), + &pGerror + ); + TryReturn(pGerror == NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, g_error_free(pGerror), "g_dbus_connection_emit_signal : %s", pGerror->message); + + return PRIV_MGR_ERROR_SUCCESS; +} diff --git a/server/src/PrivacyManagerDaemon.cpp b/server/src/PrivacyManagerDaemon.cpp new file mode 100644 index 0000000..bf84448 --- /dev/null +++ b/server/src/PrivacyManagerDaemon.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013 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 <string> +#include <PrivacyManagerDaemon.h> +#include <PrivacyInfoService.h> +#include <PrivacyManagerServer.h> +#include <SocketService.h> + +PrivacyManagerDaemon* PrivacyManagerDaemon::pInstance = NULL; + +PrivacyManagerDaemon::PrivacyManagerDaemon(void) + : pSocketService(NULL) +{ + +} + +PrivacyManagerDaemon::~PrivacyManagerDaemon(void) +{ + +} + +PrivacyManagerDaemon* +PrivacyManagerDaemon::getInstance(void) +{ + if (pInstance == NULL) + pInstance = new PrivacyManagerDaemon(); + PrivacyManagerServer::getInstance(); + return pInstance; +} + +int +PrivacyManagerDaemon::initialize(void) +{ + if (pSocketService == NULL) + pSocketService = new SocketService(); + + pSocketService->initialize(); + + PrivacyInfoService::registerCallbacks(pSocketService); + + return 0; +} + +int +PrivacyManagerDaemon::start(void) +{ + if (pSocketService == NULL) + return -1; + return pSocketService->start(); + + return 0; +} + +int +PrivacyManagerDaemon::stop(void) +{ + pSocketService->stop(); + return 0; +} + +int +PrivacyManagerDaemon::shutdown(void) +{ + pSocketService->shutdown(); + return 0; +} diff --git a/server/src/PrivacyManagerServer.cpp b/server/src/PrivacyManagerServer.cpp new file mode 100644 index 0000000..1a21007 --- /dev/null +++ b/server/src/PrivacyManagerServer.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2013 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 <sstream> +#include <dlog.h> +#include <Utils.h> +#include <PrivacyIdInfo.h> +#include <PrivacyManagerServer.h> +#include <PrivacyManagerTypes.h> +#include <PrivacyDb.h> +#include <privilege-control.h> +#include <security-server.h> +#include <pkgmgr-info.h> +#include <libintl.h> +#include <dlfcn.h> +#include <fcntl.h> +#include <vconf.h> + + +std::mutex PrivacyManagerServer::m_singletonMutex; +PrivacyManagerServer* PrivacyManagerServer::m_pInstance = NULL; +const char *pLocationPrivacy = "http://tizen.org/privacy/location"; +const char *pLocationPrivilege = "http://tizen.org/privilege/location"; +pkgmgrinfo_client *__pc = NULL; +static const char *VCONF_KEY = "db/menu_widget/language"; + +static int pkgmgrInfoCallBack(int req_id, const char *pkg_type, + const char *pkgid, const char *key, const char *val, + const void *pmsg, void *user_data) +{ + if(strncmp(pkg_type, "wgt", 3) == 0 && strncmp(key, "end", 3) == 0 ) + { + LOGD("pkg_id : %s, pkg_type : %s will remove from DB", pkgid, pkg_type); + int res = PrivacyDb::getInstance()->removeAppPackagePrivacyInfo(pkgid); + if(res != PRIV_MGR_ERROR_SUCCESS) + LOGE("failed to remove data : %d", res); + } + return 0; +} + +static void languageCallBack(keynode_t *node, void* user_data) +{ + char *language_set = vconf_get_str(VCONF_KEY); + if(!language_set) + { + LOGE("Failed to get laguage set"); + } + char* result = setlocale(LC_ALL, language_set); + if(!result) + { + LOGE("Failed to set locale"); + } + + if (language_set) + free(language_set); +} + +void +PrivacyManagerServer::createDB(void) +{ + +} + +int +PrivacyManagerServer::setPrivacySetting(const std::string pkgId, const std::string privacyId, bool enabled) +{ + int res = PrivacyDb::getInstance()->setPrivacySetting(pkgId, privacyId, enabled); + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "privacyDb::setPrivacySetting : %d", res); + + res = m_notificationServer.notifySettingChanged(pkgId, privacyId); + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "NotificationServer::notifySettingChanged : %d", res); + + res = setPermissions(pkgId, privacyId, enabled); + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "PrivacyManagerServer::setPermissions : %d", res); + + return res; +} + +int +PrivacyManagerServer::getPrivacyAppPackages(std::list <std::string>& list) +{ + return PrivacyDb::getInstance()->getPrivacyAppPackages(list); +} + +int +PrivacyManagerServer::getAppPackagePrivacyInfo(const std::string pkgId, std::list < std::pair < std::string, bool > >& privacyInfoList) +{ + return PrivacyDb::getInstance()->getAppPackagePrivacyInfo(pkgId, privacyInfoList); +} + + +int +PrivacyManagerServer::addAppPackagePrivacyInfo(const std::string pkgId, const std::list < std::string > privilegeList, bool privacyPopupRequired) +{ + return PrivacyDb::getInstance()->addAppPackagePrivacyInfo(pkgId, privilegeList, privacyPopupRequired); +} + +int +PrivacyManagerServer::removeAppPackagePrivacyInfo(const std::string pkgId) +{ + int res = PrivacyDb::getInstance()->removeAppPackagePrivacyInfo(pkgId); + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "privacyDb::removeAppPackagePrivacyInfo : %d", res); + + res = m_notificationServer.notifyPkgRemoved(pkgId); + TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "NotificationServer::notifyPkgRemoved : %d", res); + + return res; +} + +int +PrivacyManagerServer::isUserPrompted(const std::string pkgId, bool& isPrompted) +{ + return PrivacyDb::getInstance()->isUserPrompted(pkgId, isPrompted); +} + +int +PrivacyManagerServer::setUserPrompted(const std::string pkgId, bool prompted) +{ + return PrivacyDb::getInstance()->setUserPrompted(pkgId, prompted); +} + +PrivacyManagerServer::PrivacyManagerServer(void) +{ + // for non privileged W3C location apps + int event_type = PMINFO_CLIENT_STATUS_UNINSTALL; + __pc = pkgmgrinfo_client_new(PMINFO_LISTENING); + pkgmgrinfo_client_set_status_type(__pc, event_type); + pkgmgrinfo_client_listen_status(__pc, pkgmgrInfoCallBack, NULL); + + // set locale for notification + if(vconf_notify_key_changed(VCONF_KEY, languageCallBack, NULL) < 0) + LOGE("Failed to register vconf callback"); + else + LOGD("Succeed to register vconf vconf callback"); + + char *language_set = vconf_get_str(VCONF_KEY); + setlocale(LC_ALL, language_set); + if (language_set) + free(language_set); +} + +PrivacyManagerServer::~PrivacyManagerServer(void) +{ + if(__pc) + { + pkgmgrinfo_client_free(__pc); + } +} + +PrivacyManagerServer* +PrivacyManagerServer::getInstance(void) +{ + std::lock_guard < std::mutex > guard(m_singletonMutex); + + if (m_pInstance == NULL) + { + m_pInstance = new PrivacyManagerServer(); + + m_pInstance->m_notificationServer.initialize(); + } + + return m_pInstance; +} + +void destroy_char_list(char** ppList, int size) +{ + int i; + for (i = 0; i < size; ++i) + { + if (ppList[i]) + free(ppList[i]); + } + free(ppList); +} + +int privilegeListCallback(const char *privilege_name, void *user_data) +{ + if (user_data == NULL) + return PRIV_MGR_ERROR_SYSTEM_ERROR; + + std::list <std::string>* pPrivilegList = (std::list <std::string>*)user_data; + pPrivilegList->push_back(std::string(privilege_name)); + return 0; +} + +int +PrivacyManagerServer::setPermissions(const std::string pkgId, const std::string privacyId, bool enabled) +{ + SECURE_LOGD("pkgId = %s / privacyId = %s, enabled = %d", pkgId.c_str(), privacyId.c_str(), enabled); + + int ret = PMINFO_R_OK; + int res = PRIV_MGR_ERROR_SUCCESS; + + char *pType = NULL; + app_type_t appType = APP_TYPE_OSP; + + pkgmgrinfo_pkginfo_h handle; + ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle); + TryReturn(ret == PMINFO_R_OK, PRIV_MGR_ERROR_SYSTEM_ERROR,, "pkgmgrinfo_pkginfo_get_pkginfo was failed : %d", ret); + + ret = pkgmgrinfo_pkginfo_get_type(handle, &pType); + TryReturn(ret == PMINFO_R_OK, PRIV_MGR_ERROR_SYSTEM_ERROR, pkgmgrinfo_pkginfo_destroy_pkginfo(handle), "pkgmgrinfo_pkginfo_get_type was failed :%d", ret); + + int typeSize = sizeof(pType); + if (strncmp(pType, "wgt", typeSize) == 0) + { + appType = APP_TYPE_WGT; + } + else if (strncmp(pType, "tpk", typeSize) == 0) + { + appType = APP_TYPE_OSP; + } + else if (strncmp(pType, "rpm", typeSize) == 0) + { + appType = APP_TYPE_EFL; + } + else + { + LOGE("Type of package is incorrect. [TYPE: %s]", pType); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return PRIV_MGR_ERROR_SYSTEM_ERROR; + } + + std::list <std::string> pkgPrivilegeList; + res = pkgmgrinfo_pkginfo_foreach_privilege(handle, privilegeListCallback, &pkgPrivilegeList); + TryReturn(ret == PMINFO_R_OK, PRIV_MGR_ERROR_SYSTEM_ERROR, pkgmgrinfo_pkginfo_destroy_pkginfo(handle), "pkgmgrinfo_pkginfo_foreach_privilege was failed :%d", ret); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + + std::list <std::string> privacyPrivilegeList; + res = PrivacyIdInfo::getPrivilegeListFromPrivacyId(privacyId, privacyPrivilegeList); + TryReturn(res == PRIV_MGR_ERROR_SUCCESS, PRIV_MGR_ERROR_SYSTEM_ERROR, pkgPrivilegeList.clear(), "getPrivilegeListFromPrivacyId was failed."); + + std::list <std::string> privilegeList; + for (std::list <std::string>::iterator privacyPrivilegeListIter = privacyPrivilegeList.begin(); privacyPrivilegeListIter != privacyPrivilegeList.end(); ++privacyPrivilegeListIter) + { + for (std::list <std::string>::iterator pkgPrivilegeListIter = pkgPrivilegeList.begin(); pkgPrivilegeListIter != pkgPrivilegeList.end(); ++pkgPrivilegeListIter) + { + if ((*privacyPrivilegeListIter).compare(*pkgPrivilegeListIter) == 0) + { + privilegeList.push_back(std::string(*privacyPrivilegeListIter)); + SECURE_LOGD("smack rule control [%s]", (*privacyPrivilegeListIter).c_str()); + break; + } + } + } + + // for W3C Web Application using location API + if(appType == APP_TYPE_WGT && strncmp(privacyId.c_str(), pLocationPrivacy, strlen(pLocationPrivacy)) == 0) + { + LOGD("WGT location privacy request for w3c location api"); + std::list<std::string>::iterator iter = find(privilegeList.begin(), privilegeList.end(), std::string(pLocationPrivilege)); + + if(iter == privilegeList.end()) + privilegeList.push_back(std::string(pLocationPrivilege)); + } + + privacyPrivilegeList.clear(); + pkgPrivilegeList.clear(); + + unsigned int listSize = privilegeList.size(); + char** ppPrivilegeList = (char**) calloc(listSize + 1, sizeof(char*)); + TryReturn(ppPrivilegeList != NULL, PRIV_MGR_ERROR_OUT_OF_MEMORY, privilegeList.clear(),"calloc was failed."); + + std::list <std::string>::iterator iter = privilegeList.begin(); + for (unsigned int i = 0; i < listSize; ++i) + { + ppPrivilegeList[i] = (char*)calloc (strlen(iter->c_str()) + 1, sizeof(char)); + if (ppPrivilegeList[i] == NULL) + { + destroy_char_list(ppPrivilegeList, listSize + 1); + privilegeList.clear(); + LOGE("calloc was failed."); + return PRIV_MGR_ERROR_OUT_OF_MEMORY; + } + memcpy(ppPrivilegeList[i], iter->c_str(), strlen(iter->c_str())); + ++iter; + } + privilegeList.clear(); + + ppPrivilegeList[listSize] = NULL; + if (enabled == true) + { + LOGD("call: security_server_app_enable_permissions()"); + res = security_server_app_enable_permissions(pkgId.c_str(), appType, (const char**) ppPrivilegeList, 1); + LOGD("leave: security_server_app_enable_permissions()"); + TryReturn(res == 0/*SECURITY_SERVER_SUCCESS*/, PRIV_MGR_ERROR_SYSTEM_ERROR, destroy_char_list(ppPrivilegeList, listSize + 1), "security_server_app_enable_permissions was failed : %d", res); + } + else + { + LOGD("call: security_server_app_disable_permissions()"); + res = security_server_app_disable_permissions(pkgId.c_str(), appType, (const char**) ppPrivilegeList); + LOGD("leave: security_server_app_disable_permissions()"); + TryReturn(res == 0/*SECURITY_SERVER_SUCCESS*/, PRIV_MGR_ERROR_SYSTEM_ERROR, destroy_char_list(ppPrivilegeList, listSize + 1), "security_server_app_disable_permissions was failed : %d", res); + } + destroy_char_list(ppPrivilegeList, listSize + 1); + return PRIV_MGR_ERROR_SUCCESS; +} + +int +PrivacyManagerServer::notifyUserNotConsented(const std::string pkgId, const std::string privacyId) +{ + int res = PRIV_MGR_ERROR_SUCCESS; + + const char* notifyStringFormat = dgettext("privilege", "IDS_ST_TPOP_P1SS_DISABLED_IN_P2SS_ABB"); + char notifyString[1024] = {0,}; + + bool packageNameFlag = true; + char* packageName = NULL; + pkgmgrinfo_pkginfo_h handle; + res = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle); + if (res != PMINFO_R_OK) + { + SECURE_LOGE("pkgmgrinfo_pkginfo_get_pkginfo() was failed: result[%d]", res); + packageNameFlag = false; + } + else + { + res = pkgmgrinfo_pkginfo_get_label(handle, &packageName); + if (res != PMINFO_R_OK) + { + SECURE_LOGE("pkgmgrinfo_pkginfo_get_label() was failed: result[%d]", res); + packageNameFlag = false; + } + } + + std::string privacyDisplayName; + res = PrivacyIdInfo::getPrivaycDisplayName(privacyId, privacyDisplayName); + if (res != PRIV_MGR_ERROR_SUCCESS) + { + privacyDisplayName = privacyId; + } + + if (packageNameFlag) + { + snprintf(notifyString, 1024, notifyStringFormat, privacyDisplayName.c_str(), packageName); + } + else + { + snprintf(notifyString, 1024, notifyStringFormat, privacyDisplayName.c_str(), pkgId.c_str()); + } + + void* so_handle = dlopen("libnotification.so", RTLD_LAZY | RTLD_GLOBAL); + TryReturn(so_handle != NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, , "Failed to open notification binary"); + + int(*DoNotificationFunc)(const char*) = NULL; + + char* errormsg = NULL; + DoNotificationFunc = reinterpret_cast<int(*)(const char*)>(dlsym(so_handle, "notification_status_message_post")); + errormsg = dlerror(); + TryReturn(errormsg == NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, dlclose(so_handle), "Failed to find symbol"); + + DoNotificationFunc(notifyString); + dlclose(so_handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return PRIV_MGR_ERROR_SUCCESS; +} + diff --git a/server/src/SocketService.cpp b/server/src/SocketService.cpp new file mode 100644 index 0000000..9d3f892 --- /dev/null +++ b/server/src/SocketService.cpp @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2013 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 <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/signalfd.h> +#include <sys/select.h> +#include <sys/stat.h> +#include <signal.h> +#include <unistd.h> +#include <fcntl.h> +#include <memory> +#include <dlog.h> +#include <PrivacyManagerTypes.h> +#include <Utils.h> +#include "SocketService.h" +#include "SocketConnection.h" +#include <sys/smack.h> + +const int SocketService::MAX_LISTEN = 5; + +SocketService::SocketService(void) + : m_listenFd(-1) + , m_signalToClose(-1) + , m_mainThread(-1) +{ + +} + +SocketService::~SocketService(void) +{ + +} + +int +SocketService::initialize(void) +{ + LOGI("SocketService initializing"); + + m_listenFd = socket(AF_UNIX, SOCK_STREAM, 0); + TryReturn( m_listenFd != -1, PRIV_MGR_ERROR_SYSTEM_ERROR, , "socket : %s", strerror(errno)); + + TryReturn( smack_fsetlabel(m_listenFd, "*", SMACK_LABEL_IPIN) == 0, PRIV_MGR_ERROR_SYSTEM_ERROR, , "Failed to set permission to socket : %s", strerror(errno)); + + int flags = -1; + int res; + if ( (flags = fcntl(m_listenFd, F_GETFL, 0)) == -1) + flags = 0; + res = fcntl(m_listenFd, F_SETFL, flags | O_NONBLOCK); + TryReturn( res != -1, PRIV_MGR_ERROR_SYSTEM_ERROR, , "fcntl : %s", strerror(errno)); + + sockaddr_un server_address; + bzero(&server_address, sizeof(server_address)); + server_address.sun_family = AF_UNIX; + if(strlen(SERVER_ADDRESS.c_str()) <= strlen(server_address.sun_path)) + strcpy(server_address.sun_path, SERVER_ADDRESS.c_str()); + else + return PRIV_MGR_ERROR_SYSTEM_ERROR; + unlink(server_address.sun_path); + + mode_t socket_umask, original_umask; + socket_umask = 0; + original_umask = umask(socket_umask); + + res = bind(m_listenFd, (struct sockaddr*)&server_address, SUN_LEN(&server_address)); + TryReturn( res != -1, PRIV_MGR_ERROR_SYSTEM_ERROR, , "bind : %s", strerror(errno)); + + umask(original_umask); + + LOGI("SocketService initialized"); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +SocketService::start(void) +{ + LOGI("SocketService starting"); + + sigset_t sigset; + sigemptyset(&sigset); +// if ( sigaddset(&sigset, m_signalToClose) == -1 ) +// { +// LOGE("Failed to sigaddset : %s", strerror(errno)); +// return -1; +// } + + int res = 0; + res = pthread_sigmask(SIG_BLOCK, &sigset, NULL); + TryReturn( res >= 0, PRIV_MGR_ERROR_SYSTEM_ERROR, , "pthread_sigmask : %s", strerror(errno)); + + pthread_t mainThread; + res = pthread_create(&mainThread, NULL, &serverThread, this); + TryReturn( res >= 0, PRIV_MGR_ERROR_SYSTEM_ERROR, errno = res, "pthread_create : %s", strerror(res)); + + m_mainThread = mainThread; + + LOGI("SocketService started"); + + return PRIV_MGR_ERROR_SUCCESS; +} + +void* +SocketService::serverThread(void* pData) +{ + if(pthread_detach(pthread_self())!=0) + { + LOGE("Failed detach thread!"); + } + SocketService &t = *static_cast< SocketService* > (pData); + LOGI("Running main thread"); + int ret = t.mainloop(); + if (ret < 0) + { + return (void*) 1; + } + return (void*) 0; +} + +int +SocketService::mainloop(void) +{ + if( listen(m_listenFd, MAX_LISTEN) == -1 ){ + LOGE("listen : %s", strerror(errno)); + return PRIV_MGR_ERROR_IPC_ERROR; + } + + //Settings to catch closing signal in select + int signal_fd; + sigset_t sigset; + int res; + res = sigemptyset(&sigset); + TryReturn( res != -1, PRIV_MGR_ERROR_SYSTEM_ERROR, , "sigemptyset : %s", strerror(errno)); + +// if( sigaddset(&sigset, m_signalToClose) == -1) { +// LOGE("sigaddset : %s", strerror(errno)); +// return -1; +// } + signal_fd = signalfd(-1, &sigset, 0); + TryReturn( signal_fd >= 0, PRIV_MGR_ERROR_SYSTEM_ERROR, , "signalfd : %s", strerror(errno)); + + //Setting descriptors for pselect + fd_set allset, rset; + int maxfd; + FD_ZERO(&allset); + FD_SET(m_listenFd, &allset); + FD_SET(signal_fd, &allset); + maxfd = (m_listenFd > signal_fd) ? (m_listenFd) : (signal_fd); + ++maxfd; + //this will block SIGPIPE for this thread and every thread created in it + //reason : from here on we don't won't to receive SIGPIPE on writing to closed socket + //instead of signal we want to receive error from write - hence blocking SIGPIPE + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + pthread_sigmask(SIG_BLOCK, &set, NULL); + + while(1) + { + rset = allset; + if(pselect(maxfd, &rset, NULL, NULL, NULL, NULL) == -1) + { + closeConnections(); + LOGE("pselect()"); + return PRIV_MGR_ERROR_SYSTEM_ERROR; + } + + if(FD_ISSET(signal_fd, &rset)) + { + LOGI("Got signal to close"); + signalfd_siginfo siginfo; + ssize_t res; + res = read(signal_fd, &siginfo, sizeof(siginfo)); + TryReturn( res > 0, PRIV_MGR_ERROR_IPC_ERROR, closeConnections();, "read : %s", strerror(errno)); + TryReturn( (size_t)res == sizeof(siginfo), PRIV_MGR_ERROR_IPC_ERROR, closeConnections();, "couldn't read whole siginfo"); + + if((int)siginfo.ssi_signo == m_signalToClose) + { + LOGI("Server thread got signal to close"); + closeConnections(); + return PRIV_MGR_ERROR_SUCCESS; + } + else + { + LOGI("Got not handled signal"); + } + } + if(FD_ISSET(m_listenFd, &rset)) + { + int clientFd; + clientFd = accept(m_listenFd, NULL, NULL); + TryReturn( clientFd != -1, PRIV_MGR_ERROR_IPC_ERROR, closeConnections();, "accept : %s", strerror(errno)); + + LOGI("Got incoming connection"); + ConnectionInfo * connection = new ConnectionInfo(clientFd, (void *)this); + int res; + pthread_t client_thread; + if((res = pthread_create(&client_thread, NULL, &connectionThread, connection)) < 0) + { + delete connection; + errno = res; + closeConnections(); + LOGE("pthread_create()"); + return PRIV_MGR_ERROR_SYSTEM_ERROR; + } + addClientSocket(clientFd); + } + } +} + +void* +SocketService::connectionThread(void* pData) +{ + if(pthread_detach(pthread_self())!=0) + { + LOGE("Failed to detach thread"); + } + std::unique_ptr<ConnectionInfo> connectionInfo (static_cast<ConnectionInfo *>(pData)); + SocketService &t = *static_cast<SocketService *>(connectionInfo->pData); + //LOGI("Starting connection thread"); + int ret = t.connectionService(connectionInfo->connFd); + if (ret < 0) + { + LOGE("Connection thread error"); + t.removeClientSocket(connectionInfo->connFd); + close(connectionInfo->connFd); + return (void*)1; + } + //LOGI("Client serviced"); + return (void*)0; +} + +int +SocketService::connectionService(int fd) +{ + + SocketConnection connector = SocketConnection(fd); + std::string interfaceName, methodName; + + int res = connector.read(&interfaceName, &methodName); + if (res != PRIV_MGR_ERROR_SUCCESS) + { + LOGE("read : %d", res); + return res; + } + + //LOGD("Got interface : %s", interfaceName.c_str()); + //LOGD("Got method : %s", methodName.c_str()); + + if( m_callbackMap.find(interfaceName) == m_callbackMap.end()) + { + LOGE("Unknown interface : %s", interfaceName.c_str()); + return PRIV_MGR_ERROR_NO_DATA; + } + + if(m_callbackMap[interfaceName].find(methodName) == m_callbackMap[interfaceName].end()) + { + LOGE("Unknown method : %s", methodName.c_str()); + return PRIV_MGR_ERROR_NO_DATA; + } + +// if(m_callbackMap[interfaceName][methodName]->securityCallback != NULL){ +// if(!m_callbackMap[interfaceName][methodName]->securityCallback(fd)){ +// LOGE("Security check returned false"); +// return -1; +// } +// } + + //LOGI("Calling service"); + m_callbackMap[interfaceName][methodName]->serviceCallback(&connector); + + //LOGI("Removing client"); + removeClientSocket(fd); + close(fd); + + //LOGI("Call served"); + + return PRIV_MGR_ERROR_SUCCESS; +} + +int +SocketService::stop(void) +{ + LOGI("Stopping"); + if(close(m_listenFd) == -1) + if(errno != ENOTCONN) + { + LOGE("close() : %s", strerror(errno)); + return PRIV_MGR_ERROR_IPC_ERROR; + } + + int returned_value; + if((returned_value = pthread_kill(m_mainThread, m_signalToClose)) < 0) + { + errno = returned_value; + LOGE("pthread_kill() : %s", strerror(errno)); + return PRIV_MGR_ERROR_IPC_ERROR; + } + pthread_join(m_mainThread, NULL); + + LOGI("Stopped"); + return PRIV_MGR_ERROR_SUCCESS; +} + +int +SocketService::shutdown(void) +{ + return PRIV_MGR_ERROR_SUCCESS; +} + +int +SocketService::registerServiceCallback(const std::string &interfaceName, const std::string &methodName, socketServiceCallback callbackMethod) +{ + if(NULL == callbackMethod) + { + LOGE("Null callback"); + return PRIV_MGR_ERROR_INVALID_PARAMETER; + } + if(interfaceName.empty() || methodName.empty()) + { + LOGE("Interface and method name cannot be empty"); + return PRIV_MGR_ERROR_INVALID_PARAMETER; + } + + auto serviceCallbackPtr = std::make_shared<ServiceCallback>(ServiceCallback(callbackMethod)); + m_callbackMap[interfaceName][methodName] = serviceCallbackPtr; + + return PRIV_MGR_ERROR_SUCCESS; +} + +void +SocketService::addClientSocket(int clientSocket) +{ + std::lock_guard<std::mutex> guard(m_clientSocketListMutex); + m_clientSocketList.push_back(clientSocket); +} + +void +SocketService::removeClientSocket(int clientSocket) +{ + std::lock_guard<std::mutex> guard(m_clientSocketListMutex); + m_clientSocketList.remove(clientSocket); +} + +bool +SocketService::popClientSocket(int * pClientSocket) +{ + std::lock_guard<std::mutex> guard(m_clientSocketListMutex); + if(m_clientSocketList.empty()) + return false; + *pClientSocket = m_clientSocketList.front(); + m_clientSocketList.pop_front(); + return true; +} + + +void +SocketService::closeConnections(void) +{ + int clientSocket; + LOGI("Closing client sockets"); + while(popClientSocket(&clientSocket)) + { + if(close(clientSocket) == -1) + { + LOGE("close() : %s", strerror(errno)); + } + } + + LOGI("Connections closed"); +} diff --git a/server/src/main.cpp b/server/src/main.cpp new file mode 100644 index 0000000..2ae8169 --- /dev/null +++ b/server/src/main.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013 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 <PrivacyManagerDaemon.h> +#include <glib.h> + +int +main(int argc, char* argv[]) +{ + PrivacyManagerDaemon* pDaemon = PrivacyManagerDaemon::getInstance(); + + pDaemon->inialize(); + pDaemon->start(); + + GMainLoop* pLoop; + pLoop = g_main_new(TRUE); + + g_main_loop_run(pLoop); + + pDaemon->stop(); + pDaemon->shutdown(); + + return 0; +}
\ No newline at end of file diff --git a/server/src/privacy_manager_daemon.cpp b/server/src/privacy_manager_daemon.cpp new file mode 100644 index 0000000..098f414 --- /dev/null +++ b/server/src/privacy_manager_daemon.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2013 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 <privacy_manager_daemon.h> +#include <PrivacyManagerDaemon.h> + +int privacy_manager_daemon_initialize(void) +{ + PrivacyManagerDaemon* pPrivacyDaemon = PrivacyManagerDaemon::getInstance(); + + return pPrivacyDaemon->initialize(); +} + +int privacy_manager_daemon_start(void) +{ + PrivacyManagerDaemon* pInstance = PrivacyManagerDaemon::getInstance(); + + return pInstance->start(); +} + +int privacy_manager_daemon_stop(void) +{ + PrivacyManagerDaemon* pInstance = PrivacyManagerDaemon::getInstance(); + + return pInstance->stop(); +} + +int privacy_manager_daemon_shutdown(void) +{ + PrivacyManagerDaemon* pInstance = PrivacyManagerDaemon::getInstance(); + + return pInstance->shutdown(); +} diff --git a/server/src/service/PrivacyInfoService.cpp b/server/src/service/PrivacyInfoService.cpp new file mode 100644 index 0000000..e3f87e2 --- /dev/null +++ b/server/src/service/PrivacyInfoService.cpp @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2012 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 <PrivacyInfoService.h> +#include <PrivacyManagerServer.h> +#include <dlog.h> +#include <Utils.h> + +void +PrivacyInfoService::addPrivacyInfo(SocketConnection* pConnector) +{ + std::string pkgId; + std::list < std::string > list; + bool privacyPopupRequired = true; + pConnector->read(&pkgId, &list, &privacyPopupRequired); + + PrivacyManagerServer* pPrivacyManagerServer = PrivacyManagerServer::getInstance(); + int result = pPrivacyManagerServer->addAppPackagePrivacyInfo(pkgId, list, privacyPopupRequired); + + pConnector->write(result); +} + +void +PrivacyInfoService::removePrivacyInfo(SocketConnection* pConnector) +{ + std::string pkgId; + pConnector->read(&pkgId); + + PrivacyManagerServer* pPrivacyManagerServer = PrivacyManagerServer::getInstance(); + int res = pPrivacyManagerServer->removeAppPackagePrivacyInfo(pkgId); + + pConnector->write(res); +} + +void +PrivacyInfoService::setPrivacySetting(SocketConnection* pConnector) +{ + std::string pkgId; + std::string privacyId; + bool enabled = false; + pConnector->read(&pkgId, &privacyId, &enabled); + + PrivacyManagerServer* pPrivacyManagerServer = PrivacyManagerServer::getInstance(); + int result = pPrivacyManagerServer->setPrivacySetting(pkgId, privacyId, enabled); + + pConnector->write(result); +} + +void +PrivacyInfoService::getPrivacyAppPackages(SocketConnection* pConnector) +{ + PrivacyManagerServer* pPrivacyManagerServer = PrivacyManagerServer::getInstance(); + std::list <std::string> list; + int result = pPrivacyManagerServer->getPrivacyAppPackages(list); + + pConnector->write( (unsigned int) result); + pConnector->write( (unsigned int) list.size()); + pConnector->write(list); +} + +void +PrivacyInfoService::getAppPackagePrivacyInfo(SocketConnection* pConnector) +{ + std::string pkgId; + + pConnector->read(&pkgId); + PrivacyManagerServer* pPrivacyManagerServer = PrivacyManagerServer::getInstance(); + + + std::list < std::pair < std::string, bool > > infoList; + + int res = pPrivacyManagerServer->getAppPackagePrivacyInfo(pkgId, infoList); + + pConnector->write( res ); + pConnector->write( infoList ); +} + +void +PrivacyInfoService::isUserPrompted(SocketConnection* pConnector) +{ + std::string pkgId; + + pConnector->read(&pkgId); + PrivacyManagerServer* pPrivacyManagerServer = PrivacyManagerServer::getInstance(); + + bool isPrompted; + int res = pPrivacyManagerServer->isUserPrompted(pkgId, isPrompted); + + pConnector->write( res ); + pConnector->write( isPrompted ); + +} + +void +PrivacyInfoService::setUserPrompted(SocketConnection* pConnector) +{ + std::string pkgId; + bool prompted = false; + + pConnector->read(&pkgId, &prompted); + PrivacyManagerServer* pPrivacyManagerServer = PrivacyManagerServer::getInstance(); + + int res = pPrivacyManagerServer->setUserPrompted(pkgId, prompted); + LOGI("write"); + pConnector->write( res ); + +} + +void +PrivacyInfoService::notifyUserNotConsented(SocketConnection* pConnector) +{ + std::string pkgId, privacyId; + + pConnector->read(&pkgId, &privacyId); + PrivacyManagerServer* pPrivacyManagerServer = PrivacyManagerServer::getInstance(); + + int res = pPrivacyManagerServer->notifyUserNotConsented(pkgId, privacyId); + pConnector->write( res ); + +} |