• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }