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