• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
16 #include "uri_permission_utils.h"
17 
18 #include "ability_manager_errors.h"
19 #include "accesstoken_kit.h"
20 #include "bundle_mgr_client.h"
21 #include "global_constant.h"
22 #include "hilog_tag_wrapper.h"
23 #include "in_process_call_wrapper.h"
24 #include "ipc_skeleton.h"
25 #include "os_account_manager_wrapper.h"
26 #include "permission_verification.h"
27 #include "tokenid_kit.h"
28 
29 namespace OHOS {
30 namespace AAFwk {
31 namespace {
32 constexpr int32_t DEFAULT_USER_ID = 0;
33 constexpr int32_t API_VERSION_MOD = 100;
34 constexpr int32_t FOUNDATION_UID = 5523;
35 constexpr const char* NET_WORK_ID_MARK = "?networkid=";
36 }
37 
ConnectManagerHelper()38 std::shared_ptr<AppExecFwk::BundleMgrHelper> UPMSUtils::ConnectManagerHelper()
39 {
40     if (bundleMgrHelper_ == nullptr) {
41         bundleMgrHelper_ = DelayedSingleton<AppExecFwk::BundleMgrHelper>::GetInstance();
42     }
43     return bundleMgrHelper_;
44 }
45 
SendShareUnPrivilegeUriEvent(uint32_t callerTokenId,uint32_t targetTokenId)46 bool UPMSUtils::SendShareUnPrivilegeUriEvent(uint32_t callerTokenId, uint32_t targetTokenId)
47 {
48     std::string callerBundleName;
49     if (!GetBundleNameByTokenId(callerTokenId, callerBundleName)) {
50         return false;
51     }
52     std::string targetBundleName;
53     if (!GetBundleNameByTokenId(targetTokenId, targetBundleName)) {
54         return false;
55     }
56     AAFwk::EventInfo eventInfo;
57     eventInfo.callerBundleName = callerBundleName;
58     eventInfo.bundleName = targetBundleName;
59     TAG_LOGD(AAFwkTag::URIPERMMGR, "Send SHARE_UNPRIVILEGED_FILE_URI Event");
60     AAFwk::EventReport::SendGrantUriPermissionEvent(AAFwk::EventName::SHARE_UNPRIVILEGED_FILE_URI, eventInfo);
61     return true;
62 }
63 
SendSystemAppGrantUriPermissionEvent(uint32_t callerTokenId,uint32_t targetTokenId,const std::vector<Uri> & uriVec,const std::vector<bool> & resVec)64 bool UPMSUtils::SendSystemAppGrantUriPermissionEvent(uint32_t callerTokenId, uint32_t targetTokenId,
65     const std::vector<Uri> &uriVec, const std::vector<bool> &resVec)
66 {
67     TAG_LOGD(AAFwkTag::URIPERMMGR, "send grant uri permission event start.");
68     EventInfo eventInfo;
69     if (!CheckAndCreateEventInfo(callerTokenId, targetTokenId, eventInfo)) {
70         return false;
71     }
72     for (size_t i = 0; i < resVec.size(); i++) {
73         if (resVec[i]) {
74             eventInfo.uri = uriVec[i].ToString();
75             EventReport::SendGrantUriPermissionEvent(EventName::GRANT_URI_PERMISSION, eventInfo);
76         }
77     }
78     TAG_LOGD(AAFwkTag::URIPERMMGR, "send grant uri permission event end.");
79     return true;
80 }
81 
CheckAndCreateEventInfo(uint32_t callerTokenId,uint32_t targetTokenId,EventInfo & eventInfo)82 bool UPMSUtils::CheckAndCreateEventInfo(uint32_t callerTokenId, uint32_t targetTokenId,
83     EventInfo &eventInfo)
84 {
85     std::string callerBundleName;
86     if (!GetBundleNameByTokenId(callerTokenId, callerBundleName)) {
87         TAG_LOGD(AAFwkTag::URIPERMMGR, "get callerBundleName failed");
88         return false;
89     }
90     if (!CheckIsSystemAppByBundleName(callerBundleName)) {
91         TAG_LOGD(AAFwkTag::URIPERMMGR, "caller not system");
92         return false;
93     }
94     std::string targetBundleName;
95     if (!GetBundleNameByTokenId(targetTokenId, targetBundleName)) {
96         TAG_LOGD(AAFwkTag::URIPERMMGR, "get targetBundleName failed");
97         return false;
98     }
99     if (CheckIsSystemAppByBundleName(targetBundleName)) {
100         TAG_LOGD(AAFwkTag::URIPERMMGR, "target is systemApp");
101         return false;
102     }
103     eventInfo.callerBundleName = callerBundleName;
104     eventInfo.bundleName = targetBundleName;
105     return true;
106 }
107 
GetCurrentAccountId()108 int32_t UPMSUtils::GetCurrentAccountId()
109 {
110     std::vector<int32_t> osActiveAccountIds;
111     auto ret = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
112         QueryActiveOsAccountIds(osActiveAccountIds);
113     if (ret != ERR_OK) {
114         TAG_LOGE(AAFwkTag::URIPERMMGR, "QueryActiveOsAccountIds error. ret: %{public}d", ret);
115         return DEFAULT_USER_ID;
116     }
117     if (osActiveAccountIds.empty()) {
118         TAG_LOGE(AAFwkTag::URIPERMMGR, "QueryActiveOsAccountIds empty");
119         return DEFAULT_USER_ID;
120     }
121     TAG_LOGD(AAFwkTag::URIPERMMGR, "osActiveAccountId: %{public}d", osActiveAccountIds.front());
122     return osActiveAccountIds.front();
123 }
124 
IsFoundationCall()125 bool UPMSUtils::IsFoundationCall()
126 {
127     return IPCSkeleton::GetCallingUid() == FOUNDATION_UID;
128 }
129 
IsSAOrSystemAppCall()130 bool UPMSUtils::IsSAOrSystemAppCall()
131 {
132     return PermissionVerification::GetInstance()->IsSystemAppCall() ||
133         PermissionVerification::GetInstance()->IsSACall();
134 }
135 
IsSystemAppCall()136 bool UPMSUtils::IsSystemAppCall()
137 {
138     return PermissionVerification::GetInstance()->IsSystemAppCall();
139 }
140 
CheckIsSystemAppByBundleName(std::string & bundleName)141 bool UPMSUtils::CheckIsSystemAppByBundleName(std::string &bundleName)
142 {
143     auto bundleMgrHelper = ConnectManagerHelper();
144     if (bundleMgrHelper == nullptr) {
145         TAG_LOGW(AAFwkTag::URIPERMMGR, "bundleMgrHelper null");
146         return false;
147     }
148     AppExecFwk::ApplicationInfo appInfo;
149     if (!IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(bundleName,
150         AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, GetCurrentAccountId(), appInfo))) {
151         TAG_LOGW(AAFwkTag::URIPERMMGR, "GetApplicationInfo failed");
152         return false;
153     }
154     auto isSystemApp = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(appInfo.accessTokenIdEx);
155     TAG_LOGD(AAFwkTag::URIPERMMGR, "BundleName:%{public}s, isSystemApp:%{public}d", bundleName.c_str(),
156         static_cast<int32_t>(isSystemApp));
157     return isSystemApp;
158 }
159 
GetBundleApiTargetVersion(const std::string & bundleName,int32_t & targetApiVersion)160 bool UPMSUtils::GetBundleApiTargetVersion(const std::string &bundleName, int32_t &targetApiVersion)
161 {
162     auto bundleMgrHelper = ConnectManagerHelper();
163     if (bundleMgrHelper == nullptr) {
164         TAG_LOGW(AAFwkTag::URIPERMMGR, "The bundleMgrHelper is nullptr.");
165         return false;
166     }
167     AppExecFwk::ApplicationInfo appInfo;
168     if (!IN_PROCESS_CALL(bundleMgrHelper->GetApplicationInfo(bundleName,
169         AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, GetCurrentAccountId(), appInfo))) {
170         TAG_LOGI(AAFwkTag::URIPERMMGR, "Get application info failed.");
171         return false;
172     }
173     targetApiVersion = (appInfo.apiTargetVersion % API_VERSION_MOD);
174     return true;
175 }
176 
CheckIsSystemAppByTokenId(uint32_t tokenId)177 bool UPMSUtils::CheckIsSystemAppByTokenId(uint32_t tokenId)
178 {
179     std::string bundleName;
180     if (GetBundleNameByTokenId(tokenId, bundleName)) {
181         return CheckIsSystemAppByBundleName(bundleName);
182     }
183     return false;
184 }
185 
GetDirByBundleNameAndAppIndex(const std::string & bundleName,int32_t appIndex,std::string & dirName)186 bool UPMSUtils::GetDirByBundleNameAndAppIndex(const std::string &bundleName, int32_t appIndex, std::string &dirName)
187 {
188     auto bmsClient = DelayedSingleton<AppExecFwk::BundleMgrClient>::GetInstance();
189     if (bmsClient == nullptr) {
190         TAG_LOGE(AAFwkTag::URIPERMMGR, "bundleMgrClient is nullptr.");
191         return false;
192     }
193     auto bmsRet = IN_PROCESS_CALL(bmsClient->GetDirByBundleNameAndAppIndex(bundleName, appIndex, dirName));
194     if (bmsRet != ERR_OK) {
195         TAG_LOGE(AAFwkTag::URIPERMMGR, "GetDirByBundleNameAndAppIndex failed, ret:%{public}d", bmsRet);
196         return false;
197     }
198     return true;
199 }
200 
GetAlterableBundleNameByTokenId(uint32_t tokenId,std::string & bundleName)201 bool UPMSUtils::GetAlterableBundleNameByTokenId(uint32_t tokenId, std::string &bundleName)
202 {
203     auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
204     if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
205         Security::AccessToken::HapTokenInfo hapInfo;
206         auto ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo);
207         if (ret != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
208             TAG_LOGE(AAFwkTag::URIPERMMGR, "GetHapTokenInfo failed, ret:%{public}d", ret);
209             return false;
210         }
211         return GetDirByBundleNameAndAppIndex(hapInfo.bundleName, hapInfo.instIndex, bundleName);
212     }
213     return false;
214 }
215 
GetBundleNameByTokenId(uint32_t tokenId,std::string & bundleName)216 bool UPMSUtils::GetBundleNameByTokenId(uint32_t tokenId, std::string &bundleName)
217 {
218     auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
219     if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) {
220         Security::AccessToken::HapTokenInfo hapInfo;
221         auto ret = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo);
222         if (ret != Security::AccessToken::AccessTokenKitRet::RET_SUCCESS) {
223             TAG_LOGE(AAFwkTag::URIPERMMGR, "GetHapTokenInfo failed, ret:%{public}d", ret);
224             return false;
225         }
226         bundleName = hapInfo.bundleName;
227         return true;
228     }
229     return false;
230 }
231 
GetAppIdByBundleName(const std::string & bundleName,std::string & appId)232 int32_t UPMSUtils::GetAppIdByBundleName(const std::string &bundleName, std::string &appId)
233 {
234     TAG_LOGD(AAFwkTag::URIPERMMGR, "BundleName is %{public}s.", bundleName.c_str());
235     auto bms = ConnectManagerHelper();
236     if (bms == nullptr) {
237         TAG_LOGW(AAFwkTag::URIPERMMGR, "The bundleMgrHelper is nullptr.");
238         return GET_BUNDLE_MANAGER_SERVICE_FAILED;
239     }
240     auto userId = GetCurrentAccountId();
241     appId = IN_PROCESS_CALL(bms->GetAppIdByBundleName(bundleName, userId));
242     if (appId.empty()) {
243         TAG_LOGW(AAFwkTag::URIPERMMGR, "Get appId by bundle name failed, userId is %{private}d", userId);
244         return INNER_ERR;
245     }
246     return ERR_OK;
247 }
248 
GetTokenIdByBundleName(const std::string & bundleName,int32_t appIndex,uint32_t & tokenId)249 int32_t UPMSUtils::GetTokenIdByBundleName(const std::string &bundleName, int32_t appIndex, uint32_t &tokenId)
250 {
251     TAG_LOGD(AAFwkTag::URIPERMMGR, "BundleName:%{public}s, appIndex:%{public}d", bundleName.c_str(), appIndex);
252     auto bms = ConnectManagerHelper();
253     if (bms == nullptr) {
254         TAG_LOGW(AAFwkTag::URIPERMMGR, "null bms");
255         return GET_BUNDLE_MANAGER_SERVICE_FAILED;
256     }
257     AppExecFwk::BundleInfo bundleInfo;
258     auto userId = GetCurrentAccountId();
259     if (appIndex == 0) {
260         auto bundleFlag = AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO;
261         if (!IN_PROCESS_CALL(bms->GetBundleInfo(bundleName, bundleFlag, bundleInfo, userId))) {
262             TAG_LOGW(AAFwkTag::URIPERMMGR, "Failed GetBundleInfo");
263             return ERR_GET_TARGET_BUNDLE_INFO_FAILED;
264         }
265         tokenId = bundleInfo.applicationInfo.accessTokenId;
266         return ERR_OK;
267     }
268     if (appIndex <= AbilityRuntime::GlobalConstant::MAX_APP_CLONE_INDEX) {
269         auto bundleFlag = static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION);
270         if (IN_PROCESS_CALL(bms->GetCloneBundleInfo(bundleName, bundleFlag, appIndex, bundleInfo, userId)) != ERR_OK) {
271             TAG_LOGW(AAFwkTag::URIPERMMGR, "Failed GetCloneBundleInfo");
272             return ERR_GET_TARGET_BUNDLE_INFO_FAILED;
273         }
274         tokenId = bundleInfo.applicationInfo.accessTokenId;
275         return ERR_OK;
276     }
277     if (IN_PROCESS_CALL(bms->GetSandboxBundleInfo(bundleName, appIndex, userId, bundleInfo) != ERR_OK)) {
278         TAG_LOGW(AAFwkTag::URIPERMMGR, "Failed GetSandboxBundleInfo");
279         return ERR_GET_TARGET_BUNDLE_INFO_FAILED;
280     }
281     tokenId = bundleInfo.applicationInfo.accessTokenId;
282     return ERR_OK;
283 }
284 
CheckUriTypeIsValid(Uri & uri)285 bool UPMSUtils::CheckUriTypeIsValid(Uri &uri)
286 {
287     auto &&scheme = uri.GetScheme();
288     if (scheme != "file" && scheme != "content") {
289         TAG_LOGW(AAFwkTag::URIPERMMGR, "uri invalid: %{public}s-%{private}s", scheme.c_str(), uri.ToString().c_str());
290         return false;
291     }
292     return true;
293 }
294 
IsDocsCloudUri(Uri & uri)295 bool UPMSUtils::IsDocsCloudUri(Uri &uri)
296 {
297     return (uri.GetAuthority() == "docs" && uri.ToString().find(NET_WORK_ID_MARK) != std::string::npos);
298 }
299 
300 std::shared_ptr<AppExecFwk::BundleMgrHelper> UPMSUtils::bundleMgrHelper_ = nullptr;
301 }  // namespace AAFwk
302 }  // namespace OHOS
303