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