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