• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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