1 /*
2 * Copyright (c) 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 "inner_shared_bundle_installer.h"
17
18 #include "app_provision_info_manager.h"
19 #include "bundle_mgr_service.h"
20 #include "installd_client.h"
21
22 namespace OHOS {
23 namespace AppExecFwk {
24 using namespace OHOS::Security;
25 namespace {
26 const std::string HSP_VERSION_PREFIX = "v";
27 const int32_t MAX_FILE_NUMBER = 2;
28 const std::string COMPILE_SDK_TYPE_OPEN_HARMONY = "OpenHarmony";
29 const std::string DEBUG_APP_IDENTIFIER = "DEBUG_LIB_ID";
30 }
31
InnerSharedBundleInstaller(const std::string & path)32 InnerSharedBundleInstaller::InnerSharedBundleInstaller(const std::string &path)
33 : sharedBundlePath_(path), bundleInstallChecker_(std::make_unique<BundleInstallChecker>())
34 {
35 APP_LOGI("inner shared bundle installer instance is created");
36 }
37
~InnerSharedBundleInstaller()38 InnerSharedBundleInstaller::~InnerSharedBundleInstaller()
39 {
40 APP_LOGI("inner shared bundle installer instance is destroyed");
41 BundleUtil::DeleteTempDirs(toDeleteTempHspPath_);
42 }
43
ParseFiles(const InstallCheckParam & checkParam)44 ErrCode InnerSharedBundleInstaller::ParseFiles(const InstallCheckParam &checkParam)
45 {
46 APP_LOGD("parsing shared bundle files, path : %{private}s", sharedBundlePath_.c_str());
47 ErrCode result = ERR_OK;
48
49 // check file paths
50 std::vector<std::string> inBundlePaths;
51 result = BundleUtil::CheckFilePath({sharedBundlePath_}, inBundlePaths);
52 CHECK_RESULT(result, "hsp files check failed %{public}d");
53
54 if (!checkParam.isPreInstallApp) {
55 // copy the haps to the dir which cannot be accessed from caller
56 result = CopyHspToSecurityDir(inBundlePaths);
57 CHECK_RESULT(result, "copy file failed %{public}d");
58 }
59
60 // check number and type of the hsp and sig files
61 std::vector<std::string> bundlePaths;
62 result = ObtainHspFileAndSignatureFilePath(inBundlePaths, bundlePaths, signatureFileDir_);
63 CHECK_RESULT(result, "obtain hsp file path or signature file path failed due to %{public}d");
64
65 // check syscap
66 result = bundleInstallChecker_->CheckSysCap(bundlePaths);
67 CHECK_RESULT(result, "hap syscap check failed %{public}d");
68
69 // verify signature info for all haps
70 std::vector<Security::Verify::HapVerifyResult> hapVerifyResults;
71 result = bundleInstallChecker_->CheckMultipleHapsSignInfo(bundlePaths, hapVerifyResults);
72 CHECK_RESULT(result, "hap files check signature info failed %{public}d");
73
74 // parse bundle infos
75 result = bundleInstallChecker_->ParseHapFiles(bundlePaths, checkParam, hapVerifyResults, parsedBundles_);
76 CHECK_RESULT(result, "parse haps file failed %{public}d");
77
78 // check install permission
79 result = bundleInstallChecker_->CheckInstallPermission(checkParam, hapVerifyResults);
80 CHECK_RESULT(result, "check install permission failed %{public}d");
81
82 // check hsp install condition
83 result = bundleInstallChecker_->CheckHspInstallCondition(hapVerifyResults);
84 CHECK_RESULT(result, "check hsp install condition failed %{public}d");
85
86 // to send notify of start install shared application
87 sendStartSharedBundleInstallNotify(checkParam, parsedBundles_);
88
89 // check device type
90 result = bundleInstallChecker_->CheckDeviceType(parsedBundles_);
91 CHECK_RESULT(result, "check device type failed %{public}d");
92
93 // check label info
94 result = CheckAppLabelInfo();
95 CHECK_RESULT(result, "check label info failed %{public}d");
96
97 // delivery sign profile to code signature
98 result = DeliveryProfileToCodeSign(hapVerifyResults);
99 CHECK_RESULT(result, "delivery sign profile failed %{public}d");
100
101 // check native file
102 result = bundleInstallChecker_->CheckMultiNativeFile(parsedBundles_);
103 CHECK_RESULT(result, "native so is incompatible in all haps %{public}d");
104
105 // check enterprise bundle
106 /* At this place, hapVerifyResults cannot be empty and unnecessary to check it */
107 isEnterpriseBundle_ = bundleInstallChecker_->CheckEnterpriseBundle(hapVerifyResults[0]);
108 appIdentifier_ = (hapVerifyResults[0].GetProvisionInfo().type == Security::Verify::ProvisionType::DEBUG) ?
109 DEBUG_APP_IDENTIFIER : hapVerifyResults[0].GetProvisionInfo().bundleInfo.appIdentifier;
110 compileSdkType_ = parsedBundles_.empty() ? COMPILE_SDK_TYPE_OPEN_HARMONY :
111 (parsedBundles_.begin()->second).GetBaseApplicationInfo().compileSdkType;
112 AddAppProvisionInfo(bundleName_, hapVerifyResults[0].GetProvisionInfo());
113 return result;
114 }
115
sendStartSharedBundleInstallNotify(const InstallCheckParam & installCheckParam,const std::unordered_map<std::string,InnerBundleInfo> & infos)116 void InnerSharedBundleInstaller::sendStartSharedBundleInstallNotify(const InstallCheckParam &installCheckParam,
117 const std::unordered_map<std::string, InnerBundleInfo> &infos)
118 {
119 if (!installCheckParam.needSendEvent) {
120 APP_LOGW("sendStartSharedBundleInstallNotify needSendEvent is false");
121 return;
122 }
123 for (auto item : infos) {
124 APP_LOGD("sendStartSharedBundleInstallNotify %{public}s %{public}s %{public}s %{public}s",
125 item.second.GetBundleName().c_str(), item.second.GetCurModuleName().c_str(),
126 item.second.GetAppId().c_str(), item.second.GetAppIdentifier().c_str());
127 NotifyBundleEvents installRes = {
128 .bundleName = item.second.GetBundleName(),
129 .modulePackage = item.second.GetCurModuleName(),
130 .type = NotifyType::START_INSTALL,
131 .appId = item.second.GetAppId(),
132 .appIdentifier = item.second.GetAppIdentifier()
133 };
134 if (NotifyBundleStatusOfShared(installRes) != ERR_OK) {
135 APP_LOGW("notify status failed for start install");
136 }
137 }
138 }
139
NotifyBundleStatusOfShared(const NotifyBundleEvents & installRes)140 ErrCode InnerSharedBundleInstaller::NotifyBundleStatusOfShared(const NotifyBundleEvents &installRes)
141 {
142 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
143 if (!dataMgr) {
144 APP_LOGE("Get dataMgr shared_ptr nullptr");
145 return false;
146 }
147 std::shared_ptr<BundleCommonEventMgr> commonEventMgr = std::make_shared<BundleCommonEventMgr>();
148 commonEventMgr->NotifyBundleStatus(installRes, dataMgr);
149 return ERR_OK;
150 }
151
Install(const InstallParam & installParam)152 ErrCode InnerSharedBundleInstaller::Install(const InstallParam &installParam)
153 {
154 if (parsedBundles_.empty()) {
155 APP_LOGD("no bundle to install");
156 return ERR_OK;
157 }
158
159 ErrCode result = ERR_OK;
160 for (auto &item : parsedBundles_) {
161 result = ExtractSharedBundles(item.first, item.second);
162 item.second.SetApplicationFlags(installParam.preinstallSourceFlag);
163 CHECK_RESULT(result, "extract shared bundles failed %{public}d");
164 }
165
166 MergeBundleInfos();
167
168 result = SavePreInstallInfo(installParam);
169 CHECK_RESULT(result, "save pre install info failed %{public}d");
170
171 result = SaveBundleInfoToStorage();
172 CHECK_RESULT(result, "save bundle info to storage failed %{public}d");
173
174 // save specifiedDistributionType and additionalInfo
175 SaveInstallParamInfo(bundleName_, installParam);
176 // check mark install finish
177 result = MarkInstallFinish();
178 if (result != ERR_OK) {
179 APP_LOGE("mark install finish failed %{public}d", result);
180 RollBack();
181 return result;
182 }
183 APP_LOGD("install shared bundle successfully: %{public}s", bundleName_.c_str());
184 return result;
185 }
186
RollBack()187 void InnerSharedBundleInstaller::RollBack()
188 {
189 // delete created directories
190 for (auto iter = createdDirs_.crbegin(); iter != createdDirs_.crend(); ++iter) {
191 ErrCode err = InstalldClient::GetInstance()->RemoveDir(*iter);
192 if (err != ERR_OK) {
193 APP_LOGE("clean dir of %{public}s failed: %{public}s", bundleName_.c_str(), iter->c_str());
194 }
195 }
196
197 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
198 if (dataMgr == nullptr) {
199 APP_LOGE("get dataMgr failed");
200 return;
201 }
202
203 // rollback database
204 if (!isBundleExist_) {
205 if (dataMgr->DeleteSharedBundleInfo(bundleName_)) {
206 APP_LOGE("rollback new bundle failed : %{public}s", bundleName_.c_str());
207 }
208 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->DeleteAppProvisionInfo(bundleName_)) {
209 APP_LOGE("bundleName: %{public}s delete appProvisionInfo failed", bundleName_.c_str());
210 }
211 return;
212 }
213
214 if (dataMgr->UpdateInnerBundleInfo(oldBundleInfo_)) {
215 APP_LOGE("rollback old bundle failed : %{public}s", bundleName_.c_str());
216 }
217 }
218
CheckDependency(const Dependency & dependency) const219 bool InnerSharedBundleInstaller::CheckDependency(const Dependency &dependency) const
220 {
221 if (dependency.bundleName != bundleName_) {
222 APP_LOGE("bundle name not match : %{public}s, %{public}s", bundleName_.c_str(), dependency.bundleName.c_str());
223 return false;
224 }
225
226 for (const auto &item : parsedBundles_) {
227 const auto bundleInfo = item.second;
228 BaseSharedBundleInfo sharedBundle;
229 bool isModuleExist = bundleInfo.GetMaxVerBaseSharedBundleInfo(dependency.moduleName, sharedBundle);
230 if (isModuleExist && dependency.versionCode <= sharedBundle.versionCode) {
231 return true;
232 }
233 }
234
235 APP_LOGE("dependency not match");
236 return false;
237 }
238
SendBundleSystemEvent(const EventInfo & eventTemplate) const239 void InnerSharedBundleInstaller::SendBundleSystemEvent(const EventInfo &eventTemplate) const
240 {
241 EventInfo eventInfo = eventTemplate;
242 eventInfo.bundleName = bundleName_;
243 eventInfo.versionCode = newBundleInfo_.GetBaseBundleInfo().versionCode;
244 GetInstallEventInfo(eventInfo);
245
246 BundleEventType eventType = isBundleExist_ ? BundleEventType::UPDATE : BundleEventType::INSTALL;
247 EventReport::SendBundleSystemEvent(eventType, eventInfo);
248 }
249
CheckAppLabelInfo()250 ErrCode InnerSharedBundleInstaller::CheckAppLabelInfo()
251 {
252 if (parsedBundles_.empty()) {
253 APP_LOGE("parsedBundles is empty");
254 return ERR_OK;
255 }
256 bundleName_ = parsedBundles_.begin()->second.GetBundleName();
257
258 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
259 if (dataMgr == nullptr) {
260 APP_LOGE("Get dataMgr shared_ptr nullptr");
261 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
262 }
263
264 isBundleExist_ = dataMgr->FetchInnerBundleInfo(bundleName_, oldBundleInfo_);
265 if (isBundleExist_) {
266 ErrCode ret = CheckBundleTypeWithInstalledVersion();
267 CHECK_RESULT(ret, "check bundle type with installed version failed %{public}d");
268
269 // check old InnerBundleInfo together
270 parsedBundles_.emplace(bundleName_, oldBundleInfo_);
271 } else {
272 if (parsedBundles_.begin()->second.GetApplicationBundleType() != BundleType::SHARED) {
273 APP_LOGE("installing bundle is not hsp");
274 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
275 }
276 }
277
278 if (isBundleExist_) {
279 parsedBundles_.erase(bundleName_);
280 }
281 return ERR_OK;
282 }
283
CheckBundleTypeWithInstalledVersion()284 ErrCode InnerSharedBundleInstaller::CheckBundleTypeWithInstalledVersion()
285 {
286 if (oldBundleInfo_.GetApplicationBundleType() != BundleType::SHARED) {
287 APP_LOGE("old bundle is not shared");
288 return ERR_APPEXECFWK_INSTALL_COMPATIBLE_POLICY_NOT_SAME;
289 }
290
291 for (const auto &item : parsedBundles_) {
292 auto& sharedModules = item.second.GetInnerSharedModuleInfos();
293 if (sharedModules.empty() || sharedModules.begin()->second.empty()) {
294 APP_LOGW("inner shared module infos not found (%{public}s)", item.second.GetBundleName().c_str());
295 continue;
296 }
297
298 auto& sharedModule = sharedModules.begin()->second.front();
299 BaseSharedBundleInfo installedSharedModule;
300 if (oldBundleInfo_.GetMaxVerBaseSharedBundleInfo(sharedModule.moduleName, installedSharedModule) &&
301 installedSharedModule.versionCode > sharedModule.versionCode) {
302 APP_LOGE("installing lower version shared package");
303 return ERR_APPEXECFWK_INSTALL_VERSION_DOWNGRADE;
304 }
305 }
306 return ERR_OK;
307 }
308
MkdirIfNotExist(const std::string & dir)309 ErrCode InnerSharedBundleInstaller::MkdirIfNotExist(const std::string &dir)
310 {
311 bool isDirExist = false;
312 ErrCode result = InstalldClient::GetInstance()->IsExistDir(dir, isDirExist);
313 CHECK_RESULT(result, "check if dir exist failed %{public}d");
314 if (!isDirExist) {
315 result = InstalldClient::GetInstance()->CreateBundleDir(dir);
316 CHECK_RESULT(result, "create dir failed %{public}d");
317 createdDirs_.emplace_back(dir);
318 }
319 return result;
320 }
321
ExtractSharedBundles(const std::string & bundlePath,InnerBundleInfo & newInfo)322 ErrCode InnerSharedBundleInstaller::ExtractSharedBundles(const std::string &bundlePath, InnerBundleInfo &newInfo)
323 {
324 ErrCode result = ERR_OK;
325 std::string bundleDir = Constants::BUNDLE_CODE_DIR + ServiceConstants::PATH_SEPARATOR + bundleName_;
326 result = MkdirIfNotExist(bundleDir);
327 CHECK_RESULT(result, "check bundle dir failed %{public}d");
328 newInfo.SetAppCodePath(bundleDir);
329
330 uint32_t versionCode = newInfo.GetVersionCode();
331 std::string versionDir = bundleDir + ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX
332 + std::to_string(versionCode);
333 result = MkdirIfNotExist(versionDir);
334 CHECK_RESULT(result, "check version dir failed %{public}d");
335
336 auto &moduleName = newInfo.GetInnerModuleInfos().begin()->second.moduleName;
337 std::string moduleDir = versionDir + ServiceConstants::PATH_SEPARATOR + moduleName;
338 result = MkdirIfNotExist(moduleDir);
339 CHECK_RESULT(result, "check module dir failed %{public}d");
340
341 result = ProcessNativeLibrary(bundlePath, moduleDir, moduleName, versionDir, newInfo);
342 CHECK_RESULT(result, "ProcessNativeLibrary failed %{public}d");
343
344 if (newInfo.IsPreInstallApp()) {
345 // preInstallApp does not need to copy hsp
346 newInfo.SetModuleHapPath(bundlePath);
347 } else {
348 // save hsp and so files to installation dir
349 std::string realHspPath = moduleDir + ServiceConstants::PATH_SEPARATOR + moduleName +
350 ServiceConstants::HSP_FILE_SUFFIX;
351 result = SaveHspToRealInstallationDir(bundlePath, moduleDir, moduleName, realHspPath);
352 CHECK_RESULT(result, "save hsp file failed %{public}d");
353 newInfo.SetModuleHapPath(realHspPath);
354 }
355 if (newInfo.IsCompressNativeLibs(moduleName)) {
356 // move so to real path
357 result = MoveSoToRealPath(moduleName, versionDir);
358 CHECK_RESULT(result, "move so to real path failed %{public}d");
359 }
360 newInfo.AddModuleSrcDir(moduleDir);
361 newInfo.AddModuleResPath(moduleDir);
362 newInfo.UpdateSharedModuleInfo();
363 return ERR_OK;
364 }
365
UpdateInnerModuleInfo(const std::string packageName,const InnerModuleInfo & innerModuleInfo)366 void InnerSharedBundleInstaller::UpdateInnerModuleInfo(const std::string packageName,
367 const InnerModuleInfo &innerModuleInfo)
368 {
369 newBundleInfo_.ReplaceInnerModuleInfo(packageName, innerModuleInfo);
370 std::string moduleDir = std::string(Constants::BUNDLE_CODE_DIR) + ServiceConstants::PATH_SEPARATOR + bundleName_ +
371 ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX + std::to_string(innerModuleInfo.versionCode) +
372 ServiceConstants::PATH_SEPARATOR + innerModuleInfo.moduleName;
373 bool isDirExist = false;
374 ErrCode result = InstalldClient::GetInstance()->IsExistDir(moduleDir, isDirExist);
375 if (isDirExist) {
376 newBundleInfo_.SetCurrentModulePackage(packageName);
377 newBundleInfo_.AddModuleSrcDir(moduleDir);
378 newBundleInfo_.AddModuleResPath(moduleDir);
379 } else {
380 APP_LOGW("update path failed %{public}s %{public}d", moduleDir.c_str(), result);
381 }
382 }
383
MergeBundleInfos()384 void InnerSharedBundleInstaller::MergeBundleInfos()
385 {
386 auto iter = parsedBundles_.begin();
387 if (isBundleExist_) {
388 newBundleInfo_ = oldBundleInfo_;
389 } else {
390 newBundleInfo_ = iter->second;
391 ++iter;
392 }
393
394 for (; iter != parsedBundles_.end(); ++iter) {
395 const auto ¤tBundle = iter->second;
396 const auto& infos = currentBundle.GetInnerSharedModuleInfos();
397 if (infos.empty()) {
398 continue;
399 }
400
401 const auto& innerModuleInfos = infos.begin()->second;
402 if (!innerModuleInfos.empty()) {
403 const auto& innerModuleInfo = innerModuleInfos.front();
404 newBundleInfo_.InsertInnerSharedModuleInfo(innerModuleInfo.modulePackage, innerModuleInfo);
405 UpdateInnerModuleInfo(innerModuleInfo.modulePackage, innerModuleInfo);
406 }
407 // update version
408 if (newBundleInfo_.GetBaseBundleInfo().versionCode < currentBundle.GetBaseBundleInfo().versionCode) {
409 newBundleInfo_.UpdateBaseBundleInfo(currentBundle.GetBaseBundleInfo(), false);
410 newBundleInfo_.UpdateBaseApplicationInfo(currentBundle.GetBaseApplicationInfo(), false);
411 newBundleInfo_.UpdateReleaseType(currentBundle);
412 }
413 }
414
415 newBundleInfo_.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
416 newBundleInfo_.SetHideDesktopIcon(true);
417 }
418
SavePreInstallInfo(const InstallParam & installParam)419 ErrCode InnerSharedBundleInstaller::SavePreInstallInfo(const InstallParam &installParam)
420 {
421 if (!installParam.needSavePreInstallInfo) {
422 APP_LOGD("no need to save pre install info");
423 return ERR_OK;
424 }
425
426 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
427 if (dataMgr == nullptr) {
428 APP_LOGE("get dataMgr failed");
429 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
430 }
431
432 PreInstallBundleInfo preInstallBundleInfo;
433 if (!dataMgr->GetPreInstallBundleInfo(bundleName_, preInstallBundleInfo)) {
434 preInstallBundleInfo.SetBundleName(bundleName_);
435 }
436 preInstallBundleInfo.SetVersionCode(newBundleInfo_.GetBaseBundleInfo().versionCode);
437 for (const auto &item : parsedBundles_) {
438 preInstallBundleInfo.AddBundlePath(item.first);
439 }
440 #ifdef USE_PRE_BUNDLE_PROFILE
441 preInstallBundleInfo.SetRemovable(installParam.removable);
442 #else
443 preInstallBundleInfo.SetRemovable(newBundleInfo_.IsRemovable());
444 #endif
445 auto applicationInfo = newBundleInfo_.GetBaseApplicationInfo();
446 newBundleInfo_.AdaptMainLauncherResourceInfo(applicationInfo);
447 preInstallBundleInfo.SetLabelId(applicationInfo.labelResource.id);
448 preInstallBundleInfo.SetIconId(applicationInfo.iconResource.id);
449 preInstallBundleInfo.SetModuleName(applicationInfo.labelResource.moduleName);
450 preInstallBundleInfo.SetSystemApp(applicationInfo.isSystemApp);
451 preInstallBundleInfo.SetBundleType(BundleType::SHARED);
452 dataMgr->SavePreInstallBundleInfo(bundleName_, preInstallBundleInfo);
453 return ERR_OK;
454 }
455
SaveBundleInfoToStorage()456 ErrCode InnerSharedBundleInstaller::SaveBundleInfoToStorage()
457 {
458 // update install mark
459 std::string packageName;
460 newBundleInfo_.SetInstallMark(bundleName_, packageName, InstallExceptionStatus::INSTALL_FINISH);
461
462 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
463 if (dataMgr == nullptr) {
464 APP_LOGE("get dataMgr failed");
465 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
466 }
467
468 if (isBundleExist_) {
469 if (!dataMgr->UpdateInnerBundleInfo(newBundleInfo_, false)) {
470 APP_LOGE("save bundle failed : %{public}s", bundleName_.c_str());
471 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
472 }
473 return ERR_OK;
474 }
475
476 dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_START);
477 if (!dataMgr->AddInnerBundleInfo(bundleName_, newBundleInfo_)) {
478 dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_FAIL);
479 APP_LOGE("save bundle failed : %{public}s", bundleName_.c_str());
480 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
481 }
482 dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_SUCCESS);
483 return ERR_OK;
484 }
485
GetInstallEventInfo(EventInfo & eventInfo) const486 void InnerSharedBundleInstaller::GetInstallEventInfo(EventInfo &eventInfo) const
487 {
488 APP_LOGD("GetInstallEventInfo start, bundleName:%{public}s", bundleName_.c_str());
489 eventInfo.fingerprint = newBundleInfo_.GetCertificateFingerprint();
490 eventInfo.appDistributionType = newBundleInfo_.GetAppDistributionType();
491 eventInfo.hideDesktopIcon = newBundleInfo_.IsHideDesktopIcon();
492 eventInfo.timeStamp = BundleUtil::GetCurrentTimeMs();
493
494 // report hapPath and hashValue
495 for (const auto &info : parsedBundles_) {
496 for (const auto &innerModuleInfo : info.second.GetInnerModuleInfos()) {
497 eventInfo.filePath.push_back(innerModuleInfo.second.hapPath);
498 eventInfo.hashValue.push_back(innerModuleInfo.second.hashValue);
499 }
500 }
501 }
502
AddAppProvisionInfo(const std::string & bundleName,const Security::Verify::ProvisionInfo & provisionInfo) const503 void InnerSharedBundleInstaller::AddAppProvisionInfo(const std::string &bundleName,
504 const Security::Verify::ProvisionInfo &provisionInfo) const
505 {
506 AppProvisionInfo appProvisionInfo = bundleInstallChecker_->ConvertToAppProvisionInfo(provisionInfo);
507 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->AddAppProvisionInfo(
508 bundleName, appProvisionInfo)) {
509 APP_LOGW("bundleName: %{public}s add appProvisionInfo failed", bundleName.c_str());
510 }
511 }
512
SaveInstallParamInfo(const std::string & bundleName,const InstallParam & installParam) const513 void InnerSharedBundleInstaller::SaveInstallParamInfo(
514 const std::string &bundleName, const InstallParam &installParam) const
515 {
516 if (!installParam.specifiedDistributionType.empty()) {
517 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetSpecifiedDistributionType(
518 bundleName, installParam.specifiedDistributionType)) {
519 APP_LOGW("bundleName: %{public}s SetSpecifiedDistributionType failed", bundleName.c_str());
520 }
521 }
522 if (!installParam.additionalInfo.empty()) {
523 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetAdditionalInfo(
524 bundleName, installParam.additionalInfo)) {
525 APP_LOGW("bundleName: %{public}s SetAdditionalInfo failed", bundleName.c_str());
526 }
527 }
528 }
529
CopyHspToSecurityDir(std::vector<std::string> & bundlePaths)530 ErrCode InnerSharedBundleInstaller::CopyHspToSecurityDir(std::vector<std::string> &bundlePaths)
531 {
532 for (size_t index = 0; index < bundlePaths.size(); ++index) {
533 auto destination = BundleUtil::CopyFileToSecurityDir(bundlePaths[index], DirType::STREAM_INSTALL_DIR,
534 toDeleteTempHspPath_);
535 if (destination.empty()) {
536 APP_LOGE("copy file %{public}s to security dir failed", bundlePaths[index].c_str());
537 return ERR_APPEXECFWK_INSTALL_COPY_HAP_FAILED;
538 }
539 bundlePaths[index] = destination;
540 }
541 return ERR_OK;
542 }
543
ObtainHspFileAndSignatureFilePath(const std::vector<std::string> & inBundlePaths,std::vector<std::string> & bundlePaths,std::string & signatureFilePath)544 ErrCode InnerSharedBundleInstaller::ObtainHspFileAndSignatureFilePath(const std::vector<std::string> &inBundlePaths,
545 std::vector<std::string> &bundlePaths, std::string &signatureFilePath)
546 {
547 if (inBundlePaths.empty() || inBundlePaths.size() > MAX_FILE_NUMBER) {
548 APP_LOGE("number of files in single shared lib path is illegal");
549 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
550 }
551 if (inBundlePaths.size() == 1) {
552 if (!BundleUtil::EndWith(inBundlePaths[0], ServiceConstants::HSP_FILE_SUFFIX)) {
553 APP_LOGE("invalid file in shared bundle dir");
554 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
555 }
556 bundlePaths.emplace_back(inBundlePaths[0]);
557 return ERR_OK;
558 }
559 int32_t numberOfHsp = 0;
560 int32_t numberOfSignatureFile = 0;
561 for (const auto &path : inBundlePaths) {
562 if ((path.find(ServiceConstants::HSP_FILE_SUFFIX) == std::string::npos) &&
563 (path.find(ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX) == std::string::npos)) {
564 APP_LOGE("only hsp or sig file can be contained in shared bundle dir");
565 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
566 }
567 if (BundleUtil::EndWith(path, ServiceConstants::HSP_FILE_SUFFIX)) {
568 numberOfHsp++;
569 bundlePaths.emplace_back(path);
570 }
571 if (BundleUtil::EndWith(path, ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX)) {
572 numberOfSignatureFile++;
573 signatureFilePath = path;
574 }
575 if ((numberOfHsp >= MAX_FILE_NUMBER) || (numberOfSignatureFile >= MAX_FILE_NUMBER)) {
576 APP_LOGE("only one hsp and one signature file can be contained in a single shared bundle dir");
577 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
578 }
579 }
580 APP_LOGD("signatureFilePath is %{public}s", signatureFilePath.c_str());
581 return ERR_OK;
582 }
583
SaveHspToRealInstallationDir(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & realHspPath)584 ErrCode InnerSharedBundleInstaller::SaveHspToRealInstallationDir(const std::string &bundlePath,
585 const std::string &moduleDir,
586 const std::string &moduleName,
587 const std::string &realHspPath)
588 {
589 // 1. create temp dir
590 ErrCode result = ERR_OK;
591 std::string tempHspDir = moduleDir + ServiceConstants::PATH_SEPARATOR + moduleName;
592 result = MkdirIfNotExist(tempHspDir);
593 CHECK_RESULT(result, "create tempHspDir dir failed %{public}d");
594
595 // 2. copy hsp to installation dir, and then to verify code signature of hsp
596 std::string tempHspPath = tempHspDir + ServiceConstants::PATH_SEPARATOR + moduleName +
597 ServiceConstants::HSP_FILE_SUFFIX;
598 if (!signatureFileDir_.empty()) {
599 result = InstalldClient::GetInstance()->CopyFile(bundlePath, tempHspPath, signatureFileDir_);
600 } else {
601 result = InstalldClient::GetInstance()->MoveHapToCodeDir(bundlePath, tempHspPath);
602 CHECK_RESULT(result, "copy hsp to install dir failed %{public}d");
603 bool isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
604 result = VerifyCodeSignatureForHsp(tempHspPath, appIdentifier_, isEnterpriseBundle_,
605 isCompileSdkOpenHarmony, bundleName_);
606 }
607 CHECK_RESULT(result, "copy hsp to install dir failed %{public}d");
608
609 // 3. move hsp to real installation dir
610 APP_LOGD("move file from temp path %{public}s to real path %{public}s", tempHspPath.c_str(), realHspPath.c_str());
611 result = InstalldClient::GetInstance()->MoveFile(tempHspPath, realHspPath);
612 CHECK_RESULT(result, "move hsp to install dir failed %{public}d");
613
614 // 4. remove temp dir
615 result = InstalldClient::GetInstance()->RemoveDir(tempHspDir);
616 if (result != ERR_OK) {
617 APP_LOGW("remove temp hsp dir %{public}s failed, error is %{public}d", tempHspDir.c_str(), result);
618 }
619 return ERR_OK;
620 }
621
MoveSoToRealPath(const std::string & moduleName,const std::string & versionDir)622 ErrCode InnerSharedBundleInstaller::MoveSoToRealPath(const std::string &moduleName, const std::string &versionDir)
623 {
624 // 1. move so files to real installation dir
625 std::string realSoPath = versionDir + ServiceConstants::PATH_SEPARATOR + nativeLibraryPath_ +
626 ServiceConstants::PATH_SEPARATOR;
627 ErrCode result = MkdirIfNotExist(realSoPath);
628 CHECK_RESULT(result, "check module dir failed %{public}d");
629
630 std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath_);
631 if (tempNativeLibraryPath.empty()) {
632 APP_LOGI("no so libs existed");
633 return ERR_OK;
634 }
635 std::string tempSoPath = versionDir + ServiceConstants::PATH_SEPARATOR + tempNativeLibraryPath;
636 APP_LOGD("move so files from path %{public}s to path %{public}s", tempSoPath.c_str(), realSoPath.c_str());
637 result = InstalldClient::GetInstance()->MoveFiles(tempSoPath, realSoPath);
638 if (result != ERR_OK) {
639 APP_LOGE("move file to real path failed %{public}d", result);
640 return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
641 }
642
643 // 2. remove so temp dir
644 std::string deleteTempDir = versionDir + ServiceConstants::PATH_SEPARATOR + moduleName
645 + ServiceConstants::TMP_SUFFIX;
646 result = InstalldClient::GetInstance()->RemoveDir(deleteTempDir);
647 if (result != ERR_OK) {
648 APP_LOGW("remove hsp temp so dir %{public}s failed, error is %{public}d", deleteTempDir.c_str(), result);
649 }
650 return ERR_OK;
651 }
652
ObtainTempSoPath(const std::string & moduleName,const std::string & nativeLibPath)653 std::string InnerSharedBundleInstaller::ObtainTempSoPath(const std::string &moduleName,
654 const std::string &nativeLibPath)
655 {
656 std::string tempSoPath;
657 if (nativeLibPath.empty()) {
658 APP_LOGE("invalid native libs path");
659 return tempSoPath;
660 }
661 tempSoPath = nativeLibPath;
662 auto pos = tempSoPath.find(moduleName);
663 if (pos == std::string::npos) {
664 tempSoPath = moduleName + ServiceConstants::TMP_SUFFIX + ServiceConstants::PATH_SEPARATOR + tempSoPath;
665 } else {
666 std::string innerTempStr = moduleName + ServiceConstants::TMP_SUFFIX;
667 tempSoPath.replace(pos, moduleName.length(), innerTempStr);
668 }
669 return tempSoPath + ServiceConstants::PATH_SEPARATOR;
670 }
671
ProcessNativeLibrary(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & versionDir,InnerBundleInfo & newInfo)672 ErrCode InnerSharedBundleInstaller::ProcessNativeLibrary(
673 const std::string &bundlePath,
674 const std::string &moduleDir,
675 const std::string &moduleName,
676 const std::string &versionDir,
677 InnerBundleInfo &newInfo)
678 {
679 std::string cpuAbi;
680 if (!newInfo.FetchNativeSoAttrs(moduleName, cpuAbi, nativeLibraryPath_)) {
681 return ERR_OK;
682 }
683 if (newInfo.IsCompressNativeLibs(moduleName)) {
684 std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath_);
685 if (tempNativeLibraryPath.empty()) {
686 APP_LOGE("tempNativeLibraryPath is empty");
687 return ERR_APPEXECFWK_INSTALLD_EXTRACT_FILES_FAILED;
688 }
689 std::string tempSoPath = versionDir + ServiceConstants::PATH_SEPARATOR + tempNativeLibraryPath;
690 APP_LOGD("tempSoPath=%{public}s,cpuAbi=%{public}s, bundlePath=%{public}s",
691 tempSoPath.c_str(), cpuAbi.c_str(), bundlePath.c_str());
692 auto result = InstalldClient::GetInstance()->ExtractModuleFiles(bundlePath, moduleDir, tempSoPath, cpuAbi);
693 CHECK_RESULT(result, "extract module files failed %{public}d");
694 // verify hap or hsp code signature for compressed so files
695 result = VerifyCodeSignatureForNativeFiles(
696 bundlePath, cpuAbi, tempSoPath, signatureFileDir_, newInfo.IsPreInstallApp());
697 CHECK_RESULT(result, "fail to VerifyCodeSignature, error is %{public}d");
698 cpuAbi_ = cpuAbi;
699 tempSoPath_ = tempSoPath;
700 isPreInstalledBundle_ = newInfo.IsPreInstallApp();
701 } else {
702 std::vector<std::string> fileNames;
703 auto result = InstalldClient::GetInstance()->GetNativeLibraryFileNames(bundlePath, cpuAbi, fileNames);
704 CHECK_RESULT(result, "fail to GetNativeLibraryFileNames, error is %{public}d");
705 newInfo.SetNativeLibraryFileNames(moduleName, fileNames);
706 }
707 return ERR_OK;
708 }
709
VerifyCodeSignatureForNativeFiles(const std::string & bundlePath,const std::string & cpuAbi,const std::string & targetSoPath,const std::string & signatureFileDir,bool isPreInstalledBundle) const710 ErrCode InnerSharedBundleInstaller::VerifyCodeSignatureForNativeFiles(const std::string &bundlePath,
711 const std::string &cpuAbi, const std::string &targetSoPath, const std::string &signatureFileDir,
712 bool isPreInstalledBundle) const
713 {
714 if (!isPreInstalledBundle) {
715 APP_LOGD("not pre-install app, skip verify code signature for native files");
716 return ERR_OK;
717 }
718 APP_LOGD("begin to verify code signature for hsp native files");
719 bool isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
720 CodeSignatureParam codeSignatureParam;
721 codeSignatureParam.modulePath = bundlePath;
722 codeSignatureParam.cpuAbi = cpuAbi;
723 codeSignatureParam.targetSoPath = targetSoPath;
724 codeSignatureParam.signatureFileDir = signatureFileDir;
725 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle_;
726 codeSignatureParam.appIdentifier = appIdentifier_;
727 codeSignatureParam.isCompileSdkOpenHarmony = isCompileSdkOpenHarmony;
728 codeSignatureParam.isPreInstalledBundle = isPreInstalledBundle;
729 return InstalldClient::GetInstance()->VerifyCodeSignature(codeSignatureParam);
730 }
731
VerifyCodeSignatureForHsp(const std::string & tempHspPath,const std::string & appIdentifier,bool isEnterpriseBundle,bool isCompileSdkOpenHarmony,const std::string & bundleName) const732 ErrCode InnerSharedBundleInstaller::VerifyCodeSignatureForHsp(const std::string &tempHspPath,
733 const std::string &appIdentifier, bool isEnterpriseBundle, bool isCompileSdkOpenHarmony,
734 const std::string &bundleName) const
735 {
736 APP_LOGD("begin to verify code signature for hsp");
737 CodeSignatureParam codeSignatureParam;
738 codeSignatureParam.modulePath = tempHspPath;
739 codeSignatureParam.cpuAbi = cpuAbi_;
740 codeSignatureParam.targetSoPath = tempSoPath_;
741 codeSignatureParam.appIdentifier = appIdentifier;
742 codeSignatureParam.signatureFileDir = signatureFileDir_;
743 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle;
744 codeSignatureParam.isCompileSdkOpenHarmony = isCompileSdkOpenHarmony;
745 codeSignatureParam.isPreInstalledBundle = isPreInstalledBundle_;
746 return InstalldClient::GetInstance()->VerifyCodeSignatureForHap(codeSignatureParam);
747 }
748
DeliveryProfileToCodeSign(std::vector<Security::Verify::HapVerifyResult> & hapVerifyResults) const749 ErrCode InnerSharedBundleInstaller::DeliveryProfileToCodeSign(
750 std::vector<Security::Verify::HapVerifyResult> &hapVerifyResults) const
751 {
752 if (isBundleExist_) {
753 APP_LOGD("shared bundle %{public}s has been installed and unnecessary to delivery sign profile",
754 bundleName_.c_str());
755 return ERR_OK;
756 }
757 if (hapVerifyResults.empty()) {
758 APP_LOGE("no sign info in the all haps");
759 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
760 }
761
762 Security::Verify::ProvisionInfo provisionInfo = hapVerifyResults[0].GetProvisionInfo();
763 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE ||
764 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL ||
765 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM ||
766 provisionInfo.type == Security::Verify::ProvisionType::DEBUG) {
767 if (provisionInfo.profileBlockLength == 0 || provisionInfo.profileBlock == nullptr) {
768 APP_LOGE("invalid sign profile");
769 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
770 }
771 return InstalldClient::GetInstance()->DeliverySignProfile(provisionInfo.bundleInfo.bundleName,
772 provisionInfo.profileBlockLength, provisionInfo.profileBlock.get());
773 }
774 return ERR_OK;
775 }
776
SetCheckResultMsg(const std::string checkResultMsg) const777 void InnerSharedBundleInstaller::SetCheckResultMsg(const std::string checkResultMsg) const
778 {
779 bundleInstallChecker_->SetCheckResultMsg(checkResultMsg);
780 }
781
MarkInstallFinish()782 ErrCode InnerSharedBundleInstaller::MarkInstallFinish()
783 {
784 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
785 if (dataMgr == nullptr) {
786 APP_LOGE("Get dataMgr shared_ptr nullptr");
787 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
788 }
789 InnerBundleInfo info;
790 if (!dataMgr->FetchInnerBundleInfo(bundleName_, info)) {
791 APP_LOGE("mark finish failed, -n %{public}s not exist", bundleName_.c_str());
792 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
793 }
794 info.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
795 info.SetInstallMark(bundleName_, info.GetCurModuleName(), InstallExceptionStatus::INSTALL_FINISH);
796 if (!dataMgr->UpdateInnerBundleInfo(info, true)) {
797 if (!dataMgr->UpdateInnerBundleInfo(info, true)) {
798 APP_LOGE("save mark failed, -n %{public}s", bundleName_.c_str());
799 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
800 }
801 }
802 return ERR_OK;
803 }
804 } // namespace AppExecFwk
805 } // namespace OHOS
806