• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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