2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <PrivacyChecker.h>
18 #include <PrivacyIdInfo.h>
19 #include <PrivacyManagerClient.h>
20 #include <SocketClient.h>
26 #include <dbus/dbus-glib-lowlevel.h>
27 #include <sys/types.h>
30 bool PrivacyChecker::m_isInitialized = false;
31 std::map < std::string, bool >PrivacyChecker::m_privacyCache;
32 std::map < std::string, std::map < std::string, bool > > PrivacyChecker::m_privacyInfoCache;
33 std::mutex PrivacyChecker::m_cacheMutex;
34 std::string PrivacyChecker::m_pkgId;
35 DBusConnection* PrivacyChecker::m_pDBusConnection;
36 GMainLoop* PrivacyChecker::m_pLoop = NULL;
37 GMainContext* PrivacyChecker::m_pHandlerGMainContext = NULL;
38 const int MAX_LOCAL_BUF_SIZE = 128;
39 pthread_t PrivacyChecker::m_signalThread;
42 PrivacyChecker::initialize(const std::string pkgId)
44 if (m_isInitialized) {
45 return PRIV_MGR_ERROR_SUCCESS;
50 std::lock_guard < std::mutex > guard(m_cacheMutex);
52 int res = updateCache(m_pkgId, m_privacyCache);
53 TryReturn(res == 0, res, m_pkgId.clear(), "Failed to update cache : %d", res);
56 TryReturn(res == 0, res, m_pkgId.clear(), "Failed to initialize() : %d", res);
58 return PRIV_MGR_ERROR_SUCCESS;
62 PrivacyChecker::initialize(void)
64 TryReturn(!m_isInitialized, PRIV_MGR_ERROR_SUCCESS, , "Already Initalized");
66 m_pHandlerGMainContext = g_main_context_new();
67 TryReturn(m_pHandlerGMainContext != NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, m_pkgId.clear(), "cannot create m_pHandlerGMainContext");
69 m_pLoop = g_main_loop_new(m_pHandlerGMainContext, FALSE);
70 TryReturn(m_pLoop != NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, m_pkgId.clear(), "cannot create m_pLoop");
72 int res = pthread_create(&m_signalThread, NULL, &runSignalListenerThread, NULL);
73 TryReturn(res >= 0, PRIV_MGR_ERROR_SYSTEM_ERROR, errno = res;, "Failed to create listener thread :%s", strerror(res));
75 m_isInitialized = true;
77 return PRIV_MGR_ERROR_SUCCESS;
81 PrivacyChecker::runSignalListenerThread(void* pData)
83 pthread_detach(pthread_self());
84 LOGI("Running g main loop for signal");
88 g_main_loop_run(m_pLoop);
98 PrivacyChecker::initializeDbus(void)
101 dbus_error_init(&error);
103 m_pDBusConnection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
104 TryReturn(m_pDBusConnection != NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, dbus_error_free(&error), "dbus_bus_get_private [%s] : %d", PRIV_MGR_ERROR_SYSTEM_ERROR);
106 dbus_connection_setup_with_g_main(m_pDBusConnection, m_pHandlerGMainContext);
107 std::unique_ptr < char[] > pRule(new char[MAX_LOCAL_BUF_SIZE]);
109 snprintf(pRule.get(), MAX_LOCAL_BUF_SIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH.c_str(), DBUS_SIGNAL_INTERFACE.c_str());
110 dbus_bus_add_match(m_pDBusConnection, pRule.get(), &error);
111 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);
113 dbus_bool_t r = dbus_connection_add_filter(m_pDBusConnection, handleNotification, NULL, NULL);
114 TryReturn(r, PRIV_MGR_ERROR_SYSTEM_ERROR, , "dbus_connection_add_filter: %d", PRIV_MGR_ERROR_SYSTEM_ERROR);
116 return PRIV_MGR_ERROR_SUCCESS;
120 PrivacyChecker::finalizeDbus(void)
122 dbus_connection_remove_filter(m_pDBusConnection, handleNotification, NULL);
123 dbus_connection_close(m_pDBusConnection);
124 m_pDBusConnection = NULL;
126 return PRIV_MGR_ERROR_SUCCESS;
131 PrivacyChecker::handleNotification(DBusConnection* connection, DBusMessage* message, void* user_data)
135 dbus_error_init(&error);
140 if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE.c_str(), DBUS_SIGNAL_SETTING_CHANGED.c_str()))
142 r = dbus_message_get_args(message, &error,
143 DBUS_TYPE_STRING, &pPkgId,
144 DBUS_TYPE_STRING, &pPrivacyId,
146 TryReturn(r, DBUS_HANDLER_RESULT_NOT_YET_HANDLED, , "Fail to get data : %s", error.message);
148 std::lock_guard < std::mutex > guard(m_cacheMutex);
150 if (std::string(pPkgId) == m_pkgId)
152 LOGI("Current app pkg privacy information updated");
153 updateCache(m_pkgId, pPrivacyId, m_privacyCache);
157 std::map < std::string, std::map < std::string, bool > > :: iterator iter = m_privacyInfoCache.find(std::string(pPkgId));
158 if (iter != m_privacyInfoCache.end())
160 LOGI("Current pkg privacy is in cache");
161 updateCache(std::string(pPkgId), pPrivacyId, iter->second);
165 else if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE.c_str(), DBUS_SIGNAL_PKG_REMOVED.c_str()))
167 r = dbus_message_get_args(message, &error,
168 DBUS_TYPE_STRING, &pPkgId,
170 TryReturn(r, DBUS_HANDLER_RESULT_NOT_YET_HANDLED, , "Fail to get data : %s", error.message);
172 std::lock_guard < std::mutex > guard(m_cacheMutex);
174 std::map < std::string, std::map < std::string, bool > > :: iterator iter = m_privacyInfoCache.find(std::string(pPkgId));
175 if (iter != m_privacyInfoCache.end())
177 m_privacyInfoCache.erase(iter);
182 // return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
186 // This event is not only for specific handler. All handlers of daemons should be check it and handle it.
187 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
191 PrivacyChecker::check(const std::string privacyId, std::map < std::string, bool >& privacyMap)
193 TryReturn(m_isInitialized, PRIV_MGR_ERROR_NOT_INITIALIZED, , "Not initialized");
195 std::map < std::string, bool >::iterator iter;
197 iter = privacyMap.find(privacyId);
198 if (iter == privacyMap.end() )
200 LOGD("The application cannot access the privacy inforamtion.");
201 return PRIV_MGR_ERROR_USER_NOT_CONSENTED;
203 else if (!iter->second)
205 LOGD("User does not consented to access the privacy information");
206 return PRIV_MGR_ERROR_USER_NOT_CONSENTED;
209 return PRIV_MGR_ERROR_SUCCESS;
213 PrivacyChecker::check(const std::string privacyId)
215 if (!m_isInitialized)
216 return PRIV_MGR_ERROR_NOT_INITIALIZED;
218 std::lock_guard < std::mutex > guard(m_cacheMutex);
220 int res = check(privacyId, m_privacyCache);
226 PrivacyChecker::check(const std::string pkgId, const std::string privacyId)
228 if (!m_isInitialized)
231 std::lock_guard < std::mutex > guard(m_cacheMutex);
234 std::map < std::string, std::map < std::string, bool > >::iterator iter = m_privacyInfoCache.find(pkgId);
235 if (iter == m_privacyInfoCache.end() )
237 std::map < std::string, bool > pkgCacheMap;
238 res = updateCache(pkgId, pkgCacheMap);
239 TryReturn( res == PRIV_MGR_ERROR_SUCCESS, PRIV_MGR_ERROR_DB_ERROR, , "Failed to update cache : %d", res);
241 m_privacyInfoCache.insert( std::map < std::string, std::map < std::string, bool > >::value_type(std::string(pkgId), pkgCacheMap));
242 iter = m_privacyInfoCache.find(pkgId);
245 if (iter->second.size() == 0)
247 return PRIV_MGR_ERROR_USER_NOT_CONSENTED;
250 res = check(privacyId, iter->second);
256 PrivacyChecker::checkWithPrivilege(const std::string pkgId, const std::string privilege)
258 std::string privacyId;
259 int res = PrivacyIdInfo::getPrivacyIdFromPrivilege(privilege, privacyId);
260 if (res == PRIV_MGR_ERROR_NO_DATA) {
261 return PRIV_MGR_ERROR_SUCCESS;
264 TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "getPrivacyIdFromPrivilege : %d", res);
266 return check(pkgId, privacyId);
270 PrivacyChecker::checkWithPrivilege(const std::string privilege)
272 std::string privacyId;
273 int res = PrivacyIdInfo::getPrivacyIdFromPrivilege(privilege, privacyId);
274 if (res == PRIV_MGR_ERROR_NO_DATA) {
275 return PRIV_MGR_ERROR_SUCCESS;
278 TryReturn( res == PRIV_MGR_ERROR_SUCCESS, res, , "getPrivacyIdFromPrivilege : %d", res);
280 return check(privacyId);
284 PrivacyChecker::finalize(void)
286 std::lock_guard <std::mutex> guard (m_cacheMutex);
287 m_privacyCache.clear();
288 m_privacyInfoCache.clear();
292 g_main_loop_quit(m_pLoop);
296 if (m_pHandlerGMainContext != NULL)
298 g_main_context_unref(m_pHandlerGMainContext);
299 m_pHandlerGMainContext = NULL;
302 m_isInitialized = false;
304 return PRIV_MGR_ERROR_SUCCESS;
308 PrivacyChecker::printCache(void)
310 std::map < std::string, bool >::const_iterator iter = m_privacyCache.begin();
311 for (; iter != m_privacyCache.end(); ++iter)
313 LOGD(" %s : %d", iter->first.c_str(), iter->second);
318 PrivacyChecker::updateCache(const std::string pkgId, std::string privacyId, std::map < std::string, bool >& pkgCacheMap)
320 static const std::string PrivacyQuery = "SELECT IS_ENABLED from PrivacyInfo where PKG_ID=? and PRIVACY_ID=?";
322 openDb(PRIVACY_DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);
323 prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt);
324 int res = sqlite3_bind_text(pPrivacyStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT);
325 TryReturn( res == 0, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res);
327 res = sqlite3_bind_text(pPrivacyStmt.get(), 2, privacyId.c_str(), -1, SQLITE_TRANSIENT);
328 TryReturn( res == 0, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res);
330 while ( sqlite3_step(pPrivacyStmt.get()) == SQLITE_ROW )
332 bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 0) > 0 ? true : false;
334 SECURE_LOGD("Set result : %s : %d", privacyId.c_str(), privacyEnabled );
335 pkgCacheMap.erase(privacyId);
336 pkgCacheMap.insert(std::map < std::string, bool >::value_type(privacyId, privacyEnabled));
339 return PRIV_MGR_ERROR_SUCCESS;
343 PrivacyChecker::updateCache(std::string pkgId, std::map < std::string, bool >& pkgCacheMap)
345 static const std::string PrivacyQuery = "SELECT PRIVACY_ID, IS_ENABLED from PrivacyInfo where PKG_ID=?";
349 openDb(PRIVACY_DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);
350 prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt);
351 int res = sqlite3_bind_text(pPrivacyStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT);
352 TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_DB_ERROR, , "sqlite3_bind_text : %d", res);
354 while ( (res = sqlite3_step(pPrivacyStmt.get())) == SQLITE_ROW )
356 const char* privacyId = reinterpret_cast < const char* > (sqlite3_column_text(pPrivacyStmt.get(), 0));
357 bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 1) > 0 ? true : false;
359 pkgCacheMap.insert(std::map < std::string, bool >::value_type(std::string(privacyId), privacyEnabled));
361 SECURE_LOGD("Privacy found : %s %d", privacyId, privacyEnabled);
363 return PRIV_MGR_ERROR_SUCCESS;