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