Revert "Add pkg-mgr plugin and modify some code Modify plugin"
[platform/core/security/privacy-manager.git] / client / src / PrivacyChecker.cpp
1 /*\r
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
3  *\r
4  *    Licensed under the Apache License, Version 2.0 (the "License");\r
5  *    you may not use this file except in compliance with the License.\r
6  *    You may obtain a copy of the License at\r
7  *\r
8  *        http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  *    Unless required by applicable law or agreed to in writing, software\r
11  *    distributed under the License is distributed on an "AS IS" BASIS,\r
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  *    See the License for the specific language governing permissions and\r
14  *    limitations under the License.\r
15  */\r
16 \r
17 #include <PrivacyChecker.h>\r
18 #include <PrivacyManager.h>\r
19 #include <SocketClient.h>\r
20 #include <algorithm> \r
21 #include <memory>\r
22 #include <Utils.h>\r
23 #include <dlog.h>\r
24 #include <sqlite3.h>\r
25 #include <dbus/dbus-glib-lowlevel.h>\r
26 #include <sys/types.h>\r
27 #include <unistd.h>\r
28 \r
29 bool PrivacyChecker::m_isInitialized = false;\r
30 const std::string PrivacyChecker::DB_PATH("/opt/dbspace/.privacy.db");\r
31 std::map < std::string, bool >PrivacyChecker::m_privacyCache;\r
32 std::mutex PrivacyChecker::m_cacheMutex;\r
33 std::string PrivacyChecker::m_pkgId;\r
34 DBusConnection* PrivacyChecker::m_pDBusConnection;\r
35 GMainLoop* PrivacyChecker::m_pLoop = NULL;\r
36 \r
37 const int MAX_LOCAL_BUF_SIZE = 128;\r
38 \r
39 int\r
40 PrivacyChecker::getUniqueIdFromPackageId(const std::string pkgId, int& uniqueId)\r
41 {\r
42         LOGI("enter");\r
43         std::string PkgIdQuery = std::string("SELECT UNIQUE_ID from PackageInfo where PKG_ID=?");\r
44 \r
45         int res;\r
46         openDb(DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);\r
47         prepareDb(pDbH, PkgIdQuery.c_str(), pStmt);\r
48 \r
49         res = sqlite3_bind_text(pStmt.get(), 1, pkgId.c_str(), -1, SQLITE_TRANSIENT);\r
50         TryReturn( res == SQLITE_OK, PRIV_MGR_ERROR_IO_ERROR, , "sqlite3_bind_text : %d", res);\r
51 \r
52         res = sqlite3_step(pStmt.get());\r
53         TryReturn( res == SQLITE_ROW, PRIV_MGR_ERROR_IO_ERROR, , "sqlite3_step : %d", res);\r
54 \r
55         uniqueId = sqlite3_column_int(pStmt.get(), 0);\r
56         LOGI("%s : %d", pkgId.c_str(), uniqueId);\r
57 \r
58         LOGI("leave");\r
59         return PRIV_MGR_ERROR_SUCCESS;\r
60 }\r
61 \r
62 int\r
63 PrivacyChecker::initialize(const std::string pkgId)\r
64 {\r
65         LOGI("enter");\r
66 \r
67         if (m_isInitialized)\r
68                 return PRIV_MGR_ERROR_SUCCESS;\r
69 \r
70         int res;\r
71         pthread_t signalThread;\r
72         res = pthread_create(&signalThread, NULL, &runSignalListenerThread, NULL);\r
73         TryReturn(res >= 0, PRIV_MGR_ERROR_SYSTEM_ERROR, errno = res;, "Failed to create listener thread :%s", strerror(res));\r
74 \r
75         m_pkgId = pkgId;\r
76         res = updateCache();\r
77         TryReturn(res == 0, res, m_pkgId.clear(), "Failed to update cache : %d", res);\r
78 \r
79         m_isInitialized = true;\r
80 \r
81         LOGI("leave");\r
82 \r
83         return PRIV_MGR_ERROR_SUCCESS;\r
84 }\r
85 \r
86 void*\r
87 PrivacyChecker::runSignalListenerThread(void* pData)\r
88 {\r
89         pthread_detach(pthread_self());\r
90         LOGI("Running g main loop for signal");\r
91         \r
92         if (m_pLoop != NULL)\r
93                 return (void*) 0;\r
94         \r
95         m_pLoop = g_main_new(TRUE);\r
96 \r
97         initializeDbus();\r
98 \r
99         g_main_loop_run(m_pLoop);\r
100 \r
101         finalizeDbus();\r
102 \r
103         pthread_exit(NULL);\r
104 \r
105         return (void*) 0;\r
106 }\r
107 \r
108 int\r
109 PrivacyChecker::initializeDbus(void)\r
110 {\r
111         LOGI("enter");\r
112         DBusError error;\r
113         dbus_error_init(&error);\r
114 \r
115         m_pDBusConnection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);\r
116         TryReturn(m_pDBusConnection != NULL, PRIV_MGR_ERROR_SYSTEM_ERROR, dbus_error_free(&error), "dbus_bus_get_private [%s] : %d", PRIV_MGR_ERROR_SYSTEM_ERROR);\r
117 \r
118         dbus_connection_setup_with_g_main(m_pDBusConnection, NULL);\r
119         std::unique_ptr < char[] > pRule(new char[MAX_LOCAL_BUF_SIZE]);\r
120 \r
121         snprintf(pRule.get(), MAX_LOCAL_BUF_SIZE, "path='%s',type='signal',interface='%s'", DBUS_PATH.c_str(), DBUS_SIGNAL_INTERFACE.c_str());\r
122         dbus_bus_add_match(m_pDBusConnection, pRule.get(), &error);\r
123         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);\r
124 \r
125         dbus_bool_t r = dbus_connection_add_filter(m_pDBusConnection, handleNotification, NULL, NULL);\r
126         TryReturn(r, PRIV_MGR_ERROR_SYSTEM_ERROR, , "dbus_connection_add_filter: %d", PRIV_MGR_ERROR_SYSTEM_ERROR);\r
127 \r
128         LOGI("leave");\r
129 \r
130         return PRIV_MGR_ERROR_SUCCESS;\r
131 }\r
132 \r
133 int\r
134 PrivacyChecker::finalizeDbus(void)\r
135 {\r
136         dbus_connection_remove_filter(m_pDBusConnection, handleNotification, NULL);\r
137         dbus_connection_close(m_pDBusConnection);\r
138         m_pDBusConnection = NULL;\r
139 \r
140         return PRIV_MGR_ERROR_SUCCESS;\r
141 }\r
142 \r
143 \r
144 DBusHandlerResult\r
145 PrivacyChecker::handleNotification(DBusConnection* connection, DBusMessage* message, void* user_data)\r
146 {\r
147         DBusError error;\r
148         dbus_bool_t r;\r
149         dbus_error_init(&error);\r
150 \r
151         char* pPkgId;\r
152         char* pPrivacyId;\r
153 \r
154         if (dbus_message_is_signal(message, DBUS_SIGNAL_INTERFACE.c_str(), DBUS_SIGNAL_NAME.c_str()))\r
155         {\r
156                 r = dbus_message_get_args(message, &error,\r
157                         DBUS_TYPE_STRING, &pPkgId,\r
158                         DBUS_TYPE_STRING, &pPrivacyId,\r
159                         DBUS_TYPE_INVALID);\r
160                 TryReturn(r, DBUS_HANDLER_RESULT_NOT_YET_HANDLED, , "Fail to get data : %s", error.message);\r
161                 \r
162                 if (std::string(pPkgId) == m_pkgId)\r
163                 {\r
164                         LOGI("Current app pkg privacy information updated");\r
165                         updateCache(pPrivacyId);\r
166                         printCache();\r
167                 }\r
168         }\r
169         else\r
170         {\r
171                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;\r
172         }\r
173         \r
174         return DBUS_HANDLER_RESULT_HANDLED;\r
175 }\r
176 \r
177 int\r
178 PrivacyChecker::check(const std::string privacyId)\r
179 {\r
180         LOGI("enter");\r
181 \r
182         std::lock_guard < std::mutex > guard(m_cacheMutex);\r
183 \r
184         TryReturn(m_isInitialized, -1, , "Not initialized");\r
185 \r
186         std::map < std::string, bool >::const_iterator iter = m_privacyCache.find(privacyId);\r
187         if (iter == m_privacyCache.end() )\r
188         {\r
189                 LOGD("NO matcheded");\r
190                 return -1;\r
191         }\r
192         else if (!iter->second)\r
193         {\r
194                 LOGD("NOT allowed");\r
195                 return -1;\r
196         }\r
197         LOGD("OK");\r
198 \r
199         return PRIV_MGR_ERROR_SUCCESS;\r
200 }\r
201 \r
202 int\r
203 PrivacyChecker::finalize(void)\r
204 {\r
205         std::lock_guard <std::mutex> guard (m_cacheMutex);\r
206         m_privacyCache.clear();\r
207         \r
208         if (m_pLoop != NULL)\r
209         {\r
210                 g_main_loop_quit(m_pLoop);\r
211                 m_pLoop = NULL;\r
212         }\r
213 \r
214         m_isInitialized = false;\r
215 \r
216         return PRIV_MGR_ERROR_SUCCESS;\r
217 }\r
218 \r
219 int\r
220 PrivacyChecker::updateCache(void)\r
221 {\r
222         LOGI("enter");\r
223         static const std::string PrivacyQuery = "SELECT PRIVACY_ID, IS_ENABLED from Privacy where ID=?";\r
224         \r
225         std::lock_guard < std::mutex > guard(m_cacheMutex);\r
226 \r
227         int res;\r
228         int id;\r
229         res = getUniqueIdFromPackageId(m_pkgId, id);\r
230         TryReturn( res == 0, -1, , "getUniqueIdFromPackageId : %d", res);\r
231         LOGD("id : %d" ,id);\r
232         \r
233         openDb(DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);\r
234         prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt);\r
235         res = sqlite3_bind_int(pPrivacyStmt.get(), 1, id);\r
236         TryReturn( res == 0, -1, , "sqlite3_bind_int : %d", res);\r
237 \r
238 \r
239         while ( sqlite3_step(pPrivacyStmt.get()) == SQLITE_ROW )\r
240         {\r
241                 LOGI("start");\r
242                 const char* privacyId =  reinterpret_cast < const char* > (sqlite3_column_text(pPrivacyStmt.get(), 0));\r
243                 bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 1) > 0 ? true : false;\r
244 \r
245                 m_privacyCache.insert(std::map < std::string, bool >::value_type(std::string(privacyId), privacyEnabled));\r
246 \r
247                 LOGD("Privacy found : %s %d", privacyId, privacyEnabled);\r
248         }\r
249         LOGI("leave");\r
250         return PRIV_MGR_ERROR_SUCCESS;\r
251 }\r
252 void\r
253 PrivacyChecker::printCache(void)\r
254 {\r
255         std::map < std::string, bool >::const_iterator iter = m_privacyCache.begin();\r
256         for (; iter != m_privacyCache.end(); ++iter)\r
257         {\r
258                 LOGD(" %s : %d", iter->first.c_str(), iter->second);\r
259         }\r
260 }\r
261 int\r
262 PrivacyChecker::updateCache(const std::string privacyId)\r
263 {\r
264         LOGI("enter");\r
265         static const std::string PrivacyQuery = "SELECT IS_ENABLED from Privacy where ID=? and PRIVACY_ID=?";\r
266 \r
267         int res;\r
268         int id;\r
269         res = getUniqueIdFromPackageId(m_pkgId, id);\r
270         TryReturn( res == 0, -1, , "getUniqueIdFromPackageId : %d", res);\r
271 \r
272         LOGD("id : %d" ,id);\r
273         \r
274         openDb(DB_PATH.c_str(), pDbH, SQLITE_OPEN_READONLY);\r
275         prepareDb(pDbH, PrivacyQuery.c_str(), pPrivacyStmt);\r
276         res = sqlite3_bind_int(pPrivacyStmt.get(), 1, id);\r
277         TryReturn( res == 0, -1, , "sqlite3_bind_int : %d", res);\r
278 \r
279         res = sqlite3_bind_text(pPrivacyStmt.get(), 2, privacyId.c_str(),  -1, SQLITE_TRANSIENT);\r
280         TryReturn( res == 0, -1, , "sqlite3_bind_text : %d", res);\r
281 \r
282         while ( sqlite3_step(pPrivacyStmt.get()) == SQLITE_ROW )\r
283         {\r
284                 bool privacyEnabled = sqlite3_column_int(pPrivacyStmt.get(), 0) > 0 ? true : false;\r
285 \r
286                 std::lock_guard < std::mutex > guard(m_cacheMutex);\r
287                 m_privacyCache.erase(privacyId);\r
288                 m_privacyCache.insert(std::map < std::string, bool >::value_type(privacyId, privacyEnabled));\r
289         }\r
290         \r
291         LOGI("leave");\r
292 \r
293         return PRIV_MGR_ERROR_SUCCESS;\r
294 }