1 /*
2 * Copyright (c) 2022-2023 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 "distributed_bms.h"
17
18 #include <fstream>
19 #include <vector>
20
21 #include "accesstoken_kit.h"
22 #include "account_manager_helper.h"
23 #include "app_log_wrapper.h"
24 #include "appexecfwk_errors.h"
25 #include "bundle_mgr_interface.h"
26 #include "bundle_mgr_proxy.h"
27 #include "distributed_bms_proxy.h"
28 #include "distributed_data_storage.h"
29 #include "event_report.h"
30 #include "iservice_registry.h"
31 #include "if_system_ability_manager.h"
32 #include "locale_config.h"
33 #include "locale_info.h"
34 #include "image_compress.h"
35 #ifdef DISTRIBUTED_BUNDLE_IMAGE_ENABLE
36 #include "image_packer.h"
37 #include "image_source.h"
38 #endif
39 #include "ipc_skeleton.h"
40 #include "system_ability_definition.h"
41 #include "tokenid_kit.h"
42 #ifdef HICOLLIE_ENABLE
43 #include "xcollie/xcollie.h"
44 #include "xcollie/xcollie_define.h"
45 #endif
46
47 namespace OHOS {
48 namespace AppExecFwk {
49 namespace {
50 #ifdef HICOLLIE_ENABLE
51 const unsigned int LOCAL_TIME_OUT_SECONDS = 5;
52 const unsigned int REMOTE_TIME_OUT_SECONDS = 10;
53 #endif
54 const uint8_t DECODE_VALUE_ONE = 1;
55 const uint8_t DECODE_VALUE_TWO = 2;
56 const uint8_t DECODE_VALUE_THREE = 3;
57 const unsigned char DECODE_VALUE_CHAR_THREE = 3;
58 const uint8_t DECODE_VALUE_FOUR = 4;
59 const uint8_t DECODE_VALUE_SIX = 6;
60 const unsigned char DECODE_VALUE_CHAR_FIFTEEN = 15;
61 const unsigned char DECODE_VALUE_CHAR_SIXTY_THREE = 63;
62 const std::vector<char> DECODE_TABLE = {
63 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
64 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
65 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
66 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
67 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
68 };
69 const std::string POSTFIX = "_Compress.";
70 #ifdef HISYSEVENT_ENABLE
GetEventInfo(const std::vector<ElementName> & elements,const std::string & localeInfo,int32_t resultCode)71 DBMSEventInfo GetEventInfo(
72 const std::vector<ElementName> &elements, const std::string &localeInfo, int32_t resultCode)
73 {
74 DBMSEventInfo eventInfo;
75 if (elements.empty()) {
76 return eventInfo;
77 }
78
79 eventInfo.deviceID = elements[0].GetDeviceID();
80 eventInfo.localeInfo = localeInfo;
81 for (auto element : elements) {
82 if (eventInfo.bundleName.empty()) {
83 eventInfo.bundleName.append(element.GetBundleName());
84 } else {
85 eventInfo.bundleName.append(";").append(element.GetBundleName());
86 }
87
88 if (eventInfo.abilityName.empty()) {
89 eventInfo.abilityName.append(element.GetAbilityName());
90 } else {
91 eventInfo.abilityName.append(";").append(element.GetAbilityName());
92 }
93 }
94
95 eventInfo.resultCode = resultCode;
96 return eventInfo;
97 }
98
GetEventInfo(const ElementName & element,const std::string & localeInfo,int32_t resultCode)99 DBMSEventInfo GetEventInfo(
100 const ElementName &element, const std::string &localeInfo, int32_t resultCode)
101 {
102 DBMSEventInfo eventInfo;
103 eventInfo.bundleName = element.GetBundleName();
104 eventInfo.abilityName = element.GetAbilityName();
105 eventInfo.deviceID = element.GetDeviceID();
106 eventInfo.localeInfo = localeInfo;
107 eventInfo.resultCode = resultCode;
108 return eventInfo;
109 }
110 #endif
111 }
112 const bool REGISTER_RESULT =
113 SystemAbility::MakeAndRegisterAbility(DelayedSingleton<DistributedBms>::GetInstance().get());
114
DistributedBms()115 DistributedBms::DistributedBms() : SystemAbility(DISTRIBUTED_BUNDLE_MGR_SERVICE_SYS_ABILITY_ID, true)
116 {
117 APP_LOGI("DistributedBms :%{public}s call", __func__);
118 }
119
~DistributedBms()120 DistributedBms::~DistributedBms()
121 {
122 APP_LOGI("DistributedBms: DBundleMgrService");
123 }
124
OnStart()125 void DistributedBms::OnStart()
126 {
127 APP_LOGI("DistributedBms: OnStart");
128 Init();
129 bool res = Publish(this);
130 if (!res) {
131 APP_LOGE("DistributedBms: OnStart failed");
132 }
133 APP_LOGI("DistributedBms: OnStart end");
134 }
135
OnStop()136 void DistributedBms::OnStop()
137 {
138 APP_LOGI("DistributedBms: OnStop");
139 if (distributedSub_ != nullptr) {
140 EventFwk::CommonEventManager::UnSubscribeCommonEvent(distributedSub_);
141 }
142 }
143
Init()144 void DistributedBms::Init()
145 {
146 APP_LOGI("DistributedBms: Init");
147 InitDeviceManager();
148 DistributedDataStorage::GetInstance();
149 if (distributedSub_ == nullptr) {
150 EventFwk::MatchingSkills matchingSkills;
151 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
152 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED);
153 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
154 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED);
155 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
156 distributedSub_ = std::make_shared<DistributedMonitor>(subscribeInfo);
157 EventFwk::CommonEventManager::SubscribeCommonEvent(distributedSub_);
158 }
159 int32_t userId = AccountManagerHelper::GetCurrentActiveUserId();
160 if (userId == Constants::INVALID_USERID) {
161 APP_LOGW("get user id failed");
162 return;
163 }
164 DistributedDataStorage::GetInstance()->UpdateDistributedData(userId);
165 }
166
InitDeviceManager()167 void DistributedBms::InitDeviceManager()
168 {
169 if (dbmsDeviceManager_ == nullptr) {
170 std::lock_guard<std::mutex> lock(dbmsDeviceManagerMutex_);
171 if (dbmsDeviceManager_ == nullptr) {
172 APP_LOGI("Create device manager");
173 dbmsDeviceManager_ = std::make_shared<DbmsDeviceManager>();
174 }
175 }
176 }
177
GetBundleMgr()178 OHOS::sptr<OHOS::AppExecFwk::IBundleMgr> DistributedBms::GetBundleMgr()
179 {
180 if (bundleMgr_ == nullptr) {
181 std::lock_guard<std::mutex> lock(bundleMgrMutex_);
182 if (bundleMgr_ == nullptr) {
183 auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
184 if (systemAbilityManager == nullptr) {
185 APP_LOGE("GetBundleMgr GetSystemAbilityManager is null");
186 return nullptr;
187 }
188 auto bundleMgrSa = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
189 if (bundleMgrSa == nullptr) {
190 APP_LOGE("GetBundleMgr GetSystemAbility is null");
191 return nullptr;
192 }
193 bundleMgr_ = OHOS::iface_cast<IBundleMgr>(bundleMgrSa);
194 }
195 }
196 return bundleMgr_;
197 }
198
GetUdidByNetworkId(const std::string & networkId,std::string & udid)199 int32_t DistributedBms::GetUdidByNetworkId(const std::string &networkId, std::string &udid)
200 {
201 if (dbmsDeviceManager_ == nullptr) {
202 APP_LOGI("deviceManager_ is nullptr");
203 InitDeviceManager();
204 }
205 return dbmsDeviceManager_->GetUdidByNetworkId(networkId, udid);
206 }
207
GetUuidByNetworkId(const std::string & networkId,std::string & uuid)208 int32_t DistributedBms::GetUuidByNetworkId(const std::string &networkId, std::string &uuid)
209 {
210 if (dbmsDeviceManager_ == nullptr) {
211 APP_LOGI("deviceManager_ is nullptr");
212 InitDeviceManager();
213 }
214 return dbmsDeviceManager_->GetUuidByNetworkId(networkId, uuid);
215 }
216
GetLocalDevice(DistributedHardware::DmDeviceInfo & dmDeviceInfo)217 bool DistributedBms::GetLocalDevice(DistributedHardware::DmDeviceInfo& dmDeviceInfo)
218 {
219 if (dbmsDeviceManager_ == nullptr) {
220 APP_LOGI("deviceManager_ is nullptr");
221 InitDeviceManager();
222 }
223 return dbmsDeviceManager_->GetLocalDevice(dmDeviceInfo);
224 }
225
GetDistributedBundleMgr(const std::string & deviceId)226 static OHOS::sptr<OHOS::AppExecFwk::IDistributedBms> GetDistributedBundleMgr(const std::string &deviceId)
227 {
228 auto samgr = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
229 if (samgr == nullptr) {
230 APP_LOGE("GetSystemAbilityManager failed");
231 return nullptr;
232 }
233 OHOS::sptr<OHOS::IRemoteObject> remoteObject;
234 if (deviceId.empty()) {
235 APP_LOGW("GetDistributedBundleMgr deviceId is empty");
236 return nullptr;
237 } else {
238 APP_LOGI("GetDistributedBundleMgr get remote d-bms");
239 remoteObject = samgr->CheckSystemAbility(OHOS::DISTRIBUTED_BUNDLE_MGR_SERVICE_SYS_ABILITY_ID, deviceId);
240 }
241 return OHOS::iface_cast<IDistributedBms>(remoteObject);
242 }
243
GetRemoteAbilityInfo(const OHOS::AppExecFwk::ElementName & elementName,RemoteAbilityInfo & remoteAbilityInfo)244 int32_t DistributedBms::GetRemoteAbilityInfo(
245 const OHOS::AppExecFwk::ElementName &elementName, RemoteAbilityInfo &remoteAbilityInfo)
246 {
247 return GetRemoteAbilityInfo(elementName, "", remoteAbilityInfo);
248 }
249
GetRemoteAbilityInfo(const OHOS::AppExecFwk::ElementName & elementName,const std::string & localeInfo,RemoteAbilityInfo & remoteAbilityInfo)250 int32_t DistributedBms::GetRemoteAbilityInfo(const OHOS::AppExecFwk::ElementName &elementName,
251 const std::string &localeInfo, RemoteAbilityInfo &remoteAbilityInfo)
252 {
253 if (!VerifySystemApp()) {
254 APP_LOGE("verify system app failed");
255 return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
256 }
257 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
258 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
259 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
260 }
261 auto iDistBundleMgr = GetDistributedBundleMgr(elementName.GetDeviceID());
262 int32_t resultCode = 0;
263 if (!iDistBundleMgr) {
264 APP_LOGE("GetDistributedBundle object failed");
265 resultCode = ERR_BUNDLE_MANAGER_DEVICE_ID_NOT_EXIST;
266 } else {
267 #ifdef HICOLLIE_ENABLE
268 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("GetRemoteAbilityInfo", REMOTE_TIME_OUT_SECONDS,
269 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_RECOVERY);
270 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
271 #endif
272 APP_LOGD("GetDistributedBundleMgr get remote d-bms");
273 DistributedBmsAclInfo info = BuildDistributedBmsAclInfo();
274 resultCode = iDistBundleMgr->GetAbilityInfo(elementName, localeInfo, remoteAbilityInfo, &info);
275 }
276
277 #ifdef HISYSEVENT_ENABLE
278 EventReport::SendSystemEvent(
279 DBMSEventType::GET_REMOTE_ABILITY_INFO, GetEventInfo(elementName, localeInfo, resultCode));
280 #endif
281 return resultCode;
282 }
283
GetRemoteAbilityInfos(const std::vector<ElementName> & elementNames,std::vector<RemoteAbilityInfo> & remoteAbilityInfos)284 int32_t DistributedBms::GetRemoteAbilityInfos(
285 const std::vector<ElementName> &elementNames, std::vector<RemoteAbilityInfo> &remoteAbilityInfos)
286 {
287 return GetRemoteAbilityInfos(elementNames, "", remoteAbilityInfos);
288 }
289
GetRemoteAbilityInfos(const std::vector<ElementName> & elementNames,const std::string & localeInfo,std::vector<RemoteAbilityInfo> & remoteAbilityInfos)290 int32_t DistributedBms::GetRemoteAbilityInfos(const std::vector<ElementName> &elementNames,
291 const std::string &localeInfo, std::vector<RemoteAbilityInfo> &remoteAbilityInfos)
292 {
293 if (!VerifySystemApp()) {
294 APP_LOGE("verify system app failed");
295 return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
296 }
297 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
298 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
299 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
300 }
301 if (elementNames.empty()) {
302 APP_LOGE("GetDistributedBundle failed due to elementNames empty");
303 return ERR_BUNDLE_MANAGER_PARAM_ERROR;
304 }
305 auto iDistBundleMgr = GetDistributedBundleMgr(elementNames[0].GetDeviceID());
306 int32_t resultCode = 0;
307 if (!iDistBundleMgr) {
308 APP_LOGE("GetDistributedBundle object failed");
309 resultCode = ERR_BUNDLE_MANAGER_DEVICE_ID_NOT_EXIST;
310 } else {
311 #ifdef HICOLLIE_ENABLE
312 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("GetRemoteAbilityInfos", REMOTE_TIME_OUT_SECONDS,
313 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_RECOVERY);
314 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
315 #endif
316 APP_LOGD("GetDistributedBundleMgr get remote d-bms");
317 DistributedBmsAclInfo info = BuildDistributedBmsAclInfo();
318 resultCode = iDistBundleMgr->GetAbilityInfos(elementNames, localeInfo, remoteAbilityInfos, &info);
319 }
320 #ifdef HISYSEVENT_ENABLE
321 EventReport::SendSystemEvent(
322 DBMSEventType::GET_REMOTE_ABILITY_INFOS, GetEventInfo(elementNames, localeInfo, resultCode));
323 #endif
324 return resultCode;
325 }
326
BuildDistributedBmsAclInfo()327 DistributedBmsAclInfo DistributedBms::BuildDistributedBmsAclInfo()
328 {
329 DistributedBmsAclInfo info;
330 std::string accountId;
331 #ifdef ACCOUNT_ENABLE
332 AccountSA::OhosAccountInfo osAccountInfo;
333 if (!AccountManagerHelper::GetOsAccountData(osAccountInfo)) {
334 APP_LOGE("GetOsAccountData failed");
335 return info;
336 }
337 accountId = osAccountInfo.uid_;
338 #endif
339 DistributedHardware::DmDeviceInfo dmDeviceInfo;
340 if (!GetLocalDevice(dmDeviceInfo)) {
341 return info;
342 }
343 int32_t userId = AccountManagerHelper::GetCurrentActiveUserId();
344 auto iBundleMgr = GetBundleMgr();
345 if (!iBundleMgr) {
346 APP_LOGE("DistributedBms GetBundleMgr failed");
347 return info;
348 }
349 std::string callingBundleName;
350 iBundleMgr->GetNameForUid(IPCSkeleton::GetCallingUid(), callingBundleName);
351 info.networkId = dmDeviceInfo.networkId;
352 info.userId = userId;
353 info.accountId = accountId;
354 info.tokenId = OHOS::Security::AccessToken::AccessTokenKit::GetHapTokenID(userId, callingBundleName, 0);
355 info.pkgName = callingBundleName;
356 return info;
357 }
358
GetAbilityInfo(const OHOS::AppExecFwk::ElementName & elementName,RemoteAbilityInfo & remoteAbilityInfo)359 int32_t DistributedBms::GetAbilityInfo(
360 const OHOS::AppExecFwk::ElementName &elementName, RemoteAbilityInfo &remoteAbilityInfo)
361 {
362 return GetAbilityInfo(elementName, "", remoteAbilityInfo);
363 }
364
GetAbilityInfo(const OHOS::AppExecFwk::ElementName & elementName,const std::string & localeInfo,RemoteAbilityInfo & remoteAbilityInfo,DistributedBmsAclInfo * info)365 int32_t DistributedBms::GetAbilityInfo(const OHOS::AppExecFwk::ElementName &elementName,
366 const std::string &localeInfo, RemoteAbilityInfo &remoteAbilityInfo,
367 DistributedBmsAclInfo *info)
368 {
369 APP_LOGI("DistributedBms GetAbilityInfo bundleName:%{public}s , abilityName:%{public}s, localeInfo:%{public}s",
370 elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str(), localeInfo.c_str());
371 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED) &&
372 info != nullptr && !CheckAclData(*info)) {
373 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
374 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
375 }
376 auto iBundleMgr = GetBundleMgr();
377 if (!iBundleMgr) {
378 APP_LOGE("DistributedBms GetBundleMgr failed");
379 return ERR_APPEXECFWK_FAILED_SERVICE_DIED;
380 }
381 int userId = AccountManagerHelper::GetCurrentActiveUserId();
382 if (userId == Constants::INVALID_USERID) {
383 APP_LOGE("GetCurrentUserId failed");
384 return ERR_BUNDLE_MANAGER_INVALID_USER_ID;
385 }
386 std::vector<AbilityInfo> abilityInfos;
387 OHOS::AAFwk::Want want;
388 want.SetElement(elementName);
389 ErrCode ret = iBundleMgr->QueryAbilityInfosV9(want, static_cast<int32_t>(
390 GetAbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION), userId, abilityInfos);
391 if (ret != ERR_OK) {
392 APP_LOGE("DistributedBms QueryAbilityInfo failed");
393 return ret;
394 }
395 if (abilityInfos.empty()) {
396 APP_LOGE("DistributedBms QueryAbilityInfo abilityInfos empty");
397 return ERR_APPEXECFWK_FAILED_GET_ABILITY_INFO;
398 }
399 std::string label = iBundleMgr->GetStringById(
400 abilityInfos[0].bundleName, abilityInfos[0].moduleName, abilityInfos[0].labelId, userId, localeInfo);
401 if (label.empty()) {
402 APP_LOGE("DistributedBms QueryAbilityInfo label empty");
403 return ERR_APPEXECFWK_FAILED_GET_ABILITY_INFO;
404 }
405 remoteAbilityInfo.label = label;
406 remoteAbilityInfo.elementName = elementName;
407 return GetAbilityIconByContent(abilityInfos[0], userId, remoteAbilityInfo);
408 }
409
GetAbilityIconByContent(const AbilityInfo & abilityInfo,int32_t userId,RemoteAbilityInfo & remoteAbilityInfo)410 int32_t DistributedBms::GetAbilityIconByContent(
411 const AbilityInfo &abilityInfo, int32_t userId, RemoteAbilityInfo &remoteAbilityInfo)
412 {
413 auto iBundleMgr = GetBundleMgr();
414 if (!iBundleMgr) {
415 APP_LOGE("DistributedBms GetBundleMgr failed");
416 return ERR_APPEXECFWK_FAILED_SERVICE_DIED;
417 }
418 #ifdef DISTRIBUTED_BUNDLE_IMAGE_ENABLE
419 std::unique_ptr<uint8_t[]> imageContent;
420 size_t imageContentSize = 0;
421 ErrCode ret = iBundleMgr->GetMediaData(abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name,
422 imageContent, imageContentSize, userId);
423 if (ret != ERR_OK) {
424 APP_LOGE("DistributedBms GetMediaData failed");
425 return ret;
426 }
427 APP_LOGD("imageContentSize is %{public}d", static_cast<int32_t>(imageContentSize));
428 std::unique_ptr<ImageCompress> imageCompress = std::make_unique<ImageCompress>();
429 if (imageCompress->IsImageNeedCompressBySize(imageContentSize)) {
430 std::unique_ptr<uint8_t[]> compressData;
431 int64_t compressSize = 0;
432 std::string imageType;
433 if (!imageCompress->CompressImageByContent(imageContent, imageContentSize,
434 compressData, compressSize, imageType)) {
435 return Base64WithoutCompress(imageContent, imageContentSize, remoteAbilityInfo);
436 }
437 if (!GetMediaBase64(compressData, compressSize, imageType, remoteAbilityInfo.icon)) {
438 APP_LOGE("DistributedBms GetMediaBase64 failed");
439 return ERR_APPEXECFWK_ENCODE_BASE64_FILE_FAILED;
440 }
441 } else {
442 return Base64WithoutCompress(imageContent, imageContentSize, remoteAbilityInfo);
443 }
444 #endif
445 return OHOS::NO_ERROR;
446 }
447
448 #ifdef DISTRIBUTED_BUNDLE_IMAGE_ENABLE
Base64WithoutCompress(std::unique_ptr<uint8_t[]> & imageContent,size_t imageContentSize,RemoteAbilityInfo & remoteAbilityInfo)449 int32_t DistributedBms::Base64WithoutCompress(std::unique_ptr<uint8_t[]> &imageContent, size_t imageContentSize,
450 RemoteAbilityInfo &remoteAbilityInfo)
451 {
452 std::string imageType;
453 std::unique_ptr<ImageCompress> imageCompress = std::make_unique<ImageCompress>();
454 if (!imageCompress->GetImageTypeString(imageContent, imageContentSize, imageType)) {
455 return ERR_APPEXECFWK_INPUT_WRONG_TYPE_FILE;
456 }
457 if (!GetMediaBase64(imageContent, static_cast<int64_t>(imageContentSize), imageType, remoteAbilityInfo.icon)) {
458 APP_LOGE("DistributedBms GetMediaBase64 failed");
459 return ERR_APPEXECFWK_ENCODE_BASE64_FILE_FAILED;
460 }
461 return OHOS::NO_ERROR;
462 }
463 #endif
464
GetAbilityInfos(const std::vector<ElementName> & elementNames,std::vector<RemoteAbilityInfo> & remoteAbilityInfos)465 int32_t DistributedBms::GetAbilityInfos(
466 const std::vector<ElementName> &elementNames, std::vector<RemoteAbilityInfo> &remoteAbilityInfos)
467 {
468 APP_LOGD("DistributedBms GetAbilityInfos");
469 return GetAbilityInfos(elementNames, "", remoteAbilityInfos);
470 }
471
GetAbilityInfos(const std::vector<ElementName> & elementNames,const std::string & localeInfo,std::vector<RemoteAbilityInfo> & remoteAbilityInfos,DistributedBmsAclInfo * info)472 int32_t DistributedBms::GetAbilityInfos(const std::vector<ElementName> &elementNames,
473 const std::string &localeInfo, std::vector<RemoteAbilityInfo> &remoteAbilityInfos,
474 DistributedBmsAclInfo *info)
475 {
476 APP_LOGD("DistributedBms GetAbilityInfos");
477 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED) &&
478 info != nullptr && !CheckAclData(*info)) {
479 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
480 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
481 }
482 for (auto elementName : elementNames) {
483 RemoteAbilityInfo remoteAbilityInfo;
484 int32_t result = GetAbilityInfo(elementName, localeInfo, remoteAbilityInfo, info);
485 if (result) {
486 APP_LOGE("get AbilityInfo:%{public}s, %{public}s, %{public}s failed", elementName.GetBundleName().c_str(),
487 elementName.GetModuleName().c_str(), elementName.GetAbilityName().c_str());
488 return result;
489 }
490 remoteAbilityInfos.push_back(remoteAbilityInfo);
491 }
492 return OHOS::NO_ERROR;
493 }
494
CheckAclData(DistributedBmsAclInfo info)495 bool DistributedBms::CheckAclData(DistributedBmsAclInfo info)
496 {
497 if (dbmsDeviceManager_ == nullptr) {
498 APP_LOGI("deviceManager_ is nullptr");
499 InitDeviceManager();
500 }
501 return dbmsDeviceManager_->CheckAclData(info);
502 }
503
GetMediaBase64(std::unique_ptr<uint8_t[]> & data,int64_t fileLength,std::string & imageType,std::string & value)504 bool DistributedBms::GetMediaBase64(std::unique_ptr<uint8_t[]> &data, int64_t fileLength,
505 std::string &imageType, std::string &value)
506 {
507 std::unique_ptr<char[]> base64Data = EncodeBase64(data, fileLength);
508 value = "data:" + imageType + ";base64," + base64Data.get();
509 return true;
510 }
511
GetDistributedBundleInfo(const std::string & networkId,const std::string & bundleName,DistributedBundleInfo & distributedBundleInfo)512 bool DistributedBms::GetDistributedBundleInfo(const std::string &networkId, const std::string &bundleName,
513 DistributedBundleInfo &distributedBundleInfo)
514 {
515 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
516 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
517 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
518 }
519 #ifdef HICOLLIE_ENABLE
520 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("GetDistributedBundleInfo", LOCAL_TIME_OUT_SECONDS,
521 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_RECOVERY);
522 #endif
523 bool ret = DistributedDataStorage::GetInstance()->GetStorageDistributeInfo(
524 networkId, bundleName, distributedBundleInfo);
525 #ifdef HICOLLIE_ENABLE
526 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
527 #endif
528 return ret;
529 }
530
GetDistributedBundleName(const std::string & networkId,uint32_t accessTokenId,std::string & bundleName)531 int32_t DistributedBms::GetDistributedBundleName(const std::string &networkId, uint32_t accessTokenId,
532 std::string &bundleName)
533 {
534 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
535 APP_LOGE("verify calling permission failed");
536 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
537 }
538 #ifdef HICOLLIE_ENABLE
539 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("GetDistributedBundleName", LOCAL_TIME_OUT_SECONDS,
540 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_RECOVERY);
541 #endif
542 int32_t ret = DistributedDataStorage::GetInstance()->GetDistributedBundleName(
543 networkId, accessTokenId, bundleName);
544 #ifdef HICOLLIE_ENABLE
545 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
546 #endif
547 return ret;
548 }
549
EncodeBase64(std::unique_ptr<uint8_t[]> & data,int srcLen)550 std::unique_ptr<char[]> DistributedBms::EncodeBase64(std::unique_ptr<uint8_t[]> &data, int srcLen)
551 {
552 int len = (srcLen / DECODE_VALUE_THREE) * DECODE_VALUE_FOUR; // Split 3 bytes to 4 parts, each containing 6 bits.
553 int outLen = ((srcLen % DECODE_VALUE_THREE) != 0) ? (len + DECODE_VALUE_FOUR) : len;
554 const uint8_t *srcData = data.get();
555 std::unique_ptr<char[]> result = std::make_unique<char[]>(outLen + DECODE_VALUE_ONE);
556 char *dstData = result.get();
557 int j = 0;
558 int i = 0;
559 for (; i < srcLen - DECODE_VALUE_THREE; i += DECODE_VALUE_THREE) {
560 unsigned char byte1 = srcData[i];
561 unsigned char byte2 = srcData[i + DECODE_VALUE_ONE];
562 unsigned char byte3 = srcData[i + DECODE_VALUE_TWO];
563 dstData[j++] = DECODE_TABLE[byte1 >> DECODE_VALUE_TWO];
564 dstData[j++] =
565 DECODE_TABLE[(static_cast<uint8_t>(byte1 & DECODE_VALUE_CHAR_THREE) << DECODE_VALUE_FOUR)
566 | (byte2 >> DECODE_VALUE_FOUR)];
567 dstData[j++] =
568 DECODE_TABLE[(static_cast<uint8_t>(byte2 & DECODE_VALUE_CHAR_FIFTEEN)
569 << DECODE_VALUE_TWO) | (byte3 >> DECODE_VALUE_SIX)];
570 dstData[j++] = DECODE_TABLE[byte3 & DECODE_VALUE_CHAR_SIXTY_THREE];
571 }
572 if (srcLen % DECODE_VALUE_THREE == DECODE_VALUE_ONE) {
573 unsigned char byte1 = srcData[i];
574 dstData[j++] = DECODE_TABLE[byte1 >> DECODE_VALUE_TWO];
575 dstData[j++] = DECODE_TABLE[static_cast<uint8_t>(byte1 & DECODE_VALUE_CHAR_THREE) << DECODE_VALUE_FOUR];
576 dstData[j++] = '=';
577 dstData[j++] = '=';
578 } else {
579 unsigned char byte1 = srcData[i];
580 unsigned char byte2 = srcData[i + DECODE_VALUE_ONE];
581 dstData[j++] = DECODE_TABLE[byte1 >> DECODE_VALUE_TWO];
582 dstData[j++] =
583 DECODE_TABLE[(static_cast<uint8_t>(byte1 & DECODE_VALUE_CHAR_THREE) << DECODE_VALUE_FOUR)
584 | (byte2 >> DECODE_VALUE_FOUR)];
585 dstData[j++] = DECODE_TABLE[static_cast<uint8_t>(byte2 & DECODE_VALUE_CHAR_FIFTEEN)
586 << DECODE_VALUE_TWO];
587 dstData[j++] = '=';
588 }
589 dstData[outLen] = '\0';
590
591 return result;
592 }
593
VerifySystemApp()594 bool DistributedBms::VerifySystemApp()
595 {
596 APP_LOGI("verifying systemApp");
597 int32_t callingUid = IPCSkeleton::GetCallingUid();
598 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
599 if (VerifyTokenNative(callerToken) || VerifyTokenShell(callerToken)
600 || callingUid == Constants::ROOT_UID) {
601 APP_LOGI("caller tokenType is native or shell, verify success");
602 return true;
603 }
604 uint64_t accessTokenIdEx = IPCSkeleton::GetCallingFullTokenID();
605 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIdEx)) {
606 APP_LOGE("non-system app calling system api");
607 return false;
608 }
609 return true;
610 }
611
VerifyTokenNative(Security::AccessToken::AccessTokenID callerToken)612 bool DistributedBms::VerifyTokenNative(Security::AccessToken::AccessTokenID callerToken)
613 {
614 APP_LOGD("verifying system app for native token");
615 Security::AccessToken::ATokenTypeEnum tokenType =
616 Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
617 APP_LOGD("token type is %{public}d", static_cast<int32_t>(tokenType));
618 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
619 APP_LOGI("caller tokenType is native, verify success");
620 return true;
621 }
622 APP_LOGE("caller tokenType not native, verify failed");
623 return false;
624 }
625
VerifyTokenShell(Security::AccessToken::AccessTokenID callerToken)626 bool DistributedBms::VerifyTokenShell(Security::AccessToken::AccessTokenID callerToken)
627 {
628 APP_LOGD("verifying system app for shell token");
629 Security::AccessToken::ATokenTypeEnum tokenType =
630 Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
631 APP_LOGD("token type is %{public}d", static_cast<int32_t>(tokenType));
632 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
633 APP_LOGI("caller tokenType is shell, verify success");
634 return true;
635 }
636 APP_LOGE("caller tokenType not shell, verify failed");
637 return false;
638 }
639
VerifyCallingPermission(const std::string & permissionName)640 bool DistributedBms::VerifyCallingPermission(const std::string &permissionName)
641 {
642 APP_LOGD("VerifyCallingPermission permission %{public}s", permissionName.c_str());
643 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
644 auto uid = IPCSkeleton::GetCallingUid();
645 APP_LOGD("VerifyCallingPermission callingUid %{public}d", uid);
646 int32_t ret = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
647 if (ret == OHOS::Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
648 APP_LOGD("verify permission success");
649 return true;
650 }
651 APP_LOGE("permission %{public}s: PERMISSION_DENIED", permissionName.c_str());
652 return false;
653 }
654 }
655 }