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