• 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 
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