1 /*
2  * Copyright (C) 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_utils.h"
17 
18 #include "accesstoken_kit.h"
19 #include "ipc_skeleton.h"
20 #include "iservice_registry.h"
21 #include "privacy_kit.h"
22 #include "ringtone_log.h"
23 #include "ringtone_tracer.h"
24 #include "system_ability_definition.h"
25 #include "tokenid_kit.h"
26 
27 namespace OHOS {
28 namespace Media {
29 using namespace std;
30 using namespace OHOS::Security::AccessToken;
31 using namespace OHOS::AppExecFwk::Constants;
32 
33 sptr<AppExecFwk::IBundleMgr> RingtonePermissionUtils::bundleManager_ = nullptr;
34 mutex RingtonePermissionUtils::bundleManagerMutex_;
GetSysBundleManager()35 sptr<AppExecFwk::IBundleMgr> RingtonePermissionUtils::GetSysBundleManager()
36 {
37     if (bundleManager_ != nullptr) {
38         return bundleManager_;
39     }
40 
41     lock_guard<mutex> lock(bundleManagerMutex_);
42     if (bundleManager_ != nullptr) {
43         return bundleManager_;
44     }
45 
46     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
47     if (systemAbilityManager == nullptr) {
48         RINGTONE_ERR_LOG("Failed to get SystemAbilityManager.");
49         return nullptr;
50     }
51 
52     auto bundleObj = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
53     if (bundleObj == nullptr) {
54         RINGTONE_ERR_LOG("Remote object is nullptr.");
55         return nullptr;
56     }
57 
58     auto bundleManager = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
59     if (bundleManager == nullptr) {
60         RINGTONE_ERR_LOG("Failed to iface_cast");
61         return nullptr;
62     }
63     bundleManager_ = bundleManager;
64 
65     return bundleManager_;
66 }
67 
GetClientBundle(const int uid,string & bundleName)68 void RingtonePermissionUtils::GetClientBundle(const int uid, string &bundleName)
69 {
70     bundleManager_ = GetSysBundleManager();
71     if (bundleManager_ == nullptr) {
72         bundleName = "";
73         return;
74     }
75     auto result = bundleManager_->GetBundleNameForUid(uid, bundleName);
76     if (!result) {
77         RINGTONE_ERR_LOG("GetBundleNameForUid fail");
78         bundleName = "";
79     }
80 }
81 
CheckCallerPermission(const string & permission)82 bool RingtonePermissionUtils::CheckCallerPermission(const string &permission)
83 {
84     RingtoneTracer tracer;
85     tracer.Start("CheckCallerPermission");
86 
87     AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID();
88     int result = AccessTokenKit::VerifyAccessToken(tokenCaller, permission);
89     if (result != PermissionState::PERMISSION_GRANTED) {
90         RINGTONE_ERR_LOG("Have no media permission: %{public}s", permission.c_str());
91         return false;
92     }
93     return true;
94 }
95 
96 /* Check whether caller has at least one of @permsVec */
CheckHasPermission(const vector<string> & permsVec)97 bool RingtonePermissionUtils::CheckHasPermission(const vector<string> &permsVec)
98 {
99     if (permsVec.empty()) {
100         return false;
101     }
102 
103     for (const auto &perm : permsVec) {
104         if (CheckCallerPermission(perm)) {
105             return true;
106         }
107     }
108 
109     return false;
110 }
111 
GetPackageNameByBundleName(const string & bundleName)112 string RingtonePermissionUtils::GetPackageNameByBundleName(const string &bundleName)
113 {
114     const static int32_t  invalidUid = -1;
115     const static int32_t baseUserRange = 200000;
116 
117     int uid = IPCSkeleton::GetCallingUid();
118     if (uid <= invalidUid) {
119         RINGTONE_ERR_LOG("Get invalidUid UID %{public}d", uid);
120         return "";
121     }
122     int32_t userId = uid / baseUserRange;
123     RINGTONE_DEBUG_LOG("uid:%{private}d, userId:%{private}d", uid, userId);
124 
125     AAFwk::Want want;
126     auto bundleManager_ = GetSysBundleManager();
127     if (bundleManager_ == nullptr) {
128         RINGTONE_ERR_LOG("Get BundleManager failed");
129         return "";
130     }
131     int ret = bundleManager_->GetLaunchWantForBundle(bundleName, want, userId);
132     if (ret != ERR_OK) {
133         RINGTONE_ERR_LOG("Can not get bundleName by want, err=%{public}d, userId=%{private}d",
134             ret, userId);
135         return "";
136     }
137     string abilityName = want.GetOperation().GetAbilityName();
138     return bundleManager_->GetAbilityLabel(bundleName, abilityName);
139 }
140 
141 /* Check whether caller has all the @permsVec */
CheckCallerPermission(const vector<string> & permsVec)142 bool RingtonePermissionUtils::CheckCallerPermission(const vector<string> &permsVec)
143 {
144     if (permsVec.empty()) {
145         return false;
146     }
147 
148     for (const auto &perm : permsVec) {
149         if (!CheckCallerPermission(perm)) {
150             return false;
151         }
152     }
153     return true;
154 }
155 
GetTokenId()156 uint32_t RingtonePermissionUtils::GetTokenId()
157 {
158     return IPCSkeleton::GetCallingTokenID();
159 }
160 
IsSystemApp()161 bool RingtonePermissionUtils::IsSystemApp()
162 {
163     uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
164     return TokenIdKit::IsSystemAppByFullTokenID(tokenId);
165 }
166 
CheckIsSystemAppByUid()167 bool RingtonePermissionUtils::CheckIsSystemAppByUid()
168 {
169     int uid = IPCSkeleton::GetCallingUid();
170     bundleManager_ = GetSysBundleManager();
171     if (bundleManager_ == nullptr) {
172         RINGTONE_ERR_LOG("Can not get bundleMgr");
173         return false;
174     }
175     return bundleManager_->CheckIsSystemAppByUid(uid);
176 }
177 
IsNativeSAApp()178 bool RingtonePermissionUtils::IsNativeSAApp()
179 {
180     uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
181     ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
182     RINGTONE_DEBUG_LOG("check if native sa token, tokenId:%{public}d, tokenType:%{public}d", tokenId, tokenType);
183     if (tokenType == ATokenTypeEnum::TOKEN_NATIVE) {
184         return true;
185     }
186     return false;
187 }
188 }  // namespace Media
189 }  // namespace OHOS
190