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