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 MarkInstallFinish();
177 APP_LOGD("install shared bundle successfully: %{public}s", bundleName_.c_str());
178 return result;
179 }
180
RollBack()181 void InnerSharedBundleInstaller::RollBack()
182 {
183 // delete created directories
184 for (auto iter = createdDirs_.crbegin(); iter != createdDirs_.crend(); ++iter) {
185 ErrCode err = InstalldClient::GetInstance()->RemoveDir(*iter);
186 if (err != ERR_OK) {
187 APP_LOGE("clean dir of %{public}s failed: %{public}s", bundleName_.c_str(), iter->c_str());
188 }
189 }
190
191 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
192 if (dataMgr == nullptr) {
193 APP_LOGE("get dataMgr failed");
194 return;
195 }
196
197 // rollback database
198 if (!isBundleExist_) {
199 if (dataMgr->DeleteSharedBundleInfo(bundleName_)) {
200 APP_LOGE("rollback new bundle failed : %{public}s", bundleName_.c_str());
201 }
202 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->DeleteAppProvisionInfo(bundleName_)) {
203 APP_LOGE("bundleName: %{public}s delete appProvisionInfo failed", bundleName_.c_str());
204 }
205 return;
206 }
207
208 if (dataMgr->UpdateInnerBundleInfo(oldBundleInfo_)) {
209 APP_LOGE("rollback old bundle failed : %{public}s", bundleName_.c_str());
210 }
211 }
212
CheckDependency(const Dependency & dependency) const213 bool InnerSharedBundleInstaller::CheckDependency(const Dependency &dependency) const
214 {
215 if (dependency.bundleName != bundleName_) {
216 APP_LOGE("bundle name not match : %{public}s, %{public}s", bundleName_.c_str(), dependency.bundleName.c_str());
217 return false;
218 }
219
220 for (const auto &item : parsedBundles_) {
221 const auto bundleInfo = item.second;
222 BaseSharedBundleInfo sharedBundle;
223 bool isModuleExist = bundleInfo.GetMaxVerBaseSharedBundleInfo(dependency.moduleName, sharedBundle);
224 if (isModuleExist && dependency.versionCode <= sharedBundle.versionCode) {
225 return true;
226 }
227 }
228
229 APP_LOGE("dependency not match");
230 return false;
231 }
232
SendBundleSystemEvent(const EventInfo & eventTemplate) const233 void InnerSharedBundleInstaller::SendBundleSystemEvent(const EventInfo &eventTemplate) const
234 {
235 EventInfo eventInfo = eventTemplate;
236 eventInfo.bundleName = bundleName_;
237 eventInfo.versionCode = newBundleInfo_.GetBaseBundleInfo().versionCode;
238 GetInstallEventInfo(eventInfo);
239
240 BundleEventType eventType = isBundleExist_ ? BundleEventType::UPDATE : BundleEventType::INSTALL;
241 EventReport::SendBundleSystemEvent(eventType, eventInfo);
242 }
243
CheckAppLabelInfo()244 ErrCode InnerSharedBundleInstaller::CheckAppLabelInfo()
245 {
246 if (parsedBundles_.empty()) {
247 APP_LOGE("parsedBundles is empty");
248 return ERR_OK;
249 }
250 bundleName_ = parsedBundles_.begin()->second.GetBundleName();
251
252 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
253 if (dataMgr == nullptr) {
254 APP_LOGE("Get dataMgr shared_ptr nullptr");
255 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
256 }
257
258 isBundleExist_ = dataMgr->FetchInnerBundleInfo(bundleName_, oldBundleInfo_);
259 if (isBundleExist_) {
260 ErrCode ret = CheckBundleTypeWithInstalledVersion();
261 CHECK_RESULT(ret, "check bundle type with installed version failed %{public}d");
262
263 // check old InnerBundleInfo together
264 parsedBundles_.emplace(bundleName_, oldBundleInfo_);
265 } else {
266 if (parsedBundles_.begin()->second.GetApplicationBundleType() != BundleType::SHARED) {
267 APP_LOGE("installing bundle is not hsp");
268 return ERR_APPEXECFWK_INSTALL_PARAM_ERROR;
269 }
270 }
271
272 if (isBundleExist_) {
273 parsedBundles_.erase(bundleName_);
274 }
275 return ERR_OK;
276 }
277
CheckBundleTypeWithInstalledVersion()278 ErrCode InnerSharedBundleInstaller::CheckBundleTypeWithInstalledVersion()
279 {
280 if (oldBundleInfo_.GetApplicationBundleType() != BundleType::SHARED) {
281 APP_LOGE("old bundle is not shared");
282 return ERR_APPEXECFWK_INSTALL_COMPATIBLE_POLICY_NOT_SAME;
283 }
284
285 for (const auto &item : parsedBundles_) {
286 auto& sharedModules = item.second.GetInnerSharedModuleInfos();
287 if (sharedModules.empty() || sharedModules.begin()->second.empty()) {
288 APP_LOGW("inner shared module infos not found (%{public}s)", item.second.GetBundleName().c_str());
289 continue;
290 }
291
292 auto& sharedModule = sharedModules.begin()->second.front();
293 BaseSharedBundleInfo installedSharedModule;
294 if (oldBundleInfo_.GetMaxVerBaseSharedBundleInfo(sharedModule.moduleName, installedSharedModule) &&
295 installedSharedModule.versionCode > sharedModule.versionCode) {
296 APP_LOGE("installing lower version shared package");
297 return ERR_APPEXECFWK_INSTALL_VERSION_DOWNGRADE;
298 }
299 }
300 return ERR_OK;
301 }
302
MkdirIfNotExist(const std::string & dir)303 ErrCode InnerSharedBundleInstaller::MkdirIfNotExist(const std::string &dir)
304 {
305 bool isDirExist = false;
306 ErrCode result = InstalldClient::GetInstance()->IsExistDir(dir, isDirExist);
307 CHECK_RESULT(result, "check if dir exist failed %{public}d");
308 if (!isDirExist) {
309 result = InstalldClient::GetInstance()->CreateBundleDir(dir);
310 CHECK_RESULT(result, "create dir failed %{public}d");
311 createdDirs_.emplace_back(dir);
312 }
313 return result;
314 }
315
ExtractSharedBundles(const std::string & bundlePath,InnerBundleInfo & newInfo)316 ErrCode InnerSharedBundleInstaller::ExtractSharedBundles(const std::string &bundlePath, InnerBundleInfo &newInfo)
317 {
318 ErrCode result = ERR_OK;
319 std::string bundleDir = Constants::BUNDLE_CODE_DIR + ServiceConstants::PATH_SEPARATOR + bundleName_;
320 result = MkdirIfNotExist(bundleDir);
321 CHECK_RESULT(result, "check bundle dir failed %{public}d");
322 newInfo.SetAppCodePath(bundleDir);
323
324 uint32_t versionCode = newInfo.GetVersionCode();
325 std::string versionDir = bundleDir + ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX
326 + std::to_string(versionCode);
327 result = MkdirIfNotExist(versionDir);
328 CHECK_RESULT(result, "check version dir failed %{public}d");
329
330 auto &moduleName = newInfo.GetInnerModuleInfos().begin()->second.moduleName;
331 std::string moduleDir = versionDir + ServiceConstants::PATH_SEPARATOR + moduleName;
332 result = MkdirIfNotExist(moduleDir);
333 CHECK_RESULT(result, "check module dir failed %{public}d");
334
335 result = ProcessNativeLibrary(bundlePath, moduleDir, moduleName, versionDir, newInfo);
336 CHECK_RESULT(result, "ProcessNativeLibrary failed %{public}d");
337
338 if (newInfo.IsPreInstallApp()) {
339 // preInstallApp does not need to copy hsp
340 newInfo.SetModuleHapPath(bundlePath);
341 } else {
342 // save hsp and so files to installation dir
343 std::string realHspPath = moduleDir + ServiceConstants::PATH_SEPARATOR + moduleName +
344 ServiceConstants::HSP_FILE_SUFFIX;
345 result = SaveHspToRealInstallationDir(bundlePath, moduleDir, moduleName, realHspPath);
346 CHECK_RESULT(result, "save hsp file failed %{public}d");
347 newInfo.SetModuleHapPath(realHspPath);
348 }
349 if (newInfo.IsCompressNativeLibs(moduleName)) {
350 // move so to real path
351 result = MoveSoToRealPath(moduleName, versionDir);
352 CHECK_RESULT(result, "move so to real path failed %{public}d");
353 }
354 newInfo.AddModuleSrcDir(moduleDir);
355 newInfo.AddModuleResPath(moduleDir);
356 newInfo.UpdateSharedModuleInfo();
357 return ERR_OK;
358 }
359
UpdateInnerModuleInfo(const std::string packageName,const InnerModuleInfo & innerModuleInfo)360 void InnerSharedBundleInstaller::UpdateInnerModuleInfo(const std::string packageName,
361 const InnerModuleInfo &innerModuleInfo)
362 {
363 newBundleInfo_.ReplaceInnerModuleInfo(packageName, innerModuleInfo);
364 std::string moduleDir = std::string(Constants::BUNDLE_CODE_DIR) + ServiceConstants::PATH_SEPARATOR + bundleName_ +
365 ServiceConstants::PATH_SEPARATOR + HSP_VERSION_PREFIX + std::to_string(innerModuleInfo.versionCode) +
366 ServiceConstants::PATH_SEPARATOR + innerModuleInfo.moduleName;
367 bool isDirExist = false;
368 ErrCode result = InstalldClient::GetInstance()->IsExistDir(moduleDir, isDirExist);
369 if (isDirExist) {
370 newBundleInfo_.SetCurrentModulePackage(packageName);
371 newBundleInfo_.AddModuleSrcDir(moduleDir);
372 newBundleInfo_.AddModuleResPath(moduleDir);
373 } else {
374 APP_LOGW("update path failed %{public}s %{public}d", moduleDir.c_str(), result);
375 }
376 }
377
MergeBundleInfos()378 void InnerSharedBundleInstaller::MergeBundleInfos()
379 {
380 auto iter = parsedBundles_.begin();
381 if (isBundleExist_) {
382 newBundleInfo_ = oldBundleInfo_;
383 } else {
384 newBundleInfo_ = iter->second;
385 ++iter;
386 }
387
388 for (; iter != parsedBundles_.end(); ++iter) {
389 const auto ¤tBundle = iter->second;
390 const auto& infos = currentBundle.GetInnerSharedModuleInfos();
391 if (infos.empty()) {
392 continue;
393 }
394
395 const auto& innerModuleInfos = infos.begin()->second;
396 if (!innerModuleInfos.empty()) {
397 const auto& innerModuleInfo = innerModuleInfos.front();
398 newBundleInfo_.InsertInnerSharedModuleInfo(innerModuleInfo.modulePackage, innerModuleInfo);
399 UpdateInnerModuleInfo(innerModuleInfo.modulePackage, innerModuleInfo);
400 }
401 // update version
402 if (newBundleInfo_.GetBaseBundleInfo().versionCode < currentBundle.GetBaseBundleInfo().versionCode) {
403 newBundleInfo_.UpdateBaseBundleInfo(currentBundle.GetBaseBundleInfo(), false);
404 newBundleInfo_.UpdateBaseApplicationInfo(currentBundle.GetBaseApplicationInfo(), false);
405 newBundleInfo_.UpdateReleaseType(currentBundle);
406 }
407 }
408
409 newBundleInfo_.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
410 newBundleInfo_.SetHideDesktopIcon(true);
411 }
412
SavePreInstallInfo(const InstallParam & installParam)413 ErrCode InnerSharedBundleInstaller::SavePreInstallInfo(const InstallParam &installParam)
414 {
415 if (!installParam.needSavePreInstallInfo) {
416 APP_LOGD("no need to save pre install info");
417 return ERR_OK;
418 }
419
420 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
421 if (dataMgr == nullptr) {
422 APP_LOGE("get dataMgr failed");
423 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
424 }
425
426 PreInstallBundleInfo preInstallBundleInfo;
427 if (!dataMgr->GetPreInstallBundleInfo(bundleName_, preInstallBundleInfo)) {
428 preInstallBundleInfo.SetBundleName(bundleName_);
429 }
430 preInstallBundleInfo.SetVersionCode(newBundleInfo_.GetBaseBundleInfo().versionCode);
431 for (const auto &item : parsedBundles_) {
432 preInstallBundleInfo.AddBundlePath(item.first);
433 }
434 #ifdef USE_PRE_BUNDLE_PROFILE
435 preInstallBundleInfo.SetRemovable(installParam.removable);
436 #else
437 preInstallBundleInfo.SetRemovable(newBundleInfo_.IsRemovable());
438 #endif
439 auto applicationInfo = newBundleInfo_.GetBaseApplicationInfo();
440 newBundleInfo_.AdaptMainLauncherResourceInfo(applicationInfo);
441 preInstallBundleInfo.SetLabelId(applicationInfo.labelResource.id);
442 preInstallBundleInfo.SetIconId(applicationInfo.iconResource.id);
443 preInstallBundleInfo.SetModuleName(applicationInfo.labelResource.moduleName);
444 preInstallBundleInfo.SetSystemApp(applicationInfo.isSystemApp);
445 preInstallBundleInfo.SetBundleType(BundleType::SHARED);
446 dataMgr->SavePreInstallBundleInfo(bundleName_, preInstallBundleInfo);
447 return ERR_OK;
448 }
449
SaveBundleInfoToStorage()450 ErrCode InnerSharedBundleInstaller::SaveBundleInfoToStorage()
451 {
452 // update install mark
453 std::string packageName;
454 newBundleInfo_.SetInstallMark(bundleName_, packageName, InstallExceptionStatus::INSTALL_FINISH);
455
456 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
457 if (dataMgr == nullptr) {
458 APP_LOGE("get dataMgr failed");
459 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
460 }
461
462 if (isBundleExist_) {
463 if (!dataMgr->UpdateInnerBundleInfo(newBundleInfo_, false)) {
464 APP_LOGE("save bundle failed : %{public}s", bundleName_.c_str());
465 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
466 }
467 return ERR_OK;
468 }
469
470 dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_START);
471 if (!dataMgr->AddInnerBundleInfo(bundleName_, newBundleInfo_)) {
472 dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_FAIL);
473 APP_LOGE("save bundle failed : %{public}s", bundleName_.c_str());
474 return ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR;
475 }
476 dataMgr->UpdateBundleInstallState(bundleName_, InstallState::INSTALL_SUCCESS);
477 return ERR_OK;
478 }
479
GetInstallEventInfo(EventInfo & eventInfo) const480 void InnerSharedBundleInstaller::GetInstallEventInfo(EventInfo &eventInfo) const
481 {
482 APP_LOGD("GetInstallEventInfo start, bundleName:%{public}s", bundleName_.c_str());
483 eventInfo.fingerprint = newBundleInfo_.GetCertificateFingerprint();
484 eventInfo.appDistributionType = newBundleInfo_.GetAppDistributionType();
485 eventInfo.hideDesktopIcon = newBundleInfo_.IsHideDesktopIcon();
486 eventInfo.timeStamp = BundleUtil::GetCurrentTimeMs();
487
488 // report hapPath and hashValue
489 for (const auto &info : parsedBundles_) {
490 for (const auto &innerModuleInfo : info.second.GetInnerModuleInfos()) {
491 eventInfo.filePath.push_back(innerModuleInfo.second.hapPath);
492 eventInfo.hashValue.push_back(innerModuleInfo.second.hashValue);
493 }
494 }
495 }
496
AddAppProvisionInfo(const std::string & bundleName,const Security::Verify::ProvisionInfo & provisionInfo) const497 void InnerSharedBundleInstaller::AddAppProvisionInfo(const std::string &bundleName,
498 const Security::Verify::ProvisionInfo &provisionInfo) const
499 {
500 AppProvisionInfo appProvisionInfo = bundleInstallChecker_->ConvertToAppProvisionInfo(provisionInfo);
501 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->AddAppProvisionInfo(
502 bundleName, appProvisionInfo)) {
503 APP_LOGW("bundleName: %{public}s add appProvisionInfo failed", bundleName.c_str());
504 }
505 }
506
SaveInstallParamInfo(const std::string & bundleName,const InstallParam & installParam) const507 void InnerSharedBundleInstaller::SaveInstallParamInfo(
508 const std::string &bundleName, const InstallParam &installParam) const
509 {
510 if (!installParam.specifiedDistributionType.empty()) {
511 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetSpecifiedDistributionType(
512 bundleName, installParam.specifiedDistributionType)) {
513 APP_LOGW("bundleName: %{public}s SetSpecifiedDistributionType failed", bundleName.c_str());
514 }
515 }
516 if (!installParam.additionalInfo.empty()) {
517 if (!DelayedSingleton<AppProvisionInfoManager>::GetInstance()->SetAdditionalInfo(
518 bundleName, installParam.additionalInfo)) {
519 APP_LOGW("bundleName: %{public}s SetAdditionalInfo failed", bundleName.c_str());
520 }
521 }
522 }
523
CopyHspToSecurityDir(std::vector<std::string> & bundlePaths)524 ErrCode InnerSharedBundleInstaller::CopyHspToSecurityDir(std::vector<std::string> &bundlePaths)
525 {
526 for (size_t index = 0; index < bundlePaths.size(); ++index) {
527 auto destination = BundleUtil::CopyFileToSecurityDir(bundlePaths[index], DirType::STREAM_INSTALL_DIR,
528 toDeleteTempHspPath_);
529 if (destination.empty()) {
530 APP_LOGE("copy file %{public}s to security dir failed", bundlePaths[index].c_str());
531 return ERR_APPEXECFWK_INSTALL_COPY_HAP_FAILED;
532 }
533 bundlePaths[index] = destination;
534 }
535 return ERR_OK;
536 }
537
ObtainHspFileAndSignatureFilePath(const std::vector<std::string> & inBundlePaths,std::vector<std::string> & bundlePaths,std::string & signatureFilePath)538 ErrCode InnerSharedBundleInstaller::ObtainHspFileAndSignatureFilePath(const std::vector<std::string> &inBundlePaths,
539 std::vector<std::string> &bundlePaths, std::string &signatureFilePath)
540 {
541 if (inBundlePaths.empty() || inBundlePaths.size() > MAX_FILE_NUMBER) {
542 APP_LOGE("number of files in single shared lib path is illegal");
543 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
544 }
545 if (inBundlePaths.size() == 1) {
546 if (!BundleUtil::EndWith(inBundlePaths[0], ServiceConstants::HSP_FILE_SUFFIX)) {
547 APP_LOGE("invalid file in shared bundle dir");
548 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
549 }
550 bundlePaths.emplace_back(inBundlePaths[0]);
551 return ERR_OK;
552 }
553 int32_t numberOfHsp = 0;
554 int32_t numberOfSignatureFile = 0;
555 for (const auto &path : inBundlePaths) {
556 if ((path.find(ServiceConstants::HSP_FILE_SUFFIX) == std::string::npos) &&
557 (path.find(ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX) == std::string::npos)) {
558 APP_LOGE("only hsp or sig file can be contained in shared bundle dir");
559 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
560 }
561 if (BundleUtil::EndWith(path, ServiceConstants::HSP_FILE_SUFFIX)) {
562 numberOfHsp++;
563 bundlePaths.emplace_back(path);
564 }
565 if (BundleUtil::EndWith(path, ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX)) {
566 numberOfSignatureFile++;
567 signatureFilePath = path;
568 }
569 if ((numberOfHsp >= MAX_FILE_NUMBER) || (numberOfSignatureFile >= MAX_FILE_NUMBER)) {
570 APP_LOGE("only one hsp and one signature file can be contained in a single shared bundle dir");
571 return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID;
572 }
573 }
574 APP_LOGD("signatureFilePath is %{public}s", signatureFilePath.c_str());
575 return ERR_OK;
576 }
577
SaveHspToRealInstallationDir(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & realHspPath)578 ErrCode InnerSharedBundleInstaller::SaveHspToRealInstallationDir(const std::string &bundlePath,
579 const std::string &moduleDir,
580 const std::string &moduleName,
581 const std::string &realHspPath)
582 {
583 // 1. create temp dir
584 ErrCode result = ERR_OK;
585 std::string tempHspDir = moduleDir + ServiceConstants::PATH_SEPARATOR + moduleName;
586 result = MkdirIfNotExist(tempHspDir);
587 CHECK_RESULT(result, "create tempHspDir dir failed %{public}d");
588
589 // 2. copy hsp to installation dir, and then to verify code signature of hsp
590 std::string tempHspPath = tempHspDir + ServiceConstants::PATH_SEPARATOR + moduleName +
591 ServiceConstants::HSP_FILE_SUFFIX;
592 if (!signatureFileDir_.empty()) {
593 result = InstalldClient::GetInstance()->CopyFile(bundlePath, tempHspPath, signatureFileDir_);
594 } else {
595 result = InstalldClient::GetInstance()->MoveHapToCodeDir(bundlePath, tempHspPath);
596 CHECK_RESULT(result, "copy hsp to install dir failed %{public}d");
597 bool isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
598 result = VerifyCodeSignatureForHsp(tempHspPath, appIdentifier_, isEnterpriseBundle_,
599 isCompileSdkOpenHarmony, bundleName_);
600 }
601 CHECK_RESULT(result, "copy hsp to install dir failed %{public}d");
602
603 // 3. move hsp to real installation dir
604 APP_LOGD("move file from temp path %{public}s to real path %{public}s", tempHspPath.c_str(), realHspPath.c_str());
605 result = InstalldClient::GetInstance()->MoveFile(tempHspPath, realHspPath);
606 CHECK_RESULT(result, "move hsp to install dir failed %{public}d");
607
608 // 4. remove temp dir
609 result = InstalldClient::GetInstance()->RemoveDir(tempHspDir);
610 if (result != ERR_OK) {
611 APP_LOGW("remove temp hsp dir %{public}s failed, error is %{public}d", tempHspDir.c_str(), result);
612 }
613 return ERR_OK;
614 }
615
MoveSoToRealPath(const std::string & moduleName,const std::string & versionDir)616 ErrCode InnerSharedBundleInstaller::MoveSoToRealPath(const std::string &moduleName, const std::string &versionDir)
617 {
618 // 1. move so files to real installation dir
619 std::string realSoPath = versionDir + ServiceConstants::PATH_SEPARATOR + nativeLibraryPath_ +
620 ServiceConstants::PATH_SEPARATOR;
621 ErrCode result = MkdirIfNotExist(realSoPath);
622 CHECK_RESULT(result, "check module dir failed %{public}d");
623
624 std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath_);
625 if (tempNativeLibraryPath.empty()) {
626 APP_LOGI("no so libs existed");
627 return ERR_OK;
628 }
629 std::string tempSoPath = versionDir + ServiceConstants::PATH_SEPARATOR + tempNativeLibraryPath;
630 APP_LOGD("move so files from path %{public}s to path %{public}s", tempSoPath.c_str(), realSoPath.c_str());
631 result = InstalldClient::GetInstance()->MoveFiles(tempSoPath, realSoPath);
632 if (result != ERR_OK) {
633 APP_LOGE("move file to real path failed %{public}d", result);
634 return ERR_APPEXECFWK_INSTALLD_MOVE_FILE_FAILED;
635 }
636
637 // 2. remove so temp dir
638 std::string deleteTempDir = versionDir + ServiceConstants::PATH_SEPARATOR + moduleName
639 + ServiceConstants::TMP_SUFFIX;
640 result = InstalldClient::GetInstance()->RemoveDir(deleteTempDir);
641 if (result != ERR_OK) {
642 APP_LOGW("remove hsp temp so dir %{public}s failed, error is %{public}d", deleteTempDir.c_str(), result);
643 }
644 return ERR_OK;
645 }
646
ObtainTempSoPath(const std::string & moduleName,const std::string & nativeLibPath)647 std::string InnerSharedBundleInstaller::ObtainTempSoPath(const std::string &moduleName,
648 const std::string &nativeLibPath)
649 {
650 std::string tempSoPath;
651 if (nativeLibPath.empty()) {
652 APP_LOGE("invalid native libs path");
653 return tempSoPath;
654 }
655 tempSoPath = nativeLibPath;
656 auto pos = tempSoPath.find(moduleName);
657 if (pos == std::string::npos) {
658 tempSoPath = moduleName + ServiceConstants::TMP_SUFFIX + ServiceConstants::PATH_SEPARATOR + tempSoPath;
659 } else {
660 std::string innerTempStr = moduleName + ServiceConstants::TMP_SUFFIX;
661 tempSoPath.replace(pos, moduleName.length(), innerTempStr);
662 }
663 return tempSoPath + ServiceConstants::PATH_SEPARATOR;
664 }
665
ProcessNativeLibrary(const std::string & bundlePath,const std::string & moduleDir,const std::string & moduleName,const std::string & versionDir,InnerBundleInfo & newInfo)666 ErrCode InnerSharedBundleInstaller::ProcessNativeLibrary(
667 const std::string &bundlePath,
668 const std::string &moduleDir,
669 const std::string &moduleName,
670 const std::string &versionDir,
671 InnerBundleInfo &newInfo)
672 {
673 std::string cpuAbi;
674 if (!newInfo.FetchNativeSoAttrs(moduleName, cpuAbi, nativeLibraryPath_)) {
675 return ERR_OK;
676 }
677 if (newInfo.IsCompressNativeLibs(moduleName)) {
678 std::string tempNativeLibraryPath = ObtainTempSoPath(moduleName, nativeLibraryPath_);
679 if (tempNativeLibraryPath.empty()) {
680 APP_LOGE("tempNativeLibraryPath is empty");
681 return ERR_APPEXECFWK_INSTALLD_EXTRACT_FILES_FAILED;
682 }
683 std::string tempSoPath = versionDir + ServiceConstants::PATH_SEPARATOR + tempNativeLibraryPath;
684 APP_LOGD("tempSoPath=%{public}s,cpuAbi=%{public}s, bundlePath=%{public}s",
685 tempSoPath.c_str(), cpuAbi.c_str(), bundlePath.c_str());
686 auto result = InstalldClient::GetInstance()->ExtractModuleFiles(bundlePath, moduleDir, tempSoPath, cpuAbi);
687 CHECK_RESULT(result, "extract module files failed %{public}d");
688 // verify hap or hsp code signature for compressed so files
689 result = VerifyCodeSignatureForNativeFiles(
690 bundlePath, cpuAbi, tempSoPath, signatureFileDir_, newInfo.IsPreInstallApp());
691 CHECK_RESULT(result, "fail to VerifyCodeSignature, error is %{public}d");
692 cpuAbi_ = cpuAbi;
693 tempSoPath_ = tempSoPath;
694 isPreInstalledBundle_ = newInfo.IsPreInstallApp();
695 } else {
696 std::vector<std::string> fileNames;
697 auto result = InstalldClient::GetInstance()->GetNativeLibraryFileNames(bundlePath, cpuAbi, fileNames);
698 CHECK_RESULT(result, "fail to GetNativeLibraryFileNames, error is %{public}d");
699 newInfo.SetNativeLibraryFileNames(moduleName, fileNames);
700 }
701 return ERR_OK;
702 }
703
VerifyCodeSignatureForNativeFiles(const std::string & bundlePath,const std::string & cpuAbi,const std::string & targetSoPath,const std::string & signatureFileDir,bool isPreInstalledBundle) const704 ErrCode InnerSharedBundleInstaller::VerifyCodeSignatureForNativeFiles(const std::string &bundlePath,
705 const std::string &cpuAbi, const std::string &targetSoPath, const std::string &signatureFileDir,
706 bool isPreInstalledBundle) const
707 {
708 if (!isPreInstalledBundle) {
709 APP_LOGD("not pre-install app, skip verify code signature for native files");
710 return ERR_OK;
711 }
712 APP_LOGD("begin to verify code signature for hsp native files");
713 bool isCompileSdkOpenHarmony = (compileSdkType_ == COMPILE_SDK_TYPE_OPEN_HARMONY);
714 CodeSignatureParam codeSignatureParam;
715 codeSignatureParam.modulePath = bundlePath;
716 codeSignatureParam.cpuAbi = cpuAbi;
717 codeSignatureParam.targetSoPath = targetSoPath;
718 codeSignatureParam.signatureFileDir = signatureFileDir;
719 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle_;
720 codeSignatureParam.appIdentifier = appIdentifier_;
721 codeSignatureParam.isCompileSdkOpenHarmony = isCompileSdkOpenHarmony;
722 codeSignatureParam.isPreInstalledBundle = isPreInstalledBundle;
723 return InstalldClient::GetInstance()->VerifyCodeSignature(codeSignatureParam);
724 }
725
VerifyCodeSignatureForHsp(const std::string & tempHspPath,const std::string & appIdentifier,bool isEnterpriseBundle,bool isCompileSdkOpenHarmony,const std::string & bundleName) const726 ErrCode InnerSharedBundleInstaller::VerifyCodeSignatureForHsp(const std::string &tempHspPath,
727 const std::string &appIdentifier, bool isEnterpriseBundle, bool isCompileSdkOpenHarmony,
728 const std::string &bundleName) const
729 {
730 APP_LOGD("begin to verify code signature for hsp");
731 CodeSignatureParam codeSignatureParam;
732 codeSignatureParam.modulePath = tempHspPath;
733 codeSignatureParam.cpuAbi = cpuAbi_;
734 codeSignatureParam.targetSoPath = tempSoPath_;
735 codeSignatureParam.appIdentifier = appIdentifier;
736 codeSignatureParam.signatureFileDir = signatureFileDir_;
737 codeSignatureParam.isEnterpriseBundle = isEnterpriseBundle;
738 codeSignatureParam.isCompileSdkOpenHarmony = isCompileSdkOpenHarmony;
739 codeSignatureParam.isPreInstalledBundle = isPreInstalledBundle_;
740 return InstalldClient::GetInstance()->VerifyCodeSignatureForHap(codeSignatureParam);
741 }
742
DeliveryProfileToCodeSign(std::vector<Security::Verify::HapVerifyResult> & hapVerifyResults) const743 ErrCode InnerSharedBundleInstaller::DeliveryProfileToCodeSign(
744 std::vector<Security::Verify::HapVerifyResult> &hapVerifyResults) const
745 {
746 if (isBundleExist_) {
747 APP_LOGD("shared bundle %{public}s has been installed and unnecessary to delivery sign profile",
748 bundleName_.c_str());
749 return ERR_OK;
750 }
751 if (hapVerifyResults.empty()) {
752 APP_LOGE("no sign info in the all haps");
753 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
754 }
755
756 Security::Verify::ProvisionInfo provisionInfo = hapVerifyResults[0].GetProvisionInfo();
757 if (provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE ||
758 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_NORMAL ||
759 provisionInfo.distributionType == Security::Verify::AppDistType::ENTERPRISE_MDM ||
760 provisionInfo.type == Security::Verify::ProvisionType::DEBUG) {
761 if (provisionInfo.profileBlockLength == 0 || provisionInfo.profileBlock == nullptr) {
762 APP_LOGE("invalid sign profile");
763 return ERR_APPEXECFWK_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE;
764 }
765 return InstalldClient::GetInstance()->DeliverySignProfile(provisionInfo.bundleInfo.bundleName,
766 provisionInfo.profileBlockLength, provisionInfo.profileBlock.get());
767 }
768 return ERR_OK;
769 }
770
SetCheckResultMsg(const std::string checkResultMsg) const771 void InnerSharedBundleInstaller::SetCheckResultMsg(const std::string checkResultMsg) const
772 {
773 bundleInstallChecker_->SetCheckResultMsg(checkResultMsg);
774 }
775
MarkInstallFinish()776 void InnerSharedBundleInstaller::MarkInstallFinish()
777 {
778 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
779 if (dataMgr == nullptr) {
780 APP_LOGE("Get dataMgr shared_ptr nullptr");
781 return;
782 }
783 InnerBundleInfo info;
784 if (!dataMgr->FetchInnerBundleInfo(bundleName_, info)) {
785 APP_LOGE("mark finish failed, -n %{public}s not exist", bundleName_.c_str());
786 return;
787 }
788 info.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
789 info.SetInstallMark(bundleName_, info.GetCurModuleName(), InstallExceptionStatus::INSTALL_FINISH);
790 if (!dataMgr->UpdateInnerBundleInfo(info, true)) {
791 APP_LOGE("save mark failed, -n %{public}s", bundleName_.c_str());
792 }
793 }
794 } // namespace AppExecFwk
795 } // namespace OHOS
796