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