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 APP_LOGI("Create device manager");
171 dbmsDeviceManager_ = std::make_shared<DbmsDeviceManager>();
172 }
173 }
174
GetBundleMgr()175 OHOS::sptr<OHOS::AppExecFwk::IBundleMgr> DistributedBms::GetBundleMgr()
176 {
177 if (bundleMgr_ == nullptr) {
178 std::lock_guard<std::mutex> lock(bundleMgrMutex_);
179 if (bundleMgr_ == nullptr) {
180 auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
181 if (systemAbilityManager == nullptr) {
182 APP_LOGE("GetBundleMgr GetSystemAbilityManager is null");
183 return nullptr;
184 }
185 auto bundleMgrSa = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
186 if (bundleMgrSa == nullptr) {
187 APP_LOGE("GetBundleMgr GetSystemAbility is null");
188 return nullptr;
189 }
190 bundleMgr_ = OHOS::iface_cast<IBundleMgr>(bundleMgrSa);
191 }
192 }
193 return bundleMgr_;
194 }
195
GetUdidByNetworkId(const std::string & networkId,std::string & udid)196 int32_t DistributedBms::GetUdidByNetworkId(const std::string &networkId, std::string &udid)
197 {
198 if (dbmsDeviceManager_ == nullptr) {
199 APP_LOGI("deviceManager_ is nullptr");
200 InitDeviceManager();
201 }
202 return dbmsDeviceManager_->GetUdidByNetworkId(networkId, udid);
203 }
204
GetDistributedBundleMgr(const std::string & deviceId)205 static OHOS::sptr<OHOS::AppExecFwk::IDistributedBms> GetDistributedBundleMgr(const std::string &deviceId)
206 {
207 auto samgr = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
208 if (samgr == nullptr) {
209 APP_LOGE("GetSystemAbilityManager failed");
210 return nullptr;
211 }
212 OHOS::sptr<OHOS::IRemoteObject> remoteObject;
213 if (deviceId.empty()) {
214 APP_LOGW("GetDistributedBundleMgr deviceId is empty");
215 return nullptr;
216 } else {
217 APP_LOGI("GetDistributedBundleMgr get remote d-bms");
218 remoteObject = samgr->CheckSystemAbility(OHOS::DISTRIBUTED_BUNDLE_MGR_SERVICE_SYS_ABILITY_ID, deviceId);
219 }
220 return OHOS::iface_cast<IDistributedBms>(remoteObject);
221 }
222
GetRemoteAbilityInfo(const OHOS::AppExecFwk::ElementName & elementName,RemoteAbilityInfo & remoteAbilityInfo)223 int32_t DistributedBms::GetRemoteAbilityInfo(
224 const OHOS::AppExecFwk::ElementName &elementName, RemoteAbilityInfo &remoteAbilityInfo)
225 {
226 return GetRemoteAbilityInfo(elementName, "", remoteAbilityInfo);
227 }
228
GetRemoteAbilityInfo(const OHOS::AppExecFwk::ElementName & elementName,const std::string & localeInfo,RemoteAbilityInfo & remoteAbilityInfo)229 int32_t DistributedBms::GetRemoteAbilityInfo(const OHOS::AppExecFwk::ElementName &elementName,
230 const std::string &localeInfo, RemoteAbilityInfo &remoteAbilityInfo)
231 {
232 if (!VerifySystemApp()) {
233 APP_LOGE("verify system app failed");
234 return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
235 }
236 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
237 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
238 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
239 }
240 auto iDistBundleMgr = GetDistributedBundleMgr(elementName.GetDeviceID());
241 int32_t resultCode = 0;
242 if (!iDistBundleMgr) {
243 APP_LOGE("GetDistributedBundle object failed");
244 resultCode = ERR_BUNDLE_MANAGER_DEVICE_ID_NOT_EXIST;
245 } else {
246 #ifdef HICOLLIE_ENABLE
247 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("GetRemoteAbilityInfo", REMOTE_TIME_OUT_SECONDS,
248 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_RECOVERY);
249 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
250 #endif
251 APP_LOGD("GetDistributedBundleMgr get remote d-bms");
252 resultCode = iDistBundleMgr->GetAbilityInfo(elementName, localeInfo, remoteAbilityInfo);
253 }
254
255 #ifdef HISYSEVENT_ENABLE
256 EventReport::SendSystemEvent(
257 DBMSEventType::GET_REMOTE_ABILITY_INFO, GetEventInfo(elementName, localeInfo, resultCode));
258 #endif
259 return resultCode;
260 }
261
GetRemoteAbilityInfos(const std::vector<ElementName> & elementNames,std::vector<RemoteAbilityInfo> & remoteAbilityInfos)262 int32_t DistributedBms::GetRemoteAbilityInfos(
263 const std::vector<ElementName> &elementNames, std::vector<RemoteAbilityInfo> &remoteAbilityInfos)
264 {
265 return GetRemoteAbilityInfos(elementNames, "", remoteAbilityInfos);
266 }
267
GetRemoteAbilityInfos(const std::vector<ElementName> & elementNames,const std::string & localeInfo,std::vector<RemoteAbilityInfo> & remoteAbilityInfos)268 int32_t DistributedBms::GetRemoteAbilityInfos(const std::vector<ElementName> &elementNames,
269 const std::string &localeInfo, std::vector<RemoteAbilityInfo> &remoteAbilityInfos)
270 {
271 if (!VerifySystemApp()) {
272 APP_LOGE("verify system app failed");
273 return ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED;
274 }
275 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
276 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
277 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
278 }
279 if (elementNames.empty()) {
280 APP_LOGE("GetDistributedBundle failed due to elementNames empty");
281 return ERR_BUNDLE_MANAGER_PARAM_ERROR;
282 }
283 auto iDistBundleMgr = GetDistributedBundleMgr(elementNames[0].GetDeviceID());
284 int32_t resultCode = 0;
285 if (!iDistBundleMgr) {
286 APP_LOGE("GetDistributedBundle object failed");
287 resultCode = ERR_BUNDLE_MANAGER_DEVICE_ID_NOT_EXIST;
288 } else {
289 #ifdef HICOLLIE_ENABLE
290 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("GetRemoteAbilityInfos", REMOTE_TIME_OUT_SECONDS,
291 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_RECOVERY);
292 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
293 #endif
294 APP_LOGD("GetDistributedBundleMgr get remote d-bms");
295 resultCode = iDistBundleMgr->GetAbilityInfos(elementNames, localeInfo, remoteAbilityInfos);
296 }
297 #ifdef HISYSEVENT_ENABLE
298 EventReport::SendSystemEvent(
299 DBMSEventType::GET_REMOTE_ABILITY_INFOS, GetEventInfo(elementNames, localeInfo, resultCode));
300 #endif
301 return resultCode;
302 }
303
GetAbilityInfo(const OHOS::AppExecFwk::ElementName & elementName,RemoteAbilityInfo & remoteAbilityInfo)304 int32_t DistributedBms::GetAbilityInfo(
305 const OHOS::AppExecFwk::ElementName &elementName, RemoteAbilityInfo &remoteAbilityInfo)
306 {
307 return GetAbilityInfo(elementName, "", remoteAbilityInfo);
308 }
309
GetAbilityInfo(const OHOS::AppExecFwk::ElementName & elementName,const std::string & localeInfo,RemoteAbilityInfo & remoteAbilityInfo)310 int32_t DistributedBms::GetAbilityInfo(const OHOS::AppExecFwk::ElementName &elementName,
311 const std::string &localeInfo, RemoteAbilityInfo &remoteAbilityInfo)
312 {
313 APP_LOGI("DistributedBms GetAbilityInfo bundleName:%{public}s , abilityName:%{public}s, localeInfo:%{public}s",
314 elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str(), localeInfo.c_str());
315 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
316 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
317 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
318 }
319 auto iBundleMgr = GetBundleMgr();
320 if (!iBundleMgr) {
321 APP_LOGE("DistributedBms GetBundleMgr failed");
322 return ERR_APPEXECFWK_FAILED_SERVICE_DIED;
323 }
324 int userId = AccountManagerHelper::GetCurrentActiveUserId();
325 if (userId == Constants::INVALID_USERID) {
326 APP_LOGE("GetCurrentUserId failed");
327 return ERR_BUNDLE_MANAGER_INVALID_USER_ID;
328 }
329 std::vector<AbilityInfo> abilityInfos;
330 OHOS::AAFwk::Want want;
331 want.SetElement(elementName);
332 ErrCode ret = iBundleMgr->QueryAbilityInfosV9(want, static_cast<int32_t>(
333 GetAbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION), userId, abilityInfos);
334 if (ret != ERR_OK) {
335 APP_LOGE("DistributedBms QueryAbilityInfo failed");
336 return ret;
337 }
338 if (abilityInfos.empty()) {
339 APP_LOGE("DistributedBms QueryAbilityInfo abilityInfos empty");
340 return ERR_APPEXECFWK_FAILED_GET_ABILITY_INFO;
341 }
342 std::string label = iBundleMgr->GetStringById(
343 abilityInfos[0].bundleName, abilityInfos[0].moduleName, abilityInfos[0].labelId, userId, localeInfo);
344 if (label.empty()) {
345 APP_LOGE("DistributedBms QueryAbilityInfo label empty");
346 return ERR_APPEXECFWK_FAILED_GET_ABILITY_INFO;
347 }
348 remoteAbilityInfo.label = label;
349 remoteAbilityInfo.elementName = elementName;
350 return GetAbilityIconByContent(abilityInfos[0], userId, remoteAbilityInfo);
351 }
352
GetAbilityIconByContent(const AbilityInfo & abilityInfo,int32_t userId,RemoteAbilityInfo & remoteAbilityInfo)353 int32_t DistributedBms::GetAbilityIconByContent(
354 const AbilityInfo &abilityInfo, int32_t userId, RemoteAbilityInfo &remoteAbilityInfo)
355 {
356 auto iBundleMgr = GetBundleMgr();
357 if (!iBundleMgr) {
358 APP_LOGE("DistributedBms GetBundleMgr failed");
359 return ERR_APPEXECFWK_FAILED_SERVICE_DIED;
360 }
361 #ifdef DISTRIBUTED_BUNDLE_IMAGE_ENABLE
362 std::unique_ptr<uint8_t[]> imageContent;
363 size_t imageContentSize = 0;
364 ErrCode ret = iBundleMgr->GetMediaData(abilityInfo.bundleName, abilityInfo.moduleName, abilityInfo.name,
365 imageContent, imageContentSize, userId);
366 if (ret != ERR_OK) {
367 APP_LOGE("DistributedBms GetMediaData failed");
368 return ret;
369 }
370 APP_LOGD("imageContentSize is %{public}d", static_cast<int32_t>(imageContentSize));
371 std::unique_ptr<ImageCompress> imageCompress = std::make_unique<ImageCompress>();
372 if (imageCompress->IsImageNeedCompressBySize(imageContentSize)) {
373 std::unique_ptr<uint8_t[]> compressData;
374 int64_t compressSize = 0;
375 std::string imageType;
376 if (!imageCompress->CompressImageByContent(imageContent, imageContentSize,
377 compressData, compressSize, imageType)) {
378 return Base64WithoutCompress(imageContent, imageContentSize, remoteAbilityInfo);
379 }
380 if (!GetMediaBase64(compressData, compressSize, imageType, remoteAbilityInfo.icon)) {
381 APP_LOGE("DistributedBms GetMediaBase64 failed");
382 return ERR_APPEXECFWK_ENCODE_BASE64_FILE_FAILED;
383 }
384 } else {
385 return Base64WithoutCompress(imageContent, imageContentSize, remoteAbilityInfo);
386 }
387 #endif
388 return OHOS::NO_ERROR;
389 }
390
391 #ifdef DISTRIBUTED_BUNDLE_IMAGE_ENABLE
Base64WithoutCompress(std::unique_ptr<uint8_t[]> & imageContent,size_t imageContentSize,RemoteAbilityInfo & remoteAbilityInfo)392 int32_t DistributedBms::Base64WithoutCompress(std::unique_ptr<uint8_t[]> &imageContent, size_t imageContentSize,
393 RemoteAbilityInfo &remoteAbilityInfo)
394 {
395 std::string imageType;
396 std::unique_ptr<ImageCompress> imageCompress = std::make_unique<ImageCompress>();
397 if (!imageCompress->GetImageTypeString(imageContent, imageContentSize, imageType)) {
398 return ERR_APPEXECFWK_INPUT_WRONG_TYPE_FILE;
399 }
400 if (!GetMediaBase64(imageContent, static_cast<int64_t>(imageContentSize), imageType, remoteAbilityInfo.icon)) {
401 APP_LOGE("DistributedBms GetMediaBase64 failed");
402 return ERR_APPEXECFWK_ENCODE_BASE64_FILE_FAILED;
403 }
404 return OHOS::NO_ERROR;
405 }
406 #endif
407
GetAbilityInfos(const std::vector<ElementName> & elementNames,std::vector<RemoteAbilityInfo> & remoteAbilityInfos)408 int32_t DistributedBms::GetAbilityInfos(
409 const std::vector<ElementName> &elementNames, std::vector<RemoteAbilityInfo> &remoteAbilityInfos)
410 {
411 APP_LOGD("DistributedBms GetAbilityInfos");
412 return GetAbilityInfos(elementNames, "", remoteAbilityInfos);
413 }
414
GetAbilityInfos(const std::vector<ElementName> & elementNames,const std::string & localeInfo,std::vector<RemoteAbilityInfo> & remoteAbilityInfos)415 int32_t DistributedBms::GetAbilityInfos(const std::vector<ElementName> &elementNames,
416 const std::string &localeInfo, std::vector<RemoteAbilityInfo> &remoteAbilityInfos)
417 {
418 APP_LOGD("DistributedBms GetAbilityInfos");
419 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
420 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
421 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
422 }
423 for (auto elementName : elementNames) {
424 RemoteAbilityInfo remoteAbilityInfo;
425 int32_t result = GetAbilityInfo(elementName, localeInfo, remoteAbilityInfo);
426 if (result) {
427 APP_LOGE("get AbilityInfo:%{public}s, %{public}s, %{public}s failed", elementName.GetBundleName().c_str(),
428 elementName.GetModuleName().c_str(), elementName.GetAbilityName().c_str());
429 return result;
430 }
431 remoteAbilityInfos.push_back(remoteAbilityInfo);
432 }
433 return OHOS::NO_ERROR;
434 }
435
GetMediaBase64(std::unique_ptr<uint8_t[]> & data,int64_t fileLength,std::string & imageType,std::string & value)436 bool DistributedBms::GetMediaBase64(std::unique_ptr<uint8_t[]> &data, int64_t fileLength,
437 std::string &imageType, std::string &value)
438 {
439 std::unique_ptr<char[]> base64Data = EncodeBase64(data, fileLength);
440 value = "data:" + imageType + ";base64," + base64Data.get();
441 return true;
442 }
443
GetDistributedBundleInfo(const std::string & networkId,const std::string & bundleName,DistributedBundleInfo & distributedBundleInfo)444 bool DistributedBms::GetDistributedBundleInfo(const std::string &networkId, const std::string &bundleName,
445 DistributedBundleInfo &distributedBundleInfo)
446 {
447 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
448 APP_LOGE("verify GET_BUNDLE_INFO_PRIVILEGED failed");
449 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
450 }
451 #ifdef HICOLLIE_ENABLE
452 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("GetDistributedBundleInfo", LOCAL_TIME_OUT_SECONDS,
453 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_RECOVERY);
454 #endif
455 bool ret = DistributedDataStorage::GetInstance()->GetStorageDistributeInfo(
456 networkId, bundleName, distributedBundleInfo);
457 #ifdef HICOLLIE_ENABLE
458 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
459 #endif
460 return ret;
461 }
462
GetDistributedBundleName(const std::string & networkId,uint32_t accessTokenId,std::string & bundleName)463 int32_t DistributedBms::GetDistributedBundleName(const std::string &networkId, uint32_t accessTokenId,
464 std::string &bundleName)
465 {
466 if (!VerifyCallingPermission(Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED)) {
467 APP_LOGE("verify calling permission failed");
468 return ERR_BUNDLE_MANAGER_PERMISSION_DENIED;
469 }
470 #ifdef HICOLLIE_ENABLE
471 int timerId = HiviewDFX::XCollie::GetInstance().SetTimer("GetDistributedBundleName", LOCAL_TIME_OUT_SECONDS,
472 nullptr, nullptr, HiviewDFX::XCOLLIE_FLAG_RECOVERY);
473 #endif
474 int32_t ret = DistributedDataStorage::GetInstance()->GetDistributedBundleName(
475 networkId, accessTokenId, bundleName);
476 #ifdef HICOLLIE_ENABLE
477 HiviewDFX::XCollie::GetInstance().CancelTimer(timerId);
478 #endif
479 return ret;
480 }
481
EncodeBase64(std::unique_ptr<uint8_t[]> & data,int srcLen)482 std::unique_ptr<char[]> DistributedBms::EncodeBase64(std::unique_ptr<uint8_t[]> &data, int srcLen)
483 {
484 int len = (srcLen / DECODE_VALUE_THREE) * DECODE_VALUE_FOUR; // Split 3 bytes to 4 parts, each containing 6 bits.
485 int outLen = ((srcLen % DECODE_VALUE_THREE) != 0) ? (len + DECODE_VALUE_FOUR) : len;
486 const uint8_t *srcData = data.get();
487 std::unique_ptr<char[]> result = std::make_unique<char[]>(outLen + DECODE_VALUE_ONE);
488 char *dstData = result.get();
489 int j = 0;
490 int i = 0;
491 for (; i < srcLen - DECODE_VALUE_THREE; i += DECODE_VALUE_THREE) {
492 unsigned char byte1 = srcData[i];
493 unsigned char byte2 = srcData[i + DECODE_VALUE_ONE];
494 unsigned char byte3 = srcData[i + DECODE_VALUE_TWO];
495 dstData[j++] = DECODE_TABLE[byte1 >> DECODE_VALUE_TWO];
496 dstData[j++] =
497 DECODE_TABLE[(static_cast<uint8_t>(byte1 & DECODE_VALUE_CHAR_THREE) << DECODE_VALUE_FOUR)
498 | (byte2 >> DECODE_VALUE_FOUR)];
499 dstData[j++] =
500 DECODE_TABLE[(static_cast<uint8_t>(byte2 & DECODE_VALUE_CHAR_FIFTEEN)
501 << DECODE_VALUE_TWO) | (byte3 >> DECODE_VALUE_SIX)];
502 dstData[j++] = DECODE_TABLE[byte3 & DECODE_VALUE_CHAR_SIXTY_THREE];
503 }
504 if (srcLen % DECODE_VALUE_THREE == DECODE_VALUE_ONE) {
505 unsigned char byte1 = srcData[i];
506 dstData[j++] = DECODE_TABLE[byte1 >> DECODE_VALUE_TWO];
507 dstData[j++] = DECODE_TABLE[static_cast<uint8_t>(byte1 & DECODE_VALUE_CHAR_THREE) << DECODE_VALUE_FOUR];
508 dstData[j++] = '=';
509 dstData[j++] = '=';
510 } else {
511 unsigned char byte1 = srcData[i];
512 unsigned char byte2 = srcData[i + DECODE_VALUE_ONE];
513 dstData[j++] = DECODE_TABLE[byte1 >> DECODE_VALUE_TWO];
514 dstData[j++] =
515 DECODE_TABLE[(static_cast<uint8_t>(byte1 & DECODE_VALUE_CHAR_THREE) << DECODE_VALUE_FOUR)
516 | (byte2 >> DECODE_VALUE_FOUR)];
517 dstData[j++] = DECODE_TABLE[static_cast<uint8_t>(byte2 & DECODE_VALUE_CHAR_FIFTEEN)
518 << DECODE_VALUE_TWO];
519 dstData[j++] = '=';
520 }
521 dstData[outLen] = '\0';
522
523 return result;
524 }
525
VerifySystemApp()526 bool DistributedBms::VerifySystemApp()
527 {
528 APP_LOGI("verifying systemApp");
529 int32_t callingUid = IPCSkeleton::GetCallingUid();
530 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
531 if (VerifyTokenNative(callerToken) || VerifyTokenShell(callerToken)
532 || callingUid == Constants::ROOT_UID) {
533 APP_LOGI("caller tokenType is native or shell, verify success");
534 return true;
535 }
536 uint64_t accessTokenIdEx = IPCSkeleton::GetCallingFullTokenID();
537 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenIdEx)) {
538 APP_LOGE("non-system app calling system api");
539 return false;
540 }
541 return true;
542 }
543
VerifyTokenNative(Security::AccessToken::AccessTokenID callerToken)544 bool DistributedBms::VerifyTokenNative(Security::AccessToken::AccessTokenID callerToken)
545 {
546 APP_LOGD("verifying system app for native token");
547 Security::AccessToken::ATokenTypeEnum tokenType =
548 Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
549 APP_LOGD("token type is %{public}d", static_cast<int32_t>(tokenType));
550 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
551 APP_LOGI("caller tokenType is native, verify success");
552 return true;
553 }
554 APP_LOGE("caller tokenType not native, verify failed");
555 return false;
556 }
557
VerifyTokenShell(Security::AccessToken::AccessTokenID callerToken)558 bool DistributedBms::VerifyTokenShell(Security::AccessToken::AccessTokenID callerToken)
559 {
560 APP_LOGD("verifying system app for shell token");
561 Security::AccessToken::ATokenTypeEnum tokenType =
562 Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
563 APP_LOGD("token type is %{public}d", static_cast<int32_t>(tokenType));
564 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
565 APP_LOGI("caller tokenType is shell, verify success");
566 return true;
567 }
568 APP_LOGE("caller tokenType not shell, verify failed");
569 return false;
570 }
571
VerifyCallingPermission(const std::string & permissionName)572 bool DistributedBms::VerifyCallingPermission(const std::string &permissionName)
573 {
574 APP_LOGD("VerifyCallingPermission permission %{public}s", permissionName.c_str());
575 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
576 int32_t ret = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
577 if (ret == OHOS::Security::AccessToken::PermissionState::PERMISSION_DENIED) {
578 APP_LOGE("permission %{public}s: PERMISSION_DENIED", permissionName.c_str());
579 return false;
580 }
581 APP_LOGD("verify permission success");
582 return true;
583 }
584 }
585 }