1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <pthread.h>
16 #include <stdlib.h>
17
18 #ifndef APPSPAWN_CLIENT
19 #include "appspawn_sandbox.h"
20 #endif
21 #include "appspawn_client.h"
22 #include "appspawn_mount_permission.h"
23 #include "appspawn_msg.h"
24 #include "appspawn_permission.h"
25 #include "appspawn_utils.h"
26 #include "json_utils.h"
27 #include "securec.h"
28
29 typedef struct TagParseJsonContext {
30 SandboxQueue permissionQueue;
31 int32_t maxPermissionIndex;
32 uint32_t inited;
33 AppSpawnClientType type;
34 } ParseJsonContext, PermissionManager;
35
36 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
37 static PermissionManager g_permissionMgr[CLIENT_MAX] = {};
38
39 #ifdef APPSPAWN_SANDBOX_NEW
ParseAppSandboxConfig(const cJSON * root,PermissionManager * mgr)40 static int ParseAppSandboxConfig(const cJSON *root, PermissionManager *mgr)
41 {
42 // conditional
43 cJSON *json = cJSON_GetObjectItemCaseSensitive(root, "conditional");
44 APPSPAWN_CHECK(json != NULL, return 0, "No found conditional in config");
45
46 // permission
47 cJSON *config = cJSON_GetObjectItemCaseSensitive(json, "permission");
48 APPSPAWN_CHECK(config != NULL && cJSON_IsArray(config), return 0, "No found permission in config");
49
50 uint32_t configSize = cJSON_GetArraySize(config);
51 for (uint32_t i = 0; i < configSize; i++) {
52 json = cJSON_GetArrayItem(config, i);
53 char *name = GetStringFromJsonObj(json, "name");
54 APPSPAWN_CHECK(name != NULL, break, "No found name in config");
55
56 int ret = AddSandboxPermissionNode(name, &mgr->permissionQueue);
57 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
58 }
59 return 0;
60 }
61
GetPermissionMgrByType(AppSpawnClientType type)62 static PermissionManager *GetPermissionMgrByType(AppSpawnClientType type)
63 {
64 APPSPAWN_CHECK_ONLY_EXPER(type < CLIENT_MAX, return NULL);
65 g_permissionMgr[type].type = type;
66 return &g_permissionMgr[type];
67 }
68 #else
69
ParsePermissionConfig(const cJSON * permissionConfigs,PermissionManager * mgr)70 static int ParsePermissionConfig(const cJSON *permissionConfigs, PermissionManager *mgr)
71 {
72 cJSON *config = NULL;
73 cJSON_ArrayForEach(config, permissionConfigs)
74 {
75 const char *name = config->string;
76 int ret = AddSandboxPermissionNode(name, &mgr->permissionQueue);
77 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
78 }
79 return 0;
80 }
81
ParseAppSandboxConfig(const cJSON * appSandboxConfig,PermissionManager * mgr)82 static int ParseAppSandboxConfig(const cJSON *appSandboxConfig, PermissionManager *mgr)
83 {
84 cJSON *configs = cJSON_GetObjectItemCaseSensitive(appSandboxConfig, "permission");
85 APPSPAWN_CHECK(configs != NULL && cJSON_IsArray(configs), return 0, "No permission in json");
86
87 int ret = 0;
88 uint32_t configSize = cJSON_GetArraySize(configs);
89 for (uint32_t i = 0; i < configSize; i++) {
90 cJSON *json = cJSON_GetArrayItem(configs, i);
91 ret = ParsePermissionConfig(json, mgr);
92 APPSPAWN_CHECK(ret == 0, return ret, "Parse permission config fail result: %{public}d ", ret);
93 }
94 return ret;
95 }
96
GetPermissionMgrByType(AppSpawnClientType type)97 static PermissionManager *GetPermissionMgrByType(AppSpawnClientType type)
98 {
99 APPSPAWN_CHECK_ONLY_EXPER(type < CLIENT_MAX, return NULL);
100 g_permissionMgr[0].type = CLIENT_FOR_APPSPAWN;
101 return &g_permissionMgr[0];
102 }
103 #endif
104
LoadPermissionConfig(PermissionManager * mgr)105 static int LoadPermissionConfig(PermissionManager *mgr)
106 {
107 int ret = ParseJsonConfig("etc/sandbox",
108 mgr->type == CLIENT_FOR_APPSPAWN ? APP_SANDBOX_FILE_NAME : WEB_SANDBOX_FILE_NAME, ParseAppSandboxConfig, mgr);
109 APPSPAWN_CHECK(ret == 0, return ret, "Load sandbox fail %{public}d", ret);
110 mgr->maxPermissionIndex = PermissionRenumber(&mgr->permissionQueue);
111 return 0;
112 }
113
CheckPermissionManager(PermissionManager * mgr)114 static inline int32_t CheckPermissionManager(PermissionManager *mgr)
115 {
116 if (mgr != NULL && mgr->inited) {
117 return 1;
118 }
119 return 0;
120 }
121
PMGetPermissionIndex(AppSpawnClientType type,const char * permission)122 static int32_t PMGetPermissionIndex(AppSpawnClientType type, const char *permission)
123 {
124 PermissionManager *mgr = GetPermissionMgrByType(type);
125 APPSPAWN_CHECK_ONLY_EXPER(CheckPermissionManager(mgr), return INVALID_PERMISSION_INDEX);
126 return GetPermissionIndexInQueue((SandboxQueue *)&mgr->permissionQueue, permission);
127 }
128
PMGetMaxPermissionIndex(AppSpawnClientType type)129 static int32_t PMGetMaxPermissionIndex(AppSpawnClientType type)
130 {
131 PermissionManager *mgr = GetPermissionMgrByType(type);
132 APPSPAWN_CHECK_ONLY_EXPER(CheckPermissionManager(mgr), return INVALID_PERMISSION_INDEX);
133 return mgr->maxPermissionIndex;
134 }
135
PMGetPermissionByIndex(AppSpawnClientType type,int32_t index)136 static const char *PMGetPermissionByIndex(AppSpawnClientType type, int32_t index)
137 {
138 PermissionManager *mgr = GetPermissionMgrByType(type);
139 APPSPAWN_CHECK_ONLY_EXPER(CheckPermissionManager(mgr), return NULL);
140 if (mgr->maxPermissionIndex <= index) {
141 return NULL;
142 }
143 const SandboxPermissionNode *node = GetPermissionNodeInQueueByIndex((SandboxQueue *)&mgr->permissionQueue, index);
144 return PERMISSION_NAME(node);
145 }
146
LoadPermission(AppSpawnClientType type)147 APPSPAWN_STATIC int LoadPermission(AppSpawnClientType type)
148 {
149 APPSPAWN_LOGW("LoadPermission %{public}d", type);
150 pthread_mutex_lock(&g_mutex);
151 PermissionManager *mgr = GetPermissionMgrByType(type);
152 if (mgr == NULL) {
153 pthread_mutex_unlock(&g_mutex);
154 return APPSPAWN_ARG_INVALID;
155 }
156
157 if (mgr->inited) {
158 pthread_mutex_unlock(&g_mutex);
159 return 0;
160 }
161 mgr->maxPermissionIndex = -1;
162 mgr->permissionQueue.type = 0;
163 OH_ListInit(&mgr->permissionQueue.front);
164 int ret = LoadPermissionConfig(mgr);
165 if (ret == 0) {
166 mgr->inited = 1;
167 }
168 pthread_mutex_unlock(&g_mutex);
169 return ret;
170 }
171
DeletePermission(AppSpawnClientType type)172 APPSPAWN_STATIC void DeletePermission(AppSpawnClientType type)
173 {
174 APPSPAWN_LOGW("DeletePermission %{public}d", type);
175 pthread_mutex_lock(&g_mutex);
176 PermissionManager *mgr = GetPermissionMgrByType(type);
177 if (mgr == NULL || !mgr->inited) {
178 pthread_mutex_unlock(&g_mutex);
179 return;
180 }
181 DeleteSandboxPermissions(&mgr->permissionQueue);
182 mgr->maxPermissionIndex = -1;
183 mgr->inited = 0;
184 pthread_mutex_unlock(&g_mutex);
185 }
186
GetPermissionMaxCount()187 int32_t GetPermissionMaxCount()
188 {
189 int32_t maxCount = 0;
190 for (uint32_t i = 0; i < CLIENT_MAX; i++) {
191 int32_t max = PMGetMaxPermissionIndex(i);
192 if (max > maxCount) {
193 maxCount = max;
194 }
195 }
196 return maxCount;
197 }
198
GetPermissionIndex(AppSpawnClientHandle handle,const char * permission)199 int32_t GetPermissionIndex(AppSpawnClientHandle handle, const char *permission)
200 {
201 APPSPAWN_CHECK(permission != NULL, return INVALID_PERMISSION_INDEX, "Invalid permission name");
202 if (handle == NULL) {
203 return PMGetPermissionIndex(CLIENT_FOR_APPSPAWN, permission);
204 }
205 AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
206 return PMGetPermissionIndex(reqMgr->type, permission);
207 }
208
GetMaxPermissionIndex(AppSpawnClientHandle handle)209 int32_t GetMaxPermissionIndex(AppSpawnClientHandle handle)
210 {
211 if (handle == NULL) {
212 return PMGetMaxPermissionIndex(CLIENT_FOR_APPSPAWN);
213 }
214 AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
215 return PMGetMaxPermissionIndex(reqMgr->type);
216 }
217
GetPermissionByIndex(AppSpawnClientHandle handle,int32_t index)218 const char *GetPermissionByIndex(AppSpawnClientHandle handle, int32_t index)
219 {
220 if (handle == NULL) {
221 return PMGetPermissionByIndex(CLIENT_FOR_APPSPAWN, index);
222 }
223 AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle;
224 return PMGetPermissionByIndex(reqMgr->type, index);
225 }
226
LoadPermissionModule(void)227 __attribute__((constructor)) static void LoadPermissionModule(void)
228 {
229 (void)LoadPermission(CLIENT_FOR_APPSPAWN);
230 (void)LoadPermission(CLIENT_FOR_NWEBSPAWN);
231 }
232
DeletePermissionModule(void)233 __attribute__((destructor)) static void DeletePermissionModule(void)
234 {
235 DeletePermission(CLIENT_FOR_APPSPAWN);
236 DeletePermission(CLIENT_FOR_NWEBSPAWN);
237 }