• 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 "accesstoken_kit.h"
20 #include "ipc_skeleton.h"
21 #include "media_log.h"
22 #include "medialibrary_tracer.h"
23 #include "privacy_kit.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.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> PermissionUtils::bundleMgr_ = nullptr;
34 mutex PermissionUtils::bundleMgrMutex_;
35 
GetSysBundleManager()36 sptr<AppExecFwk::IBundleMgr> PermissionUtils::GetSysBundleManager()
37 {
38     if (bundleMgr_ != nullptr) {
39         return bundleMgr_;
40     }
41 
42     lock_guard<mutex> lock(bundleMgrMutex_);
43     if (bundleMgr_ != nullptr) {
44         return bundleMgr_;
45     }
46 
47     auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
48     if (systemAbilityMgr == nullptr) {
49         MEDIA_ERR_LOG("Failed to get SystemAbilityManager.");
50         return nullptr;
51     }
52 
53     auto bundleObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
54     if (bundleObj == nullptr) {
55         MEDIA_ERR_LOG("Remote object is nullptr.");
56         return nullptr;
57     }
58 
59     auto bundleMgr = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
60     if (bundleMgr == nullptr) {
61         MEDIA_ERR_LOG("Failed to iface_cast");
62         return nullptr;
63     }
64     bundleMgr_ = bundleMgr;
65 
66     return bundleMgr_;
67 }
68 
GetClientBundle(const int uid,string & bundleName,bool & isSystemApp)69 void PermissionUtils::GetClientBundle(const int uid, string &bundleName, bool &isSystemApp)
70 {
71     bundleMgr_ = GetSysBundleManager();
72     if (bundleMgr_ == nullptr) {
73         bundleName = "";
74         isSystemApp = false;
75         return;
76     }
77     auto result = bundleMgr_->GetBundleNameForUid(uid, bundleName);
78     if (!result) {
79         MEDIA_ERR_LOG("GetBundleNameForUid fail");
80         bundleName = "";
81     }
82     isSystemApp = bundleMgr_->CheckIsSystemAppByUid(uid);
83 }
84 
85 #ifdef OHOS_DEBUG
ShouldAddPermissionRecord(const AccessTokenID & token)86 bool inline ShouldAddPermissionRecord(const AccessTokenID &token)
87 {
88     return (AccessTokenKit::GetTokenTypeFlag(token) == TOKEN_HAP);
89 }
90 
AddPermissionRecord(const AccessTokenID & token,const string & perm,const bool permGranted)91 void AddPermissionRecord(const AccessTokenID &token, const string &perm, const bool permGranted)
92 {
93     if (!ShouldAddPermissionRecord(token)) {
94         return;
95     }
96 
97     int res = PrivacyKit::AddPermissionUsedRecord(token, perm, !!permGranted, !permGranted);
98     if (res != 0) {
99         /* Failed to add permission used record, not fatal */
100         MEDIA_WARN_LOG("Failed to add permission used record: %{public}s, permGranted: %{public}d, err: %{public}d",
101             perm.c_str(), permGranted, res);
102     }
103 }
104 #endif
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("MediaLibraryDataManager Query: Have no media permission: %{public}s", permission.c_str());
115 #ifdef OHOS_DEBUG
116         AddPermissionRecord(tokenCaller, permission, false);
117 #endif
118         return false;
119     }
120 #ifdef OHOS_DEBUG
121     AddPermissionRecord(tokenCaller, permission, true);
122 #endif
123 
124     return true;
125 }
126 
CheckCallerPermission(const std::array<std::string,PERM_GRP_SIZE> & perms,const uint32_t typeMask)127 bool PermissionUtils::CheckCallerPermission(const std::array<std::string, PERM_GRP_SIZE> &perms,
128     const uint32_t typeMask)
129 {
130     MediaLibraryTracer tracer;
131     tracer.Start("CheckCallerPermissionWithTypeMask");
132 
133     if (typeMask == 0) {
134         return false;
135     }
136 
137     uint32_t resultMask = 0;
138     for (auto &perm : perms) {
139         uint32_t bit = static_cast<uint32_t>(PERM_MASK_MAP.at(perm));
140         if ((bit & typeMask)) {
141             if (PermissionUtils::CheckCallerPermission(perm)) {
142                 resultMask |= bit;
143             } else {
144                 return false;
145             }
146         }
147     }
148     /*
149      * Grant if all non-zero bit in typeMask passed permission check,
150      * in that case, resultMask should be the same with typeMask
151      */
152     if (resultMask == typeMask) {
153         return true;
154     }
155 
156     return false;
157 }
158 }  // namespace Media
159 }  // namespace OHOS
160