1 /*
2  * Copyright (c) 2022-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 
16 #include "permission_checker.h"
17 
18 #include "accesstoken_kit.h"
19 #include "avsession_log.h"
20 #include "ipc_skeleton.h"
21 #include "bundle_mgr_client.h"
22 #include "tokenid_kit.h"
23 #include "avsession_errors.h"
24 
25 namespace OHOS::AVSession {
26 using namespace Security::AccessToken;
27 using AppExecFwk::BundleMgrClient;
28 
GetInstance()29 PermissionChecker& PermissionChecker::GetInstance()
30 {
31     static PermissionChecker permissionChecker;
32     return permissionChecker;
33 }
34 
CheckSystemPermission(Security::AccessToken::AccessTokenID tokenId)35 int32_t PermissionChecker::CheckSystemPermission(Security::AccessToken::AccessTokenID tokenId)
36 {
37     if (AccessTokenKit::GetTokenTypeFlag(tokenId) == TOKEN_NATIVE) {
38         return ERR_NONE;
39     }
40 
41     if (IsSystemApp()) {
42         return ERR_NONE;
43     }
44 
45     SLOGE("Check system permission faild");
46     return ERR_NO_PERMISSION;
47 }
48 
CheckPermission(int32_t checkPermissionType)49 int32_t PermissionChecker::CheckPermission(int32_t checkPermissionType)
50 {
51     Security::AccessToken::AccessTokenID callerToken = OHOS::IPCSkeleton::GetCallingTokenID();
52     if (AccessTokenKit::GetTokenTypeFlag(callerToken) == TOKEN_SHELL) {
53         return ERR_NONE;
54     }
55     switch (checkPermissionType) {
56         case CHECK_SYSTEM_PERMISSION:
57             return CheckSystemPermission(callerToken);
58         case CHECK_MEDIA_RESOURCES_PERMISSION: {
59             int32_t ret = CheckSystemPermission(callerToken);
60             if (ret == ERR_NO_PERMISSION) {
61                 return ret;
62             }
63             return CheckMediaResourcePermission(callerToken, std::string(MANAGE_MEDIA_RESOURCES));
64         }
65         default:
66             return ERR_NO_PERMISSION;
67     }
68 }
69 
CheckMediaResourcePermission(Security::AccessToken::AccessTokenID callerToken,std::string permissionName)70 int32_t PermissionChecker::CheckMediaResourcePermission(
71     Security::AccessToken::AccessTokenID callerToken, std::string permissionName)
72 {
73     const std::string &permission = permissionName;
74     int32_t ret = AccessTokenKit::VerifyAccessToken(callerToken, permission);
75     if (ret == PermissionState::PERMISSION_DENIED) {
76         SLOGE("Check media resources permission failed.");
77         return ERR_PERMISSION_DENIED;
78     }
79     return ERR_NONE;
80 }
81 
IsSystemApp()82 bool PermissionChecker::IsSystemApp()
83 {
84     uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
85     return TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
86 }
87 
CheckSystemPermissionByUid(int uid)88 bool PermissionChecker::CheckSystemPermissionByUid(int uid)
89 {
90     BundleMgrClient client;
91     std::string bundleName;
92     std::string identity = OHOS::IPCSkeleton::ResetCallingIdentity();
93     if (client.GetNameForUid(uid, bundleName) != OHOS::ERR_OK) {
94         return true;
95     }
96     OHOS::IPCSkeleton::SetCallingIdentity(identity);
97 
98     AccessTokenIDEx accessTokenIdEx = AccessTokenKit::GetHapTokenIDEx(uid / UID_TRANSFORM_DIVISOR, bundleName, 0);
99     auto tokenId = accessTokenIdEx.tokenIdExStruct.tokenID;
100     if (tokenId == INVALID_TOKENID) {
101         SLOGE("get token id failed");
102         return false;
103     }
104     if (AccessTokenKit::GetTokenTypeFlag(tokenId) == TOKEN_NATIVE) {
105         return true;
106     }
107 
108     if (AccessTokenKit::GetTokenTypeFlag(tokenId) == TOKEN_SHELL) {
109         return true;
110     }
111     bool isSystemApp = TokenIdKit::IsSystemAppByFullTokenID(accessTokenIdEx.tokenIDEx);
112     if (!isSystemApp) {
113         SLOGI("CheckSystemPermissionByUid Not system app");
114         return false;
115     }
116     SLOGD("CheckSystemPermissionByUid is system app done");
117     return true;
118 }
119 } // namespace OHOS::AVSession
120