1 /*
2 * Copyright (c) 2021-2022 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 "nativetoken_json_oper.h"
16 #include <stdlib.h>
17 #include <string.h>
18 #include <securec.h>
19
20 #include "accesstoken_klog.h"
21
FreeStrArray(char *** arr,int32_t num)22 void FreeStrArray(char ***arr, int32_t num)
23 {
24 if (arr == NULL || *arr == NULL) {
25 return;
26 }
27
28 for (int32_t i = 0; i <= num; i++) {
29 if ((*arr)[i] != NULL) {
30 free((*arr)[i]);
31 (*arr)[i] = NULL;
32 }
33 }
34
35 free(*arr);
36 *arr = NULL;
37 }
38
GetProcessNameFromJson(cJSON * cjsonItem,NativeTokenList * tokenNode)39 uint32_t GetProcessNameFromJson(cJSON *cjsonItem, NativeTokenList *tokenNode)
40 {
41 cJSON *processNameJson = cJSON_GetObjectItem(cjsonItem, PROCESS_KEY_NAME);
42 if (!cJSON_IsString(processNameJson) || (processNameJson->valuestring == NULL)) {
43 LOGC("Invalid processNameJson.");
44 return ATRET_FAILED;
45 }
46
47 if (strlen(processNameJson->valuestring) > MAX_PROCESS_NAME_LEN) {
48 LOGC("Invalid processName length.");
49 return ATRET_FAILED;
50 }
51
52 if (strcpy_s(tokenNode->processName, MAX_PROCESS_NAME_LEN + 1, processNameJson->valuestring) != EOK) {
53 LOGC("Failed to copy process name.");
54 return ATRET_FAILED;
55 }
56 return ATRET_SUCCESS;
57 }
58
GetTokenIdFromJson(cJSON * cjsonItem,NativeTokenList * tokenNode)59 uint32_t GetTokenIdFromJson(cJSON *cjsonItem, NativeTokenList *tokenNode)
60 {
61 cJSON *tokenIdJson = cJSON_GetObjectItem(cjsonItem, TOKENID_KEY_NAME);
62 if ((!cJSON_IsNumber(tokenIdJson)) || (cJSON_GetNumberValue(tokenIdJson) <= 0)) {
63 LOGC("Invalid tokenIdJson.");
64 return ATRET_FAILED;
65 }
66
67 AtInnerInfo *atIdInfo = (AtInnerInfo *)&(tokenIdJson->valueint);
68 if (atIdInfo->type != TOKEN_NATIVE_TYPE && atIdInfo->type != TOKEN_SHELL_TYPE) {
69 LOGC("Invalid tokenId type.");
70 return ATRET_FAILED;
71 }
72
73 tokenNode->tokenId = (NativeAtId)tokenIdJson->valueint;
74 return ATRET_SUCCESS;
75 }
76
GetAplFromJson(cJSON * cjsonItem,NativeTokenList * tokenNode)77 uint32_t GetAplFromJson(cJSON *cjsonItem, NativeTokenList *tokenNode)
78 {
79 cJSON *aplJson = cJSON_GetObjectItem(cjsonItem, APL_KEY_NAME);
80 if (!cJSON_IsNumber(aplJson)) {
81 LOGC("Invalid aplJson.");
82 return ATRET_FAILED;
83 }
84 int32_t apl = cJSON_GetNumberValue(aplJson);
85 if (apl <= 0 || apl > SYSTEM_CORE) {
86 LOGC("Invalid apl=%d.", apl);
87 return ATRET_FAILED;
88 }
89 tokenNode->apl = aplJson->valueint;
90 return ATRET_SUCCESS;
91 }
92
GetInfoArrFromJson(cJSON * cjsonItem,char ** strArr[],int32_t * strNum,StrArrayAttr * attr)93 uint32_t GetInfoArrFromJson(cJSON *cjsonItem, char **strArr[], int32_t *strNum, StrArrayAttr *attr)
94 {
95 cJSON *strArrJson = cJSON_GetObjectItem(cjsonItem, attr->strKey);
96 int32_t size = cJSON_GetArraySize(strArrJson);
97 if (size > MAX_MALLOC_SIZE) {
98 LOGC("Invalid size=%d.", size);
99 return ATRET_FAILED;
100 }
101 if (size == 0) {
102 *strArr = NULL;
103 return ATRET_SUCCESS;
104 }
105 *strNum = size;
106 *strArr = (char **)malloc(size * sizeof(char *));
107 if (*strArr == NULL) {
108 LOGC("Failed to alloc memory for strArr.");
109 return ATRET_FAILED;
110 }
111
112 for (int32_t i = 0; i < size; i++) {
113 cJSON *item = cJSON_GetArrayItem(strArrJson, i);
114 if ((item == NULL) || (!cJSON_IsString(item)) || (item->valuestring == NULL)) {
115 FreeStrArray(strArr, i - 1);
116 LOGC("Failed to cJSON_GetArrayItem.");
117 return ATRET_FAILED;
118 }
119 size_t length = strlen(item->valuestring);
120 if (length > attr->maxStrLen) {
121 FreeStrArray(strArr, i - 1);
122 LOGC("Invalid item length=%zu.", length);
123 return ATRET_FAILED;
124 }
125 (*strArr)[i] = (char *)malloc(sizeof(char) * (length + 1));
126 if ((*strArr)[i] == NULL) {
127 FreeStrArray(strArr, i - 1);
128 LOGC("Failed to alloc memory for strArray.");
129 return ATRET_FAILED;
130 }
131 if (strcpy_s((*strArr)[i], length + 1, item->valuestring) != EOK) {
132 FreeStrArray(strArr, i);
133 LOGC("Failed to copy value.");
134 return ATRET_FAILED;
135 }
136 (*strArr)[i][length] = '\0';
137 }
138 return ATRET_SUCCESS;
139 }
140
AddStrArrayInfo(cJSON * object,char * const strArray[],int32_t strNum,const char * strKey)141 static int32_t AddStrArrayInfo(cJSON *object, char* const strArray[], int32_t strNum, const char *strKey)
142 {
143 cJSON *strJsonArr = cJSON_CreateArray();
144 if (strJsonArr == NULL) {
145 LOGC("CreateArray failed, strKey :%s.", strKey);
146 return ATRET_FAILED;
147 }
148 for (int32_t i = 0; i < strNum; i++) {
149 cJSON *item = cJSON_CreateString(strArray[i]);
150 if (item == NULL || !cJSON_AddItemToArray(strJsonArr, item)) {
151 LOGC("Failed to AddItemToArray, strKey=%s.", strKey);
152 cJSON_Delete(item);
153 cJSON_Delete(strJsonArr);
154 return ATRET_FAILED;
155 }
156 }
157 if (!cJSON_AddItemToObject(object, strKey, strJsonArr)) {
158 LOGC("Failed to AddItemToObject, strKey=%s.", strKey);
159 cJSON_Delete(strJsonArr);
160 return ATRET_FAILED;
161 }
162 return ATRET_SUCCESS;
163 }
164
SetNativeTokenJsonObject(const NativeTokenList * curr,cJSON * object)165 int32_t SetNativeTokenJsonObject(const NativeTokenList *curr, cJSON *object)
166 {
167 cJSON *item = cJSON_CreateString(curr->processName);
168 if (item == NULL || !cJSON_AddItemToObject(object, PROCESS_KEY_NAME, item)) {
169 LOGC("Failed to cJSON_AddItemToObject for processName.");
170 cJSON_Delete(item);
171 return ATRET_FAILED;
172 }
173
174 item = cJSON_CreateNumber(curr->apl);
175 if (item == NULL || !cJSON_AddItemToObject(object, APL_KEY_NAME, item)) {
176 LOGC("Failed to cJSON_AddItemToObject for APL.");
177 cJSON_Delete(item);
178 return ATRET_FAILED;
179 }
180
181 item = cJSON_CreateNumber(DEFAULT_AT_VERSION);
182 if (item == NULL || !cJSON_AddItemToObject(object, VERSION_KEY_NAME, item)) {
183 LOGC("Failed to cJSON_AddItemToObject for version.");
184 cJSON_Delete(item);
185 return ATRET_FAILED;
186 }
187
188 item = cJSON_CreateNumber(curr->tokenId);
189 if (item == NULL || !cJSON_AddItemToObject(object, TOKENID_KEY_NAME, item)) {
190 LOGC("Failed to cJSON_AddItemToObject for tokenId.");
191 cJSON_Delete(item);
192 return ATRET_FAILED;
193 }
194
195 item = cJSON_CreateNumber(0);
196 if (item == NULL || !cJSON_AddItemToObject(object, TOKEN_ATTR_KEY_NAME, item)) {
197 LOGC("Failed to cJSON_AddItemToObject for tokenAttr.");
198 cJSON_Delete(item);
199 return ATRET_FAILED;
200 }
201
202 int32_t ret = AddStrArrayInfo(object, curr->dcaps, curr->dcapsNum, DCAPS_KEY_NAME);
203 if (ret != ATRET_SUCCESS) {
204 return ret;
205 }
206
207 ret = AddStrArrayInfo(object, curr->perms, curr->permsNum, PERMS_KEY_NAME);
208 if (ret != ATRET_SUCCESS) {
209 return ret;
210 }
211
212 ret = AddStrArrayInfo(object, curr->acls, curr->aclsNum, ACLS_KEY_NAME);
213 return ret;
214 }
215
CreateNativeTokenJsonObject(const NativeTokenList * curr)216 cJSON *CreateNativeTokenJsonObject(const NativeTokenList *curr)
217 {
218 cJSON *object = cJSON_CreateObject();
219 if (object == NULL) {
220 LOGC("Failed to cJSON_CreateObject.");
221 return NULL;
222 }
223 if (SetNativeTokenJsonObject(curr, object) != ATRET_SUCCESS) {
224 cJSON_Delete(object);
225 return NULL;
226 }
227
228 return object;
229 }
230
UpdateStrArrayType(char * const strArr[],int32_t strNum,const char * strKey,cJSON * record)231 static uint32_t UpdateStrArrayType(char* const strArr[], int32_t strNum, const char *strKey, cJSON *record)
232 {
233 cJSON *strArrJson = cJSON_CreateArray();
234 if (strArrJson == NULL) {
235 LOGC("Failed to cJSON_CreateArray.");
236 return ATRET_FAILED;
237 }
238 for (int32_t i = 0; i < strNum; i++) {
239 cJSON *item = cJSON_CreateString(strArr[i]);
240 if (item == NULL) {
241 LOGC("Failed to cJSON_CreateString.");
242 cJSON_Delete(strArrJson);
243 return ATRET_FAILED;
244 }
245 if (!cJSON_AddItemToArray(strArrJson, item)) {
246 LOGC("Failed to cJSON_AddItemToArray.");
247 cJSON_Delete(item);
248 cJSON_Delete(strArrJson);
249 return ATRET_FAILED;
250 }
251 }
252 if (cJSON_GetObjectItem(record, strKey) != NULL) {
253 if (!cJSON_ReplaceItemInObject(record, strKey, strArrJson)) {
254 LOGC("Failed to cJSON_ReplaceItemInObject.");
255 cJSON_Delete(strArrJson);
256 return ATRET_FAILED;
257 }
258 } else {
259 if (!cJSON_AddItemToObject(record, strKey, strArrJson)) {
260 LOGC("Failed to cJSON_AddItemToObject.");
261 cJSON_Delete(strArrJson);
262 return ATRET_FAILED;
263 }
264 }
265
266 return ATRET_SUCCESS;
267 }
268
UpdateItemcontent(const NativeTokenList * tokenNode,cJSON * record)269 static uint32_t UpdateItemcontent(const NativeTokenList *tokenNode, cJSON *record)
270 {
271 cJSON *itemApl = cJSON_CreateNumber(tokenNode->apl);
272 if (itemApl == NULL) {
273 return ATRET_FAILED;
274 }
275 if (!cJSON_ReplaceItemInObject(record, APL_KEY_NAME, itemApl)) {
276 cJSON_Delete(itemApl);
277 LOGC("Failed to update APL for processName(%s).", tokenNode->processName);
278 return ATRET_FAILED;
279 }
280
281 uint32_t ret = UpdateStrArrayType(tokenNode->dcaps, tokenNode->dcapsNum, DCAPS_KEY_NAME, record);
282 if (ret != ATRET_SUCCESS) {
283 LOGC("Failed to update dcaps for processName(%s).", tokenNode->processName);
284 return ATRET_FAILED;
285 }
286
287 ret = UpdateStrArrayType(tokenNode->perms, tokenNode->permsNum, PERMS_KEY_NAME, record);
288 if (ret != ATRET_SUCCESS) {
289 LOGC("Failed to update perms for processName(%s).", tokenNode->processName);
290 return ATRET_FAILED;
291 }
292
293 ret = UpdateStrArrayType(tokenNode->acls, tokenNode->aclsNum, ACLS_KEY_NAME, record);
294 if (ret != ATRET_SUCCESS) {
295 LOGC("Failed to update acls for processName(%s).", tokenNode->processName);
296 return ATRET_FAILED;
297 }
298 return ATRET_SUCCESS;
299 }
300
UpdateGoalItemFromRecord(const NativeTokenList * tokenNode,cJSON * record)301 uint32_t UpdateGoalItemFromRecord(const NativeTokenList *tokenNode, cJSON *record)
302 {
303 int32_t arraySize = cJSON_GetArraySize(record);
304 for (int32_t i = 0; i < arraySize; i++) {
305 cJSON *cjsonItem = cJSON_GetArrayItem(record, i);
306 if (cjsonItem == NULL) {
307 LOGC("Failed to cJSON_GetArrayItem.");
308 return ATRET_FAILED;
309 }
310 cJSON *processNameJson = cJSON_GetObjectItem(cjsonItem, PROCESS_KEY_NAME);
311 if ((processNameJson == NULL) || (!cJSON_IsString(processNameJson)) || (processNameJson->valuestring == NULL)) {
312 LOGC("ProcessNameJson is null.");
313 return ATRET_FAILED;
314 }
315 if (strcmp(processNameJson->valuestring, tokenNode->processName) == 0) {
316 return UpdateItemcontent(tokenNode, cjsonItem);
317 }
318 }
319 LOGC("Cannot find process in config file.");
320 return ATRET_FAILED;
321 }
322