1f58050adf6e8852175ea41837a6bddbda481f34
[platform/core/security/privilege-info.git] / src / privilege_information.c
1 /*
2  * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <libintl.h>
20 #include <dlog.h>
21 #include <system_info.h>
22 #include <locale.h>
23 #include <glib.h>
24
25 #include <privilege_db_manager.h>
26 #include <privilege_info.h>
27
28 #include "privilege_information.h"
29
30 #ifdef LOG_TAG
31 #undef LOG_TAG
32 #define LOG_TAG "PRIVILEGE_INFO"
33 #endif
34
35 #define PRIVACY_FEATURE "http://tizen.org/feature/security.privacy_privilege"
36 #define CHECK_FEATURE_SUPPORTED(feature_name) \
37         do { \
38                 bool is_supported = false; \
39                 int ret = system_info_get_platform_bool(feature_name, &is_supported); \
40                 if (ret != SYSTEM_INFO_ERROR_NONE) { \
41                         LOGE("system_info_get_platform_bool failed. ret = %d", ret); \
42                         return PRVINFO_ERROR_INTERNAL_ERROR; \
43                 } \
44                 if (!is_supported) { \
45                         LOGE("%s is disabled", feature_name); \
46                         return PRVINFO_ERROR_NOT_SUPPORTED; \
47                 } \
48         } while (0)
49
50 #define TryReturn(condition, expr, returnValue, ...)  \
51         if (!(condition)) { \
52                 expr; \
53                 LOGE(__VA_ARGS__); \
54                 return returnValue; \
55         }
56
57 #ifndef PI_API
58 #define PI_API __attribute__((visibility("default")))
59 #endif
60
61 int privilege_info_get_string_id(const char *package_type_string, int display, const char *api_version, const char *privilege, char **string_id)
62 {
63         char* temp = NULL;
64         int ret;
65         privilege_manager_package_type_e package_type;
66
67         if (package_type_string != NULL)
68                 goto get_string_id_with_package_type;
69
70         /* Check NATIVE */
71         if (display)
72                 ret = privilege_db_manager_get_privilege_display(PRVMGR_PACKAGE_TYPE_CORE, privilege, api_version, &temp);
73         else
74                 ret = privilege_db_manager_get_privilege_description(PRVMGR_PACKAGE_TYPE_CORE, privilege, api_version, &temp);
75
76         if (ret == PRIVILEGE_DB_MANAGER_ERR_NONE && temp != NULL)
77                 goto string_id_found;
78         else if (ret != PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT)
79                 goto err;
80
81         /* Check WEB */
82
83 get_string_id_with_package_type:
84         if (package_type_string == NULL || strcmp(package_type_string, "PRVINFO_PACKAGE_TYPE_WEB") == 0)
85                 package_type = PRVMGR_PACKAGE_TYPE_WRT;
86         else if (strcmp(package_type_string, "PRVINFO_PACKAGE_TYPE_NATIVE") == 0)
87                 package_type = PRVMGR_PACKAGE_TYPE_CORE;
88         else
89                 return PRVINFO_ERROR_INVALID_PARAMETER;
90
91         if (display)
92                 ret = privilege_db_manager_get_privilege_display(package_type, privilege, api_version, &temp);
93         else
94                 ret = privilege_db_manager_get_privilege_description(package_type, privilege, api_version, &temp);
95
96         if (ret == PRIVILEGE_DB_MANAGER_ERR_NONE && temp != NULL)
97                 goto string_id_found;
98         else
99                 goto err;
100
101 string_id_found:
102         *string_id = strdup(temp);
103         TryReturn(*string_id != NULL, free(temp), PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation is failed.");
104         free(temp);
105         return PRVINFO_ERROR_NONE;
106
107 err:
108         *string_id = NULL;
109         if (temp != NULL)
110                 free(temp);
111         if (ret == PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT)
112                 return PRVINFO_ERROR_NO_MATCHING_PRIVILEGE;
113         else
114                 return PRVINFO_ERROR_INTERNAL_ERROR;
115 }
116
117 int privilege_info_get_string_by_string_id(const char *string_id, char **string)
118 {
119         TryReturn(string_id != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] string_id is NULL");
120         char* temp = NULL;
121         temp = dgettext("privilege", string_id);
122
123         *string = strdup(temp);
124         TryReturn(*string != NULL, , PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] strdup of string failed.");
125
126         return PRVINFO_ERROR_NONE;
127 }
128
129 PI_API
130 int privilege_info_get_display_name(const char *api_version, const char *privilege, char **display_name)
131 {
132         TryReturn(api_version != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] api_version is NULL");
133         TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
134
135         int ret = 0;
136         char* string_id = NULL;
137
138         ret = privilege_info_get_string_id(NULL, 1, api_version, privilege, &string_id);
139
140         if (ret == PRVINFO_ERROR_NONE)
141                 ret = privilege_info_get_string_by_string_id(string_id, display_name);
142         if (string_id != NULL)
143                 free(string_id);
144         return ret;
145 }
146
147 PI_API
148 int privilege_info_get_description(const char *api_version, const char *privilege, char **description)
149 {
150         TryReturn(api_version != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] api_version is NULL");
151         TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
152
153         int ret = 0;
154         char* string_id = NULL;
155
156         ret = privilege_info_get_string_id(NULL, 0, api_version, privilege, &string_id);
157
158         if (ret == PRVINFO_ERROR_NONE)
159                 ret = privilege_info_get_string_by_string_id(string_id, description);
160         if (string_id != NULL)
161                 free(string_id);
162
163         return ret;
164 }
165
166 PI_API
167 int privilege_info_get_display_name_by_pkgtype(const char *package_type, const char *api_version, const char *privilege, char **display_name)
168 {
169         TryReturn(package_type != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] package_type is NULL");
170         TryReturn(api_version != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] api_version is NULL");
171         TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
172
173         int ret = 0;
174         char* string_id = NULL;
175
176         ret = privilege_info_get_string_id(package_type, 1, api_version, privilege, &string_id);
177         TryReturn(ret != PRVINFO_ERROR_INVALID_PARAMETER, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] invalid package_type : %s", package_type);
178
179         if (ret == PRVINFO_ERROR_NONE)
180                 ret = privilege_info_get_string_by_string_id(string_id, display_name);
181         if (string_id != NULL)
182                 free(string_id);
183
184         return ret;
185 }
186
187 PI_API
188 int privilege_info_get_description_by_pkgtype(const char *package_type, const char *api_version, const char *privilege, char **description)
189 {
190         TryReturn(package_type != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] package_type is NULL");
191         TryReturn(api_version != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] api_version is NULL");
192         TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
193
194         int ret = 0;
195         char* string_id = NULL;
196
197         ret = privilege_info_get_string_id(package_type, 0, api_version, privilege, &string_id);
198         TryReturn(ret != PRVINFO_ERROR_INVALID_PARAMETER, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] invalid package_type : %s", package_type);
199
200         if (ret == PRVINFO_ERROR_NONE)
201                 ret = privilege_info_get_string_by_string_id(string_id, description);
202         if (string_id != NULL)
203                 free(string_id);
204
205         return ret;
206 }
207
208 PI_API
209 int privilege_info_get_privacy_display_name(const char *privilege, char **privacy_display_name)
210 {
211         CHECK_FEATURE_SUPPORTED(PRIVACY_FEATURE);
212         TryReturn(privilege != NULL, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege is NULL");
213         TryReturn(privilege_db_manager_is('p', privilege) == 1, , PRVINFO_ERROR_INVALID_PARAMETER, "[PRVINFO_ERROR_INVALID_PARAMETER] privilege does not exist or is not a privacy related");
214
215         char* privacy_id = NULL;
216         char* privacy_display_string_id = NULL;
217
218         TryReturn(privilege_db_manager_get_privacy_by_privilege(privilege, &privacy_id) == PRIVILEGE_DB_MANAGER_ERR_NONE && privacy_id != NULL, , PRVINFO_ERROR_INTERNAL_ERROR, "[PRVINFO_ERROR_INTERNAL_ERROR] privilege_db_manager_get_privacy_by_privilege failed");
219
220         TryReturn(privilege_db_manager_get_privacy_display(privacy_id, &privacy_display_string_id) == PRIVILEGE_DB_MANAGER_ERR_NONE && privacy_display_string_id != NULL, free(privacy_id), PRVINFO_ERROR_INTERNAL_ERROR, "[PRVINFO_ERROR_INTERNAL_ERROR] privilege_db_manager_get_privacy_display failed");
221
222         TryReturn(privilege_info_get_string_by_string_id(privacy_display_string_id, privacy_display_name) == PRVINFO_ERROR_NONE && *privacy_display_name != NULL, free(privacy_id); free(privacy_display_string_id), PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
223
224         free(privacy_id);
225         free(privacy_display_string_id);
226         return PRVINFO_ERROR_NONE;
227 }
228
229 PI_API
230 int privilege_info_get_privilege_info_list(const char* locale, GList* privilege_name_list, GList** privilege_info_list, privilege_consumer_return_code_e* return_result)
231 {
232         GList *l;
233         GList *temp_privilege_info_list = NULL;
234         char* privilege_display = NULL;
235         char* privilege_description = NULL;
236         int is_invaild_parameter_count = 0;
237         int privilege_name_list_size = 0;
238         privilege_consumer_return_code_e consumer_return_code = PRIVILEGE_CONSUMER_RETURN_CODE_SUCCESS;
239         int ret = PRVINFO_ERROR_NONE;
240
241         if (privilege_name_list == NULL) {
242                 LOGE("[PRVINFO_ERROR_INVALID_PARAMETER] privilege_list is NULL");
243                 return PRVINFO_ERROR_INVALID_PARAMETER;
244         }
245         char *orig_locale = NULL;
246         char *result = (char *)setlocale(LC_ALL, NULL);
247         if (!result) {
248                 LOGE("failed to get original locale. errno = %d", errno);
249         } else {
250                 orig_locale = strdup(result);
251                 TryReturn(orig_locale != NULL, , PRVINFO_ERROR_OUT_OF_MEMORY, "[PRVINFO_ERROR_OUT_OF_MEMORY] strdup of orig_locale failed");
252                 LOGD("orig_locale = %s", orig_locale);
253         }
254         result = (char *)setlocale(LC_ALL, locale);
255         if (result) {
256                 LOGI("succeeded in setting locale = %s", result);
257         } else {
258                 LOGE("failed to set locale. set locale to en_US.UTF8. errno = %d", errno);
259                 setlocale(LC_ALL, "en_US.UTF8");
260
261                 consumer_return_code = PRIVILEGE_CONSUMER_RETURN_CODE_UNKNOWN_LOCALE_CODE;
262         }
263
264         for (l = privilege_name_list; l != NULL; l = l->next) {
265                 char* privilege_name = (char*)l->data;
266
267                 LOGI("privilege_name = %s", privilege_name);
268
269                 ret = privilege_info_get_privilege_display_name(privilege_name, &privilege_display);
270                 if (ret == PRVMGR_ERR_NONE) {
271                         if (privilege_display != NULL) {
272                                 LOGI("display : %s", privilege_display);
273                         } else {
274                                 privilege_display = strdup("");
275                                 if (privilege_display == NULL) {
276                                         LOGE("[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
277                                         ret = PRVINFO_ERROR_OUT_OF_MEMORY;
278                                         goto FINISH;
279                                 }
280                                 is_invaild_parameter_count++;
281                         }
282                 } else {
283                         LOGE("failed to call privilege_info_get_privilege_display_name.");
284                         ret = PRVINFO_ERROR_INTERNAL_ERROR;
285                         goto FINISH;
286                 }
287
288                 LOGI("privilege_display = %s", privilege_display);
289
290                 ret = privilege_info_get_privilege_description(privilege_name, &privilege_description);
291                 if (ret == PRVMGR_ERR_NONE) {
292                         if (privilege_description != NULL) {
293                                 LOGI("description : %s", privilege_description);
294                         } else {
295                                 privilege_description = strdup("");
296                                 if (privilege_description == NULL) {
297                                         LOGE("[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
298                                         ret = PRVINFO_ERROR_OUT_OF_MEMORY;
299                                         goto FINISH;
300                                 }
301                         }
302                 } else {
303                         LOGE("failed to call privilege_info_get_privilege_description.");
304                         ret = PRVINFO_ERROR_INTERNAL_ERROR;
305                         goto FINISH;
306                 }
307
308                 LOGD("privilege_description = %s", privilege_description);
309
310                 privilege_info_s* privilege_info = (privilege_info_s*)malloc(sizeof(privilege_info_s));
311                 memset(privilege_info, 0, sizeof(privilege_info_s));
312
313                 privilege_info->privilege_name = strdup(privilege_name);
314                 if (privilege_info->privilege_name == NULL) {
315                         LOGE("[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
316                         ret = PRVINFO_ERROR_OUT_OF_MEMORY;
317                         free(privilege_info);
318                         goto FINISH;
319                 }
320                 privilege_info->display_name = strdup(privilege_display);
321                 if (privilege_info->display_name == NULL) {
322                         LOGE("[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
323                         ret = PRVINFO_ERROR_OUT_OF_MEMORY;
324                         free(privilege_info->privilege_name);
325                         free(privilege_info);
326                         goto FINISH;
327                 }
328                 privilege_info->description = strdup(privilege_description);
329                 if (privilege_info->description == NULL) {
330                         LOGE("[PRVINFO_ERROR_OUT_OF_MEMORY] Memory allocation failed.");
331                         ret = PRVINFO_ERROR_OUT_OF_MEMORY;
332                         free(privilege_info->privilege_name);
333                         free(privilege_info->display_name);
334                         free(privilege_info);
335                         goto FINISH;
336                 }
337                 LOGI("privilege_info->privilege_name = %s", privilege_info->privilege_name);
338                 LOGI("privilege_info->display_name = %s", privilege_info->display_name);
339                 LOGI("privilege_info->description = %s", privilege_info->description);
340
341                 temp_privilege_info_list = g_list_append(temp_privilege_info_list, privilege_info);
342
343                 privilege_name_list_size++;
344
345                 if (privilege_display != NULL) {
346                         free(privilege_display);
347                         privilege_display = NULL;
348                 }
349
350                 if (privilege_description != NULL) {
351                         free(privilege_description);
352                         privilege_description = NULL;
353                 }
354         }
355
356         if (is_invaild_parameter_count == privilege_name_list_size)
357                 consumer_return_code = PRIVILEGE_CONSUMER_RETURN_CODE_INVALID_PARAMETER;
358
359 FINISH:
360
361         *privilege_info_list = temp_privilege_info_list;
362         *return_result = consumer_return_code;
363
364         if (privilege_display != NULL) {
365                 free(privilege_display);
366                 privilege_display = NULL;
367         }
368
369         if (privilege_description != NULL) {
370                 free(privilege_description);
371                 privilege_description = NULL;
372         }
373         if (orig_locale != NULL) {
374                 setlocale(LC_ALL, orig_locale);
375                 free(orig_locale);
376                 orig_locale = NULL;
377         }
378
379         return ret;
380 }
381
382 PI_API
383 int privilege_info_free_privilege_info_list(GList* privilege_info_list)
384 {
385         if (privilege_info_list == NULL)
386                 return PRVINFO_ERROR_INVALID_PARAMETER;
387
388         GList* l = NULL;
389         for (l = privilege_info_list; l != NULL; l = l->next) {
390                 privilege_info_s* privilege_info = (privilege_info_s*)l->data;
391                 free(privilege_info->privilege_name);
392                 free(privilege_info->display_name);
393                 free(privilege_info->description);
394         }
395         g_list_free(privilege_info_list);
396         return PRVINFO_ERROR_NONE;
397 }