1 /*
2  * Copyright (c) 2021-2024 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 "permission_entry.h"
16 
17 #include <securec.h>
18 
19 #include "anonymizer.h"
20 #include "cJSON.h"
21 #include "comm_log.h"
22 #include "common_list.h"
23 #include "permission_utils.h"
24 #include "regex.h"
25 #include "softbus_adapter_file.h"
26 #include "softbus_adapter_mem.h"
27 #include "softbus_adapter_thread.h"
28 #include "softbus_def.h"
29 #include "softbus_errcode.h"
30 #include "softbus_json_utils.h"
31 #include "softbus_permission.h"
32 #include "softbus_utils.h"
33 
34 #define ENFORCING 1
35 
36 #define PERMISSION_JSON_LEN 20000
37 #define TEMP_STR_MAX_LEN 128
38 
39 /* permission entry key */
40 #define SESSION_NAME_STR "SESSION_NAME"
41 #define REGEXP_STR "REGEXP"
42 #define DEVID_STR "DEVID"
43 #define SEC_LEVEL_STR "SEC_LEVEL"
44 #define APP_INFO_STR "APP_INFO"
45 
46 /* app info key */
47 #define APP_INFO_TYPE_STR "TYPE"
48 #define APP_INFO_PKG_NAME_STR "PKG_NAME"
49 #define APP_INFO_ACTION_STR "ACTIONS"
50 #define APP_INFO_UID_STR "UID"
51 
52 /* permission entry regexp value */
53 #define TRUE_STR "true"
54 #define FALSE_STR "false"
55 
56 /* permission entry sec level value */
57 #define PUBLIC_STR "public"
58 #define PRIVATE_STR "private"
59 
60 /* permission entry devid value */
61 #define UDID_STR "UDID"
62 #define UUID_STR "UUID"
63 #define NETWORK_ID_STR "NETWORKID"
64 
65 /* app info type value */
66 #define SYSTEM_APP_STR "system_app"
67 #define NATIVE_APP_STR "native_app"
68 #define SELF_APP_STR "self_app"
69 #define NORMAL_APP_STR "normal_app"
70 #define GRANTED_APP_STR "granted_app"
71 
72 /* app info actions value */
73 #define OPEN_ACTIONS_STR "open"
74 #define CREATE_ACTIONS_STR "create"
75 #define ACTIONS_SPLIT ","
76 
77 #define DBINDER_SERVICE_NAME "DBinderService"
78 #define DBINDER_BUS_NAME_PREFIX "DBinder"
79 #define DBINDER_PACKAGE_NAME "DBinderBus"
80 #define DYNAMIC_PERMISSION_MAX_SIZE 100
81 
82 typedef struct {
83     const char *key;
84     int32_t value;
85 } PeMap;
86 
87 static SoftBusList *g_permissionEntryList = NULL;
88 static SoftBusList *g_dynamicPermissionList = NULL;
89 static char g_permissonJson[PERMISSION_JSON_LEN];
90 
91 static PeMap g_peMap[] = {
92     {SYSTEM_APP_STR, SYSTEM_APP},
93     {NATIVE_APP_STR, NATIVE_APP},
94     {SELF_APP_STR, SELF_APP},
95     {NORMAL_APP_STR, NORMAL_APP},
96     {GRANTED_APP_STR, GRANTED_APP},
97     {UDID_STR, UDID},
98     {UUID_STR, UUID},
99     {NETWORK_ID_STR, NETWORKID},
100     {PRIVATE_STR, LEVEL_PRIVATE},
101     {PUBLIC_STR, LEVEL_PUBLIC},
102     {TRUE_STR, 1},
103     {FALSE_STR, 0},
104 };
105 
ReadConfigJson(const char * permissionFile)106 static int32_t ReadConfigJson(const char* permissionFile)
107 {
108     if (memset_s(g_permissonJson, PERMISSION_JSON_LEN, 0, PERMISSION_JSON_LEN) != EOK) {
109         COMM_LOGE(COMM_PERM, "ReadConfigJson memset_s failed.");
110         return SOFTBUS_MEM_ERR;
111     }
112     if (SoftBusReadFullFile(permissionFile, g_permissonJson, PERMISSION_JSON_LEN - 1) != SOFTBUS_OK) {
113         COMM_LOGE(COMM_PERM, "ReadConfigJson failed.");
114         return SOFTBUS_FILE_ERR;
115     }
116     return SOFTBUS_OK;
117 }
118 
GetPeMapValue(const char * string)119 static int32_t GetPeMapValue(const char *string)
120 {
121     uint32_t mapSize = sizeof(g_peMap) / sizeof(PeMap);
122     uint32_t index;
123     for (index = 0; index < mapSize; index++) {
124         if (strcmp(string, g_peMap[index].key) == 0) {
125             return g_peMap[index].value;
126         }
127     }
128     return UNKNOWN_VALUE;
129 }
130 
StrIsEmpty(const char * string)131 static bool StrIsEmpty(const char *string)
132 {
133     if (string == NULL || strlen(string) == 0) {
134         return true;
135     }
136     return false;
137 }
138 
StrStartWith(const char * string,const char * target)139 static bool StrStartWith(const char *string, const char *target)
140 {
141     if (string == NULL || target == NULL) {
142         COMM_LOGE(COMM_PERM, "invalid param");
143         return false;
144     }
145     size_t stringLen = strlen(string);
146     size_t targetLen = strlen(target);
147     if (stringLen == 0 || targetLen == 0 || stringLen < targetLen) {
148         COMM_LOGE(COMM_PERM, "invalid len param");
149         return false;
150     }
151     for (size_t index = 0; index < targetLen; index++) {
152         if (string[index] != target[index]) {
153             return false;
154         }
155     }
156     return true;
157 }
158 
AppInfoMemoryRequest()159 static SoftBusAppInfo *AppInfoMemoryRequest()
160 {
161     SoftBusAppInfo *appInfo = (SoftBusAppInfo *)SoftBusCalloc(sizeof(SoftBusAppInfo));
162     if (appInfo == NULL) {
163         return NULL;
164     }
165 
166     ListInit(&appInfo->node);
167     appInfo->type = UNKNOWN_VALUE;
168     appInfo->uid = UNKNOWN_VALUE;
169     appInfo->pid = UNKNOWN_VALUE;
170     appInfo->actions = 0;
171 
172     return appInfo;
173 }
174 
ProcessAppInfo(cJSON * object)175 static SoftBusAppInfo *ProcessAppInfo(cJSON *object)
176 {
177     if (object == NULL) {
178         COMM_LOGE(COMM_PERM, "object is null");
179         return NULL;
180     }
181 
182     SoftBusAppInfo *appInfo = AppInfoMemoryRequest();
183     if (appInfo == NULL) {
184         return NULL;
185     }
186 
187     char mapKey[TEMP_STR_MAX_LEN];
188     char *actionStr = NULL;
189     int32_t ret = GetStringItemByJsonObject(object, APP_INFO_PKG_NAME_STR, appInfo->pkgName, PKG_NAME_SIZE_MAX);
190     if (ret != SOFTBUS_OK) {
191         if (ret == SOFTBUS_INVALID_PARAM) {
192             COMM_LOGE(COMM_PERM, "pkgname is too long");
193             goto EXIT;
194         }
195         COMM_LOGD(COMM_PERM, "appInfo has no pkgname");
196     }
197     if (GetJsonObjectStringItem(object, APP_INFO_TYPE_STR, mapKey, TEMP_STR_MAX_LEN)) {
198         appInfo->type = GetPeMapValue(mapKey);
199         if (appInfo->type == UNKNOWN_VALUE) {
200             goto EXIT;
201         }
202     } else {
203         goto EXIT;
204     }
205     if (GetJsonObjectStringItem(object, APP_INFO_UID_STR, mapKey, TEMP_STR_MAX_LEN)) {
206         appInfo->uid = atoi(mapKey);
207     }
208     if (GetJsonObjectStringItem(object, APP_INFO_ACTION_STR, mapKey, TEMP_STR_MAX_LEN)) {
209         char *nextToken = NULL;
210         actionStr = strtok_s(mapKey, ACTIONS_SPLIT, &nextToken);
211         while (actionStr != NULL) {
212             if (strcmp(actionStr, "open") == 0) {
213                 appInfo->actions |= ACTION_OPEN;
214             } else if (strcmp(actionStr, "create") == 0) {
215                 appInfo->actions |= ACTION_CREATE;
216             }
217             actionStr = strtok_s(NULL, ACTIONS_SPLIT, &nextToken);
218         }
219     }
220     if (appInfo->actions == 0) {
221         goto EXIT;
222     }
223     return appInfo;
224 EXIT:
225     SoftBusFree(appInfo);
226     return NULL;
227 }
228 
ProcessPermissionEntry(cJSON * object)229 static SoftBusPermissionEntry *ProcessPermissionEntry(cJSON *object)
230 {
231     if (object == NULL) {
232         COMM_LOGE(COMM_PERM, "object is null.");
233         return NULL;
234     }
235 
236     SoftBusPermissionEntry *permissionEntry = (SoftBusPermissionEntry *)SoftBusCalloc(sizeof(SoftBusPermissionEntry));
237     if (permissionEntry == NULL) {
238         COMM_LOGE(COMM_PERM, "permission entry calloc fail.");
239         return NULL;
240     }
241     ListInit(&permissionEntry->node);
242     ListInit(&permissionEntry->appInfo);
243     permissionEntry->regexp = false;
244     permissionEntry->devId = UNKNOWN_VALUE;
245     permissionEntry->secLevel = UNKNOWN_VALUE;
246 
247     char mapKey[TEMP_STR_MAX_LEN];
248     int appInfoSize;
249     int appInfoIndex;
250     if (!GetJsonObjectStringItem(object, SESSION_NAME_STR, permissionEntry->sessionName, SESSION_NAME_SIZE_MAX)) {
251         SoftBusFree(permissionEntry);
252         return NULL;
253     }
254     if (GetJsonObjectStringItem(object, REGEXP_STR, mapKey, TEMP_STR_MAX_LEN)) {
255         permissionEntry->regexp = GetPeMapValue(mapKey);
256     }
257     if (GetJsonObjectStringItem(object, DEVID_STR, mapKey, TEMP_STR_MAX_LEN)) {
258         permissionEntry->devId = GetPeMapValue(mapKey);
259     }
260     if (GetJsonObjectStringItem(object, SEC_LEVEL_STR, mapKey, TEMP_STR_MAX_LEN)) {
261         permissionEntry->secLevel = GetPeMapValue(mapKey);
262     }
263     cJSON *appInfoArray = cJSON_GetObjectItem(object, APP_INFO_STR);
264     if (appInfoArray != NULL) {
265         appInfoSize = cJSON_GetArraySize(appInfoArray);
266         for (appInfoIndex = 0; appInfoIndex < appInfoSize; appInfoIndex++) {
267             SoftBusAppInfo *appInfo = ProcessAppInfo(cJSON_GetArrayItem(appInfoArray, appInfoIndex));
268             if (appInfo != NULL) {
269                 ListNodeInsert(&permissionEntry->appInfo, &appInfo->node);
270             }
271         }
272     }
273     return permissionEntry;
274 }
275 
PrintAnonymousMessage(const char * src,const char * dest)276 static void PrintAnonymousMessage(const char *src, const char *dest)
277 {
278     char *tmpSrc = NULL;
279     char *tmpDest = NULL;
280     Anonymize(src, &tmpSrc);
281     Anonymize(dest, &tmpDest);
282     COMM_LOGD(COMM_PERM, "src=%{public}s, dest=%{public}s", AnonymizeWrapper(tmpSrc), AnonymizeWrapper(tmpDest));
283     AnonymizeFree(tmpSrc);
284     AnonymizeFree(tmpDest);
285 }
286 
CompareString(const char * src,const char * dest,bool regexp)287 int32_t CompareString(const char *src, const char *dest, bool regexp)
288 {
289     if (src == NULL || dest == NULL) {
290         return SOFTBUS_INVALID_PARAM;
291     }
292     if (regexp) {
293         regex_t regComp;
294         if (regcomp(&regComp, src, REG_EXTENDED | REG_NOSUB) != 0) {
295             COMM_LOGE(COMM_PERM, "regcomp failed");
296             return SOFTBUS_PERMISSION_DENIED;
297         }
298         if (regexec(&regComp, dest, 0, NULL, 0) == 0) {
299             PrintAnonymousMessage(src, dest);
300             regfree(&regComp);
301             return SOFTBUS_OK;
302         }
303         regfree(&regComp);
304     } else {
305         if (strcmp(src, dest) == 0) {
306             PrintAnonymousMessage(src, dest);
307             return SOFTBUS_OK;
308         }
309     }
310     return SOFTBUS_PERMISSION_DENIED;
311 }
312 
GetPermType(const SoftBusAppInfo * appInfo,const SoftBusPermissionItem * pItem)313 static int32_t GetPermType(const SoftBusAppInfo *appInfo, const SoftBusPermissionItem *pItem)
314 {
315     if (appInfo == NULL || pItem == NULL) {
316         return SOFTBUS_INVALID_PARAM;
317     }
318     switch (appInfo->type) {
319         case NATIVE_APP:
320             /* same as system app */
321         case SYSTEM_APP:
322             if (pItem->permType == SYSTEM_APP ||
323                 pItem->permType == NATIVE_APP) {
324                 return pItem->permType;
325             }
326             break;
327         case GRANTED_APP:
328             if (pItem->actions == ACTION_CREATE) {
329                 if (pItem->permType == SYSTEM_APP ||
330                     pItem->permType == NATIVE_APP ||
331                     pItem->permType == NORMAL_APP) {
332                     return pItem->permType;
333                 }
334             } else if (pItem->actions == ACTION_OPEN) {
335                 if (pItem->permType == GRANTED_APP) {
336                     return appInfo->type;
337                 }
338             }
339             break;
340         case NORMAL_APP:
341             if (pItem->permType == SYSTEM_APP ||
342                 pItem->permType == NATIVE_APP ||
343                 pItem->permType == NORMAL_APP) {
344                 return pItem->permType;
345             }
346             break;
347         case SELF_APP:
348             if (pItem->permType == SELF_APP) {
349                 return SELF_APP;
350             }
351             break;
352         default:
353             return SOFTBUS_INVALID_PARAM;
354     }
355     return SOFTBUS_PERMISSION_DENIED;
356 }
357 
CheckPermissionAppInfo(const SoftBusPermissionEntry * pe,const SoftBusPermissionItem * pItem)358 static int32_t CheckPermissionAppInfo(const SoftBusPermissionEntry *pe,
359     const SoftBusPermissionItem *pItem)
360 {
361     if (pe == NULL || pItem == NULL) {
362         COMM_LOGE(COMM_PERM, "invalid param");
363         return SOFTBUS_INVALID_PARAM;
364     }
365     if (pItem->actions == 0) {
366         COMM_LOGE(COMM_PERM, "permission denied");
367         return SOFTBUS_PERMISSION_DENIED;
368     }
369     int32_t permType;
370     SoftBusAppInfo *appInfo = NULL;
371     LIST_FOR_EACH_ENTRY(appInfo, &pe->appInfo, SoftBusAppInfo, node) {
372         if ((appInfo->actions & pItem->actions) != pItem->actions) {
373             continue;
374         }
375         permType = GetPermType(appInfo, pItem);
376         if (permType < 0) {
377             continue;
378         }
379         if ((appInfo->uid >= 0) && (appInfo->uid != pItem->uid)) {
380             continue;
381         }
382         if ((appInfo->pid >= 0) && (appInfo->pid != pItem->pid)) {
383             continue;
384         }
385         if (!StrIsEmpty(appInfo->pkgName)) {
386             if (!StrIsEmpty(pItem->pkgName) &&
387                 (CompareString(appInfo->pkgName, pItem->pkgName, false) != SOFTBUS_OK)) {
388                 continue;
389             }
390             if (appInfo->type == SYSTEM_APP || appInfo->type == NORMAL_APP) {
391                 return permType;
392             }
393         }
394         return permType;
395     }
396     char *tmpName = NULL;
397     Anonymize(pe->sessionName, &tmpName);
398     COMM_LOGE(COMM_PERM, "appinfo not find, sessionName=%{public}s", tmpName);
399     AnonymizeFree(tmpName);
400     return SOFTBUS_PERMISSION_DENIED;
401 }
402 
CheckDBinder(const char * sessionName)403 bool CheckDBinder(const char *sessionName)
404 {
405     if (StrIsEmpty(sessionName)) {
406         return false;
407     }
408     if (strcmp(DBINDER_SERVICE_NAME, sessionName) == 0) {
409         return true;
410     }
411     if (StrStartWith(sessionName, DBINDER_BUS_NAME_PREFIX)) {
412         return true;
413     }
414     return false;
415 }
416 
HaveGrantedPermission(const char * sessionName)417 static bool HaveGrantedPermission(const char *sessionName)
418 {
419     if (sessionName == NULL || g_dynamicPermissionList == NULL) {
420         return false;
421     }
422     SoftBusPermissionEntry *pe = NULL;
423     // The lock was acquired before being called
424     LIST_FOR_EACH_ENTRY(pe, &g_dynamicPermissionList->list, SoftBusPermissionEntry, node) {
425         if (CompareString(pe->sessionName, sessionName, pe->regexp) == SOFTBUS_OK) {
426             return true;
427         }
428     }
429     return false;
430 }
431 
LoadPermissionJson(const char * fileName)432 int32_t LoadPermissionJson(const char *fileName)
433 {
434     if (fileName == NULL) {
435         COMM_LOGE(COMM_PERM, "fileName is null.");
436         return SOFTBUS_INVALID_PARAM;
437     }
438     int ret = ReadConfigJson(fileName);
439     if (ret != SOFTBUS_OK) {
440         return ret;
441     }
442     if (g_permissionEntryList == NULL) {
443         g_permissionEntryList = CreateSoftBusList();
444         if (g_permissionEntryList == NULL) {
445             return SOFTBUS_MALLOC_ERR;
446         }
447     }
448     cJSON *jsonArray = cJSON_Parse(g_permissonJson);
449     if (jsonArray == NULL) {
450         COMM_LOGE(COMM_PERM, "parse failed. fileName=%{public}s", fileName);
451         return SOFTBUS_PARSE_JSON_ERR;
452     }
453     int itemNum = cJSON_GetArraySize(jsonArray);
454     if (itemNum <= 0) {
455         cJSON_Delete(jsonArray);
456         return SOFTBUS_PARSE_JSON_ERR;
457     }
458     int index;
459     SoftBusPermissionEntry *pe = NULL;
460     if (SoftBusMutexLock(&g_permissionEntryList->lock) != SOFTBUS_OK) {
461         COMM_LOGE(COMM_PERM, "lock fail.");
462         cJSON_Delete(jsonArray);
463         return SOFTBUS_LOCK_ERR;
464     }
465     for (index = 0; index < itemNum; index++) {
466         cJSON *permissionEntryObeject = cJSON_GetArrayItem(jsonArray, index);
467         pe = ProcessPermissionEntry(permissionEntryObeject);
468         if (pe != NULL) {
469             ListNodeInsert(&g_permissionEntryList->list, &pe->node);
470             g_permissionEntryList->cnt++;
471         }
472     }
473     (void)SoftBusMutexUnlock(&g_permissionEntryList->lock);
474     cJSON_Delete(jsonArray);
475     return SOFTBUS_OK;
476 }
477 
ClearAppInfo(const ListNode * appInfo)478 void ClearAppInfo(const ListNode *appInfo)
479 {
480     if (appInfo == NULL) {
481         return;
482     }
483     while (!IsListEmpty(appInfo)) {
484         SoftBusAppInfo *item = LIST_ENTRY(appInfo->next, SoftBusAppInfo, node);
485         ListDelete(&item->node);
486         SoftBusFree(item);
487     }
488 }
489 
DeinitPermissionJson(void)490 void DeinitPermissionJson(void)
491 {
492     if (g_permissionEntryList == NULL) {
493         return;
494     }
495     SoftBusMutexLock(&g_permissionEntryList->lock);
496     while (!IsListEmpty(&g_permissionEntryList->list)) {
497         SoftBusPermissionEntry *item = LIST_ENTRY((&g_permissionEntryList->list)->next, SoftBusPermissionEntry, node);
498         if (item == NULL) {
499             (void)SoftBusMutexUnlock(&g_permissionEntryList->lock);
500             COMM_LOGE(COMM_PERM, "get item is NULL");
501             return;
502         }
503         ClearAppInfo(&item->appInfo);
504         ListDelete(&item->node);
505         SoftBusFree(item);
506     }
507     (void)SoftBusMutexUnlock(&g_permissionEntryList->lock);
508     DestroySoftBusList(g_permissionEntryList);
509 }
510 
CreatePermissionItem(int32_t permType,int32_t uid,int32_t pid,const char * pkgName,uint32_t actions)511 SoftBusPermissionItem *CreatePermissionItem(int32_t permType, int32_t uid, int32_t pid,
512     const char *pkgName, uint32_t actions)
513 {
514     SoftBusPermissionItem *pItem = (SoftBusPermissionItem *)SoftBusCalloc(sizeof(SoftBusPermissionItem));
515     if (pItem == NULL) {
516         return NULL;
517     }
518     pItem->permType = permType;
519     pItem->uid = uid;
520     pItem->pid = pid;
521     pItem->pkgName = (char *)pkgName;
522     pItem->actions = actions;
523     return pItem;
524 }
525 
CheckPidAndUidDynamic(const SoftBusPermissionEntry * pe,const SoftBusPermissionItem * pItem)526 static int32_t CheckPidAndUidDynamic(const SoftBusPermissionEntry *pe, const SoftBusPermissionItem *pItem)
527 {
528     SoftBusAppInfo *appInfo = NULL;
529     LIST_FOR_EACH_ENTRY(appInfo, &pe->appInfo, SoftBusAppInfo, node) {
530         if (appInfo->uid == pItem->uid && appInfo->pid == pItem->pid) {
531             return GRANTED_APP;
532         }
533     }
534     if (appInfo == NULL) {
535         COMM_LOGE(COMM_PERM, "Linked list is empty");
536         return SOFTBUS_TRANS_SESSION_INFO_NOT_FOUND;
537     }
538     char *tmpName = NULL;
539     Anonymize(pe->sessionName, &tmpName);
540     COMM_LOGE(COMM_PERM,
541         "check fail,sessionName=%{public}s, pe->uid=%{public}d, pe->pid=%{public}d, uid=%{public}d, pid=%{public}d",
542         AnonymizeWrapper(tmpName), appInfo->uid, appInfo->pid, pItem->uid, pItem->pid);
543     AnonymizeFree(tmpName);
544     return SOFTBUS_PERMISSION_DENIED;
545 }
546 
CheckPermissionEntry(const char * sessionName,const SoftBusPermissionItem * pItem)547 int32_t CheckPermissionEntry(const char *sessionName, const SoftBusPermissionItem *pItem)
548 {
549     if (sessionName == NULL || pItem == NULL) {
550         COMM_LOGE(COMM_PERM, "INVALID PARAM");
551         return SOFTBUS_INVALID_PARAM;
552     }
553     int permType;
554     SoftBusPermissionEntry *pe = NULL;
555     char *tmpName = NULL;
556     bool isDynamicPermission = CheckDBinder(sessionName);
557     SoftBusList *permissionList = isDynamicPermission ? g_dynamicPermissionList : g_permissionEntryList;
558     if (permissionList == NULL) {
559         COMM_LOGE(COMM_PERM, "permissionList is NULL");
560         return SOFTBUS_INVALID_PARAM;
561     }
562     (void)SoftBusMutexLock(&permissionList->lock);
563     LIST_FOR_EACH_ENTRY(pe, &permissionList->list, SoftBusPermissionEntry, node) {
564         if (CompareString(pe->sessionName, sessionName, pe->regexp) == SOFTBUS_OK) {
565             if (isDynamicPermission) {
566                 permType = CheckPidAndUidDynamic(pe, pItem);
567                 (void)SoftBusMutexUnlock(&permissionList->lock);
568                 return permType;
569             }
570             permType = CheckPermissionAppInfo(pe, pItem);
571             if (permType < 0) {
572                 Anonymize(sessionName, &tmpName);
573                 COMM_LOGE(COMM_PERM, "permType is invalid, permType=%{public}d, sessionName=%{public}s",
574                     permType, tmpName);
575                 AnonymizeFree(tmpName);
576                 (void)SoftBusMutexUnlock(&permissionList->lock);
577                 return ENFORCING ? SOFTBUS_PERMISSION_DENIED : permType;
578             }
579             (void)SoftBusMutexUnlock(&permissionList->lock);
580             return permType;
581         }
582     }
583     if (pItem->permType != NORMAL_APP) {
584         Anonymize(sessionName, &tmpName);
585         COMM_LOGI(COMM_PERM, "permType is not normal, permType=%{public}d, sessionName=%{public}s",
586             pItem->permType, tmpName);
587         AnonymizeFree(tmpName);
588         (void)SoftBusMutexUnlock(&permissionList->lock);
589         return ENFORCING ? SOFTBUS_PERMISSION_DENIED : permType;
590     }
591     if (pItem->actions == ACTION_CREATE) {
592         if (IsValidPkgName(pItem->uid, pItem->pkgName) != SOFTBUS_OK) {
593             Anonymize(sessionName, &tmpName);
594             COMM_LOGE(COMM_PERM, "invalid param, sessionName=%{public}s", tmpName);
595             AnonymizeFree(tmpName);
596             (void)SoftBusMutexUnlock(&permissionList->lock);
597             return ENFORCING ? SOFTBUS_PERMISSION_DENIED : permType;
598         }
599         if (!StrStartWith(sessionName, pItem->pkgName)) {
600             Anonymize(sessionName, &tmpName);
601             COMM_LOGE(COMM_PERM, "invalid param, sessionName=%{public}s", tmpName);
602             AnonymizeFree(tmpName);
603             (void)SoftBusMutexUnlock(&permissionList->lock);
604             return ENFORCING ? SOFTBUS_PERMISSION_DENIED : permType;
605         }
606     }
607     (void)SoftBusMutexUnlock(&permissionList->lock);
608     return SOFTBUS_PERMISSION_DENIED;
609 }
610 
PermIsSecLevelPublic(const char * sessionName)611 bool PermIsSecLevelPublic(const char *sessionName)
612 {
613     if (sessionName == NULL) {
614         return false;
615     }
616     if (CheckDBinder(sessionName)) {
617         return true;
618     }
619     SoftBusPermissionEntry *pe = NULL;
620     bool ret = false;
621 
622     if (SoftBusMutexLock(&g_permissionEntryList->lock) != 0) {
623         return false;
624     }
625     LIST_FOR_EACH_ENTRY(pe, &g_permissionEntryList->list, SoftBusPermissionEntry, node) {
626         if (CompareString(pe->sessionName, sessionName, pe->regexp) == SOFTBUS_OK) {
627             if (pe->secLevel == LEVEL_PUBLIC) {
628                 ret = true;
629             }
630             break;
631         }
632     }
633     (void)SoftBusMutexUnlock(&g_permissionEntryList->lock);
634     char *tmpName = NULL;
635     Anonymize(sessionName, &tmpName);
636     COMM_LOGD(COMM_PERM, "sessionName=%{public}s, ret=%{public}d", AnonymizeWrapper(tmpName), ret);
637     AnonymizeFree(tmpName);
638     return ret;
639 }
640 
InitDynamicPermission(void)641 int32_t InitDynamicPermission(void)
642 {
643     if (g_dynamicPermissionList == NULL) {
644         g_dynamicPermissionList = CreateSoftBusList();
645         if (g_dynamicPermissionList == NULL) {
646             COMM_LOGI(COMM_PERM, "dynamic permission init failed");
647             return SOFTBUS_MALLOC_ERR;
648         }
649     }
650     return SOFTBUS_OK;
651 }
652 
NewDynamicPermissionEntry(SoftBusPermissionEntry * permissionEntry,const char * sessionName,int32_t callingUid,int32_t callingPid)653 static int32_t NewDynamicPermissionEntry(SoftBusPermissionEntry *permissionEntry, const char *sessionName,
654     int32_t callingUid, int32_t callingPid)
655 {
656     if (permissionEntry == NULL) {
657         COMM_LOGE(COMM_PERM, "permission entry is null");
658         return SOFTBUS_INVALID_PARAM;
659     }
660     if (sessionName == NULL) {
661         COMM_LOGE(COMM_PERM, "sessionName is null");
662         return SOFTBUS_INVALID_PARAM;
663     }
664     ListInit(&permissionEntry->node);
665     ListInit(&permissionEntry->appInfo);
666 
667     size_t length = strlen(sessionName);
668     if (length >= SESSION_NAME_SIZE_MAX) {
669         char *tmpName = NULL;
670         Anonymize(sessionName, &tmpName);
671         COMM_LOGE(COMM_PERM, "the length is too long. length=%{public}zd, sessionName=%{public}s",
672             length, AnonymizeWrapper(tmpName));
673         AnonymizeFree(tmpName);
674         return SOFTBUS_INVALID_PARAM;
675     }
676     if (strcpy_s(permissionEntry->sessionName, SESSION_NAME_SIZE_MAX, sessionName) != EOK) {
677         COMM_LOGE(COMM_PERM, "strcpy failed");
678         return SOFTBUS_STRCPY_ERR;
679     }
680     permissionEntry->regexp = false;
681     permissionEntry->devId = UNKNOWN_VALUE;
682     permissionEntry->secLevel = LEVEL_PUBLIC;
683 
684     SoftBusAppInfo *appInfo = (SoftBusAppInfo *)SoftBusCalloc(sizeof(SoftBusAppInfo));
685     if (appInfo == NULL) {
686         return SOFTBUS_MALLOC_ERR;
687     }
688     ListInit(&appInfo->node);
689     if (strcpy_s(appInfo->pkgName, PKG_NAME_SIZE_MAX, DBINDER_PACKAGE_NAME) != EOK) {
690         COMM_LOGE(COMM_PERM, "strcpy failed");
691         SoftBusFree(appInfo);
692         return SOFTBUS_STRCPY_ERR;
693     }
694     appInfo->type = GRANTED_APP;
695     appInfo->actions = ACTION_CREATE | ACTION_OPEN;
696     appInfo->uid = callingUid;
697     appInfo->pid = callingPid;
698     ListNodeInsert(&permissionEntry->appInfo, &appInfo->node);
699     return SOFTBUS_OK;
700 }
701 
AddDynamicPermission(int32_t callingUid,int32_t callingPid,const char * sessionName)702 int32_t AddDynamicPermission(int32_t callingUid, int32_t callingPid, const char *sessionName)
703 {
704     if (sessionName == NULL) {
705         COMM_LOGE(COMM_PERM, "sessionName is null");
706         return SOFTBUS_INVALID_PARAM;
707     }
708     SoftBusMutexLock(&g_dynamicPermissionList->lock);
709     if (g_dynamicPermissionList->cnt >= DYNAMIC_PERMISSION_MAX_SIZE) {
710         COMM_LOGE(COMM_PERM, "dynamic permission reach the upper limit");
711         (void)SoftBusMutexUnlock(&g_dynamicPermissionList->lock);
712         return SOFTBUS_NO_ENOUGH_DATA;
713     }
714 
715     if (HaveGrantedPermission(sessionName)) {
716         COMM_LOGD(COMM_PERM, "dynamic permission already granted");
717         (void)SoftBusMutexUnlock(&g_dynamicPermissionList->lock);
718         return SOFTBUS_OK;
719     }
720 
721     SoftBusPermissionEntry *permissionEntry = (SoftBusPermissionEntry *)SoftBusCalloc(sizeof(SoftBusPermissionEntry));
722     if (permissionEntry == NULL) {
723         COMM_LOGE(COMM_PERM, "AddDynamicPermission malloc failed!");
724         (void)SoftBusMutexUnlock(&g_dynamicPermissionList->lock);
725         return SOFTBUS_MALLOC_ERR;
726     }
727 
728     int32_t ret = NewDynamicPermissionEntry(permissionEntry, sessionName, callingUid, callingPid);
729     if (ret != SOFTBUS_OK) {
730         COMM_LOGE(COMM_PERM, "NewDynamicPermissionEntry failed. ret=%{public}d", ret);
731         SoftBusFree(permissionEntry);
732         (void)SoftBusMutexUnlock(&g_dynamicPermissionList->lock);
733         return ret;
734     }
735 
736     ListNodeInsert(&g_dynamicPermissionList->list, &permissionEntry->node);
737     g_dynamicPermissionList->cnt++;
738 
739     char *tmpName = NULL;
740     Anonymize(sessionName, &tmpName);
741     COMM_LOGD(COMM_PERM, "session dynamic permission granted. sessionName=%{public}s, count=%{public}d",
742         AnonymizeWrapper(tmpName), g_dynamicPermissionList->cnt);
743     AnonymizeFree(tmpName);
744     (void)SoftBusMutexUnlock(&g_dynamicPermissionList->lock);
745     return SOFTBUS_OK;
746 }
747 
DeleteDynamicPermission(const char * sessionName)748 int32_t DeleteDynamicPermission(const char *sessionName)
749 {
750     if (sessionName == NULL) {
751         COMM_LOGE(COMM_PERM, "sessionName is null");
752         return SOFTBUS_INVALID_PARAM;
753     }
754     SoftBusMutexLock(&g_dynamicPermissionList->lock);
755     SoftBusPermissionEntry *pe = NULL;
756     LIST_FOR_EACH_ENTRY(pe, &g_dynamicPermissionList->list, SoftBusPermissionEntry, node) {
757         if (CompareString(pe->sessionName, sessionName, pe->regexp) == SOFTBUS_OK) {
758             ClearAppInfo(&pe->appInfo);
759             ListDelete(&pe->node);
760             SoftBusFree(pe);
761             g_dynamicPermissionList->cnt--;
762             char *tmpName = NULL;
763             Anonymize(sessionName, &tmpName);
764             COMM_LOGI(COMM_PERM, "session dynamic permission deleted. sessionName=%{public}s, count=%{public}d",
765                 AnonymizeWrapper(tmpName), g_dynamicPermissionList->cnt);
766             AnonymizeFree(tmpName);
767             (void)SoftBusMutexUnlock(&g_dynamicPermissionList->lock);
768             return SOFTBUS_OK;
769         }
770     }
771     (void)SoftBusMutexUnlock(&g_dynamicPermissionList->lock);
772     return SOFTBUS_NOT_FIND;
773 }
774