• 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.h"
16 
17 #ifdef WITH_SELINUX
18 #include <policycoreutils.h>
19 #endif // WITH_SELINUX
20 
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include "securec.h"
29 #include "nativetoken_json_oper.h"
30 #include "nativetoken_kit.h"
31 #include "nativetoken_klog.h"
32 
33 
34 NativeTokenList *g_tokenListHead;
35 int32_t g_isNativeTokenInited = 0;
36 
GetFileBuff(const char * cfg,char ** retBuff)37 int32_t GetFileBuff(const char *cfg, char **retBuff)
38 {
39     struct stat fileStat;
40 
41     char filePath[PATH_MAX_LEN + 1] = {0};
42     if (realpath(cfg, filePath) == NULL) {
43         if (errno == ENOENT) {
44             /* file doesn't exist */
45             *retBuff = NULL;
46             return ATRET_SUCCESS;
47         }
48         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:invalid filePath.", __func__);
49         return ATRET_FAILED;
50     }
51 
52     if (stat(filePath, &fileStat) != 0) {
53         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:stat file failed.", __func__);
54         return ATRET_FAILED;
55     }
56 
57     if (fileStat.st_size == 0) {
58         *retBuff = NULL;
59         return ATRET_SUCCESS;
60     }
61 
62     if (fileStat.st_size > MAX_JSON_FILE_LEN) {
63         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:stat file size is invalid.", __func__);
64         return ATRET_FAILED;
65     }
66 
67     size_t fileSize = (unsigned)fileStat.st_size;
68 
69     FILE *cfgFd = fopen(filePath, "r");
70     if (cfgFd == NULL) {
71         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:fopen file failed.", __func__);
72         return ATRET_FAILED;
73     }
74 
75     char *buff = (char *)malloc((size_t)(fileSize + 1));
76     if (buff == NULL) {
77         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:memory alloc failed.", __func__);
78         fclose(cfgFd);
79         return ATRET_FAILED;
80     }
81 
82     if (fread(buff, fileSize, 1, cfgFd) != 1) {
83         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:fread failed.", __func__);
84         free(buff);
85         buff = NULL;
86         fclose(cfgFd);
87         return ATRET_FAILED;
88     }
89     buff[fileSize] = '\0';
90     *retBuff = buff;
91     fclose(cfgFd);
92     return ATRET_SUCCESS;
93 }
94 
StrAttrSet(StrArrayAttr * attr,uint32_t maxStrLen,int32_t maxStrNum,const char * strKey)95 static void StrAttrSet(StrArrayAttr *attr, uint32_t maxStrLen, int32_t maxStrNum, const char *strKey)
96 {
97     attr->maxStrLen = maxStrLen;
98     attr->maxStrNum = maxStrNum;
99     attr->strKey = strKey;
100 }
101 
GetNativeTokenFromJson(cJSON * cjsonItem,NativeTokenList * tokenNode)102 static int32_t GetNativeTokenFromJson(cJSON *cjsonItem, NativeTokenList *tokenNode)
103 {
104     uint32_t ret;
105     StrArrayAttr attr;
106 
107     ret = GetProcessNameFromJson(cjsonItem, tokenNode);
108     ret |= GetTokenIdFromJson(cjsonItem, tokenNode);
109     ret |= GetAplFromJson(cjsonItem, tokenNode);
110 
111     StrAttrSet(&attr, MAX_DCAP_LEN, MAX_DCAPS_NUM, DCAPS_KEY_NAME);
112     ret |= GetInfoArrFromJson(cjsonItem, tokenNode->dcaps, &(tokenNode->dcapsNum), &attr);
113     if (ret != ATRET_SUCCESS) {
114         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:GetInfoArrFromJson failed for dcaps.", __func__);
115         return ATRET_FAILED;
116     }
117 
118     StrAttrSet(&attr, MAX_PERM_LEN, MAX_PERM_NUM, PERMS_KEY_NAME);
119     ret = GetInfoArrFromJson(cjsonItem, tokenNode->perms, &(tokenNode->permsNum), &attr);
120     if (ret != ATRET_SUCCESS) {
121         FreeStrArray(tokenNode->dcaps, tokenNode->dcapsNum - 1);
122         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:GetInfoArrFromJson failed for perms.", __func__);
123         return ATRET_FAILED;
124     }
125 
126     StrAttrSet(&attr, MAX_PERM_LEN, MAX_PERM_NUM, ACLS_KEY_NAME);
127     ret = GetInfoArrFromJson(cjsonItem, tokenNode->acls, &(tokenNode->aclsNum), &attr);
128     if (ret != ATRET_SUCCESS) {
129         FreeStrArray(tokenNode->dcaps, tokenNode->dcapsNum - 1);
130         FreeStrArray(tokenNode->perms, tokenNode->permsNum - 1);
131         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:GetInfoArrFromJson failed for acls.", __func__);
132         return ATRET_FAILED;
133     }
134     return ATRET_SUCCESS;
135 }
136 
GetTokenList(const cJSON * object)137 static int32_t GetTokenList(const cJSON *object)
138 {
139     NativeTokenList *tmp = NULL;
140 
141     if (object == NULL) {
142         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:object is null.", __func__);
143         return ATRET_FAILED;
144     }
145     int32_t arraySize = cJSON_GetArraySize(object);
146 
147     for (int32_t i = 0; i < arraySize; i++) {
148         tmp = (NativeTokenList *)malloc(sizeof(NativeTokenList));
149         if (tmp == NULL) {
150             NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:memory alloc failed.", __func__);
151             return ATRET_FAILED;
152         }
153         cJSON *cjsonItem = cJSON_GetArrayItem(object, i);
154         if (cjsonItem == NULL) {
155             free(tmp);
156             NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:cJSON_GetArrayItem failed.", __func__);
157             return ATRET_FAILED;
158         }
159         if (GetNativeTokenFromJson(cjsonItem, tmp) != ATRET_SUCCESS) {
160             free(tmp);
161             return ATRET_FAILED;
162         }
163 
164         tmp->next = g_tokenListHead->next;
165         g_tokenListHead->next = tmp;
166     }
167     return ATRET_SUCCESS;
168 }
169 
ParseTokenInfo(void)170 static int32_t ParseTokenInfo(void)
171 {
172     char *fileBuff = NULL;
173     cJSON *record = NULL;
174     int32_t ret;
175 
176     ret = GetFileBuff(TOKEN_ID_CFG_FILE_PATH, &fileBuff);
177     if (ret != ATRET_SUCCESS) {
178         return ret;
179     }
180     if (fileBuff == NULL) {
181         return ATRET_SUCCESS;
182     }
183     record = cJSON_Parse(fileBuff);
184     free(fileBuff);
185     fileBuff = NULL;
186 
187     ret = GetTokenList(record);
188     cJSON_Delete(record);
189 
190     return ret;
191 }
192 
CreateCfgFile(void)193 static int32_t CreateCfgFile(void)
194 {
195     int32_t fd = open(TOKEN_ID_CFG_FILE_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP);
196     if (fd < 0) {
197         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:open failed.", __func__);
198         return ATRET_FAILED;
199     }
200 
201 #ifdef WITH_SELINUX
202     Restorecon(TOKEN_ID_CFG_FILE_PATH);
203 #endif // WITH_SELINUX
204 
205     close(fd);
206     fd = -1;
207 
208     struct stat buf;
209     if (stat(TOKEN_ID_CFG_DIR_PATH, &buf) != 0) {
210         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:stat folder path is invalid %d.", __func__, errno);
211         return ATRET_FAILED;
212     }
213     if (chown(TOKEN_ID_CFG_FILE_PATH, buf.st_uid, buf.st_gid) != 0) {
214         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:chown failed, errno is %d.", __func__, errno);
215         return ATRET_FAILED;
216     }
217 
218     return ATRET_SUCCESS;
219 }
220 
AtlibInit(void)221 int32_t AtlibInit(void)
222 {
223     g_tokenListHead = (NativeTokenList *)malloc(sizeof(NativeTokenList));
224     if (g_tokenListHead == NULL) {
225         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:g_tokenListHead memory alloc failed.", __func__);
226         return ATRET_FAILED;
227     }
228     g_tokenListHead->next = NULL;
229 
230     int32_t ret = ParseTokenInfo();
231     if (ret != ATRET_SUCCESS) {
232         free(g_tokenListHead);
233         g_tokenListHead = NULL;
234         return ret;
235     }
236 
237     if (g_tokenListHead->next == NULL) {
238         if (CreateCfgFile() != ATRET_SUCCESS) {
239             return ATRET_FAILED;
240         }
241     }
242     g_isNativeTokenInited = 1;
243 
244     return ATRET_SUCCESS;
245 }
246 
GetRandomTokenId(uint32_t * randNum)247 static int32_t GetRandomTokenId(uint32_t *randNum)
248 {
249     uint32_t random;
250     ssize_t len;
251     int32_t fd = open("/dev/urandom", O_RDONLY);
252     if (fd < 0) {
253         return ATRET_FAILED;
254     }
255     len = read(fd, &random, sizeof(random));
256     (void)close(fd);
257 
258     if (len != sizeof(random)) {
259         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:read failed.", __func__);
260         return ATRET_FAILED;
261     }
262     *randNum = random;
263     return ATRET_SUCCESS;
264 }
265 
IsTokenUniqueIdExist(uint32_t tokenUniqueId)266 static int32_t IsTokenUniqueIdExist(uint32_t tokenUniqueId)
267 {
268     NativeTokenList *tokenNode = g_tokenListHead->next;
269     while (tokenNode != NULL) {
270         AtInnerInfo *existToken = (AtInnerInfo *)&(tokenNode->tokenId);
271         if (tokenUniqueId == existToken->tokenUniqueId) {
272             return 1;
273         }
274         tokenNode = tokenNode->next;
275     }
276     return 0;
277 }
278 
CreateNativeTokenId(const char * processName)279 static NativeAtId CreateNativeTokenId(const char *processName)
280 {
281     uint32_t rand;
282     NativeAtId tokenId;
283     AtInnerInfo *innerId = (AtInnerInfo *)(&tokenId);
284     int32_t retry = MAX_RETRY_TIMES;
285 
286     while (retry > 0) {
287         if (GetRandomTokenId(&rand) != ATRET_SUCCESS) {
288             return INVALID_TOKEN_ID;
289         }
290         if (IsTokenUniqueIdExist(rand & (TOKEN_RANDOM_MASK)) == 0) {
291             break;
292         }
293         retry--;
294     }
295     if (retry == 0) {
296         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:retry times is 0.", __func__);
297         return INVALID_TOKEN_ID;
298     }
299 
300     innerId->reserved = 0;
301     innerId->tokenUniqueId = rand & (TOKEN_RANDOM_MASK);
302     innerId->version = 1;
303 
304     if (strcmp(processName, HDC_PROCESS_NAME) == 0) {
305         innerId->type = TOKEN_SHELL_TYPE;
306     } else {
307         innerId->type = TOKEN_NATIVE_TYPE;
308     }
309 
310     return tokenId;
311 }
312 
GetAplLevel(const char * aplStr)313 static int32_t GetAplLevel(const char *aplStr)
314 {
315     if (aplStr == NULL) {
316         return 0;
317     }
318     if (strcmp(aplStr, "system_core") == 0) {
319         return SYSTEM_CORE; // system_core means apl level is 3
320     }
321     if (strcmp(aplStr, "system_basic") == 0) {
322         return SYSTEM_BASIC; // system_basic means apl level is 2
323     }
324     if (strcmp(aplStr, "normal") == 0) {
325         return NORMAL;
326     }
327     NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:aplStr is invalid.", __func__);
328     return 0;
329 }
330 
WriteToFile(const cJSON * root)331 static void WriteToFile(const cJSON *root)
332 {
333     char *jsonStr = NULL;
334     jsonStr = cJSON_PrintUnformatted(root);
335     if (jsonStr == NULL) {
336         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:cJSON_PrintUnformatted failed.", __func__);
337         return;
338     }
339 
340     do {
341         int32_t fd = open(TOKEN_ID_CFG_FILE_PATH, O_RDWR | O_CREAT | O_TRUNC,
342                           S_IRUSR | S_IWUSR | S_IRGRP);
343         if (fd < 0) {
344             NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:open failed.", __func__);
345             break;
346         }
347         size_t strLen = strlen(jsonStr);
348         ssize_t writtenLen = write(fd, (void *)jsonStr, (size_t)strLen);
349         if (fsync(fd) != 0) {
350             NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:fsync failed, errno is %d.", __func__, errno);
351         }
352         close(fd);
353         if (writtenLen < 0 || (size_t)writtenLen != strLen) {
354             NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:write failed, writtenLen is %zu.", __func__, writtenLen);
355             break;
356         }
357     } while (0);
358 
359     cJSON_free(jsonStr);
360     return;
361 }
362 
SaveTokenIdToCfg(const NativeTokenList * curr)363 static void SaveTokenIdToCfg(const NativeTokenList *curr)
364 {
365     char *fileBuff = NULL;
366     cJSON *record = NULL;
367     int32_t ret;
368 
369     ret = GetFileBuff(TOKEN_ID_CFG_FILE_PATH, &fileBuff);
370     if (ret != ATRET_SUCCESS) {
371         return;
372     }
373 
374     if (fileBuff == NULL) {
375         record = cJSON_CreateArray();
376     } else {
377         record = cJSON_Parse(fileBuff);
378         free(fileBuff);
379         fileBuff = NULL;
380     }
381 
382     if (record == NULL) {
383         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:get record failed.", __func__);
384         return;
385     }
386 
387     cJSON *node = CreateNativeTokenJsonObject(curr);
388     if (node == NULL) {
389         cJSON_Delete(record);
390         return;
391     }
392     cJSON_AddItemToArray(record, node);
393 
394     WriteToFile(record);
395     cJSON_Delete(record);
396     return;
397 }
398 
CheckStrArray(const char ** strArray,int32_t strNum,int32_t maxNum,uint32_t maxInfoLen)399 static uint32_t CheckStrArray(const char **strArray, int32_t strNum, int32_t maxNum, uint32_t maxInfoLen)
400 {
401     if (((strArray == NULL) && (strNum != 0)) ||
402         (strNum > maxNum) || (strNum < 0)) {
403         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:strArray is null or strNum is invalid.", __func__);
404         return ATRET_FAILED;
405     }
406     for (int32_t i = 0; i < strNum; i++) {
407         if ((strArray[i] == NULL) || (strlen(strArray[i]) > maxInfoLen) || (strlen(strArray[i]) == 0)) {
408             NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:strArray[%d] length is invalid.", __func__, i);
409             return ATRET_FAILED;
410         }
411     }
412     return ATRET_SUCCESS;
413 }
414 
CheckProcessInfo(NativeTokenInfoParams * tokenInfo,int32_t * aplRet)415 static uint32_t CheckProcessInfo(NativeTokenInfoParams *tokenInfo, int32_t *aplRet)
416 {
417     if ((tokenInfo->processName == NULL) || strlen(tokenInfo->processName) > MAX_PROCESS_NAME_LEN ||
418         strlen(tokenInfo->processName) == 0) {
419         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:processName is invalid.", __func__);
420         return ATRET_FAILED;
421     }
422     uint32_t retDcap = CheckStrArray(tokenInfo->dcaps, tokenInfo->dcapsNum, MAX_DCAPS_NUM, MAX_DCAP_LEN);
423     if (retDcap != ATRET_SUCCESS) {
424         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:dcaps is invalid.", __func__);
425         return ATRET_FAILED;
426     }
427     uint32_t retPerm = CheckStrArray(tokenInfo->perms, tokenInfo->permsNum, MAX_PERM_NUM, MAX_PERM_LEN);
428     if (retPerm != ATRET_SUCCESS) {
429         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:perms is invalid.", __func__);
430         return ATRET_FAILED;
431     }
432 
433     uint32_t retAcl = CheckStrArray(tokenInfo->acls, tokenInfo->aclsNum, MAX_PERM_NUM, MAX_PERM_LEN);
434     if (retAcl != ATRET_SUCCESS) {
435         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:acls is invalid.", __func__);
436         return ATRET_FAILED;
437     }
438 
439     if (tokenInfo->aclsNum > tokenInfo->permsNum) {
440         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:aclsNum is invalid.", __func__);
441         return ATRET_FAILED;
442     }
443     int32_t apl = GetAplLevel(tokenInfo->aplStr);
444     if (apl == 0) {
445         return ATRET_FAILED;
446     }
447     *aplRet = apl;
448     return ATRET_SUCCESS;
449 }
450 
CreateStrArray(int32_t num,const char ** strArr,char ** strArrRes)451 static uint32_t CreateStrArray(int32_t num, const char **strArr, char **strArrRes)
452 {
453     for (int32_t i = 0; i < num; i++) {
454         strArrRes[i] = (char *)malloc(sizeof(char) * (strlen(strArr[i]) + 1));
455         if (strArrRes[i] == NULL ||
456             (strcpy_s(strArrRes[i], strlen(strArr[i]) + 1, strArr[i]) != EOK)) {
457             NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:copy strArr[%d] failed.", __func__, i);
458             FreeStrArray(strArrRes, i);
459             return ATRET_FAILED;
460         }
461     }
462     return ATRET_SUCCESS;
463 }
464 
AddNewTokenToListAndFile(const NativeTokenInfoParams * tokenInfo,int32_t aplIn,NativeAtId * tokenId)465 static uint32_t AddNewTokenToListAndFile(const NativeTokenInfoParams *tokenInfo,
466     int32_t aplIn, NativeAtId *tokenId)
467 {
468     NativeTokenList *tokenNode;
469     NativeAtId id;
470 
471     id = CreateNativeTokenId(tokenInfo->processName);
472     if (id == INVALID_TOKEN_ID) {
473         return ATRET_FAILED;
474     }
475 
476     tokenNode = (NativeTokenList *)malloc(sizeof(NativeTokenList));
477     if (tokenNode == NULL) {
478         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:memory alloc failed.", __func__);
479         return ATRET_FAILED;
480     }
481     tokenNode->tokenId = id;
482     tokenNode->apl = aplIn;
483     if (strcpy_s(tokenNode->processName, MAX_PROCESS_NAME_LEN + 1, tokenInfo->processName) != EOK) {
484         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:strcpy_s failed.", __func__);
485         free(tokenNode);
486         return ATRET_FAILED;
487     }
488     tokenNode->dcapsNum = tokenInfo->dcapsNum;
489     tokenNode->permsNum = tokenInfo->permsNum;
490     tokenNode->aclsNum = tokenInfo->aclsNum;
491 
492     if (CreateStrArray(tokenInfo->dcapsNum, tokenInfo->dcaps, tokenNode->dcaps) != ATRET_SUCCESS) {
493         free(tokenNode);
494         return ATRET_FAILED;
495     }
496     if (CreateStrArray(tokenInfo->permsNum, tokenInfo->perms, tokenNode->perms) != ATRET_SUCCESS) {
497         FreeStrArray(tokenNode->dcaps, tokenInfo->dcapsNum - 1);
498         free(tokenNode);
499         return ATRET_FAILED;
500     }
501     if (CreateStrArray(tokenInfo->aclsNum, tokenInfo->acls, tokenNode->acls) != ATRET_SUCCESS) {
502         FreeStrArray(tokenNode->dcaps, tokenInfo->dcapsNum - 1);
503         FreeStrArray(tokenNode->perms, tokenInfo->permsNum - 1);
504         free(tokenNode);
505         return ATRET_FAILED;
506     }
507 
508     tokenNode->next = g_tokenListHead->next;
509     g_tokenListHead->next = tokenNode;
510 
511     *tokenId = id;
512 
513     SaveTokenIdToCfg(tokenNode);
514     return ATRET_SUCCESS;
515 }
516 
CompareTokenInfo(const NativeTokenList * tokenNode,const char ** dcapsIn,int32_t dcapNumIn,int32_t aplIn)517 static int32_t CompareTokenInfo(const NativeTokenList *tokenNode,
518                                 const char **dcapsIn, int32_t dcapNumIn, int32_t aplIn)
519 {
520     if (tokenNode->apl != aplIn) {
521         return 1;
522     }
523     if (tokenNode->dcapsNum != dcapNumIn) {
524         return 1;
525     }
526     for (int32_t i = 0; i < dcapNumIn; i++) {
527         if (strcmp(tokenNode->dcaps[i], dcapsIn[i]) != 0) {
528             return 1;
529         }
530     }
531     return 0;
532 }
533 
ComparePermsInfo(const NativeTokenList * tokenNode,const char ** permsIn,int32_t permsNumIn)534 static int32_t ComparePermsInfo(const NativeTokenList *tokenNode,
535                                 const char **permsIn, int32_t permsNumIn)
536 {
537     if (tokenNode->permsNum != permsNumIn) {
538         return 1;
539     }
540     for (int32_t i = 0; i < permsNumIn; i++) {
541         if (strcmp(tokenNode->perms[i], permsIn[i]) != 0) {
542             return 1;
543         }
544     }
545     return 0;
546 }
547 
UpdateStrArrayInList(char * strArr[],int32_t * strNum,const char ** strArrNew,int32_t strNumNew)548 static uint32_t UpdateStrArrayInList(char *strArr[], int32_t *strNum,
549     const char **strArrNew, int32_t strNumNew)
550 {
551     for (int32_t i = 0; i < *strNum; i++) {
552         free(strArr[i]);
553         strArr[i] = NULL;
554     }
555 
556     *strNum = strNumNew;
557     for (int32_t i = 0; i < strNumNew; i++) {
558         size_t len = strlen(strArrNew[i]) + 1;
559         strArr[i] = (char *)malloc(sizeof(char) * len);
560         if (strArr[i] == NULL || (strcpy_s(strArr[i], len, strArrNew[i]) != EOK)) {
561             NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:copy strArr[%d] failed.", __func__, i);
562             FreeStrArray(strArr, i);
563             return ATRET_FAILED;
564         }
565     }
566     return ATRET_SUCCESS;
567 }
568 
UpdateTokenInfoInList(NativeTokenList * tokenNode,const NativeTokenInfoParams * tokenInfo)569 static uint32_t UpdateTokenInfoInList(NativeTokenList *tokenNode,
570                                       const NativeTokenInfoParams *tokenInfo)
571 {
572     tokenNode->apl = GetAplLevel(tokenInfo->aplStr);
573 
574     uint32_t ret = UpdateStrArrayInList(tokenNode->dcaps, &(tokenNode->dcapsNum),
575         tokenInfo->dcaps, tokenInfo->dcapsNum);
576     if (ret != ATRET_SUCCESS) {
577         return ret;
578     }
579     ret = UpdateStrArrayInList(tokenNode->perms, &(tokenNode->permsNum),
580         tokenInfo->perms, tokenInfo->permsNum);
581     if (ret != ATRET_SUCCESS) {
582         FreeStrArray(tokenNode->dcaps, tokenNode->dcapsNum - 1);
583     }
584     ret = UpdateStrArrayInList(tokenNode->acls, &(tokenNode->aclsNum),
585         tokenInfo->acls, tokenInfo->aclsNum);
586     if (ret != ATRET_SUCCESS) {
587         FreeStrArray(tokenNode->dcaps, tokenNode->dcapsNum - 1);
588         FreeStrArray(tokenNode->perms, tokenNode->permsNum - 1);
589     }
590     return ret;
591 }
592 
UpdateInfoInCfgFile(const NativeTokenList * tokenNode)593 static uint32_t UpdateInfoInCfgFile(const NativeTokenList *tokenNode)
594 {
595     cJSON *record = NULL;
596     char *fileBuffer = NULL;
597     uint32_t ret;
598 
599     if (GetFileBuff(TOKEN_ID_CFG_FILE_PATH, &fileBuffer) != ATRET_SUCCESS) {
600         return ATRET_FAILED;
601     }
602 
603     if (fileBuffer == NULL) {
604         record = cJSON_CreateArray();
605     } else {
606         record = cJSON_Parse(fileBuffer);
607         free(fileBuffer);
608         fileBuffer = NULL;
609     }
610 
611     if (record == NULL) {
612         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:get record failed.", __func__);
613         return ATRET_FAILED;
614     }
615 
616     ret = UpdateGoalItemFromRecord(tokenNode, record);
617     if (ret != ATRET_SUCCESS) {
618         NativeTokenKmsg(NATIVETOKEN_KERROR, "[%s]:UpdateGoalItemFromRecord failed.", __func__);
619         cJSON_Delete(record);
620         return ATRET_FAILED;
621     }
622 
623     WriteToFile(record);
624     cJSON_Delete(record);
625     return ATRET_SUCCESS;
626 }
627 
GetAccessTokenId(NativeTokenInfoParams * tokenInfo)628 uint64_t GetAccessTokenId(NativeTokenInfoParams *tokenInfo)
629 {
630     NativeAtId tokenId = 0;
631     uint64_t result = 0;
632     int32_t apl;
633     NativeAtIdEx *atPoint = (NativeAtIdEx *)(&result);
634 
635     if ((g_isNativeTokenInited == 0) && (AtlibInit() != ATRET_SUCCESS)) {
636         return INVALID_TOKEN_ID;
637     }
638     uint32_t ret = CheckProcessInfo(tokenInfo, &apl);
639     if (ret != ATRET_SUCCESS) {
640         return INVALID_TOKEN_ID;
641     }
642 
643     NativeTokenList *tokenNode = g_tokenListHead->next;
644     while (tokenNode != NULL) {
645         if (strcmp(tokenNode->processName, tokenInfo->processName) == 0) {
646             tokenId = tokenNode->tokenId;
647             break;
648         }
649         tokenNode = tokenNode->next;
650     }
651 
652     if (tokenNode == NULL) {
653         ret = AddNewTokenToListAndFile(tokenInfo, apl, &tokenId);
654     } else {
655         int32_t needTokenUpdate = CompareTokenInfo(tokenNode, tokenInfo->dcaps, tokenInfo->dcapsNum, apl);
656         int32_t needPermUpdate = ComparePermsInfo(tokenNode, tokenInfo->perms, tokenInfo->permsNum);
657         if ((needTokenUpdate != 0) || (needPermUpdate != 0)) {
658             ret = UpdateTokenInfoInList(tokenNode, tokenInfo);
659             ret |= UpdateInfoInCfgFile(tokenNode);
660         }
661     }
662     if (ret != ATRET_SUCCESS) {
663         return INVALID_TOKEN_ID;
664     }
665 
666     atPoint->tokenId = tokenId;
667     atPoint->tokenAttr = 0;
668     return result;
669 }
670