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