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