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