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
87 #ifdef OHOS_DEBUG
ShouldAddPermissionRecord(const AccessTokenID & token)88 bool inline ShouldAddPermissionRecord(const AccessTokenID &token)
89 {
90 return (AccessTokenKit::GetTokenTypeFlag(token) == TOKEN_HAP);
91 }
92
AddPermissionRecord(const AccessTokenID & token,const string & perm,const bool permGranted)93 void AddPermissionRecord(const AccessTokenID &token, const string &perm, const bool permGranted)
94 {
95 if (!ShouldAddPermissionRecord(token)) {
96 return;
97 }
98
99 int res = PrivacyKit::AddPermissionUsedRecord(token, perm, !!permGranted, !permGranted);
100 if (res != 0) {
101 /* Failed to add permission used record, not fatal */
102 MEDIA_WARN_LOG("Failed to add permission used record: %{public}s, permGranted: %{public}d, err: %{public}d",
103 perm.c_str(), permGranted, res);
104 }
105 }
106 #endif
107
CheckCallerPermission(const string & permission)108 bool PermissionUtils::CheckCallerPermission(const string &permission)
109 {
110 MediaLibraryTracer tracer;
111 tracer.Start("CheckCallerPermission");
112
113 AccessTokenID tokenCaller = IPCSkeleton::GetCallingTokenID();
114 int res = AccessTokenKit::VerifyAccessToken(tokenCaller, permission);
115 if (res != PermissionState::PERMISSION_GRANTED) {
116 MEDIA_ERR_LOG("Have no media permission: %{public}s", permission.c_str());
117 #ifdef OHOS_DEBUG
118 AddPermissionRecord(tokenCaller, permission, false);
119 #endif
120 return false;
121 }
122 #ifdef OHOS_DEBUG
123 AddPermissionRecord(tokenCaller, permission, true);
124 #endif
125
126 return true;
127 }
128
CheckNapiCallerPermission(const std::string & permission)129 bool PermissionUtils::CheckNapiCallerPermission(const std::string &permission)
130 {
131 MediaLibraryTracer tracer;
132 tracer.Start("CheckNapiCallerPermission");
133
134 AccessTokenID tokenCaller = IPCSkeleton::GetSelfTokenID();
135 int res = AccessTokenKit::VerifyAccessToken(tokenCaller, permission);
136 if (res != PermissionState::PERMISSION_GRANTED) {
137 MEDIA_ERR_LOG("Have no media permission: %{public}s", permission.c_str());
138 return false;
139 }
140
141 return true;
142 }
143
144 /* Check whether caller has at least one of @perms */
CheckHasPermission(const vector<string> & perms)145 bool PermissionUtils::CheckHasPermission(const vector<string> &perms)
146 {
147 if (perms.empty()) {
148 return false;
149 }
150
151 for (const auto &perm : perms) {
152 if (CheckCallerPermission(perm)) {
153 return true;
154 }
155 }
156
157 return false;
158 }
159
160 /* Check whether caller has all the @perms */
CheckCallerPermission(const vector<string> & perms)161 bool PermissionUtils::CheckCallerPermission(const vector<string> &perms)
162 {
163 if (perms.empty()) {
164 return false;
165 }
166
167 for (const auto &perm : perms) {
168 if (!CheckCallerPermission(perm)) {
169 return false;
170 }
171 }
172 return true;
173 }
174
GetTokenId()175 uint32_t PermissionUtils::GetTokenId()
176 {
177 return IPCSkeleton::GetCallingTokenID();
178 }
179
IsSystemApp()180 bool PermissionUtils::IsSystemApp()
181 {
182 uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
183 return TokenIdKit::IsSystemAppByFullTokenID(tokenId);
184 }
185
CheckIsSystemAppByUid()186 bool PermissionUtils::CheckIsSystemAppByUid()
187 {
188 int uid = IPCSkeleton::GetCallingUid();
189 bundleMgr_ = GetSysBundleManager();
190 if (bundleMgr_ == nullptr) {
191 MEDIA_ERR_LOG("Can not get bundleMgr");
192 return false;
193 }
194 return bundleMgr_->CheckIsSystemAppByUid(uid);
195 }
196
IsNativeSAApp()197 bool PermissionUtils::IsNativeSAApp()
198 {
199 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
200 ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
201 MEDIA_DEBUG_LOG("check if native sa token, tokenId:%{public}d, tokenType:%{public}d",
202 tokenId, tokenType);
203 if (tokenType == ATokenTypeEnum::TOKEN_NATIVE) {
204 return true;
205 }
206 return false;
207 }
208
GetPackageNameByBundleName(const string & bundleName)209 string PermissionUtils::GetPackageNameByBundleName(const string &bundleName)
210 {
211 const static int32_t INVALID_UID = -1;
212 const static int32_t BASE_USER_RANGE = 200000;
213
214 int uid = IPCSkeleton::GetCallingUid();
215 if (uid <= INVALID_UID) {
216 MEDIA_ERR_LOG("Get INVALID_UID UID %{public}d", uid);
217 return "";
218 }
219 int32_t userId = uid / BASE_USER_RANGE;
220 MEDIA_DEBUG_LOG("uid:%{private}d, userId:%{private}d", uid, userId);
221
222 AAFwk::Want want;
223 auto bundleMgr_ = GetSysBundleManager();
224 if (bundleMgr_ == nullptr) {
225 MEDIA_ERR_LOG("Get BundleManager failed");
226 return "";
227 }
228 int ret = bundleMgr_->GetLaunchWantForBundle(bundleName, want, userId);
229 if (ret != ERR_OK) {
230 MEDIA_ERR_LOG("Can not get bundleName by want, err=%{public}d, userId=%{private}d",
231 ret, userId);
232 return "";
233 }
234 string abilityName = want.GetOperation().GetAbilityName();
235 return bundleMgr_->GetAbilityLabel(bundleName, abilityName);
236 }
237 } // namespace Media
238 } // namespace OHOS
239